xref: /aosp_15_r20/external/dagger2/javatests/dagger/internal/codegen/MultibindsValidationTest.java (revision f585d8a307d0621d6060bd7e80091fdcbf94fe27)
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 return type must be either a Set or Map type.");
58   }
59 
60   @Test
primitiveMethod()61   public void primitiveMethod() {
62     assertThatModuleMethod("@Multibinds abstract int primitive();")
63         .withDeclaration(moduleDeclaration)
64         .hasError("@Multibinds methods return type must be either a Set or Map type.");
65   }
66 
67   @Test
rawMap()68   public void rawMap() {
69     assertThatModuleMethod("@Multibinds abstract Map rawMap();")
70         .withDeclaration(moduleDeclaration)
71         .hasError("return type cannot be a raw Map type");
72   }
73 
74   @Test
wildcardMapValue()75   public void wildcardMapValue() {
76     assertThatModuleMethod("@Multibinds abstract Map<String, ?> wildcardMap();")
77         .withDeclaration(moduleDeclaration)
78         .hasError("return type cannot use a wildcard as the Map value type.");
79   }
80 
81   @Test
wildcardMapValueWithBounds()82   public void wildcardMapValueWithBounds() {
83     assertThatModuleMethod("@Multibinds abstract Map<String, ? extends Number> wildcardMap();")
84         .withDeclaration(moduleDeclaration)
85         .hasError("return type cannot use a wildcard as the Map value type.");
86   }
87 
88   @Test
wildcardMapKey()89   public void wildcardMapKey() {
90     assertThatModuleMethod("@Multibinds abstract Map<?, String> wildcardMap();")
91         .withDeclaration(moduleDeclaration)
92         .hasError("return type cannot use a wildcard as the Map key type.");
93   }
94 
95   @Test
wildcardMapKeyWithBounds()96   public void wildcardMapKeyWithBounds() {
97     assertThatModuleMethod("@Multibinds abstract Map<? extends Number, String> wildcardMap();")
98         .withDeclaration(moduleDeclaration)
99         .hasError("return type cannot use a wildcard as the Map key type.");
100   }
101 
102   @Test
providerMap()103   public void providerMap() {
104     assertThatModuleMethod("@Multibinds abstract Map<String, Provider<Object>> providerMap();")
105         .withDeclaration(moduleDeclaration)
106         .hasError("return type cannot use 'Provider' in the Map value type.");
107   }
108 
109   @Test
producerMap()110   public void producerMap() {
111     assertThatModuleMethod("@Multibinds abstract Map<String, Producer<Object>> producerMap();")
112         .withDeclaration(moduleDeclaration)
113         .hasError("return type cannot use 'Producer' in the Map value type.");
114   }
115 
116   @Test
producedMap()117   public void producedMap() {
118     assertThatModuleMethod("@Multibinds abstract Map<String, Produced<Object>> producedMap();")
119         .withDeclaration(moduleDeclaration)
120         .hasError("return type cannot use 'Produced' in the Map value type.");
121   }
122 
123   @Test
rawSet()124   public void rawSet() {
125     assertThatModuleMethod("@Multibinds abstract Set rawSet();")
126         .withDeclaration(moduleDeclaration)
127         .hasError("return type cannot be a raw Set type");
128   }
129 
130   @Test
wildcardSet()131   public void wildcardSet() {
132     assertThatModuleMethod("@Multibinds abstract Set<?> wildcardSet();")
133         .withDeclaration(moduleDeclaration)
134         .hasError("return type cannot use a wildcard as the Set value type.");
135   }
136 
137   @Test
wildcardSetWithBounds()138   public void wildcardSetWithBounds() {
139     assertThatModuleMethod("@Multibinds abstract Set<? extends Number> wildcardSet();")
140         .withDeclaration(moduleDeclaration)
141         .hasError("return type cannot use a wildcard as the Set value type.");
142   }
143 
144   @Test
providerSet()145   public void providerSet() {
146     assertThatModuleMethod("@Multibinds abstract Set<Provider<Object>> providerSet();")
147         .withDeclaration(moduleDeclaration)
148         .hasError("return type cannot use 'Provider' in the Set value type.");
149   }
150 
151   @Test
producerSet()152   public void producerSet() {
153     assertThatModuleMethod("@Multibinds abstract Set<Producer<Object>> producerSet();")
154         .withDeclaration(moduleDeclaration)
155         .hasError("return type cannot use 'Producer' in the Set value type.");
156   }
157 
158   @Test
producedSet()159   public void producedSet() {
160     assertThatModuleMethod("@Multibinds abstract Set<Produced<Object>> producedSet();")
161         .withDeclaration(moduleDeclaration)
162         .hasError("return type cannot use 'Produced' in the Set value type.");
163   }
164 
165   @Test
overqualifiedSet()166   public void overqualifiedSet() {
167     assertThatModuleMethod(
168             "@Multibinds @SomeQualifier @OtherQualifier "
169                 + "abstract Set<Object> tooManyQualifiersSet();")
170         .withDeclaration(moduleDeclaration)
171         .importing(SomeQualifier.class, OtherQualifier.class)
172         .hasError("may not use more than one @Qualifier");
173   }
174 
175   @Test
overqualifiedMap()176   public void overqualifiedMap() {
177     assertThatModuleMethod(
178             "@Multibinds @SomeQualifier @OtherQualifier "
179                 + "abstract Map<String, Object> tooManyQualifiersMap();")
180         .withDeclaration(moduleDeclaration)
181         .importing(SomeQualifier.class, OtherQualifier.class)
182         .hasError("may not use more than one @Qualifier");
183   }
184 
185   @Test
hasParameters()186   public void hasParameters() {
187     assertThatModuleMethod("@Multibinds abstract Set<String> parameters(Object param);")
188         .hasError("@Multibinds methods cannot have parameters");
189   }
190 
191   @Qualifier
192   public @interface SomeQualifier {}
193 
194   @Qualifier
195   public @interface OtherQualifier {}
196 }
197