1 /*
2  * Copyright (C) 2014 The Dagger Authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package dagger.internal.codegen;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 import static javax.lang.model.util.ElementFilter.methodsIn;
21 
22 import com.google.common.collect.ImmutableList;
23 import com.google.common.collect.Iterables;
24 import com.google.testing.compile.CompilationRule;
25 import dagger.BindsInstance;
26 import dagger.Component;
27 import dagger.Module;
28 import dagger.Provides;
29 import dagger.internal.codegen.MethodSignatureFormatterTest.OuterClass.InnerClass;
30 import dagger.internal.codegen.binding.InjectionAnnotations;
31 import dagger.internal.codegen.binding.MethodSignatureFormatter;
32 import dagger.internal.codegen.langmodel.DaggerElements;
33 import dagger.internal.codegen.langmodel.DaggerTypes;
34 import javax.inject.Inject;
35 import javax.inject.Singleton;
36 import javax.lang.model.element.ExecutableElement;
37 import javax.lang.model.element.TypeElement;
38 import org.junit.Before;
39 import org.junit.Rule;
40 import org.junit.Test;
41 import org.junit.runner.RunWith;
42 import org.junit.runners.JUnit4;
43 
44 @RunWith(JUnit4.class)
45 public class MethodSignatureFormatterTest {
46   @Rule public CompilationRule compilationRule = new CompilationRule();
47 
48   @Inject DaggerElements elements;
49   @Inject DaggerTypes types;
50   @Inject InjectionAnnotations injectionAnnotations;
51 
52   static class OuterClass {
53     @interface Foo {
bar()54        Class<?> bar();
55     }
56 
57     static class InnerClass {
58       @Foo(bar = String.class)
59       @Singleton
foo( @uppressWarnings"unused") int a, @SuppressWarnings("unused") ImmutableList<Boolean> blah)60       String foo(
61           @SuppressWarnings("unused") int a,
62           @SuppressWarnings("unused") ImmutableList<Boolean> blah) {
63         return "foo";
64       }
65     }
66   }
67 
68   @Before
setUp()69   public void setUp() {
70     DaggerMethodSignatureFormatterTest_TestComponent.factory().create(compilationRule).inject(this);
71   }
72 
methodSignatureTest()73   @Test public void methodSignatureTest() {
74     TypeElement inner = elements.getTypeElement(InnerClass.class);
75     ExecutableElement method = Iterables.getOnlyElement(methodsIn(inner.getEnclosedElements()));
76     String formatted = new MethodSignatureFormatter(types, injectionAnnotations).format(method);
77     // This is gross, but it turns out that annotation order is not guaranteed when getting
78     // all the AnnotationMirrors from an Element, so I have to test this chopped-up to make it
79     // less brittle.
80     assertThat(formatted).contains("@Singleton");
81     assertThat(formatted).doesNotContain("@javax.inject.Singleton"); // maybe more importantly
82     assertThat(formatted)
83         .contains("@dagger.internal.codegen.MethodSignatureFormatterTest.OuterClass.Foo"
84             + "(bar=String.class)");
85     assertThat(formatted).contains(" String "); // return type compressed
86     assertThat(formatted).contains("int, ImmutableList<Boolean>)"); // parameters compressed.
87   }
88 
89   @Singleton
90   @Component(modules = TestModule.class)
91   interface TestComponent {
inject(MethodSignatureFormatterTest test)92     void inject(MethodSignatureFormatterTest test);
93 
94     @Component.Factory
95     interface Factory {
create(@indsInstance CompilationRule compilationRule)96       TestComponent create(@BindsInstance CompilationRule compilationRule);
97     }
98   }
99 
100   @Module
101   static class TestModule {
102     @Provides
elements(CompilationRule compilationRule)103     static DaggerElements elements(CompilationRule compilationRule) {
104       return new DaggerElements(compilationRule.getElements(), compilationRule.getTypes());
105     }
106 
107     @Provides
types(CompilationRule compilationRule, DaggerElements elements)108     static DaggerTypes types(CompilationRule compilationRule, DaggerElements elements) {
109       return new DaggerTypes(compilationRule.getTypes(), elements);
110     }
111   }
112 }
113