| /* |
| * Copyright 2019 Google LLC |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package com.google.auto.common; |
| |
| import static com.google.common.collect.ImmutableList.toImmutableList; |
| import static com.google.common.truth.Truth.assertThat; |
| |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.truth.Correspondence; |
| import com.google.testing.compile.CompilationRule; |
| import javax.lang.model.element.AnnotationMirror; |
| import javax.lang.model.element.AnnotationValue; |
| import javax.lang.model.element.Element; |
| import javax.lang.model.element.Name; |
| import javax.lang.model.element.TypeElement; |
| import javax.lang.model.element.VariableElement; |
| import javax.lang.model.type.DeclaredType; |
| import javax.lang.model.type.TypeMirror; |
| import javax.lang.model.util.Elements; |
| import javax.lang.model.util.Types; |
| import org.junit.Before; |
| import org.junit.Rule; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.junit.runners.JUnit4; |
| |
| /** Tests {@link AnnotationValues}. */ |
| @RunWith(JUnit4.class) |
| public final class AnnotationValuesTest { |
| |
| private @interface InsideAnnotation { |
| int value(); |
| } |
| |
| private static class GenericClass<T> {} |
| |
| private static class InsideClassA {} |
| |
| private static class InsideClassB {} |
| |
| private @interface MultiValueAnnotation { |
| Class<InsideClassA> classValue(); |
| |
| Class<?>[] classValues(); |
| |
| Class<?> genericClassValue(); |
| |
| InsideAnnotation insideAnnotationValue(); |
| |
| InsideAnnotation[] insideAnnotationValues(); |
| |
| String stringValue(); |
| |
| String[] stringValues(); |
| |
| Foo enumValue(); |
| |
| Foo[] enumValues(); |
| |
| int intValue(); |
| |
| int[] intValues(); |
| |
| long longValue(); |
| |
| long[] longValues(); |
| |
| byte byteValue(); |
| |
| byte[] byteValues(); |
| |
| short shortValue(); |
| |
| short[] shortValues(); |
| |
| float floatValue(); |
| |
| float[] floatValues(); |
| |
| double doubleValue(); |
| |
| double[] doubleValues(); |
| |
| boolean booleanValue(); |
| |
| boolean[] booleanValues(); |
| |
| char charValue(); |
| |
| char[] charValues(); |
| } |
| |
| private enum Foo { |
| BAR, |
| BAZ, |
| BAH; |
| } |
| |
| @MultiValueAnnotation( |
| classValue = InsideClassA.class, |
| classValues = {InsideClassA.class, InsideClassB.class}, |
| genericClassValue = GenericClass.class, |
| insideAnnotationValue = @InsideAnnotation(19), |
| insideAnnotationValues = {@InsideAnnotation(20), @InsideAnnotation(21)}, |
| stringValue = "hello", |
| stringValues = {"it's", "me"}, |
| enumValue = Foo.BAR, |
| enumValues = {Foo.BAZ, Foo.BAH}, |
| intValue = 5, |
| intValues = {1, 2}, |
| longValue = 6L, |
| longValues = {3L, 4L}, |
| byteValue = (byte) 7, |
| byteValues = {(byte) 8, (byte) 9}, |
| shortValue = (short) 10, |
| shortValues = {(short) 11, (short) 12}, |
| floatValue = 13F, |
| floatValues = {14F, 15F}, |
| doubleValue = 16D, |
| doubleValues = {17D, 18D}, |
| booleanValue = true, |
| booleanValues = {true, false}, |
| charValue = 'a', |
| charValues = {'b', 'c'}) |
| private static class AnnotatedClass {} |
| |
| @Rule public final CompilationRule compilation = new CompilationRule(); |
| |
| private Elements elements; |
| private Types types; |
| private AnnotationMirror annotationMirror; |
| |
| @Before |
| public void setUp() { |
| elements = compilation.getElements(); |
| types = compilation.getTypes(); |
| TypeElement annotatedClass = getTypeElement(AnnotatedClass.class); |
| annotationMirror = |
| MoreElements.getAnnotationMirror(annotatedClass, MultiValueAnnotation.class).get(); |
| } |
| |
| @Test |
| public void getTypeMirror() { |
| TypeElement insideClassA = getTypeElement(InsideClassA.class); |
| AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "classValue"); |
| assertThat(AnnotationValues.getTypeMirror(value).asElement()).isEqualTo(insideClassA); |
| } |
| |
| @Test |
| public void getTypeMirrorGenericClass() { |
| TypeElement genericClass = getTypeElement(GenericClass.class); |
| AnnotationValue gvalue = |
| AnnotationMirrors.getAnnotationValue(annotationMirror, "genericClassValue"); |
| assertThat(AnnotationValues.getTypeMirror(gvalue).asElement()).isEqualTo(genericClass); |
| } |
| |
| @Test |
| public void getTypeMirrors() { |
| TypeMirror insideClassA = getTypeElement(InsideClassA.class).asType(); |
| TypeMirror insideClassB = getTypeElement(InsideClassB.class).asType(); |
| AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "classValues"); |
| ImmutableList<DeclaredType> valueElements = AnnotationValues.getTypeMirrors(value); |
| assertThat(valueElements) |
| .comparingElementsUsing(Correspondence.from(types::isSameType, "has Same Type")) |
| .containsExactly(insideClassA, insideClassB) |
| .inOrder(); |
| } |
| |
| @Test |
| public void getAnnotationMirror() { |
| TypeElement insideAnnotation = getTypeElement(InsideAnnotation.class); |
| AnnotationValue value = |
| AnnotationMirrors.getAnnotationValue(annotationMirror, "insideAnnotationValue"); |
| AnnotationMirror annotationMirror = AnnotationValues.getAnnotationMirror(value); |
| assertThat(annotationMirror.getAnnotationType().asElement()).isEqualTo(insideAnnotation); |
| assertThat(AnnotationMirrors.getAnnotationValue(annotationMirror, "value").getValue()) |
| .isEqualTo(19); |
| } |
| |
| @Test |
| public void getAnnotationMirrors() { |
| TypeElement insideAnnotation = getTypeElement(InsideAnnotation.class); |
| AnnotationValue value = |
| AnnotationMirrors.getAnnotationValue(annotationMirror, "insideAnnotationValues"); |
| ImmutableList<AnnotationMirror> annotationMirrors = |
| AnnotationValues.getAnnotationMirrors(value); |
| ImmutableList<Element> valueElements = |
| annotationMirrors.stream() |
| .map(AnnotationMirror::getAnnotationType) |
| .map(DeclaredType::asElement) |
| .collect(toImmutableList()); |
| assertThat(valueElements).containsExactly(insideAnnotation, insideAnnotation); |
| ImmutableList<Object> valuesStoredInAnnotation = |
| annotationMirrors.stream() |
| .map( |
| annotationMirror -> |
| AnnotationMirrors.getAnnotationValue(annotationMirror, "value").getValue()) |
| .collect(toImmutableList()); |
| assertThat(valuesStoredInAnnotation).containsExactly(20, 21).inOrder(); |
| } |
| |
| @Test |
| public void getString() { |
| AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "stringValue"); |
| assertThat(AnnotationValues.getString(value)).isEqualTo("hello"); |
| } |
| |
| @Test |
| public void getStrings() { |
| AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "stringValues"); |
| assertThat(AnnotationValues.getStrings(value)).containsExactly("it's", "me").inOrder(); |
| } |
| |
| @Test |
| public void getEnum() { |
| AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "enumValue"); |
| assertThat(AnnotationValues.getEnum(value)).isEqualTo(value.getValue()); |
| } |
| |
| @Test |
| public void getEnums() { |
| AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "enumValues"); |
| assertThat(getEnumNames(AnnotationValues.getEnums(value))) |
| .containsExactly(Foo.BAZ.name(), Foo.BAH.name()) |
| .inOrder(); |
| } |
| |
| @Test |
| public void getAnnotationValues() { |
| AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "intValues"); |
| ImmutableList<AnnotationValue> values = AnnotationValues.getAnnotationValues(value); |
| assertThat(values) |
| .comparingElementsUsing(Correspondence.transforming(AnnotationValue::getValue, "has value")) |
| .containsExactly(1, 2) |
| .inOrder(); |
| } |
| |
| @Test |
| public void getInt() { |
| AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "intValue"); |
| assertThat(AnnotationValues.getInt(value)).isEqualTo(5); |
| } |
| |
| @Test |
| public void getInts() { |
| AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "intValues"); |
| assertThat(AnnotationValues.getInts(value)).containsExactly(1, 2).inOrder(); |
| } |
| |
| @Test |
| public void getLong() { |
| AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "longValue"); |
| assertThat(AnnotationValues.getLong(value)).isEqualTo(6L); |
| } |
| |
| @Test |
| public void getLongs() { |
| AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "longValues"); |
| assertThat(AnnotationValues.getLongs(value)).containsExactly(3L, 4L).inOrder(); |
| } |
| |
| @Test |
| public void getByte() { |
| AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "byteValue"); |
| assertThat(AnnotationValues.getByte(value)).isEqualTo((byte) 7); |
| } |
| |
| @Test |
| public void getBytes() { |
| AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "byteValues"); |
| assertThat(AnnotationValues.getBytes(value)).containsExactly((byte) 8, (byte) 9).inOrder(); |
| } |
| |
| @Test |
| public void getShort() { |
| AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "shortValue"); |
| assertThat(AnnotationValues.getShort(value)).isEqualTo((short) 10); |
| } |
| |
| @Test |
| public void getShorts() { |
| AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "shortValues"); |
| assertThat(AnnotationValues.getShorts(value)).containsExactly((short) 11, (short) 12).inOrder(); |
| } |
| |
| @Test |
| public void getFloat() { |
| AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "floatValue"); |
| assertThat(AnnotationValues.getFloat(value)).isEqualTo(13F); |
| } |
| |
| @Test |
| public void getFloats() { |
| AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "floatValues"); |
| assertThat(AnnotationValues.getFloats(value)).containsExactly(14F, 15F).inOrder(); |
| } |
| |
| @Test |
| public void getDouble() { |
| AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "doubleValue"); |
| assertThat(AnnotationValues.getDouble(value)).isEqualTo(16D); |
| } |
| |
| @Test |
| public void getDoubles() { |
| AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "doubleValues"); |
| assertThat(AnnotationValues.getDoubles(value)).containsExactly(17D, 18D).inOrder(); |
| } |
| |
| @Test |
| public void getBoolean() { |
| AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "booleanValue"); |
| assertThat(AnnotationValues.getBoolean(value)).isTrue(); |
| } |
| |
| @Test |
| public void getBooleans() { |
| AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "booleanValues"); |
| assertThat(AnnotationValues.getBooleans(value)).containsExactly(true, false).inOrder(); |
| } |
| |
| @Test |
| public void getChar() { |
| AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "charValue"); |
| assertThat(AnnotationValues.getChar(value)).isEqualTo('a'); |
| } |
| |
| @Test |
| public void getChars() { |
| AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "charValues"); |
| assertThat(AnnotationValues.getChars(value)).containsExactly('b', 'c').inOrder(); |
| } |
| |
| private TypeElement getTypeElement(Class<?> clazz) { |
| return elements.getTypeElement(clazz.getCanonicalName()); |
| } |
| |
| private static ImmutableList<String> getEnumNames(ImmutableList<VariableElement> values) { |
| return values.stream() |
| .map(VariableElement::getSimpleName) |
| .map(Name::toString) |
| .collect(toImmutableList()); |
| } |
| } |