diff options
author | Adrian Roos <roosa@google.com> | 2020-03-30 11:55:20 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-03-30 11:55:20 +0000 |
commit | 93fbec92595e2bc9b6a3e593a04aa73b53ddea73 (patch) | |
tree | 8107af79f333219cf2f043078e4e733974edc19c /javatests/com/google/turbine/processing/TurbineAnnotationProxyTest.java | |
parent | 61aa957f55fb065224ea3695460b4fc047945037 (diff) | |
parent | 0d6829d18aedcaf5dd02b6c5f51d721e2e01791f (diff) | |
download | turbine-93fbec92595e2bc9b6a3e593a04aa73b53ddea73.tar.gz |
Merge upstream into AOSP am: b3b9a496c8 am: 0d6829d18a
Change-Id: I1e12da2f674663fd498d62d653ceb4735130a082
Diffstat (limited to 'javatests/com/google/turbine/processing/TurbineAnnotationProxyTest.java')
-rw-r--r-- | javatests/com/google/turbine/processing/TurbineAnnotationProxyTest.java | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/javatests/com/google/turbine/processing/TurbineAnnotationProxyTest.java b/javatests/com/google/turbine/processing/TurbineAnnotationProxyTest.java new file mode 100644 index 0000000..d339700 --- /dev/null +++ b/javatests/com/google/turbine/processing/TurbineAnnotationProxyTest.java @@ -0,0 +1,219 @@ +/* + * Copyright 2019 Google Inc. All Rights Reserved. + * + * 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.turbine.processing; + +import static com.google.common.collect.ImmutableList.toImmutableList; +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.fail; + +import com.google.common.base.Joiner; +import com.google.common.collect.ImmutableList; +import com.google.common.io.ByteStreams; +import com.google.common.primitives.Ints; +import com.google.common.testing.EqualsTester; +import com.google.turbine.binder.Binder; +import com.google.turbine.binder.ClassPathBinder; +import com.google.turbine.binder.bound.TypeBoundClass; +import com.google.turbine.binder.env.CompoundEnv; +import com.google.turbine.binder.env.Env; +import com.google.turbine.binder.env.SimpleEnv; +import com.google.turbine.binder.sym.ClassSymbol; +import com.google.turbine.diag.SourceFile; +import com.google.turbine.lower.IntegrationTestSupport.TestInput; +import com.google.turbine.parse.Parser; +import com.google.turbine.processing.TurbineElement.TurbineTypeElement; +import com.google.turbine.testing.TestClassPaths; +import com.google.turbine.tree.Tree.CompUnit; +import java.io.IOException; +import java.io.InputStream; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Optional; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; +import javax.lang.model.element.TypeElement; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.MirroredTypeException; +import javax.lang.model.type.MirroredTypesException; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class TurbineAnnotationProxyTest { + + @Rule public final TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Retention(RetentionPolicy.RUNTIME) + public @interface A { + B b() default @B(-1); + + ElementType e() default ElementType.PACKAGE; + + int[] xs() default {}; + + Class<?> c() default String.class; + + Class<?>[] cx() default {}; + } + + @Retention(RetentionPolicy.RUNTIME) + @Inherited + public @interface B { + int value(); + } + + @Retention(RetentionPolicy.RUNTIME) + public @interface C {} + + @Retention(RetentionPolicy.RUNTIME) + public @interface RS { + R[] value() default {}; + } + + @Repeatable(RS.class) + @Retention(RetentionPolicy.RUNTIME) + public @interface R { + int value() default 1; + } + + @A + static class I {} + + @Test + public void test() throws IOException { + + Path lib = temporaryFolder.newFile("lib.jar").toPath(); + try (JarOutputStream jos = new JarOutputStream(Files.newOutputStream(lib))) { + addClass(jos, TurbineAnnotationProxyTest.class); + addClass(jos, A.class); + addClass(jos, B.class); + addClass(jos, C.class); + addClass(jos, R.class); + } + + TestInput input = + TestInput.parse( + Joiner.on('\n') + .join( + "=== Super.java ===", + "import " + B.class.getCanonicalName() + ";", + "import " + C.class.getCanonicalName() + ";", + "@B(42)", + "@C", + "class Super {}", + "=== Test.java ===", + "import " + A.class.getCanonicalName() + ";", + "import " + R.class.getCanonicalName() + ";", + "@A(xs = {1,2,3}, cx = {Integer.class, Long.class})", + "@R(1)", + "@R(2)", + "@R(3)", + "class Test extends Super {}", + "")); + + ImmutableList<CompUnit> units = + input.sources.entrySet().stream() + .map(e -> new SourceFile(e.getKey(), e.getValue())) + .map(Parser::parse) + .collect(toImmutableList()); + + Binder.BindingResult bound = + Binder.bind( + units, + ClassPathBinder.bindClasspath(ImmutableList.of(lib)), + TestClassPaths.TURBINE_BOOTCLASSPATH, + Optional.empty()); + + Env<ClassSymbol, TypeBoundClass> env = + CompoundEnv.<ClassSymbol, TypeBoundClass>of(bound.classPathEnv()) + .append(new SimpleEnv<>(bound.units())); + ModelFactory factory = new ModelFactory(env, ClassLoader.getSystemClassLoader(), bound.tli()); + TurbineTypeElement te = factory.typeElement(new ClassSymbol("Test")); + + A a = te.getAnnotation(A.class); + B b = te.getAnnotation(B.class); + assertThat(te.getAnnotation(C.class)).isNull(); + + assertThat(a.b().value()).isEqualTo(-1); + assertThat(a.e()).isEqualTo(ElementType.PACKAGE); + try { + a.c(); + fail(); + } catch (MirroredTypeException e) { + assertThat(e.getTypeMirror().getKind()).isEqualTo(TypeKind.DECLARED); + assertThat(getQualifiedName(e.getTypeMirror())).contains("java.lang.String"); + } + try { + a.cx(); + fail(); + } catch (MirroredTypesException e) { + assertThat( + e.getTypeMirrors().stream().map(m -> getQualifiedName(m)).collect(toImmutableList())) + .containsExactly("java.lang.Integer", "java.lang.Long"); + } + assertThat(Ints.asList(a.xs())).containsExactly(1, 2, 3).inOrder(); + assertThat(a.annotationType()).isEqualTo(A.class); + + assertThat(b.value()).isEqualTo(42); + + RS container = te.getAnnotation(RS.class); + assertThat(container.value()).hasLength(3); + R[] rs = te.getAnnotationsByType(R.class); + assertThat(rs).hasLength(3); + assertThat(Arrays.toString(rs)) + .isEqualTo( + String.format( + "[@%s(1), @%s(2), @%s(3)]", + R.class.getCanonicalName(), + R.class.getCanonicalName(), + R.class.getCanonicalName())); + + new EqualsTester() + .addEqualityGroup(a, te.getAnnotation(A.class)) + .addEqualityGroup(b, te.getAnnotation(B.class)) + .addEqualityGroup(rs[0]) + .addEqualityGroup(rs[1]) + .addEqualityGroup(rs[2]) + .addEqualityGroup(container) + .addEqualityGroup(I.class.getAnnotation(A.class)) + .addEqualityGroup("unrelated") + .testEquals(); + } + + private static void addClass(JarOutputStream jos, Class<?> clazz) throws IOException { + String entryPath = clazz.getName().replace('.', '/') + ".class"; + jos.putNextEntry(new JarEntry(entryPath)); + try (InputStream is = clazz.getClassLoader().getResourceAsStream(entryPath)) { + ByteStreams.copy(is, jos); + } + } + + private static String getQualifiedName(TypeMirror typeMirror) { + return ((TypeElement) ((DeclaredType) typeMirror).asElement()).getQualifiedName().toString(); + } +} |