• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 dagger.internal.codegen.DaggerModuleMethodSubject.Factory.assertThatMethodInUnannotatedClass;
20 import static dagger.internal.codegen.DaggerModuleMethodSubject.Factory.assertThatModuleMethod;
21 
22 import com.google.common.collect.ImmutableList;
23 import dagger.Module;
24 import dagger.producers.ProducerModule;
25 import java.lang.annotation.Annotation;
26 import java.util.Collection;
27 import javax.inject.Qualifier;
28 import org.junit.Test;
29 import org.junit.runner.RunWith;
30 import org.junit.runners.Parameterized;
31 import org.junit.runners.Parameterized.Parameters;
32 
33 @RunWith(Parameterized.class)
34 public class MultibindsValidationTest {
35 
36   @Parameters(name = "{0}")
parameters()37   public static Collection<Object[]> parameters() {
38     return ImmutableList.copyOf(new Object[][] {{Module.class}, {ProducerModule.class}});
39   }
40 
41   private final String moduleDeclaration;
42 
MultibindsValidationTest(Class<? extends Annotation> moduleAnnotation)43   public MultibindsValidationTest(Class<? extends Annotation> moduleAnnotation) {
44     moduleDeclaration = "@" + moduleAnnotation.getCanonicalName() + " abstract class %s { %s }";
45   }
46 
47   @Test
notWithinModule()48   public void notWithinModule() {
49     assertThatMethodInUnannotatedClass("@Multibinds abstract Set<Object> emptySet();")
50         .hasError("@Multibinds methods can only be present within a @Module or @ProducerModule");
51   }
52 
53   @Test
voidMethod()54   public void voidMethod() {
55     assertThatModuleMethod("@Multibinds abstract void voidMethod();")
56         .withDeclaration(moduleDeclaration)
57         .hasError("@Multibinds methods must return Map<K, V> or Set<T>");
58   }
59 
60   @Test
primitiveMethod()61   public void primitiveMethod() {
62     assertThatModuleMethod("@Multibinds abstract int primitive();")
63         .withDeclaration(moduleDeclaration)
64         .hasError("@Multibinds methods must return Map<K, V> or Set<T>");
65   }
66 
67   @Test
rawMap()68   public void rawMap() {
69     assertThatModuleMethod("@Multibinds abstract Map rawMap();")
70         .withDeclaration(moduleDeclaration)
71         .hasError("@Multibinds methods must return Map<K, V> or Set<T>");
72   }
73 
74   @Test
wildcardMap()75   public void wildcardMap() {
76     assertThatModuleMethod("@Multibinds abstract Map<?, ?> wildcardMap();")
77         .withDeclaration(moduleDeclaration)
78         .hasError("@Multibinds methods must return Map<K, V> or Set<T>");
79   }
80 
81   @Test
providerMap()82   public void providerMap() {
83     assertThatModuleMethod("@Multibinds abstract Map<String, Provider<Object>> providerMap();")
84         .withDeclaration(moduleDeclaration)
85         .hasError("@Multibinds methods must return Map<K, V> or Set<T>");
86   }
87 
88   @Test
producerMap()89   public void producerMap() {
90     assertThatModuleMethod("@Multibinds abstract Map<String, Producer<Object>> producerMap();")
91         .withDeclaration(moduleDeclaration)
92         .hasError("@Multibinds methods must return Map<K, V> or Set<T>");
93   }
94 
95   @Test
producedMap()96   public void producedMap() {
97     assertThatModuleMethod("@Multibinds abstract Map<String, Produced<Object>> producedMap();")
98         .withDeclaration(moduleDeclaration)
99         .hasError("@Multibinds methods must return Map<K, V> or Set<T>");
100   }
101 
102   @Test
rawSet()103   public void rawSet() {
104     assertThatModuleMethod("@Multibinds abstract Set rawSet();")
105         .withDeclaration(moduleDeclaration)
106         .hasError("@Multibinds methods must return Map<K, V> or Set<T>");
107   }
108 
109   @Test
wildcardSet()110   public void wildcardSet() {
111     assertThatModuleMethod("@Multibinds abstract Set<?> wildcardSet();")
112         .withDeclaration(moduleDeclaration)
113         .hasError("@Multibinds methods must return Map<K, V> or Set<T>");
114   }
115 
116   @Test
providerSet()117   public void providerSet() {
118     assertThatModuleMethod("@Multibinds abstract Set<Provider<Object>> providerSet();")
119         .withDeclaration(moduleDeclaration)
120         .hasError("@Multibinds methods must return Map<K, V> or Set<T>");
121   }
122 
123   @Test
producerSet()124   public void producerSet() {
125     assertThatModuleMethod("@Multibinds abstract Set<Producer<Object>> producerSet();")
126         .withDeclaration(moduleDeclaration)
127         .hasError("@Multibinds methods must return Map<K, V> or Set<T>");
128   }
129 
130   @Test
producedSet()131   public void producedSet() {
132     assertThatModuleMethod("@Multibinds abstract Set<Produced<Object>> producedSet();")
133         .withDeclaration(moduleDeclaration)
134         .hasError("@Multibinds methods must return Map<K, V> or Set<T>");
135   }
136 
137   @Test
overqualifiedSet()138   public void overqualifiedSet() {
139     assertThatModuleMethod(
140             "@Multibinds @SomeQualifier @OtherQualifier "
141                 + "abstract Set<Object> tooManyQualifiersSet();")
142         .withDeclaration(moduleDeclaration)
143         .importing(SomeQualifier.class, OtherQualifier.class)
144         .hasError("may not use more than one @Qualifier");
145   }
146 
147   @Test
overqualifiedMap()148   public void overqualifiedMap() {
149     assertThatModuleMethod(
150             "@Multibinds @SomeQualifier @OtherQualifier "
151                 + "abstract Map<String, Object> tooManyQualifiersMap();")
152         .withDeclaration(moduleDeclaration)
153         .importing(SomeQualifier.class, OtherQualifier.class)
154         .hasError("may not use more than one @Qualifier");
155   }
156 
157   @Test
hasParameters()158   public void hasParameters() {
159     assertThatModuleMethod("@Multibinds abstract Set<String> parameters(Object param);")
160         .hasError("@Multibinds methods cannot have parameters");
161   }
162 
163   @Qualifier
164   public @interface SomeQualifier {}
165 
166   @Qualifier
167   public @interface OtherQualifier {}
168 }
169