• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 Google LLC
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 package com.google.auto.common;
17 
18 import static com.google.common.collect.ImmutableList.toImmutableList;
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import com.google.common.collect.ImmutableList;
22 import com.google.common.truth.Correspondence;
23 import com.google.testing.compile.CompilationRule;
24 import javax.lang.model.element.AnnotationMirror;
25 import javax.lang.model.element.AnnotationValue;
26 import javax.lang.model.element.Element;
27 import javax.lang.model.element.Name;
28 import javax.lang.model.element.TypeElement;
29 import javax.lang.model.element.VariableElement;
30 import javax.lang.model.type.DeclaredType;
31 import javax.lang.model.type.TypeMirror;
32 import javax.lang.model.util.Elements;
33 import javax.lang.model.util.Types;
34 import org.junit.Before;
35 import org.junit.Rule;
36 import org.junit.Test;
37 import org.junit.runner.RunWith;
38 import org.junit.runners.JUnit4;
39 
40 /** Tests {@link AnnotationValues}. */
41 @RunWith(JUnit4.class)
42 public final class AnnotationValuesTest {
43 
44   private @interface InsideAnnotation {
value()45     int value();
46   }
47 
48   private static class GenericClass<T> {}
49 
50   private static class InsideClassA {}
51 
52   private static class InsideClassB {}
53 
54   private @interface MultiValueAnnotation {
classValue()55     Class<InsideClassA> classValue();
56 
classValues()57     Class<?>[] classValues();
58 
genericClassValue()59     Class<?> genericClassValue();
60 
insideAnnotationValue()61     InsideAnnotation insideAnnotationValue();
62 
insideAnnotationValues()63     InsideAnnotation[] insideAnnotationValues();
64 
stringValue()65     String stringValue();
66 
stringValues()67     String[] stringValues();
68 
enumValue()69     Foo enumValue();
70 
enumValues()71     Foo[] enumValues();
72 
intValue()73     int intValue();
74 
intValues()75     int[] intValues();
76 
longValue()77     long longValue();
78 
longValues()79     long[] longValues();
80 
byteValue()81     byte byteValue();
82 
byteValues()83     byte[] byteValues();
84 
shortValue()85     short shortValue();
86 
shortValues()87     short[] shortValues();
88 
floatValue()89     float floatValue();
90 
floatValues()91     float[] floatValues();
92 
doubleValue()93     double doubleValue();
94 
doubleValues()95     double[] doubleValues();
96 
booleanValue()97     boolean booleanValue();
98 
booleanValues()99     boolean[] booleanValues();
100 
charValue()101     char charValue();
102 
charValues()103     char[] charValues();
104   }
105 
106   private enum Foo {
107     BAR,
108     BAZ,
109     BAH;
110   }
111 
112   @MultiValueAnnotation(
113       classValue = InsideClassA.class,
114       classValues = {InsideClassA.class, InsideClassB.class},
115       genericClassValue = GenericClass.class,
116       insideAnnotationValue = @InsideAnnotation(19),
117       insideAnnotationValues = {@InsideAnnotation(20), @InsideAnnotation(21)},
118       stringValue = "hello",
119       stringValues = {"it's", "me"},
120       enumValue = Foo.BAR,
121       enumValues = {Foo.BAZ, Foo.BAH},
122       intValue = 5,
123       intValues = {1, 2},
124       longValue = 6L,
125       longValues = {3L, 4L},
126       byteValue = (byte) 7,
127       byteValues = {(byte) 8, (byte) 9},
128       shortValue = (short) 10,
129       shortValues = {(short) 11, (short) 12},
130       floatValue = 13F,
131       floatValues = {14F, 15F},
132       doubleValue = 16D,
133       doubleValues = {17D, 18D},
134       booleanValue = true,
135       booleanValues = {true, false},
136       charValue = 'a',
137       charValues = {'b', 'c'})
138   private static class AnnotatedClass {}
139 
140   @Rule public final CompilationRule compilation = new CompilationRule();
141 
142   private Elements elements;
143   private Types types;
144   private AnnotationMirror annotationMirror;
145 
146   @Before
setUp()147   public void setUp() {
148     elements = compilation.getElements();
149     types = compilation.getTypes();
150     TypeElement annotatedClass = getTypeElement(AnnotatedClass.class);
151     annotationMirror =
152         MoreElements.getAnnotationMirror(annotatedClass, MultiValueAnnotation.class).get();
153   }
154 
155   @Test
getTypeMirror()156   public void getTypeMirror() {
157     TypeElement insideClassA = getTypeElement(InsideClassA.class);
158     AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "classValue");
159     assertThat(AnnotationValues.getTypeMirror(value).asElement()).isEqualTo(insideClassA);
160   }
161 
162   @Test
getTypeMirrorGenericClass()163   public void getTypeMirrorGenericClass() {
164     TypeElement genericClass = getTypeElement(GenericClass.class);
165     AnnotationValue gvalue =
166         AnnotationMirrors.getAnnotationValue(annotationMirror, "genericClassValue");
167     assertThat(AnnotationValues.getTypeMirror(gvalue).asElement()).isEqualTo(genericClass);
168   }
169 
170   @Test
getTypeMirrors()171   public void getTypeMirrors() {
172     TypeMirror insideClassA = getTypeElement(InsideClassA.class).asType();
173     TypeMirror insideClassB = getTypeElement(InsideClassB.class).asType();
174     AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "classValues");
175     ImmutableList<DeclaredType> valueElements = AnnotationValues.getTypeMirrors(value);
176     assertThat(valueElements)
177         .comparingElementsUsing(Correspondence.from(types::isSameType, "has Same Type"))
178         .containsExactly(insideClassA, insideClassB)
179         .inOrder();
180   }
181 
182   @Test
getAnnotationMirror()183   public void getAnnotationMirror() {
184     TypeElement insideAnnotation = getTypeElement(InsideAnnotation.class);
185     AnnotationValue value =
186         AnnotationMirrors.getAnnotationValue(annotationMirror, "insideAnnotationValue");
187     AnnotationMirror annotationMirror = AnnotationValues.getAnnotationMirror(value);
188     assertThat(annotationMirror.getAnnotationType().asElement()).isEqualTo(insideAnnotation);
189     assertThat(AnnotationMirrors.getAnnotationValue(annotationMirror, "value").getValue())
190         .isEqualTo(19);
191   }
192 
193   @Test
getAnnotationMirrors()194   public void getAnnotationMirrors() {
195     TypeElement insideAnnotation = getTypeElement(InsideAnnotation.class);
196     AnnotationValue value =
197         AnnotationMirrors.getAnnotationValue(annotationMirror, "insideAnnotationValues");
198     ImmutableList<AnnotationMirror> annotationMirrors =
199         AnnotationValues.getAnnotationMirrors(value);
200     ImmutableList<Element> valueElements =
201         annotationMirrors.stream()
202             .map(AnnotationMirror::getAnnotationType)
203             .map(DeclaredType::asElement)
204             .collect(toImmutableList());
205     assertThat(valueElements).containsExactly(insideAnnotation, insideAnnotation);
206     ImmutableList<Object> valuesStoredInAnnotation =
207         annotationMirrors.stream()
208             .map(
209                 annotationMirror ->
210                     AnnotationMirrors.getAnnotationValue(annotationMirror, "value").getValue())
211             .collect(toImmutableList());
212     assertThat(valuesStoredInAnnotation).containsExactly(20, 21).inOrder();
213   }
214 
215   @Test
getString()216   public void getString() {
217     AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "stringValue");
218     assertThat(AnnotationValues.getString(value)).isEqualTo("hello");
219   }
220 
221   @Test
getStrings()222   public void getStrings() {
223     AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "stringValues");
224     assertThat(AnnotationValues.getStrings(value)).containsExactly("it's", "me").inOrder();
225   }
226 
227   @Test
getEnum()228   public void getEnum() {
229     AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "enumValue");
230     assertThat(AnnotationValues.getEnum(value)).isEqualTo(value.getValue());
231   }
232 
233   @Test
getEnums()234   public void getEnums() {
235     AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "enumValues");
236     assertThat(getEnumNames(AnnotationValues.getEnums(value)))
237         .containsExactly(Foo.BAZ.name(), Foo.BAH.name())
238         .inOrder();
239   }
240 
241   @Test
getAnnotationValues()242   public void getAnnotationValues() {
243     AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "intValues");
244     ImmutableList<AnnotationValue> values = AnnotationValues.getAnnotationValues(value);
245     assertThat(values)
246         .comparingElementsUsing(Correspondence.transforming(AnnotationValue::getValue, "has value"))
247         .containsExactly(1, 2)
248         .inOrder();
249   }
250 
251   @Test
getInt()252   public void getInt() {
253     AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "intValue");
254     assertThat(AnnotationValues.getInt(value)).isEqualTo(5);
255   }
256 
257   @Test
getInts()258   public void getInts() {
259     AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "intValues");
260     assertThat(AnnotationValues.getInts(value)).containsExactly(1, 2).inOrder();
261   }
262 
263   @Test
getLong()264   public void getLong() {
265     AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "longValue");
266     assertThat(AnnotationValues.getLong(value)).isEqualTo(6L);
267   }
268 
269   @Test
getLongs()270   public void getLongs() {
271     AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "longValues");
272     assertThat(AnnotationValues.getLongs(value)).containsExactly(3L, 4L).inOrder();
273   }
274 
275   @Test
getByte()276   public void getByte() {
277     AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "byteValue");
278     assertThat(AnnotationValues.getByte(value)).isEqualTo((byte) 7);
279   }
280 
281   @Test
getBytes()282   public void getBytes() {
283     AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "byteValues");
284     assertThat(AnnotationValues.getBytes(value)).containsExactly((byte) 8, (byte) 9).inOrder();
285   }
286 
287   @Test
getShort()288   public void getShort() {
289     AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "shortValue");
290     assertThat(AnnotationValues.getShort(value)).isEqualTo((short) 10);
291   }
292 
293   @Test
getShorts()294   public void getShorts() {
295     AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "shortValues");
296     assertThat(AnnotationValues.getShorts(value)).containsExactly((short) 11, (short) 12).inOrder();
297   }
298 
299   @Test
getFloat()300   public void getFloat() {
301     AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "floatValue");
302     assertThat(AnnotationValues.getFloat(value)).isEqualTo(13F);
303   }
304 
305   @Test
getFloats()306   public void getFloats() {
307     AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "floatValues");
308     assertThat(AnnotationValues.getFloats(value)).containsExactly(14F, 15F).inOrder();
309   }
310 
311   @Test
getDouble()312   public void getDouble() {
313     AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "doubleValue");
314     assertThat(AnnotationValues.getDouble(value)).isEqualTo(16D);
315   }
316 
317   @Test
getDoubles()318   public void getDoubles() {
319     AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "doubleValues");
320     assertThat(AnnotationValues.getDoubles(value)).containsExactly(17D, 18D).inOrder();
321   }
322 
323   @Test
getBoolean()324   public void getBoolean() {
325     AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "booleanValue");
326     assertThat(AnnotationValues.getBoolean(value)).isTrue();
327   }
328 
329   @Test
getBooleans()330   public void getBooleans() {
331     AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "booleanValues");
332     assertThat(AnnotationValues.getBooleans(value)).containsExactly(true, false).inOrder();
333   }
334 
335   @Test
getChar()336   public void getChar() {
337     AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "charValue");
338     assertThat(AnnotationValues.getChar(value)).isEqualTo('a');
339   }
340 
341   @Test
getChars()342   public void getChars() {
343     AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "charValues");
344     assertThat(AnnotationValues.getChars(value)).containsExactly('b', 'c').inOrder();
345   }
346 
getTypeElement(Class<?> clazz)347   private TypeElement getTypeElement(Class<?> clazz) {
348     return elements.getTypeElement(clazz.getCanonicalName());
349   }
350 
getEnumNames(ImmutableList<VariableElement> values)351   private static ImmutableList<String> getEnumNames(ImmutableList<VariableElement> values) {
352     return values.stream()
353         .map(VariableElement::getSimpleName)
354         .map(Name::toString)
355         .collect(toImmutableList());
356   }
357 }
358