Make separate test targets for the AutoValue functional tests, rather than using globs. This also revealed that the functional tests for AutoAnnotation weren't being released to open source because of a faulty glob exclusion.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=141655009
diff --git a/value/src/it/functional/pom.xml b/value/src/it/functional/pom.xml
index 2d765d6..47ca447 100644
--- a/value/src/it/functional/pom.xml
+++ b/value/src/it/functional/pom.xml
@@ -72,7 +72,11 @@
<configuration>
<source>1.6</source>
<target>1.6</target>
- <compilerArgument>-Xlint:all</compilerArgument>
+ <compilerArgs>
+ <arg>-Xlint:all</arg>
+ <arg>-encoding</arg>
+ <arg>utf8</arg>
+ </compilerArgs>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
@@ -95,6 +99,8 @@
<compilerArgs>
<arg>-Xlint:all</arg>
<arg>-Acom.google.auto.value.EclipseHackTest=1</arg>
+ <arg>-encoding</arg>
+ <arg>utf8</arg>
</compilerArgs>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
diff --git a/value/src/it/functional/src/test/java/com/google/auto/value/AutoAnnotationDefaultsTest.java b/value/src/it/functional/src/test/java/com/google/auto/value/AutoAnnotationDefaultsTest.java
new file mode 100644
index 0000000..5fd64a3
--- /dev/null
+++ b/value/src/it/functional/src/test/java/com/google/auto/value/AutoAnnotationDefaultsTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2014 Google Inc.
+ *
+ * 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.value;
+
+import com.google.auto.value.enums.MyEnum;
+import com.google.common.testing.EqualsTester;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import junit.framework.TestCase;
+
+/**
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+public class AutoAnnotationDefaultsTest extends TestCase {
+ @Retention(RetentionPolicy.RUNTIME)
+ @interface EverythingWithDefaults {
+ byte aByte() default 1;
+ short aShort() default 2;
+ int anInt() default 3;
+ long aLong() default Long.MAX_VALUE;
+ float aFloat() default Float.MAX_VALUE;
+ double aDouble() default -Double.MAX_VALUE;
+ char aChar() default '#';
+ boolean aBoolean() default true;
+ String aString() default "maybe\nmaybe not\n";
+ String spaces() default " ( x ) , ( y )"; // ensure the formatter doesn't eat spaces
+ MyEnum anEnum() default MyEnum.TWO;
+ byte[] bytes() default {-1, 0, 1};
+ short[] shorts() default {-2, 0, 2};
+ int[] ints() default {};
+ long[] longs() default {-Long.MAX_VALUE};
+ float[] floats() default {
+ -Float.MIN_VALUE, Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY, Float.NaN,
+ };
+ double[] doubles() default {
+ -Double.MIN_VALUE, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.NaN,
+ };
+ char[] chars() default {'f', '\n', '\uffef'};
+ boolean[] booleans() default {false, true};
+ String[] strings() default {"", "\uffef\n"};
+ MyEnum[] enums() default {MyEnum.ONE, MyEnum.TWO};
+ }
+
+ @AutoAnnotation static EverythingWithDefaults newEverythingWithDefaults() {
+ return new AutoAnnotation_AutoAnnotationDefaultsTest_newEverythingWithDefaults();
+ }
+
+ public void testDefaults() throws Exception {
+ @EverythingWithDefaults class Annotated {}
+ EverythingWithDefaults expected = Annotated.class.getAnnotation(EverythingWithDefaults.class);
+ EverythingWithDefaults actual = newEverythingWithDefaults();
+
+ // Iterate over the annotation members to see if any differ. We could just compare expected and
+ // actual but if the comparison failed it could be hard to see exactly what differed.
+ StringBuilder differencesBuilder = new StringBuilder();
+ for (Method member : EverythingWithDefaults.class.getDeclaredMethods()) {
+ String name = member.getName();
+ Object expectedValue = member.invoke(expected);
+ Object actualValue = member.invoke(actual);
+ if (!equal(expectedValue, actualValue)) {
+ differencesBuilder.append("For ").append(name)
+ .append(" expected <").append(string(expectedValue))
+ .append("> but was <").append(string(actualValue)).append(">\n");
+ }
+ }
+ String differences = differencesBuilder.toString();
+ assertTrue(differences, differences.isEmpty());
+
+ // All the members were the same. Check that the equals and hashCode results say so too.
+ new EqualsTester()
+ .addEqualityGroup(expected, actual)
+ .testEquals();
+ }
+
+ private static boolean equal(Object x, Object y) {
+ return Arrays.deepEquals(new Object[] {x}, new Object[] {y});
+ }
+
+ private static String string(Object x) {
+ String s = Arrays.deepToString(new Object[] {x});
+ return s.substring(1, s.length() - 1);
+ }
+}
diff --git a/value/src/it/functional/src/test/java/com/google/auto/value/AutoAnnotationTest.java b/value/src/it/functional/src/test/java/com/google/auto/value/AutoAnnotationTest.java
new file mode 100644
index 0000000..31dd4ce
--- /dev/null
+++ b/value/src/it/functional/src/test/java/com/google/auto/value/AutoAnnotationTest.java
@@ -0,0 +1,410 @@
+/*
+ * Copyright (C) 2014 Google Inc.
+ *
+ * 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.value;
+
+import com.google.auto.value.annotations.Empty;
+import com.google.auto.value.annotations.GwtArrays;
+import com.google.auto.value.annotations.StringValues;
+import com.google.common.collect.ImmutableCollection;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSortedSet;
+import com.google.common.primitives.Ints;
+import com.google.common.testing.EqualsTester;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import junit.framework.TestCase;
+
+/**
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+public class AutoAnnotationTest extends TestCase {
+ @AutoAnnotation private static StringValues newStringValues(String[] value) {
+ return new AutoAnnotation_AutoAnnotationTest_newStringValues(value);
+ }
+
+ @Empty
+ @StringValues("oops")
+ class AnnotatedClass {}
+
+ public void testSimple() {
+ StringValues expectedStringValues = AnnotatedClass.class.getAnnotation(StringValues.class);
+ StringValues actualStringValues = newStringValues(new String[] {"oops"});
+ StringValues otherStringValues = newStringValues(new String[] {});
+ new EqualsTester()
+ .addEqualityGroup(expectedStringValues, actualStringValues)
+ .addEqualityGroup(otherStringValues)
+ .testEquals();
+ }
+
+ public void testArraysAreCloned() {
+ String[] array = {"Jekyll"};
+ StringValues stringValues = newStringValues(array);
+ array[0] = "Hyde";
+ assertEquals("Jekyll", stringValues.value()[0]);
+ stringValues.value()[0] = "Hyde";
+ assertEquals("Jekyll", stringValues.value()[0]);
+ }
+
+ public void testGwtArraysAreCloned() {
+ String[] strings = {"Jekyll"};
+ int[] ints = {2, 3, 5};
+ GwtArrays arrays = newGwtArrays(strings, ints);
+ assertEquals(ImmutableList.of("Jekyll"), ImmutableList.copyOf(arrays.strings()));
+ assertEquals(ImmutableList.of(2, 3, 5), Ints.asList(arrays.ints()));
+ strings[0] = "Hyde";
+ ints[0] = -1;
+ assertEquals(ImmutableList.of("Jekyll"), ImmutableList.copyOf(arrays.strings()));
+ assertEquals(ImmutableList.of(2, 3, 5), Ints.asList(arrays.ints()));
+ }
+
+ @AutoAnnotation private static GwtArrays newGwtArrays(String[] strings, int[] ints) {
+ return new AutoAnnotation_AutoAnnotationTest_newGwtArrays(strings, ints);
+ }
+
+ @AutoAnnotation private static StringValues newStringValuesVarArgs(String... value) {
+ return new AutoAnnotation_AutoAnnotationTest_newStringValuesVarArgs(value);
+ }
+
+ public void testSimpleVarArgs() {
+ StringValues expectedStringValues = AnnotatedClass.class.getAnnotation(StringValues.class);
+ StringValues actualStringValues = newStringValuesVarArgs("oops");
+ StringValues otherStringValues = newStringValuesVarArgs(new String[] {});
+ new EqualsTester()
+ .addEqualityGroup(expectedStringValues, actualStringValues)
+ .addEqualityGroup(otherStringValues)
+ .testEquals();
+ }
+
+ @AutoAnnotation private static Empty newEmpty() {
+ return new AutoAnnotation_AutoAnnotationTest_newEmpty();
+ }
+
+ public void testEmpty() {
+ Empty expectedEmpty = AnnotatedClass.class.getAnnotation(Empty.class);
+ Empty actualEmpty = newEmpty();
+ new EqualsTester()
+ .addEqualityGroup(expectedEmpty, actualEmpty)
+ .testEquals();
+ }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @interface Everything {
+ byte aByte();
+ short aShort();
+ int anInt();
+ long aLong();
+ float aFloat();
+ double aDouble();
+ char aChar();
+ boolean aBoolean();
+ String aString();
+ RetentionPolicy anEnum();
+ StringValues anAnnotation();
+ byte[] bytes();
+ short[] shorts();
+ int[] ints();
+ long[] longs();
+ float[] floats();
+ double[] doubles();
+ char[] chars();
+ boolean[] booleans();
+ String[] strings();
+ RetentionPolicy[] enums();
+ StringValues[] annotations();
+ }
+
+ @AutoAnnotation static Everything newEverything(
+ byte aByte,
+ short aShort,
+ int anInt,
+ long aLong,
+ float aFloat,
+ double aDouble,
+ char aChar,
+ boolean aBoolean,
+ String aString,
+ RetentionPolicy anEnum,
+ StringValues anAnnotation,
+ byte[] bytes,
+ short[] shorts,
+ int[] ints,
+ long[] longs,
+ float[] floats,
+ double[] doubles,
+ char[] chars,
+ boolean[] booleans,
+ String[] strings,
+ RetentionPolicy[] enums,
+ StringValues[] annotations) {
+ return new AutoAnnotation_AutoAnnotationTest_newEverything(
+ aByte, aShort, anInt, aLong, aFloat, aDouble, aChar, aBoolean, aString, anEnum,
+ anAnnotation, bytes, shorts, ints, longs, floats, doubles, chars, booleans, strings, enums,
+ annotations);
+ }
+
+ @AutoAnnotation static Everything newEverythingCollections(
+ byte aByte,
+ short aShort,
+ int anInt,
+ long aLong,
+ float aFloat,
+ double aDouble,
+ char aChar,
+ boolean aBoolean,
+ String aString,
+ RetentionPolicy anEnum,
+ StringValues anAnnotation,
+ Collection<Byte> bytes,
+ List<Short> shorts,
+ ArrayList<Integer> ints,
+ Set<Long> longs,
+ SortedSet<Float> floats,
+ TreeSet<Double> doubles,
+ LinkedHashSet<Character> chars,
+ ImmutableCollection<Boolean> booleans,
+ ImmutableList<String> strings,
+ ImmutableSet<RetentionPolicy> enums,
+ Set<StringValues> annotations) {
+ return new AutoAnnotation_AutoAnnotationTest_newEverythingCollections(
+ aByte, aShort, anInt, aLong, aFloat, aDouble, aChar, aBoolean, aString, anEnum,
+ anAnnotation, bytes, shorts, ints, longs, floats, doubles, chars, booleans, strings, enums,
+ annotations);
+ }
+
+ @Everything(
+ aByte = 1,
+ aShort = 2,
+ anInt = 3,
+ aLong = -4,
+ aFloat = Float.NaN,
+ aDouble = Double.NaN,
+ aChar = '#',
+ aBoolean = true,
+ aString = "maybe\nmaybe not\n",
+ anEnum = RetentionPolicy.RUNTIME,
+ anAnnotation = @StringValues("whatever"),
+ bytes = {5, 6},
+ shorts = {},
+ ints = {7},
+ longs = {8, 9},
+ floats = {10, 11},
+ doubles = {Double.NEGATIVE_INFINITY, -12.0, Double.POSITIVE_INFINITY},
+ chars = {'?', '!', '\n'},
+ booleans = {false, true, false},
+ strings = {"ver", "vers", "vert", "verre", "vair"},
+ enums = {RetentionPolicy.CLASS, RetentionPolicy.RUNTIME},
+ annotations = {
+ @StringValues({}), @StringValues({"foo", "bar"})
+ }
+ )
+ private static class AnnotatedWithEverything {}
+
+ // Get an instance of @Everything via reflection on the class AnnotatedWithEverything,
+ // fabricate an instance using newEverything that is supposed to be equal to it, and
+ // fabricate another instance using newEverything that is supposed to be different.
+ private static final Everything EVERYTHING_FROM_REFLECTION =
+ AnnotatedWithEverything.class.getAnnotation(Everything.class);
+ private static final Everything EVERYTHING_FROM_AUTO = newEverything(
+ (byte) 1, (short) 2, 3, -4, Float.NaN, Double.NaN, '#', true,
+ "maybe\nmaybe not\n",
+ RetentionPolicy.RUNTIME,
+ newStringValues(new String[] {"whatever"}),
+ new byte[] {5, 6},
+ new short[] {},
+ new int[] {7},
+ new long[] {8, 9},
+ new float[] {10, 11},
+ new double[] {Double.NEGATIVE_INFINITY, -12.0, Double.POSITIVE_INFINITY},
+ new char[] {'?', '!', '\n'},
+ new boolean[] {false, true, false},
+ new String[] {"ver", "vers", "vert", "verre", "vair"},
+ new RetentionPolicy[] {RetentionPolicy.CLASS, RetentionPolicy.RUNTIME},
+ new StringValues[] {
+ newStringValues(new String[] {}),
+ newStringValues(new String[] {"foo", "bar"}),
+ });
+ private static final Everything EVERYTHING_FROM_AUTO_COLLECTIONS = newEverythingCollections(
+ (byte) 1, (short) 2, 3, -4, Float.NaN, Double.NaN, '#', true,
+ "maybe\nmaybe not\n",
+ RetentionPolicy.RUNTIME,
+ newStringValues(new String[] {"whatever"}),
+ Arrays.asList((byte) 5, (byte) 6),
+ Collections.<Short>emptyList(),
+ new ArrayList<Integer>(Collections.singleton(7)),
+ ImmutableSet.of(8L, 9L),
+ ImmutableSortedSet.of(10f, 11f),
+ new TreeSet<Double>(
+ ImmutableList.of(Double.NEGATIVE_INFINITY, -12.0, Double.POSITIVE_INFINITY)),
+ new LinkedHashSet<Character>(ImmutableList.of('?', '!', '\n')),
+ ImmutableList.of(false, true, false),
+ ImmutableList.of("ver", "vers", "vert", "verre", "vair"),
+ ImmutableSet.of(RetentionPolicy.CLASS, RetentionPolicy.RUNTIME),
+ ImmutableSet.of(
+ newStringValues(new String[] {}),
+ newStringValues(new String[] {"foo", "bar"})));
+ private static final Everything EVERYTHING_ELSE_FROM_AUTO = newEverything(
+ (byte) 0, (short) 0, 0, 0, 0, 0, '0', false, "", RetentionPolicy.SOURCE,
+ newStringValues(new String[] {""}),
+ new byte[0], new short[0], new int[0], new long[0], new float[0], new double[0],
+ new char[0], new boolean[0], new String[0], new RetentionPolicy[0], new StringValues[0]);
+ private static final Everything EVERYTHING_ELSE_FROM_AUTO_COLLECTIONS = newEverythingCollections(
+ (byte) 0, (short) 0, 0, 0, 0, 0, '0', false, "", RetentionPolicy.SOURCE,
+ newStringValues(new String[] {""}),
+ ImmutableList.<Byte>of(),
+ Collections.<Short>emptyList(),
+ new ArrayList<Integer>(),
+ Collections.<Long>emptySet(),
+ ImmutableSortedSet.<Float>of(),
+ new TreeSet<Double>(),
+ new LinkedHashSet<Character>(),
+ ImmutableSet.<Boolean>of(),
+ ImmutableList.<String>of(),
+ ImmutableSet.<RetentionPolicy>of(),
+ Collections.<StringValues>emptySet());
+
+ public void testEqualsAndHashCode() {
+ new EqualsTester()
+ .addEqualityGroup(
+ EVERYTHING_FROM_REFLECTION, EVERYTHING_FROM_AUTO, EVERYTHING_FROM_AUTO_COLLECTIONS)
+ .addEqualityGroup(EVERYTHING_ELSE_FROM_AUTO, EVERYTHING_ELSE_FROM_AUTO_COLLECTIONS)
+ .testEquals();
+ }
+
+ public static class IntList extends ArrayList<Integer> {
+ IntList(Collection<Integer> c) {
+ super(c);
+ }
+ }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @interface IntArray {
+ int[] ints();
+ }
+
+ @IntArray(ints = {1, 2, 3})
+ private static class AnnotatedWithIntArray {}
+
+ @AutoAnnotation static IntArray newIntArray(IntList ints) {
+ return new AutoAnnotation_AutoAnnotationTest_newIntArray(ints);
+ }
+
+ /**
+ * Test that we can represent a primitive array member with a parameter whose type is a
+ * collection of the corresponding wrapper type, even if the wrapper type is not explicitly a type
+ * parameter. Specifically, if the member is an {@code int[]} then obviously we can represent it
+ * as a {@code List<Integer>}, but here we test that we can also represent it as an {@code
+ * IntList}, which is only a {@code List<Integer>} by virtue of inheritance. This is a separate
+ * test rather than just putting an {@code IntList} parameter into {@link
+ * #newEverythingCollections} because we want to check that we are still able to detect the
+ * primitive wrapper type even though it's hidden in this way. We need to generate a helper method
+ * for every primitive wrapper.
+ */
+ public void testDerivedPrimitiveCollection() {
+ IntList intList = new IntList(ImmutableList.of(1, 2, 3));
+ IntArray actual = newIntArray(intList);
+ IntArray expected = AnnotatedWithIntArray.class.getAnnotation(IntArray.class);
+ assertEquals(expected, actual);
+ }
+
+ public void testToString() {
+ String expected = "@com.google.auto.value.AutoAnnotationTest.Everything("
+ + "aByte=1, aShort=2, anInt=3, aLong=-4, aFloat=NaN, aDouble=NaN, aChar='#', "
+ + "aBoolean=true, aString=\"maybe\\nmaybe not\\n\", anEnum=RUNTIME, "
+ + "anAnnotation=@com.google.auto.value.annotations.StringValues([\"whatever\"]), "
+ + "bytes=[5, 6], shorts=[], ints=[7], longs=[8, 9], floats=[10.0, 11.0], "
+ + "doubles=[-Infinity, -12.0, Infinity], "
+ + "chars=['?', '!', '\\n'], "
+ + "booleans=[false, true, false], "
+ + "strings=[\"ver\", \"vers\", \"vert\", \"verre\", \"vair\"], "
+ + "enums=[CLASS, RUNTIME], "
+ + "annotations=["
+ + "@com.google.auto.value.annotations.StringValues([]), "
+ + "@com.google.auto.value.annotations.StringValues([\"foo\", \"bar\"])"
+ + "]"
+ + ")";
+ assertEquals(expected, EVERYTHING_FROM_AUTO.toString());
+ assertEquals(expected, EVERYTHING_FROM_AUTO_COLLECTIONS.toString());
+ }
+
+ public void testStringQuoting() {
+ StringValues instance = newStringValues(
+ new String[] {
+ "",
+ "\r\n",
+ "hello, world",
+ "Éamonn",
+ "\007\uffef",
+ });
+ String expected = "@com.google.auto.value.annotations.StringValues("
+ + "[\"\", \"\\r\\n\", \"hello, world\", \"Éamonn\", \"\\007\\uffef\"])";
+ assertEquals(expected, instance.toString());
+ }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @interface AnnotationsAnnotation {
+ Class<? extends Annotation>[] value();
+ }
+
+ @AnnotationsAnnotation(AnnotationsAnnotation.class)
+ static class AnnotatedWithAnnotationsAnnotation {}
+
+ @AutoAnnotation static AnnotationsAnnotation newAnnotationsAnnotation(
+ List<Class<? extends Annotation>> value) {
+ return new AutoAnnotation_AutoAnnotationTest_newAnnotationsAnnotation(value);
+ }
+
+ public void testGenericArray() {
+ AnnotationsAnnotation generated =
+ newAnnotationsAnnotation(
+ ImmutableList.<Class<? extends Annotation>>of(AnnotationsAnnotation.class));
+ AnnotationsAnnotation fromReflect =
+ AnnotatedWithAnnotationsAnnotation.class.getAnnotation(AnnotationsAnnotation.class);
+ assertEquals(fromReflect, generated);
+ }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @interface ClassesAnnotation {
+ Class<?>[] value();
+ }
+
+ @ClassesAnnotation(AnnotationsAnnotation.class)
+ static class AnnotatedWithClassesAnnotation {}
+
+ @AutoAnnotation static ClassesAnnotation newClassesAnnotation(
+ List<Class<?>> value) {
+ return new AutoAnnotation_AutoAnnotationTest_newClassesAnnotation(value);
+ }
+
+ public void testWildcardArray() {
+ ClassesAnnotation generated =
+ newClassesAnnotation(
+ Arrays.<Class<?>>asList(AnnotationsAnnotation.class));
+ ClassesAnnotation fromReflect =
+ AnnotatedWithClassesAnnotation.class.getAnnotation(ClassesAnnotation.class);
+ assertEquals(fromReflect, generated);
+ }
+}
diff --git a/value/src/it/functional/src/test/java/com/google/auto/value/annotations/Empty.java b/value/src/it/functional/src/test/java/com/google/auto/value/annotations/Empty.java
new file mode 100644
index 0000000..23e70e0
--- /dev/null
+++ b/value/src/it/functional/src/test/java/com/google/auto/value/annotations/Empty.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2014 Google Inc.
+ *
+ * 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.value.annotations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * An annotation with no members, for tests, and runtime retention so it can be accessed through
+ * reflection.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Empty {
+}
diff --git a/value/src/it/functional/src/test/java/com/google/auto/value/annotations/GwtArrays.java b/value/src/it/functional/src/test/java/com/google/auto/value/annotations/GwtArrays.java
new file mode 100644
index 0000000..b6acb04
--- /dev/null
+++ b/value/src/it/functional/src/test/java/com/google/auto/value/annotations/GwtArrays.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2015 Google Inc.
+ *
+ * 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.value.annotations;
+
+import com.google.common.annotations.GwtCompatible;
+
+/**
+ * An annotation that is marked {@code @GwtCompatible} and that contains an array member.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@GwtCompatible
+public @interface GwtArrays {
+ String[] strings();
+ int[] ints();
+}
diff --git a/value/src/it/functional/src/test/java/com/google/auto/value/annotations/StringValues.java b/value/src/it/functional/src/test/java/com/google/auto/value/annotations/StringValues.java
new file mode 100644
index 0000000..2343255
--- /dev/null
+++ b/value/src/it/functional/src/test/java/com/google/auto/value/annotations/StringValues.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2014 Google Inc.
+ *
+ * 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.value.annotations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * An annotation with one member, an array of strings with the default name {@code value}, and
+ * runtime retention so it can be accessed through reflection.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface StringValues {
+ String[] value();
+}