| /* |
| * Copyright 2012 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.value; |
| |
| import static com.google.common.truth.Truth.assertThat; |
| import static com.google.common.truth.Truth.assertWithMessage; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertNotSame; |
| import static org.junit.Assert.assertNull; |
| import static org.junit.Assert.assertSame; |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| |
| import com.google.common.base.MoreObjects; |
| import com.google.common.collect.ComparisonChain; |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.ImmutableMap; |
| import com.google.common.collect.ImmutableSet; |
| import com.google.common.collect.ImmutableSortedMap; |
| import com.google.common.collect.ImmutableSortedSet; |
| import com.google.common.collect.ImmutableTable; |
| import com.google.common.testing.EqualsTester; |
| import com.google.common.testing.SerializableTester; |
| import java.io.ObjectStreamClass; |
| import java.io.Serializable; |
| import java.lang.annotation.Annotation; |
| import java.lang.annotation.Inherited; |
| import java.lang.annotation.Retention; |
| import java.lang.annotation.RetentionPolicy; |
| import java.lang.reflect.Constructor; |
| import java.lang.reflect.Method; |
| import java.lang.reflect.Modifier; |
| import java.lang.reflect.Type; |
| import java.math.BigInteger; |
| import java.util.AbstractList; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.LinkedHashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.NavigableMap; |
| import java.util.NavigableSet; |
| import java.util.NoSuchElementException; |
| import java.util.SortedMap; |
| import java.util.TreeMap; |
| import java.util.TreeSet; |
| import javax.annotation.Nullable; |
| import org.junit.BeforeClass; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.junit.runners.JUnit4; |
| |
| /** @author emcmanus@google.com (Éamonn McManus) */ |
| @RunWith(JUnit4.class) |
| public class AutoValueTest { |
| private static boolean omitIdentifiers; |
| |
| @BeforeClass |
| public static void initOmitIdentifiers() { |
| omitIdentifiers = System.getProperty("OmitIdentifiers") != null; |
| } |
| |
| @AutoValue |
| abstract static class Simple { |
| public abstract String publicString(); |
| |
| protected abstract int protectedInt(); |
| |
| abstract Map<String, Long> packageMap(); |
| |
| public static Simple create(String s, int i, Map<String, Long> m) { |
| return new AutoValue_AutoValueTest_Simple(s, i, m); |
| } |
| } |
| |
| @Test |
| public void testSimple() throws Exception { |
| Simple instance1a = Simple.create("example", 23, ImmutableMap.of("twenty-three", 23L)); |
| Simple instance1b = Simple.create("example", 23, ImmutableMap.of("twenty-three", 23L)); |
| Simple instance2 = Simple.create("", 0, ImmutableMap.<String, Long>of()); |
| assertEquals("example", instance1a.publicString()); |
| assertEquals(23, instance1a.protectedInt()); |
| assertEquals(ImmutableMap.of("twenty-three", 23L), instance1a.packageMap()); |
| MoreObjects.ToStringHelper toStringHelper = MoreObjects.toStringHelper(Simple.class); |
| toStringHelper.add("publicString", "example"); |
| toStringHelper.add("protectedInt", 23); |
| toStringHelper.add("packageMap", ImmutableMap.of("twenty-three", 23L)); |
| String expectedString = |
| omitIdentifiers ? "{example, 23, {twenty-three=23}}" : toStringHelper.toString(); |
| assertThat(instance1a.toString()).isEqualTo(expectedString); |
| new EqualsTester() |
| .addEqualityGroup(instance1a, instance1b) |
| .addEqualityGroup(instance2) |
| .testEquals(); |
| } |
| |
| @AutoValue |
| abstract static class Empty { |
| public static Empty create() { |
| return new AutoValue_AutoValueTest_Empty(); |
| } |
| } |
| |
| @Test |
| public void testEmpty() throws Exception { |
| Empty instance = Empty.create(); |
| String expectedString = omitIdentifiers ? "{}" : "Empty{}"; |
| assertThat(instance.toString()).isEqualTo(expectedString); |
| assertEquals(instance, instance); |
| assertEquals(instance, Empty.create()); |
| } |
| |
| @AutoValue |
| abstract static class SimpleWithGetters { |
| abstract int getFoo(); |
| |
| abstract boolean isBar(); |
| |
| abstract boolean getOtherBar(); |
| |
| abstract String getPackage(); // package is a reserved word |
| |
| abstract String getPackage0(); |
| |
| abstract String getHTMLPage(); |
| |
| static SimpleWithGetters create( |
| int foo, boolean bar, boolean otherBar, String pkg, String pkg0, String htmlPage) { |
| return new AutoValue_AutoValueTest_SimpleWithGetters(foo, bar, otherBar, pkg, pkg0, htmlPage); |
| } |
| } |
| |
| @Test |
| public void testGetters() { |
| SimpleWithGetters instance = SimpleWithGetters.create(23, true, false, "foo", "bar", "<html>"); |
| String expectedString = |
| omitIdentifiers |
| ? "{23, true, false, foo, bar, <html>}" |
| : "SimpleWithGetters{" |
| + "foo=23, bar=true, otherBar=false, package=foo, package0=bar, HTMLPage=<html>}"; |
| assertThat(instance.toString()).isEqualTo(expectedString); |
| } |
| |
| @AutoValue |
| abstract static class NotAllGetters { |
| abstract int getFoo(); |
| |
| abstract boolean bar(); |
| |
| static NotAllGetters create(int foo, boolean bar) { |
| return new AutoValue_AutoValueTest_NotAllGetters(foo, bar); |
| } |
| } |
| |
| @Test |
| public void testNotGetters() { |
| NotAllGetters instance = NotAllGetters.create(23, true); |
| String expectedString = omitIdentifiers ? "{23, true}" : "NotAllGetters{getFoo=23, bar=true}"; |
| assertThat(instance.toString()).isEqualTo(expectedString); |
| } |
| |
| @AutoValue |
| abstract static class StrangeGetters { |
| abstract int get1st(); |
| abstract int get_1st(); // by default we'll use _1st where identifiers are needed, so foil that. |
| |
| @AutoValue.Builder |
| abstract static class Builder { |
| abstract Builder set1st(int x); |
| abstract Builder set_1st(int x); |
| abstract StrangeGetters build(); |
| } |
| |
| static Builder builder() { |
| return new AutoValue_AutoValueTest_StrangeGetters.Builder(); |
| } |
| } |
| |
| @Test |
| public void testStrangeGetters() { |
| StrangeGetters instance = StrangeGetters.builder().set1st(17).set_1st(23).build(); |
| String expectedString = omitIdentifiers ? "{17, 23}" : "StrangeGetters{1st=17, _1st=23}"; |
| assertThat(instance.toString()).isEqualTo(expectedString); |
| } |
| |
| @AutoValue |
| abstract static class GettersAndConcreteNonGetters { |
| abstract int getFoo(); |
| |
| @SuppressWarnings("mutable") |
| abstract byte[] getBytes(); |
| |
| boolean hasNoBytes() { |
| return getBytes().length == 0; |
| } |
| |
| static GettersAndConcreteNonGetters create(int foo, byte[] bytes) { |
| return new AutoValue_AutoValueTest_GettersAndConcreteNonGetters(foo, bytes); |
| } |
| } |
| |
| @Test |
| public void testGettersAndConcreteNonGetters() { |
| GettersAndConcreteNonGetters instance = GettersAndConcreteNonGetters.create(23, new byte[] {1}); |
| assertFalse(instance.hasNoBytes()); |
| String expectedString = |
| omitIdentifiers ? "{23, [1]}" : "GettersAndConcreteNonGetters{foo=23, bytes=[1]}"; |
| assertThat(instance.toString()).isEqualTo(expectedString); |
| } |
| |
| @AutoValue |
| abstract static class ClassProperty { |
| abstract Class<?> theClass(); |
| |
| static ClassProperty create(Class<?> theClass) { |
| return new AutoValue_AutoValueTest_ClassProperty(theClass); |
| } |
| } |
| |
| @Test |
| public void testClassProperty() { |
| ClassProperty instance = ClassProperty.create(Thread.class); |
| assertThat(instance.theClass()).isEqualTo(Thread.class); |
| |
| try { |
| ClassProperty.create(null); |
| fail(); |
| } catch (NullPointerException expected) { |
| } |
| } |
| |
| @AutoValue |
| abstract static class ClassPropertyWithBuilder { |
| abstract Class<? extends Number> numberClass(); |
| |
| static Builder builder() { |
| return new AutoValue_AutoValueTest_ClassPropertyWithBuilder.Builder(); |
| } |
| |
| @AutoValue.Builder |
| abstract static class Builder { |
| abstract Builder setNumberClass(Class<? extends Number> x); |
| |
| abstract ClassPropertyWithBuilder build(); |
| } |
| } |
| |
| @Test |
| public void testClassPropertyWithBuilder() { |
| ClassPropertyWithBuilder instance = |
| ClassPropertyWithBuilder.builder().setNumberClass(Integer.class).build(); |
| assertThat(instance.numberClass()).isEqualTo(Integer.class); |
| |
| try { |
| ClassPropertyWithBuilder.builder().build(); |
| fail(); |
| } catch (IllegalStateException expected) { |
| } |
| |
| try { |
| ClassPropertyWithBuilder.builder().setNumberClass(null); |
| fail(); |
| } catch (NullPointerException expected) { |
| } |
| } |
| |
| @AutoValue |
| public abstract static class Serialize implements Serializable { |
| public abstract int integer(); |
| |
| public abstract String string(); |
| |
| public abstract BigInteger bigInteger(); |
| |
| public static Serialize create(int integer, String string, BigInteger bigInteger) { |
| return new AutoValue_AutoValueTest_Serialize(integer, string, bigInteger); |
| } |
| } |
| |
| @Test |
| public void testSerialize() throws Exception { |
| Serialize instance = Serialize.create(23, "23", BigInteger.valueOf(23)); |
| assertEquals(instance, SerializableTester.reserialize(instance)); |
| } |
| |
| @AutoValue |
| public abstract static class SerializeWithVersionUID implements Serializable { |
| private static final long serialVersionUID = 4294967297L; |
| |
| public abstract int integer(); |
| |
| public abstract String string(); |
| |
| public static SerializeWithVersionUID create(int integer, String string) { |
| return new AutoValue_AutoValueTest_SerializeWithVersionUID(integer, string); |
| } |
| } |
| |
| @Test |
| public void testSerializeWithVersionUID() throws Exception { |
| SerializeWithVersionUID instance = SerializeWithVersionUID.create(23, "23"); |
| assertEquals(instance, SerializableTester.reserialize(instance)); |
| |
| long serialVersionUID = |
| ObjectStreamClass.lookup(AutoValue_AutoValueTest_SerializeWithVersionUID.class) |
| .getSerialVersionUID(); |
| assertEquals(4294967297L, serialVersionUID); |
| } |
| |
| @AutoValue |
| abstract static class LongProperty { |
| public abstract long longProperty(); |
| |
| public static LongProperty create(long longProperty) { |
| return new AutoValue_AutoValueTest_LongProperty(longProperty); |
| } |
| } |
| |
| @Test |
| public void testLongHashCode() { |
| long longValue = 0x1234567887654321L; |
| LongProperty longProperty = LongProperty.create(longValue); |
| assertEquals(singlePropertyHash(longValue), longProperty.hashCode()); |
| } |
| |
| @AutoValue |
| abstract static class IntProperty { |
| public abstract int intProperty(); |
| |
| public static IntProperty create(int intProperty) { |
| return new AutoValue_AutoValueTest_IntProperty(intProperty); |
| } |
| } |
| |
| @Test |
| public void testIntHashCode() { |
| int intValue = 0x12345678; |
| IntProperty intProperty = IntProperty.create(intValue); |
| assertEquals(singlePropertyHash(intValue), intProperty.hashCode()); |
| } |
| |
| @AutoValue |
| abstract static class ShortProperty { |
| public abstract short shortProperty(); |
| |
| public static ShortProperty create(short shortProperty) { |
| return new AutoValue_AutoValueTest_ShortProperty(shortProperty); |
| } |
| } |
| |
| @Test |
| public void testShortHashCode() { |
| short shortValue = 0x1234; |
| ShortProperty shortProperty = ShortProperty.create(shortValue); |
| assertEquals(singlePropertyHash(shortValue), shortProperty.hashCode()); |
| } |
| |
| @AutoValue |
| abstract static class ByteProperty { |
| public abstract byte byteProperty(); |
| |
| public static ByteProperty create(byte byteProperty) { |
| return new AutoValue_AutoValueTest_ByteProperty(byteProperty); |
| } |
| } |
| |
| @Test |
| public void testByteHashCode() { |
| byte byteValue = 123; |
| ByteProperty byteProperty = ByteProperty.create(byteValue); |
| assertEquals(singlePropertyHash(byteValue), byteProperty.hashCode()); |
| } |
| |
| @AutoValue |
| abstract static class CharProperty { |
| public abstract char charProperty(); |
| |
| public static CharProperty create(char charProperty) { |
| return new AutoValue_AutoValueTest_CharProperty(charProperty); |
| } |
| } |
| |
| @Test |
| public void testCharHashCode() { |
| char charValue = 123; |
| CharProperty charProperty = CharProperty.create(charValue); |
| assertEquals(singlePropertyHash(charValue), charProperty.hashCode()); |
| } |
| |
| @AutoValue |
| abstract static class BooleanProperty { |
| public abstract boolean booleanProperty(); |
| |
| public static BooleanProperty create(boolean booleanProperty) { |
| return new AutoValue_AutoValueTest_BooleanProperty(booleanProperty); |
| } |
| } |
| |
| @Test |
| public void testBooleanHashCode() { |
| for (boolean booleanValue : new boolean[] {false, true}) { |
| BooleanProperty booleanProperty = BooleanProperty.create(booleanValue); |
| assertEquals(singlePropertyHash(booleanValue), booleanProperty.hashCode()); |
| } |
| } |
| |
| @AutoValue |
| abstract static class FloatProperty { |
| public abstract float floatProperty(); |
| |
| public static FloatProperty create(float floatProperty) { |
| return new AutoValue_AutoValueTest_FloatProperty(floatProperty); |
| } |
| } |
| |
| @Test |
| public void testFloatHashCode() { |
| float floatValue = 123456f; |
| FloatProperty floatProperty = FloatProperty.create(floatValue); |
| assertEquals(singlePropertyHash(floatValue), floatProperty.hashCode()); |
| } |
| |
| @AutoValue |
| abstract static class DoubleProperty { |
| public abstract double doubleProperty(); |
| |
| public static DoubleProperty create(double doubleProperty) { |
| return new AutoValue_AutoValueTest_DoubleProperty(doubleProperty); |
| } |
| } |
| |
| @Test |
| public void testDoubleHashCode() { |
| double doubleValue = 1234567890123456d; |
| DoubleProperty doubleProperty = DoubleProperty.create(doubleValue); |
| assertEquals(singlePropertyHash(doubleValue), doubleProperty.hashCode()); |
| } |
| |
| @Test |
| public void testFloatingEquality() { |
| FloatProperty floatZero = FloatProperty.create(0.0f); |
| FloatProperty floatMinusZero = FloatProperty.create(-0.0f); |
| FloatProperty floatNaN = FloatProperty.create(Float.NaN); |
| DoubleProperty doubleZero = DoubleProperty.create(0.0); |
| DoubleProperty doubleMinusZero = DoubleProperty.create(-0.0); |
| DoubleProperty doubleNaN = DoubleProperty.create(Double.NaN); |
| new EqualsTester() |
| .addEqualityGroup(floatZero) |
| .addEqualityGroup(floatMinusZero) |
| .addEqualityGroup(floatNaN) |
| .addEqualityGroup(doubleZero) |
| .addEqualityGroup(doubleMinusZero) |
| .addEqualityGroup(doubleNaN) |
| .testEquals(); |
| } |
| |
| private static int singlePropertyHash(Object property) { |
| return 1000003 ^ property.hashCode(); |
| } |
| |
| abstract static class Super { |
| public abstract Object superObject(); |
| |
| public abstract boolean superBoolean(); |
| // The above two are out of alphabetical order to test EclipseHack. |
| } |
| |
| @AutoValue |
| public abstract static class Sub extends Super { |
| public abstract int subInt(); |
| |
| public static Sub create(Object superObject, boolean superBoolean, int subInt) { |
| return new AutoValue_AutoValueTest_Sub(superObject, superBoolean, subInt); |
| } |
| } |
| |
| // The @AutoValue class can inherit abstract methods from its superclass. |
| @Test |
| public void testSuperclass() throws Exception { |
| Sub instance = Sub.create("blim", true, 1729); |
| assertEquals("blim", instance.superObject()); |
| assertTrue(instance.superBoolean()); |
| assertEquals(1729, instance.subInt()); |
| assertEquals(instance, instance); |
| assertEqualsNullIsFalse(instance); |
| } |
| |
| abstract static class NonPublicSuper { |
| abstract Object superObject(); |
| } |
| |
| // The properties in this subclass are not in alphabetical order, which enables us to test that |
| // everything works correctly when Eclipse sorts them into the order |
| // [superObject, subInt, subString], since it sorts per class. |
| @AutoValue |
| abstract static class NonPublicSub extends NonPublicSuper { |
| abstract String subString(); |
| |
| abstract int subInt(); |
| |
| static NonPublicSub create(Object superObject, String subString, int subInt) { |
| return new AutoValue_AutoValueTest_NonPublicSub(superObject, subString, subInt); |
| } |
| } |
| |
| @Test |
| public void testNonPublicInheritedGetters() throws Exception { |
| NonPublicSub instance = NonPublicSub.create("blim", "blam", 1729); |
| assertEquals("blim", instance.superObject()); |
| assertEquals("blam", instance.subString()); |
| assertEquals(1729, instance.subInt()); |
| assertEquals(instance, instance); |
| assertEqualsNullIsFalse(instance); |
| } |
| |
| @SuppressWarnings("ObjectEqualsNull") |
| private void assertEqualsNullIsFalse(Object instance) { |
| assertFalse(instance.equals(null)); |
| } |
| |
| @AutoValue |
| abstract static class NullableProperties { |
| @Nullable |
| abstract String nullableString(); |
| |
| abstract int randomInt(); |
| |
| static NullableProperties create(@Nullable String nullableString, int randomInt) { |
| return new AutoValue_AutoValueTest_NullableProperties(nullableString, randomInt); |
| } |
| } |
| |
| @Test |
| public void testNullablePropertiesCanBeNull() { |
| NullableProperties instance = NullableProperties.create(null, 23); |
| assertNull(instance.nullableString()); |
| assertThat(instance.randomInt()).isEqualTo(23); |
| String expectedString = |
| omitIdentifiers ? "{null, 23}" : "NullableProperties{nullableString=null, randomInt=23}"; |
| assertThat(instance.toString()).isEqualTo(expectedString); |
| } |
| |
| @AutoAnnotation |
| static Nullable nullable() { |
| return new AutoAnnotation_AutoValueTest_nullable(); |
| } |
| |
| @Test |
| public void testNullablePropertyConstructorParameterIsNullable() throws NoSuchMethodException { |
| Constructor<?> constructor = |
| AutoValue_AutoValueTest_NullableProperties.class.getDeclaredConstructor( |
| String.class, int.class); |
| assertThat(constructor.getParameterAnnotations()[0]).asList().contains(nullable()); |
| } |
| |
| @AutoValue |
| abstract static class AlternativeNullableProperties { |
| @interface Nullable {} |
| |
| @AlternativeNullableProperties.Nullable |
| abstract String nullableString(); |
| |
| abstract int randomInt(); |
| |
| static AlternativeNullableProperties create(@Nullable String nullableString, int randomInt) { |
| return new AutoValue_AutoValueTest_AlternativeNullableProperties(nullableString, randomInt); |
| } |
| } |
| |
| @Test |
| public void testNullableCanBeFromElsewhere() throws Exception { |
| AlternativeNullableProperties instance = AlternativeNullableProperties.create(null, 23); |
| assertNull(instance.nullableString()); |
| assertThat(instance.randomInt()).isEqualTo(23); |
| String expectedString = |
| omitIdentifiers |
| ? "{null, 23}" |
| : "AlternativeNullableProperties{nullableString=null, randomInt=23}"; |
| assertThat(instance.toString()).isEqualTo(expectedString); |
| } |
| |
| @AutoValue |
| abstract static class NonNullableProperties { |
| abstract String nonNullableString(); |
| |
| abstract int randomInt(); |
| |
| static NonNullableProperties create(String nonNullableString, int randomInt) { |
| return new AutoValue_AutoValueTest_NonNullableProperties(nonNullableString, randomInt); |
| } |
| } |
| |
| @Test |
| public void testNonNullablePropertiesCannotBeNull() throws Exception { |
| try { |
| NonNullableProperties.create(null, 23); |
| fail("Object creation succeeded but should not have"); |
| } catch (NullPointerException expected) { |
| } |
| NonNullableProperties instance = NonNullableProperties.create("nonnull", 23); |
| assertEquals("nonnull", instance.nonNullableString()); |
| assertEquals(23, instance.randomInt()); |
| } |
| |
| @AutoValue |
| abstract static class NullableListProperties { |
| @Nullable |
| abstract ImmutableList<String> nullableStringList(); |
| |
| static NullableListProperties create(@Nullable ImmutableList<String> nullableStringList) { |
| return new AutoValue_AutoValueTest_NullableListProperties(nullableStringList); |
| } |
| } |
| |
| @Test |
| public void testNullableListPropertiesCanBeNonNull() { |
| NullableListProperties instance = NullableListProperties.create(ImmutableList.of("foo", "bar")); |
| assertEquals(ImmutableList.of("foo", "bar"), instance.nullableStringList()); |
| } |
| |
| @Test |
| public void testNullableListPropertiesCanBeNull() { |
| NullableListProperties instance = NullableListProperties.create(null); |
| assertNull(instance.nullableStringList()); |
| } |
| |
| @AutoValue |
| abstract static class NullableListPropertiesWithBuilder { |
| @Nullable |
| abstract ImmutableList<String> nullableStringList(); |
| |
| static Builder builder() { |
| return new AutoValue_AutoValueTest_NullableListPropertiesWithBuilder.Builder(); |
| } |
| |
| @AutoValue.Builder |
| interface Builder { |
| Builder nullableStringList(List<String> nullableStringList); |
| |
| NullableListPropertiesWithBuilder build(); |
| } |
| } |
| |
| @Test |
| public void testNullableListPropertiesWithBuilderCanBeNonNull() { |
| NullableListPropertiesWithBuilder instance = |
| NullableListPropertiesWithBuilder.builder() |
| .nullableStringList(ImmutableList.of("foo", "bar")) |
| .build(); |
| assertEquals(ImmutableList.of("foo", "bar"), instance.nullableStringList()); |
| } |
| |
| @Test |
| public void testNullableListPropertiesWithBuilderCanBeUnset() { |
| NullableListPropertiesWithBuilder instance = |
| NullableListPropertiesWithBuilder.builder().build(); |
| assertNull(instance.nullableStringList()); |
| } |
| |
| @Test |
| public void testNullableListPropertiesWithBuilderCanBeNull() { |
| NullableListPropertiesWithBuilder instance = |
| NullableListPropertiesWithBuilder.builder().nullableStringList(null).build(); |
| assertNull(instance.nullableStringList()); |
| } |
| |
| static class Nested { |
| @AutoValue |
| abstract static class Doubly { |
| @Nullable |
| abstract String nullableString(); |
| |
| abstract int randomInt(); |
| |
| static Doubly create(String nullableString, int randomInt) { |
| return new AutoValue_AutoValueTest_Nested_Doubly(nullableString, randomInt); |
| } |
| } |
| } |
| |
| @Test |
| public void testDoublyNestedClass() throws Exception { |
| Nested.Doubly instance = Nested.Doubly.create(null, 23); |
| assertNull(instance.nullableString()); |
| assertThat(instance.randomInt()).isEqualTo(23); |
| String expectedString = |
| omitIdentifiers ? "{null, 23}" : "Doubly{nullableString=null, randomInt=23}"; |
| assertThat(instance.toString()).isEqualTo(expectedString); |
| } |
| |
| static interface NestedInInterface { |
| @AutoValue |
| abstract class Doubly { |
| abstract String string(); |
| |
| abstract Map<String, Integer> map(); |
| |
| static Doubly create(String string, Map<String, Integer> map) { |
| return new AutoValue_AutoValueTest_NestedInInterface_Doubly(string, map); |
| } |
| } |
| } |
| |
| @Test |
| public void testClassNestedInInterface() throws Exception { |
| Map<String, Integer> map = ImmutableMap.of("vingt-et-un", 21); |
| NestedInInterface.Doubly instance = NestedInInterface.Doubly.create("foo", map); |
| assertEquals("foo", instance.string()); |
| assertEquals(map, instance.map()); |
| } |
| |
| @AutoValue |
| abstract static class NullableNonNullable { |
| @Nullable |
| abstract String nullableString(); |
| |
| @Nullable |
| abstract String otherNullableString(); |
| |
| abstract String nonNullableString(); |
| |
| static NullableNonNullable create( |
| String nullableString, String otherNullableString, String nonNullableString) { |
| return new AutoValue_AutoValueTest_NullableNonNullable( |
| nullableString, otherNullableString, nonNullableString); |
| } |
| } |
| |
| @Test |
| public void testEqualsWithNullable() throws Exception { |
| NullableNonNullable everythingNull = |
| NullableNonNullable.create(null, null, "nonNullableString"); |
| NullableNonNullable somethingNull = |
| NullableNonNullable.create(null, "otherNullableString", "nonNullableString"); |
| NullableNonNullable nothingNull = |
| NullableNonNullable.create("nullableString", "otherNullableString", "nonNullableString"); |
| NullableNonNullable nothingNullAgain = |
| NullableNonNullable.create("nullableString", "otherNullableString", "nonNullableString"); |
| new EqualsTester() |
| .addEqualityGroup(everythingNull) |
| .addEqualityGroup(somethingNull) |
| .addEqualityGroup(nothingNull, nothingNullAgain) |
| .testEquals(); |
| } |
| |
| @AutoValue |
| abstract static class GenericProperties { |
| abstract Map<String, Integer> simpleMap(); |
| |
| abstract Map<String, Map<String, Integer>> hairyMap(); |
| |
| static GenericProperties create( |
| Map<String, Integer> simpleMap, Map<String, Map<String, Integer>> hairyMap) { |
| return new AutoValue_AutoValueTest_GenericProperties(simpleMap, hairyMap); |
| } |
| } |
| |
| @Test |
| public void testGenericProperties() throws Exception { |
| GenericProperties instance1 = |
| GenericProperties.create( |
| ImmutableMap.of("twenty-three", 23), |
| ImmutableMap.of("very", (Map<String, Integer>) ImmutableMap.of("hairy", 17))); |
| GenericProperties instance2 = |
| GenericProperties.create( |
| ImmutableMap.of("seventeen", 17), |
| ImmutableMap.of("very", (Map<String, Integer>) ImmutableMap.of("hairy", 23))); |
| new EqualsTester().addEqualityGroup(instance1).addEqualityGroup(instance2).testEquals(); |
| assertEquals( |
| ImmutableMap.of("very", (Map<String, Integer>) ImmutableMap.of("hairy", 23)), |
| instance2.hairyMap()); |
| } |
| |
| @AutoValue |
| abstract static class GenericClass<K, V> { |
| abstract K key(); |
| |
| abstract Map<K, V> map(); |
| |
| static <K, V> GenericClass<K, V> create(K key, Map<K, V> map) { |
| return new AutoValue_AutoValueTest_GenericClass<K, V>(key, map); |
| } |
| } |
| |
| @Test |
| public void testGenericClass() throws Exception { |
| GenericClass<String, Boolean> instance = |
| GenericClass.create("whatever", ImmutableMap.of("no", false)); |
| assertEquals(instance, instance); |
| assertEquals("whatever", instance.key()); |
| assertEquals(ImmutableMap.of("no", false), instance.map()); |
| } |
| |
| @AutoValue |
| abstract static class GenericClassSimpleBounds<K extends Number, V extends K> { |
| abstract K key(); |
| |
| abstract Map<K, V> map(); |
| |
| static <K extends Number, V extends K> GenericClassSimpleBounds<K, V> create( |
| K key, Map<K, V> map) { |
| return new AutoValue_AutoValueTest_GenericClassSimpleBounds<K, V>(key, map); |
| } |
| } |
| |
| @Test |
| public void testGenericClassWithSimpleBounds() throws Exception { |
| GenericClassSimpleBounds<Integer, Integer> instance = |
| GenericClassSimpleBounds.create(23, ImmutableMap.of(17, 23)); |
| assertEquals(instance, instance); |
| assertEquals(23, (int) instance.key()); |
| assertEquals(ImmutableMap.of(17, 23), instance.map()); |
| } |
| |
| @AutoValue |
| abstract static class GenericClassHairyBounds<K extends List<V> & Comparable<K>, V> { |
| abstract K key(); |
| |
| abstract Map<K, V> map(); |
| |
| static <K extends List<V> & Comparable<K>, V> GenericClassHairyBounds<K, V> create( |
| K key, Map<K, V> map) { |
| return new AutoValue_AutoValueTest_GenericClassHairyBounds<K, V>(key, map); |
| } |
| } |
| |
| @Test |
| public void testGenericClassWithHairyBounds() throws Exception { |
| class ComparableList<E> extends ArrayList<E> implements Comparable<ComparableList<E>> { |
| @Override |
| public int compareTo(ComparableList<E> list) { |
| throw new UnsupportedOperationException(); |
| } |
| } |
| ComparableList<String> emptyList = new ComparableList<String>(); |
| GenericClassHairyBounds<ComparableList<String>, String> instance = |
| GenericClassHairyBounds.create(emptyList, ImmutableMap.of(emptyList, "23")); |
| assertEquals(instance, instance); |
| assertEquals(emptyList, instance.key()); |
| assertEquals(ImmutableMap.of(emptyList, "23"), instance.map()); |
| } |
| |
| interface Mergeable<M extends Mergeable<M>> { |
| M merge(M other); |
| } |
| |
| @AutoValue |
| abstract static class Delta<M extends Mergeable<M>> { |
| abstract M meta(); |
| |
| static <M extends Mergeable<M>> Delta<M> create(M meta) { |
| return new AutoValue_AutoValueTest_Delta<M>(meta); |
| } |
| } |
| |
| @Test |
| public void testRecursiveGeneric() { |
| class MergeableImpl implements Mergeable<MergeableImpl> { |
| @Override |
| public MergeableImpl merge(MergeableImpl other) { |
| return this; |
| } |
| } |
| MergeableImpl mergeable = new MergeableImpl(); |
| Delta<MergeableImpl> instance = Delta.create(mergeable); |
| assertSame(mergeable, instance.meta()); |
| } |
| |
| static class NodeType<O> {} |
| |
| abstract static class NodeExpressionClass<O> { |
| abstract NodeType<O> getType(); |
| } |
| |
| @AutoValue |
| abstract static class NotNodeExpression extends NodeExpressionClass<Boolean> { |
| static NotNodeExpression create() { |
| return new AutoValue_AutoValueTest_NotNodeExpression(new NodeType<Boolean>()); |
| } |
| } |
| |
| interface NodeExpressionInterface<O> { |
| NodeType<O> getType(); |
| } |
| |
| @AutoValue |
| abstract static class NotNodeExpression2 implements NodeExpressionInterface<Boolean> { |
| static NotNodeExpression2 create() { |
| return new AutoValue_AutoValueTest_NotNodeExpression2(new NodeType<Boolean>()); |
| } |
| } |
| |
| @Test |
| public void testConcreteWithGenericParent() { |
| NotNodeExpression instance = NotNodeExpression.create(); |
| assertThat(instance.getType()).isInstanceOf(NodeType.class); |
| NotNodeExpression2 instance2 = NotNodeExpression2.create(); |
| assertThat(instance2.getType()).isInstanceOf(NodeType.class); |
| } |
| |
| @AutoValue |
| abstract static class ExplicitToString { |
| abstract String string(); |
| |
| static ExplicitToString create(String string) { |
| return new AutoValue_AutoValueTest_ExplicitToString(string); |
| } |
| |
| @Override |
| public String toString() { |
| return "Bazinga{" + string() + "}"; |
| } |
| } |
| |
| // We should not generate a toString() method if there already is a non-default one. |
| @Test |
| public void testExplicitToString() throws Exception { |
| ExplicitToString instance = ExplicitToString.create("foo"); |
| assertEquals("Bazinga{foo}", instance.toString()); |
| } |
| |
| abstract static class NonAutoExplicitToString { |
| abstract String string(); |
| |
| @Override |
| public String toString() { |
| return "Bazinga{" + string() + "}"; |
| } |
| } |
| |
| @AutoValue |
| abstract static class InheritedExplicitToString extends NonAutoExplicitToString { |
| static InheritedExplicitToString create(String string) { |
| return new AutoValue_AutoValueTest_InheritedExplicitToString(string); |
| } |
| } |
| |
| // We should not generate a toString() method if we already inherit a non-default one. |
| @Test |
| public void testInheritedExplicitToString() throws Exception { |
| InheritedExplicitToString instance = InheritedExplicitToString.create("foo"); |
| assertEquals("Bazinga{foo}", instance.toString()); |
| } |
| |
| @AutoValue |
| abstract static class AbstractToString { |
| abstract String string(); |
| |
| static AbstractToString create(String string) { |
| return new AutoValue_AutoValueTest_AbstractToString(string); |
| } |
| |
| @Override |
| public abstract String toString(); |
| } |
| |
| // We should generate a toString() method if the parent class has an abstract one. |
| // That allows users to cancel a toString() from a parent class if they want. |
| @Test |
| public void testAbstractToString() throws Exception { |
| AbstractToString instance = AbstractToString.create("foo"); |
| String expectedString = omitIdentifiers ? "{foo}" : "AbstractToString{string=foo}"; |
| assertThat(instance.toString()).isEqualTo(expectedString); |
| } |
| |
| abstract static class NonAutoAbstractToString { |
| abstract String string(); |
| |
| @Override |
| public abstract String toString(); |
| } |
| |
| @AutoValue |
| abstract static class SubAbstractToString extends NonAutoAbstractToString { |
| static SubAbstractToString create(String string) { |
| return new AutoValue_AutoValueTest_SubAbstractToString(string); |
| } |
| } |
| |
| // We should generate a toString() method if the parent class inherits an abstract one. |
| @Test |
| public void testInheritedAbstractToString() throws Exception { |
| SubAbstractToString instance = SubAbstractToString.create("foo"); |
| String expectedString = omitIdentifiers ? "{foo}" : "SubAbstractToString{string=foo}"; |
| assertThat(instance.toString()).isEqualTo(expectedString); |
| } |
| |
| @AutoValue |
| abstract static class ExplicitHashCode { |
| abstract String string(); |
| |
| static ExplicitHashCode create(String string) { |
| return new AutoValue_AutoValueTest_ExplicitHashCode(string); |
| } |
| |
| @Override |
| public int hashCode() { |
| return 1234; |
| } |
| } |
| |
| @Test |
| public void testExplicitHashCode() throws Exception { |
| ExplicitHashCode instance = ExplicitHashCode.create("foo"); |
| assertEquals(1234, instance.hashCode()); |
| } |
| |
| @AutoValue |
| @SuppressWarnings("EqualsHashCode") |
| abstract static class ExplicitEquals { |
| int equalsCount; |
| |
| static ExplicitEquals create() { |
| return new AutoValue_AutoValueTest_ExplicitEquals(); |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| equalsCount++; |
| return super.equals(o); |
| } |
| } |
| |
| @SuppressWarnings("SelfEquals") |
| @Test |
| public void testExplicitEquals() throws Exception { |
| ExplicitEquals instance = ExplicitEquals.create(); |
| assertEquals(0, instance.equalsCount); |
| assertTrue(instance.equals(instance)); |
| assertEquals(1, instance.equalsCount); |
| Method equals = instance.getClass().getMethod("equals", Object.class); |
| assertNotSame(ExplicitEquals.class, instance.getClass()); |
| assertSame(ExplicitEquals.class, equals.getDeclaringClass()); |
| } |
| |
| @Retention(RetentionPolicy.RUNTIME) |
| @interface MyAnnotation { |
| String value(); |
| } |
| |
| @AutoAnnotation |
| private static MyAnnotation myAnnotation(String value) { |
| return new AutoAnnotation_AutoValueTest_myAnnotation(value); |
| } |
| |
| @AutoValue |
| abstract static class PrimitiveArrays { |
| @SuppressWarnings("mutable") |
| abstract boolean[] booleans(); |
| |
| @SuppressWarnings("mutable") |
| @Nullable |
| abstract int[] ints(); |
| |
| static PrimitiveArrays create(boolean[] booleans, int[] ints) { |
| // Real code would likely clone these parameters, but here we want to check that the |
| // generated constructor rejects a null value for booleans. |
| return new AutoValue_AutoValueTest_PrimitiveArrays(booleans, ints); |
| } |
| } |
| |
| @Test |
| public void testPrimitiveArrays() { |
| PrimitiveArrays object0 = PrimitiveArrays.create(new boolean[0], new int[0]); |
| boolean[] booleans = {false, true, true, false}; |
| int[] ints = {6, 28, 496, 8128, 33550336}; |
| PrimitiveArrays object1 = PrimitiveArrays.create(booleans.clone(), ints.clone()); |
| PrimitiveArrays object2 = PrimitiveArrays.create(booleans.clone(), ints.clone()); |
| new EqualsTester().addEqualityGroup(object1, object2).addEqualityGroup(object0).testEquals(); |
| // EqualsTester also exercises hashCode(). We clone the arrays above to ensure that using the |
| // default Object.hashCode() will fail. |
| |
| String expectedString = |
| omitIdentifiers |
| ? ("{" + Arrays.toString(booleans) + ", " + Arrays.toString(ints) + "}") |
| : ("PrimitiveArrays{booleans=" |
| + Arrays.toString(booleans) |
| + ", " |
| + "ints=" |
| + Arrays.toString(ints) |
| + "}"); |
| assertThat(object1.toString()).isEqualTo(expectedString); |
| assertThat(object1.ints()).isSameInstanceAs(object1.ints()); |
| } |
| |
| @Test |
| public void testNullablePrimitiveArrays() { |
| PrimitiveArrays object0 = PrimitiveArrays.create(new boolean[0], null); |
| boolean[] booleans = {false, true, true, false}; |
| PrimitiveArrays object1 = PrimitiveArrays.create(booleans.clone(), null); |
| PrimitiveArrays object2 = PrimitiveArrays.create(booleans.clone(), null); |
| new EqualsTester().addEqualityGroup(object1, object2).addEqualityGroup(object0).testEquals(); |
| |
| String expectedString = |
| omitIdentifiers |
| ? ("{" + Arrays.toString(booleans) + ", null}") |
| : ("PrimitiveArrays{booleans=" + Arrays.toString(booleans) + ", " + "ints=null}"); |
| assertThat(object1.toString()).isEqualTo(expectedString); |
| |
| assertThat(object1.booleans()).isSameInstanceAs(object1.booleans()); |
| assertThat(object1.booleans()).isEqualTo(booleans); |
| object1.booleans()[0] ^= true; |
| assertThat(object1.booleans()).isNotEqualTo(booleans); |
| } |
| |
| @Test |
| public void testNotNullablePrimitiveArrays() { |
| try { |
| PrimitiveArrays.create(null, new int[0]); |
| fail("Construction with null value for non-@Nullable array should have failed"); |
| } catch (NullPointerException e) { |
| if (omitIdentifiers) { |
| assertThat(e).hasMessageThat().isNull(); |
| } else { |
| assertThat(e).hasMessageThat().contains("booleans"); |
| } |
| } |
| } |
| |
| // If users are mad enough to define their own Arrays class and have some properties of that |
| // class and others of primitive array type, then we can't import java.util.Arrays. |
| // This is unlikely. |
| @AutoValue |
| abstract static class AmbiguousArrays { |
| static class Arrays {} |
| |
| abstract Arrays arrays(); |
| |
| @SuppressWarnings("mutable") |
| abstract int[] ints(); |
| |
| static AmbiguousArrays create(Arrays arrays, int[] ints) { |
| return new AutoValue_AutoValueTest_AmbiguousArrays(arrays, ints); |
| } |
| } |
| |
| @Test |
| public void testAmbiguousArrays() { |
| // If this test compiles at all then we presumably don't have the import problem above. |
| AmbiguousArrays object1 = AmbiguousArrays.create(new AmbiguousArrays.Arrays(), new int[0]); |
| assertNotNull(object1.arrays()); |
| assertEquals(0, object1.ints().length); |
| } |
| |
| static final class HashCodeObserver { |
| int hashCodeCount; |
| |
| @Override |
| public boolean equals(Object obj) { |
| return obj instanceof HashCodeObserver; |
| } |
| |
| @Override |
| public int hashCode() { |
| hashCodeCount++; |
| return 23; |
| } |
| } |
| |
| @AutoValue |
| abstract static class MaybeCachedHashCode { |
| abstract HashCodeObserver hashCodeObserver(); |
| |
| abstract int randomInt(); |
| |
| static MaybeCachedHashCode create(HashCodeObserver hashCodeObserver, int randomInt) { |
| return new AutoValue_AutoValueTest_MaybeCachedHashCode(hashCodeObserver, randomInt); |
| } |
| } |
| |
| @Test |
| public void testHashCodeNotCached() { |
| HashCodeObserver observer = new HashCodeObserver(); |
| MaybeCachedHashCode maybeCached = MaybeCachedHashCode.create(observer, 17); |
| int hash1 = maybeCached.hashCode(); |
| int hash2 = maybeCached.hashCode(); |
| assertEquals(hash1, hash2); |
| assertEquals(2, observer.hashCodeCount); |
| } |
| |
| @AutoValue |
| abstract static class Version implements Comparable<Version> { |
| abstract int major(); |
| |
| abstract int minor(); |
| |
| static Version create(int major, int minor) { |
| return new AutoValue_AutoValueTest_Version(major, minor); |
| } |
| |
| @Override |
| public int compareTo(Version that) { |
| return ComparisonChain.start() |
| .compare(this.major(), that.major()) |
| .compare(this.minor(), that.minor()) |
| .result(); |
| } |
| } |
| |
| @Test |
| public void testComparisonChain() { |
| assertEquals(Version.create(1, 2), Version.create(1, 2)); |
| Version[] versions = {Version.create(1, 2), Version.create(1, 3), Version.create(2, 1)}; |
| for (int i = 0; i < versions.length; i++) { |
| for (int j = 0; j < versions.length; j++) { |
| int actual = Integer.signum(versions[i].compareTo(versions[j])); |
| int expected = Integer.signum(i - j); |
| assertEquals(expected, actual); |
| } |
| } |
| } |
| |
| abstract static class LukesBase { |
| interface LukesVisitor<T> { |
| T visit(LukesSub s); |
| } |
| |
| abstract <T> T accept(LukesVisitor<T> visitor); |
| |
| @AutoValue |
| abstract static class LukesSub extends LukesBase { |
| static LukesSub create() { |
| return new AutoValue_AutoValueTest_LukesBase_LukesSub(); |
| } |
| |
| @Override |
| <T> T accept(LukesVisitor<T> visitor) { |
| return visitor.visit(this); |
| } |
| } |
| } |
| |
| @Test |
| public void testVisitor() { |
| LukesBase.LukesVisitor<String> visitor = |
| new LukesBase.LukesVisitor<String>() { |
| @Override |
| public String visit(LukesBase.LukesSub s) { |
| return s.toString(); |
| } |
| }; |
| LukesBase.LukesSub sub = LukesBase.LukesSub.create(); |
| assertEquals(sub.toString(), sub.accept(visitor)); |
| } |
| |
| @AutoValue |
| public abstract static class ComplexInheritance extends AbstractBase implements A, B { |
| public static ComplexInheritance create(String name) { |
| return new AutoValue_AutoValueTest_ComplexInheritance(name); |
| } |
| |
| abstract String name(); |
| } |
| |
| static class AbstractBase implements Base { |
| @Override |
| public int answer() { |
| return 42; |
| } |
| } |
| |
| interface A extends Base {} |
| |
| interface B extends Base {} |
| |
| interface Base { |
| int answer(); |
| } |
| |
| @Test |
| public void testComplexInheritance() { |
| ComplexInheritance complex = ComplexInheritance.create("fred"); |
| assertEquals("fred", complex.name()); |
| assertEquals(42, complex.answer()); |
| } |
| |
| // This tests the case where we inherit abstract methods on more than one path. AbstractList |
| // extends AbstractCollection, which implements Collection; and AbstractList also implements List, |
| // which extends Collection. So the class here inherits the methods of Collection on more than |
| // one path. In an earlier version of the logic for handling inheritance, this confused us into |
| // thinking that the methods from Collection were still abstract and therefore candidates for |
| // implementation, even though we inherit concrete implementations of them from AbstractList. |
| @AutoValue |
| public static class MoreComplexInheritance extends AbstractList<String> { |
| @Override |
| public String get(int index) { |
| throw new NoSuchElementException(String.valueOf(index)); |
| } |
| |
| @Override |
| public int size() { |
| return 0; |
| } |
| |
| public static MoreComplexInheritance create() { |
| return new AutoValue_AutoValueTest_MoreComplexInheritance(); |
| } |
| } |
| |
| @Test |
| public void testMoreComplexInheritance() { |
| MoreComplexInheritance instance1 = MoreComplexInheritance.create(); |
| MoreComplexInheritance instance2 = MoreComplexInheritance.create(); |
| assertThat(instance1).isEqualTo(instance2); |
| assertThat(instance1).isNotSameInstanceAs(instance2); |
| } |
| |
| // Test that we are not misled by the privateness of an ancestor into thinking that its methods |
| // are invisible to descendants. |
| public abstract static class PublicGrandparent { |
| public abstract String foo(); |
| } |
| |
| private static class PrivateParent extends PublicGrandparent { |
| @Override |
| public String foo() { |
| return "foo"; |
| } |
| } |
| |
| @AutoValue |
| static class EffectiveVisibility extends PrivateParent { |
| static EffectiveVisibility create() { |
| return new AutoValue_AutoValueTest_EffectiveVisibility(); |
| } |
| } |
| |
| @Test |
| public void testEffectiveVisibility() { |
| EffectiveVisibility instance1 = EffectiveVisibility.create(); |
| EffectiveVisibility instance2 = EffectiveVisibility.create(); |
| assertThat(instance1).isEqualTo(instance2); |
| assertThat(instance1).isNotSameInstanceAs(instance2); |
| } |
| |
| @AutoValue |
| public abstract static class InheritTwice implements A, B { |
| public static InheritTwice create(int answer) { |
| return new AutoValue_AutoValueTest_InheritTwice(answer); |
| } |
| } |
| |
| @Test |
| public void testInheritTwice() { |
| InheritTwice inheritTwice = InheritTwice.create(42); |
| assertEquals(42, inheritTwice.answer()); |
| } |
| |
| @AutoValue |
| public abstract static class Optional { |
| public abstract com.google.common.base.Optional<Object> getOptional(); |
| |
| public static Optional create(com.google.common.base.Optional<Object> opt) { |
| return new AutoValue_AutoValueTest_Optional(opt); |
| } |
| } |
| |
| @Test |
| public void testAmbiguityFromAutoValueType() { |
| Optional autoOptional = Optional.create(com.google.common.base.Optional.absent()); |
| assertEquals(com.google.common.base.Optional.absent(), autoOptional.getOptional()); |
| } |
| |
| static class BaseWithNestedType { |
| static class Optional {} |
| } |
| |
| @AutoValue |
| public abstract static class InheritsNestedType extends BaseWithNestedType { |
| public abstract com.google.common.base.Optional<Object> getOptional(); |
| |
| public static InheritsNestedType create(com.google.common.base.Optional<Object> opt) { |
| return new AutoValue_AutoValueTest_InheritsNestedType(opt); |
| } |
| } |
| |
| @Test |
| public void testAmbiguityFromInheritedType() { |
| InheritsNestedType inheritsNestedType = |
| InheritsNestedType.create(com.google.common.base.Optional.absent()); |
| assertEquals(com.google.common.base.Optional.absent(), inheritsNestedType.getOptional()); |
| } |
| |
| abstract static class AbstractParent { |
| abstract int foo(); |
| } |
| |
| @AutoValue |
| abstract static class AbstractChild extends AbstractParent { |
| // The main point of this test is to ensure that we don't try to copy this @Override into the |
| // generated implementation alongside the @Override that we put on all implementation methods. |
| @Override |
| abstract int foo(); |
| |
| static AbstractChild create(int foo) { |
| return new AutoValue_AutoValueTest_AbstractChild(foo); |
| } |
| } |
| |
| @Test |
| public void testOverrideNotDuplicated() { |
| AbstractChild instance = AbstractChild.create(23); |
| assertEquals(23, instance.foo()); |
| } |
| |
| @AutoValue |
| public abstract static class BasicWithBuilder { |
| public abstract int foo(); |
| |
| public static Builder builder() { |
| return new AutoValue_AutoValueTest_BasicWithBuilder.Builder(); |
| } |
| |
| @AutoValue.Builder |
| public interface Builder { |
| Builder foo(int foo); |
| |
| BasicWithBuilder build(); |
| } |
| } |
| |
| @Test |
| public void testBasicWithBuilder() { |
| BasicWithBuilder x = BasicWithBuilder.builder().foo(23).build(); |
| assertEquals(23, x.foo()); |
| try { |
| BasicWithBuilder.builder().build(); |
| fail("Expected exception for missing property"); |
| } catch (IllegalStateException e) { |
| if (omitIdentifiers) { |
| assertThat(e).hasMessageThat().isNull(); |
| } else { |
| assertThat(e).hasMessageThat().contains("foo"); |
| } |
| } |
| } |
| |
| @Test |
| public void testBasicWithBuilderHasOnlyOneConstructor() throws Exception { |
| Class<?> builderClass = AutoValue_AutoValueTest_BasicWithBuilder.Builder.class; |
| Constructor<?>[] constructors = builderClass.getDeclaredConstructors(); |
| assertThat(constructors).hasLength(1); |
| Constructor<?> constructor = constructors[0]; |
| assertThat(constructor.getParameterTypes()).isEmpty(); |
| } |
| |
| @AutoValue |
| public abstract static class EmptyWithBuilder { |
| public static Builder builder() { |
| return new AutoValue_AutoValueTest_EmptyWithBuilder.Builder(); |
| } |
| |
| @AutoValue.Builder |
| public interface Builder { |
| EmptyWithBuilder build(); |
| } |
| } |
| |
| @Test |
| public void testEmptyWithBuilder() { |
| EmptyWithBuilder x = EmptyWithBuilder.builder().build(); |
| EmptyWithBuilder y = EmptyWithBuilder.builder().build(); |
| assertEquals(x, y); |
| } |
| |
| @AutoValue |
| public abstract static class TwoPropertiesWithBuilderClass { |
| public abstract String string(); |
| |
| public abstract int integer(); |
| |
| public static Builder builder() { |
| return new AutoValue_AutoValueTest_TwoPropertiesWithBuilderClass.Builder(); |
| } |
| |
| public static Builder builder(String string) { |
| return new AutoValue_AutoValueTest_TwoPropertiesWithBuilderClass.Builder().string(string); |
| } |
| |
| @AutoValue.Builder |
| public abstract static class Builder { |
| public abstract Builder string(String x); |
| |
| public abstract Builder integer(int x); |
| |
| public abstract TwoPropertiesWithBuilderClass build(); |
| } |
| } |
| |
| @Test |
| public void testTwoPropertiesWithBuilderClass() { |
| TwoPropertiesWithBuilderClass a1 = |
| TwoPropertiesWithBuilderClass.builder().string("23").integer(17).build(); |
| TwoPropertiesWithBuilderClass a2 = |
| TwoPropertiesWithBuilderClass.builder("23").integer(17).build(); |
| TwoPropertiesWithBuilderClass a3 = |
| TwoPropertiesWithBuilderClass.builder().integer(17).string("23").build(); |
| TwoPropertiesWithBuilderClass b = |
| TwoPropertiesWithBuilderClass.builder().string("17").integer(17).build(); |
| new EqualsTester().addEqualityGroup(a1, a2, a3).addEqualityGroup(b).testEquals(); |
| |
| try { |
| TwoPropertiesWithBuilderClass.builder().string(null); |
| fail("Did not get expected exception"); |
| } catch (NullPointerException expected) { |
| } |
| } |
| |
| @AutoValue |
| public abstract static class NullablePropertyWithBuilder { |
| public abstract String notNullable(); |
| |
| @Nullable |
| public abstract String nullable(); |
| |
| public static Builder builder() { |
| return new AutoValue_AutoValueTest_NullablePropertyWithBuilder.Builder(); |
| } |
| |
| @AutoValue.Builder |
| public interface Builder { |
| Builder notNullable(String s); |
| |
| Builder nullable(@Nullable String s); |
| |
| NullablePropertyWithBuilder build(); |
| } |
| } |
| |
| @Test |
| public void testOmitNullableWithBuilder() { |
| NullablePropertyWithBuilder instance1 = |
| NullablePropertyWithBuilder.builder().notNullable("hello").build(); |
| assertThat(instance1.notNullable()).isEqualTo("hello"); |
| assertThat(instance1.nullable()).isNull(); |
| |
| NullablePropertyWithBuilder instance2 = |
| NullablePropertyWithBuilder.builder().notNullable("hello").nullable(null).build(); |
| assertThat(instance2.notNullable()).isEqualTo("hello"); |
| assertThat(instance2.nullable()).isNull(); |
| assertThat(instance1).isEqualTo(instance2); |
| |
| NullablePropertyWithBuilder instance3 = |
| NullablePropertyWithBuilder.builder().notNullable("hello").nullable("world").build(); |
| assertThat(instance3.notNullable()).isEqualTo("hello"); |
| assertThat(instance3.nullable()).isEqualTo("world"); |
| |
| try { |
| NullablePropertyWithBuilder.builder().build(); |
| fail("Expected IllegalStateException for unset non-@Nullable property"); |
| } catch (IllegalStateException e) { |
| if (omitIdentifiers) { |
| assertThat(e).hasMessageThat().isNull(); |
| } else { |
| assertThat(e).hasMessageThat().contains("notNullable"); |
| } |
| } |
| } |
| |
| @AutoValue |
| public abstract static class PrimitiveAndBoxed { |
| public abstract int anInt(); |
| |
| @Nullable |
| public abstract Integer aNullableInteger(); |
| |
| public abstract Integer aNonNullableInteger(); |
| |
| public abstract Builder toBuilder(); |
| |
| public static Builder builder() { |
| return new AutoValue_AutoValueTest_PrimitiveAndBoxed.Builder(); |
| } |
| |
| @AutoValue.Builder |
| public interface Builder { |
| Builder setAnInt(Integer x); |
| |
| Builder setANullableInteger(int x); |
| |
| Builder setANonNullableInteger(int x); |
| |
| PrimitiveAndBoxed build(); |
| } |
| } |
| |
| @Test |
| public void testPrimitiveAndBoxed() { |
| PrimitiveAndBoxed instance1 = |
| PrimitiveAndBoxed.builder().setAnInt(17).setANonNullableInteger(23).build(); |
| assertThat(instance1.anInt()).isEqualTo(17); |
| assertThat(instance1.aNullableInteger()).isNull(); |
| assertThat(instance1.aNonNullableInteger()).isEqualTo(23); |
| |
| PrimitiveAndBoxed instance2 = instance1.toBuilder().setANullableInteger(5).build(); |
| assertThat(instance2.aNullableInteger()).isEqualTo(5); |
| |
| try { |
| instance1.toBuilder().setAnInt(null); |
| fail(); |
| } catch (NullPointerException expected) { |
| } |
| } |
| |
| @AutoValue |
| public abstract static class OptionalPropertiesWithBuilder { |
| public abstract com.google.common.base.Optional<String> optionalString(); |
| |
| public abstract com.google.common.base.Optional<Integer> optionalInteger(); |
| |
| public static Builder builder() { |
| return new AutoValue_AutoValueTest_OptionalPropertiesWithBuilder.Builder(); |
| } |
| |
| @AutoValue.Builder |
| public interface Builder { |
| Builder setOptionalString(com.google.common.base.Optional<String> s); |
| |
| Builder setOptionalString(String s); |
| |
| Builder setOptionalInteger(com.google.common.base.Optional<Integer> i); |
| |
| Builder setOptionalInteger(int i); |
| |
| OptionalPropertiesWithBuilder build(); |
| } |
| } |
| |
| @Test |
| public void testOmitOptionalWithBuilder() { |
| OptionalPropertiesWithBuilder omitted = OptionalPropertiesWithBuilder.builder().build(); |
| assertThat(omitted.optionalString()).isAbsent(); |
| assertThat(omitted.optionalInteger()).isAbsent(); |
| |
| OptionalPropertiesWithBuilder supplied = |
| OptionalPropertiesWithBuilder.builder() |
| .setOptionalString(com.google.common.base.Optional.of("foo")) |
| .build(); |
| assertThat(supplied.optionalString()).hasValue("foo"); |
| assertThat(omitted.optionalInteger()).isAbsent(); |
| |
| OptionalPropertiesWithBuilder suppliedDirectly = |
| OptionalPropertiesWithBuilder.builder() |
| .setOptionalString("foo") |
| .setOptionalInteger(23) |
| .build(); |
| assertThat(suppliedDirectly.optionalString()).hasValue("foo"); |
| assertThat(suppliedDirectly.optionalInteger()).hasValue(23); |
| } |
| |
| @AutoValue |
| public abstract static class OptionalPropertyWithNullableBuilder { |
| public abstract String notOptional(); |
| |
| public abstract com.google.common.base.Optional<String> optional(); |
| |
| public static Builder builder() { |
| return new AutoValue_AutoValueTest_OptionalPropertyWithNullableBuilder.Builder(); |
| } |
| |
| @AutoValue.Builder |
| public interface Builder { |
| Builder notOptional(String s); |
| |
| Builder optional(@Nullable String s); |
| |
| OptionalPropertyWithNullableBuilder build(); |
| } |
| } |
| |
| @Test |
| public void testOmitOptionalWithNullableBuilder() { |
| OptionalPropertyWithNullableBuilder instance1 = |
| OptionalPropertyWithNullableBuilder.builder().notOptional("hello").build(); |
| assertThat(instance1.notOptional()).isEqualTo("hello"); |
| assertThat(instance1.optional()).isAbsent(); |
| |
| OptionalPropertyWithNullableBuilder instance2 = |
| OptionalPropertyWithNullableBuilder.builder().notOptional("hello").optional(null).build(); |
| assertThat(instance2.notOptional()).isEqualTo("hello"); |
| assertThat(instance2.optional()).isAbsent(); |
| assertThat(instance1).isEqualTo(instance2); |
| |
| OptionalPropertyWithNullableBuilder instance3 = |
| OptionalPropertyWithNullableBuilder.builder() |
| .notOptional("hello") |
| .optional("world") |
| .build(); |
| assertThat(instance3.notOptional()).isEqualTo("hello"); |
| assertThat(instance3.optional()).hasValue("world"); |
| |
| try { |
| OptionalPropertyWithNullableBuilder.builder().build(); |
| fail("Expected IllegalStateException for unset non-Optional property"); |
| } catch (IllegalStateException expected) { |
| } |
| } |
| |
| @AutoValue |
| public abstract static class NullableOptionalPropertiesWithBuilder { |
| @Nullable |
| public abstract com.google.common.base.Optional<String> optionalString(); |
| |
| public static Builder builder() { |
| return new AutoValue_AutoValueTest_NullableOptionalPropertiesWithBuilder.Builder(); |
| } |
| |
| @AutoValue.Builder |
| public interface Builder { |
| Builder setOptionalString(com.google.common.base.Optional<String> s); |
| |
| NullableOptionalPropertiesWithBuilder build(); |
| } |
| } |
| |
| @Test |
| public void testOmitNullableOptionalWithBuilder() { |
| NullableOptionalPropertiesWithBuilder omitted = |
| NullableOptionalPropertiesWithBuilder.builder().build(); |
| assertThat(omitted.optionalString()).isNull(); |
| |
| NullableOptionalPropertiesWithBuilder supplied = |
| NullableOptionalPropertiesWithBuilder.builder() |
| .setOptionalString(com.google.common.base.Optional.of("foo")) |
| .build(); |
| assertThat(supplied.optionalString()).hasValue("foo"); |
| } |
| |
| @AutoValue |
| public abstract static class OptionalPropertiesWithBuilderSimpleSetter { |
| public abstract com.google.common.base.Optional<String> optionalString(); |
| |
| public static Builder builder() { |
| return new AutoValue_AutoValueTest_OptionalPropertiesWithBuilderSimpleSetter.Builder(); |
| } |
| |
| @AutoValue.Builder |
| public interface Builder { |
| Builder setOptionalString(String s); |
| |
| OptionalPropertiesWithBuilderSimpleSetter build(); |
| } |
| } |
| |
| @Test |
| public void testOptionalPropertySimpleSetter() { |
| OptionalPropertiesWithBuilderSimpleSetter omitted = |
| OptionalPropertiesWithBuilderSimpleSetter.builder().build(); |
| assertThat(omitted.optionalString()).isAbsent(); |
| |
| OptionalPropertiesWithBuilderSimpleSetter supplied = |
| OptionalPropertiesWithBuilderSimpleSetter.builder().setOptionalString("foo").build(); |
| assertThat(supplied.optionalString()).hasValue("foo"); |
| } |
| |
| @AutoValue |
| public abstract static class PropertyWithOptionalGetter { |
| public abstract String getString(); |
| |
| public abstract int getInt(); |
| |
| public static Builder builder() { |
| return new AutoValue_AutoValueTest_PropertyWithOptionalGetter.Builder(); |
| } |
| |
| @AutoValue.Builder |
| public interface Builder { |
| Builder setString(String s); |
| |
| com.google.common.base.Optional<String> getString(); |
| |
| Builder setInt(int x); |
| |
| com.google.common.base.Optional<Integer> getInt(); |
| |
| PropertyWithOptionalGetter build(); |
| } |
| } |
| |
| @Test |
| public void testOptionalGetter() { |
| PropertyWithOptionalGetter.Builder omitted = PropertyWithOptionalGetter.builder(); |
| assertThat(omitted.getString()).isAbsent(); |
| assertThat(omitted.getInt()).isAbsent(); |
| |
| PropertyWithOptionalGetter.Builder supplied = |
| PropertyWithOptionalGetter.builder().setString("foo").setInt(23); |
| assertThat(supplied.getString()).hasValue("foo"); |
| assertThat(supplied.getInt()).hasValue(23); |
| } |
| |
| @AutoValue |
| public abstract static class PropertyNamedMissing { |
| public abstract String missing(); |
| |
| public static Builder builder() { |
| return new AutoValue_AutoValueTest_PropertyNamedMissing.Builder(); |
| } |
| |
| @AutoValue.Builder |
| public abstract static class Builder { |
| public abstract Builder setMissing(String x); |
| |
| public abstract PropertyNamedMissing build(); |
| } |
| } |
| |
| // https://github.com/google/auto/issues/412 |
| @Test |
| public void testPropertyNamedMissing() { |
| try { |
| PropertyNamedMissing.builder().build(); |
| fail(); |
| } catch (IllegalStateException expected) { |
| } |
| PropertyNamedMissing x = PropertyNamedMissing.builder().setMissing("foo").build(); |
| assertThat(x.missing()).isEqualTo("foo"); |
| } |
| |
| @AutoValue |
| public abstract static class GenericsWithBuilder<T extends Number & Comparable<T>, U extends T> { |
| public abstract List<T> list(); |
| |
| public abstract U u(); |
| |
| public static <T extends Number & Comparable<T>, U extends T> Builder<T, U> builder() { |
| return new AutoValue_AutoValueTest_GenericsWithBuilder.Builder<T, U>(); |
| } |
| |
| public abstract Builder<T, U> toBuilderGenerated(); |
| |
| @AutoValue.Builder |
| public interface Builder<T extends Number & Comparable<T>, U extends T> { |
| Builder<T, U> list(List<T> list); |
| |
| Builder<T, U> u(U u); |
| |
| GenericsWithBuilder<T, U> build(); |
| } |
| } |
| |
| @Test |
| public void testBuilderGenerics() { |
| List<Integer> integers = ImmutableList.of(1, 2, 3); |
| GenericsWithBuilder<Integer, Integer> instance = |
| GenericsWithBuilder.<Integer, Integer>builder().list(integers).u(23).build(); |
| assertEquals(integers, instance.list()); |
| assertEquals((Integer) 23, instance.u()); |
| |
| GenericsWithBuilder<Integer, Integer> instance2 = instance.toBuilderGenerated().build(); |
| assertEquals(instance, instance2); |
| assertNotSame(instance, instance2); |
| |
| GenericsWithBuilder<Integer, Integer> instance3 = instance.toBuilderGenerated().u(17).build(); |
| assertEquals(integers, instance3.list()); |
| assertEquals((Integer) 17, instance3.u()); |
| } |
| |
| @AutoValue |
| public abstract static class BuilderWithSet<T extends Comparable<T>> { |
| public abstract List<T> list(); |
| |
| public abstract T t(); |
| |
| public static <T extends Comparable<T>> Builder<T> builder() { |
| return new AutoValue_AutoValueTest_BuilderWithSet.Builder<T>(); |
| } |
| |
| @AutoValue.Builder |
| public interface Builder<T extends Comparable<T>> { |
| Builder<T> setList(List<T> list); |
| |
| Builder<T> setT(T t); |
| |
| BuilderWithSet<T> build(); |
| } |
| } |
| |
| @Test |
| public void testBuilderWithSet() { |
| List<Integer> integers = ImmutableList.of(1, 2, 3); |
| BuilderWithSet<Integer> instance = |
| BuilderWithSet.<Integer>builder().setList(integers).setT(23).build(); |
| assertEquals(integers, instance.list()); |
| assertEquals((Integer) 23, instance.t()); |
| } |
| |
| @AutoValue |
| public abstract static class BuilderWithSetAndGet { |
| public abstract List<Integer> getAList(); |
| |
| public abstract int getAnInt(); |
| |
| public static Builder builder() { |
| return new AutoValue_AutoValueTest_BuilderWithSetAndGet.Builder(); |
| } |
| |
| public abstract Builder toBuilder(); |
| |
| @AutoValue.Builder |
| public interface Builder { |
| Builder setAList(List<Integer> list); |
| |
| Builder setAnInt(int i); |
| |
| BuilderWithSetAndGet build(); |
| } |
| } |
| |
| @Test |
| public void testBuilderWithSetAndGet() { |
| List<Integer> integers = ImmutableList.of(1, 2, 3); |
| BuilderWithSetAndGet instance = |
| BuilderWithSetAndGet.builder().setAList(integers).setAnInt(23).build(); |
| assertEquals(integers, instance.getAList()); |
| assertEquals(23, instance.getAnInt()); |
| |
| BuilderWithSetAndGet instance2 = instance.toBuilder().build(); |
| assertEquals(instance, instance2); |
| assertNotSame(instance, instance2); |
| |
| BuilderWithSetAndGet instance3 = instance.toBuilder().setAnInt(17).build(); |
| assertEquals(integers, instance3.getAList()); |
| assertEquals(17, instance3.getAnInt()); |
| } |
| |
| @AutoValue |
| public abstract static class BuilderWithUnprefixedGetters<T extends Comparable<T>> { |
| public abstract ImmutableList<T> list(); |
| |
| @Nullable |
| public abstract T t(); |
| |
| @SuppressWarnings("mutable") |
| public abstract int[] ints(); |
| |
| public abstract int noGetter(); |
| |
| public abstract String oAuth(); |
| |
| public abstract String oBrien(); |
| |
| public static <T extends Comparable<T>> Builder<T> builder() { |
| return new AutoValue_AutoValueTest_BuilderWithUnprefixedGetters.Builder<T>(); |
| } |
| |
| @AutoValue.Builder |
| public interface Builder<T extends Comparable<T>> { |
| Builder<T> setList(ImmutableList<T> list); |
| |
| Builder<T> setT(T t); |
| |
| Builder<T> setInts(int[] ints); |
| |
| Builder<T> setNoGetter(int x); |
| |
| Builder<T> setoAuth(String x); // this ugly spelling is for compatibility |
| |
| Builder<T> setOBrien(String x); |
| |
| ImmutableList<T> list(); |
| |
| T t(); |
| |
| int[] ints(); |
| |
| String oAuth(); |
| |
| String oBrien(); |
| |
| BuilderWithUnprefixedGetters<T> build(); |
| } |
| } |
| |
| @Test |
| public void testBuilderWithUnprefixedGetter() { |
| ImmutableList<String> names = ImmutableList.of("fred", "jim"); |
| int[] ints = {6, 28, 496, 8128, 33550336}; |
| int noGetter = -1; |
| |
| BuilderWithUnprefixedGetters.Builder<String> builder = BuilderWithUnprefixedGetters.builder(); |
| assertNull(builder.t()); |
| try { |
| builder.list(); |
| fail("Attempt to retrieve unset list property should have failed"); |
| } catch (IllegalStateException e) { |
| if (omitIdentifiers) { |
| assertThat(e).hasMessageThat().isNull(); |
| } else { |
| assertThat(e).hasMessageThat().isEqualTo("Property \"list\" has not been set"); |
| } |
| } |
| try { |
| builder.ints(); |
| fail("Attempt to retrieve unset ints property should have failed"); |
| } catch (IllegalStateException e) { |
| if (omitIdentifiers) { |
| assertThat(e).hasMessageThat().isNull(); |
| } else { |
| assertThat(e).hasMessageThat().isEqualTo("Property \"ints\" has not been set"); |
| } |
| } |
| |
| builder.setList(names); |
| assertThat(builder.list()).isSameInstanceAs(names); |
| builder.setInts(ints); |
| assertThat(builder.ints()).isEqualTo(ints); |
| builder.setoAuth("OAuth"); |
| assertThat(builder.oAuth()).isEqualTo("OAuth"); |
| builder.setOBrien("Flann"); |
| assertThat(builder.oBrien()).isEqualTo("Flann"); |
| // The array is not cloned by the getter, so the client can modify it (but shouldn't). |
| ints[0] = 0; |
| assertThat(builder.ints()[0]).isEqualTo(0); |
| ints[0] = 6; |
| |
| BuilderWithUnprefixedGetters<String> instance = builder.setNoGetter(noGetter).build(); |
| assertThat(instance.list()).isSameInstanceAs(names); |
| assertThat(instance.t()).isNull(); |
| assertThat(instance.ints()).isEqualTo(ints); |
| assertThat(instance.noGetter()).isEqualTo(noGetter); |
| assertThat(instance.oAuth()).isEqualTo("OAuth"); |
| assertThat(instance.oBrien()).isEqualTo("Flann"); |
| } |
| |
| @AutoValue |
| public abstract static class BuilderWithPrefixedGetters<T extends Comparable<T>> { |
| public abstract ImmutableList<T> getList(); |
| |
| public abstract T getT(); |
| |
| @SuppressWarnings("mutable") |
| @Nullable |
| public abstract int[] getInts(); |
| |
| public abstract String getOAuth(); |
| |
| public abstract int getNoGetter(); |
| |
| public static <T extends Comparable<T>> Builder<T> builder() { |
| return new AutoValue_AutoValueTest_BuilderWithPrefixedGetters.Builder<T>(); |
| } |
| |
| @AutoValue.Builder |
| public abstract static class Builder<T extends Comparable<T>> { |
| public abstract Builder<T> setList(ImmutableList<T> list); |
| |
| public abstract Builder<T> setT(T t); |
| |
| public abstract Builder<T> setInts(int[] ints); |
| |
| public abstract Builder<T> setNoGetter(int x); |
| |
| public abstract Builder<T> setOAuth(String x); |
| |
| abstract ImmutableList<T> getList(); |
| |
| abstract T getT(); |
| |
| abstract int[] getInts(); |
| |
| public abstract BuilderWithPrefixedGetters<T> build(); |
| } |
| } |
| |
| @Test |
| public void testBuilderWithPrefixedGetter() { |
| ImmutableList<String> names = ImmutableList.of("fred", "jim"); |
| String name = "sheila"; |
| int noGetter = -1; |
| |
| BuilderWithPrefixedGetters.Builder<String> builder = BuilderWithPrefixedGetters.builder(); |
| assertThat(builder.getInts()).isNull(); |
| try { |
| builder.getList(); |
| fail("Attempt to retrieve unset list property should have failed"); |
| } catch (IllegalStateException e) { |
| if (omitIdentifiers) { |
| assertThat(e).hasMessageThat().isNull(); |
| } else { |
| assertThat(e).hasMessageThat().isEqualTo("Property \"list\" has not been set"); |
| } |
| } |
| |
| builder.setList(names); |
| assertThat(builder.getList()).isSameInstanceAs(names); |
| builder.setT(name); |
| assertThat(builder.getInts()).isNull(); |
| builder.setOAuth("OAuth"); |
| |
| BuilderWithPrefixedGetters<String> instance = builder.setNoGetter(noGetter).build(); |
| assertThat(instance.getList()).isSameInstanceAs(names); |
| assertThat(instance.getT()).isEqualTo(name); |
| assertThat(instance.getInts()).isNull(); |
| assertThat(instance.getNoGetter()).isEqualTo(noGetter); |
| assertThat(instance.getOAuth()).isEqualTo("OAuth"); |
| } |
| |
| @AutoValue |
| public abstract static class BuilderWithPropertyBuilders<FooT extends Comparable<FooT>> { |
| public abstract ImmutableList<FooT> getFoos(); |
| |
| public abstract ImmutableSet<String> getStrings(); |
| |
| public abstract BuilderWithPropertyBuilders.Builder<FooT> toBuilder(); |
| |
| public static <FooT extends Comparable<FooT>> Builder<FooT> builder() { |
| return new AutoValue_AutoValueTest_BuilderWithPropertyBuilders.Builder<FooT>(); |
| } |
| |
| @AutoValue.Builder |
| public abstract static class Builder<FooT extends Comparable<FooT>> { |
| public abstract ImmutableList<FooT> getFoos(); |
| |
| public Builder<FooT> addFoos(Iterable<FooT> foos) { |
| foosBuilder().addAll(foos); |
| return this; |
| } |
| |
| abstract ImmutableList.Builder<FooT> foosBuilder(); |
| |
| public Builder<FooT> addToTs(FooT element) { |
| foosBuilder().add(element); |
| return this; |
| } |
| |
| abstract Builder<FooT> setStrings(ImmutableList<String> strings); |
| |
| abstract ImmutableSet.Builder<String> stringsBuilder(); |
| |
| public Builder<FooT> addToStrings(String element) { |
| stringsBuilder().add(element); |
| return this; |
| } |
| |
| public abstract BuilderWithPropertyBuilders<FooT> build(); |
| } |
| } |
| |
| @Test |
| public void testBuilderWithPropertyBuilders() { |
| ImmutableList<Integer> numbers = ImmutableList.of(1, 1, 2, 6, 24); |
| ImmutableSet<String> names = ImmutableSet.of("one", "two", "six", "twenty-four"); |
| |
| BuilderWithPropertyBuilders<Integer> a = |
| BuilderWithPropertyBuilders.<Integer>builder() |
| .addFoos(numbers) |
| .addToStrings("one") |
| .addToStrings("two") |
| .addToStrings("six") |
| .addToStrings("twenty-four") |
| .build(); |
| |
| assertEquals(numbers, a.getFoos()); |
| assertEquals(names, a.getStrings()); |
| |
| BuilderWithPropertyBuilders.Builder<Integer> bBuilder = BuilderWithPropertyBuilders.builder(); |
| bBuilder.stringsBuilder().addAll(names); |
| bBuilder.foosBuilder().addAll(numbers); |
| |
| assertEquals(numbers, bBuilder.getFoos()); |
| |
| BuilderWithPropertyBuilders<Integer> b = bBuilder.build(); |
| assertEquals(a, b); |
| |
| BuilderWithPropertyBuilders.Builder<Integer> cBuilder = a.toBuilder(); |
| cBuilder.addToStrings("one hundred and twenty"); |
| cBuilder.addToTs(120); |
| BuilderWithPropertyBuilders<Integer> c = cBuilder.build(); |
| assertEquals( |
| ImmutableSet.of("one", "two", "six", "twenty-four", "one hundred and twenty"), |
| c.getStrings()); |
| assertEquals(ImmutableList.of(1, 1, 2, 6, 24, 120), c.getFoos()); |
| |
| BuilderWithPropertyBuilders.Builder<Integer> dBuilder = a.toBuilder(); |
| dBuilder.addFoos(ImmutableList.of(120, 720)); |
| BuilderWithPropertyBuilders<Integer> d = dBuilder.build(); |
| assertEquals(ImmutableList.of(1, 1, 2, 6, 24, 120, 720), d.getFoos()); |
| assertEquals(names, d.getStrings()); |
| |
| BuilderWithPropertyBuilders<Integer> empty = |
| BuilderWithPropertyBuilders.<Integer>builder().build(); |
| assertEquals(ImmutableList.of(), empty.getFoos()); |
| assertEquals(ImmutableSet.of(), empty.getStrings()); |
| |
| try { |
| BuilderWithPropertyBuilders.<Integer>builder().setStrings(null).build(); |
| fail("Did not get expected exception"); |
| } catch (RuntimeException expected) { |
| // We don't specify whether you get the exception on setStrings(null) or on build(), nor |
| // which exception it is exactly. |
| } |
| } |
| |
| interface ImmutableListOf<T> { |
| ImmutableList<T> list(); |
| } |
| |
| @AutoValue |
| abstract static class PropertyBuilderInheritsType implements ImmutableListOf<String> { |
| static Builder builder() { |
| return new AutoValue_AutoValueTest_PropertyBuilderInheritsType.Builder(); |
| } |
| |
| @AutoValue.Builder |
| abstract static class Builder { |
| abstract ImmutableList.Builder<String> listBuilder(); |
| abstract PropertyBuilderInheritsType build(); |
| } |
| } |
| |
| @Test |
| public void propertyBuilderInheritsType() { |
| PropertyBuilderInheritsType.Builder builder = PropertyBuilderInheritsType.builder(); |
| builder.listBuilder().add("foo", "bar"); |
| PropertyBuilderInheritsType x = builder.build(); |
| assertThat(x.list()).containsExactly("foo", "bar").inOrder(); |
| } |
| |
| @AutoValue |
| public abstract static class BuilderWithExoticPropertyBuilders< |
| K extends Number, V extends Comparable<K>> { |
| public abstract ImmutableMap<String, V> map(); |
| |
| public abstract ImmutableTable<String, K, V> table(); |
| |
| public static <K extends Number, V extends Comparable<K>> Builder<K, V> builder() { |
| return new AutoValue_AutoValueTest_BuilderWithExoticPropertyBuilders.Builder<K, V>(); |
| } |
| |
| @AutoValue.Builder |
| public abstract static class Builder<K extends Number, V extends Comparable<K>> { |
| public Builder<K, V> putAll(Map<String, V> map) { |
| mapBuilder().putAll(map); |
| return this; |
| } |
| |
| public abstract ImmutableMap.Builder<String, V> mapBuilder(); |
| |
| public Builder<K, V> putAll(ImmutableTable<String, K, V> table) { |
| tableBuilder().putAll(table); |
| return this; |
| } |
| |
| public abstract ImmutableTable.Builder<String, K, V> tableBuilder(); |
| |
| public abstract BuilderWithExoticPropertyBuilders<K, V> build(); |
| } |
| } |
| |
| @Test |
| public void testBuilderWithExoticPropertyBuilders() { |
| ImmutableMap<String, Integer> map = ImmutableMap.of("one", 1); |
| ImmutableTable<String, Integer, Integer> table = ImmutableTable.of("one", 1, -1); |
| |
| BuilderWithExoticPropertyBuilders<Integer, Integer> a = |
| BuilderWithExoticPropertyBuilders.<Integer, Integer>builder() |
| .putAll(map) |
| .putAll(table) |
| .build(); |
| assertEquals(map, a.map()); |
| assertEquals(table, a.table()); |
| |
| BuilderWithExoticPropertyBuilders.Builder<Integer, Integer> bBuilder = |
| BuilderWithExoticPropertyBuilders.builder(); |
| bBuilder.mapBuilder().putAll(map); |
| bBuilder.tableBuilder().putAll(table); |
| BuilderWithExoticPropertyBuilders<Integer, Integer> b = bBuilder.build(); |
| assertEquals(a, b); |
| |
| BuilderWithExoticPropertyBuilders<Integer, Integer> empty = |
| BuilderWithExoticPropertyBuilders.<Integer, Integer>builder().build(); |
| assertEquals(ImmutableMap.of(), empty.map()); |
| assertEquals(ImmutableTable.of(), empty.table()); |
| } |
| |
| @AutoValue |
| public abstract static class BuilderWithCopyingSetters<T extends Number> { |
| public abstract ImmutableSet<? extends T> things(); |
| |
| public abstract ImmutableList<Number> numbers(); |
| |
| public abstract ImmutableMap<String, T> map(); |
| |
| public static <T extends Number> Builder<T> builder(T value) { |
| return new AutoValue_AutoValueTest_BuilderWithCopyingSetters.Builder<T>() |
| .setNumbers(ImmutableSet.of(17, 23.0)) |
| .setMap(Collections.singletonMap("foo", value)); |
| } |
| |
| @AutoValue.Builder |
| public interface Builder<T extends Number> { |
| Builder<T> setThings(ImmutableSet<T> things); |
| |
| Builder<T> setThings(Iterable<? extends T> things); |
| |
| Builder<T> setThings(T... things); |
| |
| Builder<T> setNumbers(Collection<? extends Number> strings); |
| |
| Builder<T> setMap(Map<String, T> map); |
| |
| BuilderWithCopyingSetters<T> build(); |
| } |
| } |
| |
| @Test |
| public void testBuilderWithCopyingSetters() { |
| BuilderWithCopyingSetters.Builder<Integer> builder = BuilderWithCopyingSetters.builder(23); |
| |
| BuilderWithCopyingSetters<Integer> a = builder.setThings(ImmutableSet.of(1, 2)).build(); |
| assertThat(a.things()).containsExactly(1, 2); |
| assertThat(a.numbers()).containsExactly(17, 23.0).inOrder(); |
| assertThat(a.map()).containsExactly("foo", 23); |
| |
| BuilderWithCopyingSetters<Integer> b = builder.setThings(Arrays.asList(1, 2)).build(); |
| assertThat(b).isEqualTo(a); |
| |
| BuilderWithCopyingSetters<Integer> c = builder.setThings(1, 2).build(); |
| assertThat(c).isEqualTo(a); |
| } |
| |
| @AutoValue |
| public abstract static class BuilderWithImmutableSorted<T extends Comparable<T>> { |
| public abstract ImmutableSortedSet<T> sortedSet(); |
| |
| public abstract ImmutableSortedMap<T, Integer> sortedMap(); |
| |
| public static <T extends Comparable<T>> Builder<T> builder() { |
| return new AutoValue_AutoValueTest_BuilderWithImmutableSorted.Builder<T>() |
| .setSortedSet(new TreeSet<T>()) |
| .setSortedMap(new TreeMap<T, Integer>()); |
| } |
| |
| @AutoValue.Builder |
| public interface Builder<T extends Comparable<T>> { |
| @SuppressWarnings("unchecked") |
| Builder<T> setSortedSet(T... x); |
| |
| Builder<T> setSortedSet(NavigableSet<T> x); |
| |
| ImmutableSortedSet.Builder<T> sortedSetBuilder(); |
| |
| Builder<T> setSortedMap(SortedMap<T, Integer> x); |
| |
| Builder<T> setSortedMap(NavigableMap<T, Integer> x); |
| |
| ImmutableSortedMap.Builder<T, Integer> sortedMapBuilder(); |
| |
| BuilderWithImmutableSorted<T> build(); |
| } |
| } |
| |
| @Test |
| public void testBuilderWithImmutableSorted_Varargs() { |
| BuilderWithImmutableSorted<String> x = |
| BuilderWithImmutableSorted.<String>builder().setSortedSet("foo", "bar", "baz").build(); |
| assertThat(x.sortedSet()).containsExactly("bar", "baz", "foo").inOrder(); |
| } |
| |
| @Test |
| public void testBuilderWithImmutableSorted_SetSet() { |
| BuilderWithImmutableSorted<String> x = |
| BuilderWithImmutableSorted.<String>builder() |
| .setSortedSet(new TreeSet<String>(String.CASE_INSENSITIVE_ORDER)) |
| .build(); |
| assertThat(x.sortedSet().comparator()).isEqualTo(String.CASE_INSENSITIVE_ORDER); |
| } |
| |
| @Test |
| public void testBuilderWithImmutableSorted_SetMap() { |
| BuilderWithImmutableSorted<String> x = |
| BuilderWithImmutableSorted.<String>builder() |
| .setSortedMap(new TreeMap<String, Integer>(String.CASE_INSENSITIVE_ORDER)) |
| .build(); |
| assertThat(x.sortedMap().comparator()).isEqualTo(String.CASE_INSENSITIVE_ORDER); |
| } |
| |
| @Test |
| public void testBuilderWithImmutableSorted_SetCollectionBuilder() { |
| BuilderWithImmutableSorted.Builder<String> builder = |
| BuilderWithImmutableSorted.<String>builder(); |
| builder.sortedSetBuilder().add("is", "ea", "id"); |
| BuilderWithImmutableSorted<String> x = builder.build(); |
| assertThat(x.sortedSet()).containsExactly("ea", "id", "is").inOrder(); |
| } |
| |
| @Test |
| public void testBuilderWithImmutableSorted_MapCollectionBuilder() { |
| BuilderWithImmutableSorted.Builder<String> builder = |
| BuilderWithImmutableSorted.<String>builder(); |
| builder.sortedMapBuilder().put("two", 2).put("one", 1); |
| BuilderWithImmutableSorted<String> x = builder.build(); |
| assertThat(x.sortedMap()).containsExactly("one", 1, "two", 2).inOrder(); |
| } |
| |
| @AutoValue |
| public abstract static class BuilderWithCollectionBuilderAndSetter<T extends Number> { |
| public abstract ImmutableList<T> things(); |
| |
| public static <T extends Number> Builder<T> builder() { |
| return new AutoValue_AutoValueTest_BuilderWithCollectionBuilderAndSetter.Builder<T>(); |
| } |
| |
| @AutoValue.Builder |
| public interface Builder<T extends Number> { |
| Builder<T> setThings(List<T> things); |
| |
| ImmutableList<T> things(); |
| |
| ImmutableList.Builder<T> thingsBuilder(); |
| |
| BuilderWithCollectionBuilderAndSetter<T> build(); |
| } |
| } |
| |
| @Test |
| public void testBuilderAndSetterDefaultsEmpty() { |
| BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder = |
| BuilderWithCollectionBuilderAndSetter.<Integer>builder(); |
| assertThat(builder.things()).isEmpty(); |
| assertThat(builder.build().things()).isEmpty(); |
| } |
| |
| @Test |
| public void testBuilderAndSetterUsingBuilder() { |
| BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder = |
| BuilderWithCollectionBuilderAndSetter.builder(); |
| builder.thingsBuilder().add(17, 23); |
| BuilderWithCollectionBuilderAndSetter<Integer> x = builder.build(); |
| assertThat(x.things()).isEqualTo(ImmutableList.of(17, 23)); |
| } |
| |
| @Test |
| public void testBuilderAndSetterUsingSetter() { |
| ImmutableList<Integer> things = ImmutableList.of(17, 23); |
| BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder = |
| BuilderWithCollectionBuilderAndSetter.<Integer>builder().setThings(things); |
| assertThat(builder.things()).isSameInstanceAs(things); |
| assertThat(builder.build().things()).isSameInstanceAs(things); |
| |
| List<Integer> moreThings = Arrays.asList(5, 17, 23); |
| BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder2 = |
| BuilderWithCollectionBuilderAndSetter.<Integer>builder().setThings(moreThings); |
| assertThat(builder2.things()).isEqualTo(moreThings); |
| assertThat(builder2.build().things()).isEqualTo(moreThings); |
| } |
| |
| @Test |
| public void testBuilderAndSetterUsingSetterThenBuilder() { |
| BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder = |
| BuilderWithCollectionBuilderAndSetter.builder(); |
| builder.setThings(ImmutableList.of(5)); |
| builder.thingsBuilder().add(17, 23); |
| List<Integer> expectedThings = ImmutableList.of(5, 17, 23); |
| assertThat(builder.things()).isEqualTo(expectedThings); |
| assertThat(builder.build().things()).isEqualTo(expectedThings); |
| } |
| |
| @Test |
| public void testBuilderAndSetterCannotSetAfterBuilder() { |
| BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder = |
| BuilderWithCollectionBuilderAndSetter.builder(); |
| builder.setThings(ImmutableList.of(5)); |
| builder.thingsBuilder().add(17, 23); |
| try { |
| builder.setThings(ImmutableList.of(1729)); |
| fail("Setting list after retrieving builder should provoke an exception"); |
| } catch (IllegalStateException e) { |
| if (omitIdentifiers) { |
| assertThat(e).hasMessageThat().isNull(); |
| } else { |
| assertThat(e).hasMessageThat().isEqualTo("Cannot set things after calling thingsBuilder()"); |
| } |
| } |
| } |
| |
| abstract static class AbstractParentWithBuilder { |
| abstract String foo(); |
| |
| abstract static class Builder<B extends Builder<B>> { |
| abstract B foo(String s); |
| } |
| } |
| |
| @AutoValue |
| abstract static class ChildWithBuilder extends AbstractParentWithBuilder { |
| abstract String bar(); |
| |
| static Builder builder() { |
| return new AutoValue_AutoValueTest_ChildWithBuilder.Builder(); |
| } |
| |
| @AutoValue.Builder |
| abstract static class Builder extends AbstractParentWithBuilder.Builder<Builder> { |
| abstract Builder bar(String s); |
| |
| abstract ChildWithBuilder build(); |
| } |
| } |
| |
| @Test |
| public void testInheritedBuilder() { |
| ChildWithBuilder x = ChildWithBuilder.builder().foo("foo").bar("bar").build(); |
| assertThat(x.foo()).isEqualTo("foo"); |
| assertThat(x.bar()).isEqualTo("bar"); |
| } |
| |
| @Retention(RetentionPolicy.RUNTIME) |
| @interface GwtCompatible { |
| boolean funky() default false; |
| } |
| |
| @AutoValue |
| @GwtCompatible(funky = true) |
| abstract static class GwtCompatibleTest { |
| abstract int foo(); |
| |
| static GwtCompatibleTest create(int foo) { |
| return new AutoValue_AutoValueTest_GwtCompatibleTest(foo); |
| } |
| } |
| |
| @AutoValue |
| @GwtCompatible |
| abstract static class GwtCompatibleTestNoArgs { |
| abstract String bar(); |
| |
| static GwtCompatibleTestNoArgs create(String bar) { |
| return new AutoValue_AutoValueTest_GwtCompatibleTestNoArgs(bar); |
| } |
| } |
| |
| @Test |
| public void testGwtCompatibleInherited() { |
| GwtCompatibleTest test = GwtCompatibleTest.create(23); |
| GwtCompatible gwtCompatible = test.getClass().getAnnotation(GwtCompatible.class); |
| assertNotNull(gwtCompatible); |
| assertTrue(gwtCompatible.funky()); |
| |
| GwtCompatibleTestNoArgs testNoArgs = GwtCompatibleTestNoArgs.create("23"); |
| GwtCompatible gwtCompatibleNoArgs = testNoArgs.getClass().getAnnotation(GwtCompatible.class); |
| assertNotNull(gwtCompatibleNoArgs); |
| assertFalse(gwtCompatibleNoArgs.funky()); |
| } |
| |
| @interface NestedAnnotation { |
| int anInt(); |
| |
| Class<?>[] aClassArray(); |
| } |
| |
| @Retention(RetentionPolicy.RUNTIME) |
| @interface HairyAnnotation { |
| String aString(); |
| |
| Class<? extends Number> aClass(); |
| |
| RetentionPolicy anEnum(); |
| |
| NestedAnnotation anAnnotation(); |
| } |
| |
| @Retention(RetentionPolicy.RUNTIME) |
| @interface CopiedAnnotation {} |
| |
| @Retention(RetentionPolicy.RUNTIME) |
| @interface ExcludedAnnotation {} |
| |
| @Retention(RetentionPolicy.RUNTIME) |
| @Inherited |
| @interface InheritedAnnotation {} |
| |
| @CopiedAnnotation |
| @ExcludedAnnotation |
| @InheritedAnnotation |
| @AutoValue |
| @AutoValue.CopyAnnotations(exclude = {ExcludedAnnotation.class}) |
| abstract static class CopyAnnotation { |
| @HairyAnnotation( |
| aString = "hello", |
| aClass = Integer.class, |
| anEnum = RetentionPolicy.RUNTIME, |
| anAnnotation = |
| @NestedAnnotation( |
| anInt = 73, |
| aClassArray = {String.class, Object.class})) |
| abstract String field1(); |
| |
| @CopiedAnnotation |
| @ExcludedAnnotation |
| @InheritedAnnotation |
| @AutoValue.CopyAnnotations(exclude = {ExcludedAnnotation.class}) |
| abstract String field2(); |
| |
| static CopyAnnotation create() { |
| return new AutoValue_AutoValueTest_CopyAnnotation("field1", "field2"); |
| } |
| } |
| |
| @Test |
| public void testCopyClassAnnotations() throws Exception { |
| CopyAnnotation x = CopyAnnotation.create(); |
| Class<?> c = x.getClass(); |
| assertNotSame(CopyAnnotation.class, c); |
| |
| // Sanity check: if these don't appear on CopyAnnotation, it makes no sense to assert that they |
| // don't appear on the AutoValue_ subclass. |
| { |
| List<Class<? extends Annotation>> annotationsOnSuperclass = |
| new ArrayList<Class<? extends Annotation>>(); |
| for (Annotation annotation : CopyAnnotation.class.getDeclaredAnnotations()) { |
| annotationsOnSuperclass.add(annotation.annotationType()); |
| } |
| assertThat(annotationsOnSuperclass) |
| .containsAtLeast( |
| CopiedAnnotation.class, ExcludedAnnotation.class, InheritedAnnotation.class); |
| } |
| |
| { |
| List<Class<? extends Annotation>> annotationsOnSubclass = |
| new ArrayList<Class<? extends Annotation>>(); |
| for (Annotation annotation : c.getDeclaredAnnotations()) { |
| annotationsOnSubclass.add(annotation.annotationType()); |
| } |
| assertThat(annotationsOnSubclass).containsExactly(CopiedAnnotation.class); |
| } |
| } |
| |
| @Test |
| public void testCopyMethodAnnotations() throws Exception { |
| CopyAnnotation x = CopyAnnotation.create(); |
| Class<?> c = x.getClass(); |
| assertNotSame(CopyAnnotation.class, c); |
| |
| Method methodInSubclass = c.getDeclaredMethod("field2"); |
| Method methodInSuperclass = CopyAnnotation.class.getDeclaredMethod("field2"); |
| |
| // Sanity check: if these don't appear on CopyAnnotation, it makes no sense to assert that they |
| // don't appear on the AutoValue_ subclass. |
| assertThat(methodInSuperclass.isAnnotationPresent(CopiedAnnotation.class)).isTrue(); |
| assertThat(methodInSuperclass.isAnnotationPresent(ExcludedAnnotation.class)).isTrue(); |
| assertThat(methodInSuperclass.isAnnotationPresent(InheritedAnnotation.class)).isTrue(); |
| |
| assertThat(methodInSubclass.isAnnotationPresent(CopiedAnnotation.class)).isTrue(); |
| assertThat(methodInSubclass.isAnnotationPresent(ExcludedAnnotation.class)).isFalse(); |
| assertThat(methodInSubclass.isAnnotationPresent(InheritedAnnotation.class)).isTrue(); |
| } |
| |
| @Test |
| public void testCopyMethodAnnotationsByDefault() throws Exception { |
| CopyAnnotation x = CopyAnnotation.create(); |
| Class<?> c = x.getClass(); |
| assertNotSame(CopyAnnotation.class, c); |
| Method methodInSubclass = c.getDeclaredMethod("field1"); |
| Method methodInSuperclass = CopyAnnotation.class.getDeclaredMethod("field1"); |
| assertNotSame(methodInSuperclass, methodInSubclass); |
| HairyAnnotation annotationInSubclass = methodInSubclass.getAnnotation(HairyAnnotation.class); |
| HairyAnnotation annotationInSuperclass = |
| methodInSuperclass.getAnnotation(HairyAnnotation.class); |
| assertEquals(annotationInSuperclass, annotationInSubclass); |
| } |
| |
| @AutoValue |
| abstract static class HProperty { |
| public abstract Object h(); |
| |
| public static HProperty create(Object h) { |
| return new AutoValue_AutoValueTest_HProperty(h); |
| } |
| } |
| |
| @Test |
| public void testHProperty() throws Exception { |
| // Checks that we can have a property called `h`. The generated hashCode() method has |
| // a local variable of that name and can cause the error `int cannot be dereferenced` |
| HProperty.create(new Object()); |
| } |
| |
| interface Parent1 { |
| int something(); |
| } |
| |
| interface Parent2 { |
| int something(); |
| } |
| |
| @AutoValue |
| abstract static class InheritSameMethodTwice implements Parent1, Parent2 { |
| static InheritSameMethodTwice create(int something) { |
| return new AutoValue_AutoValueTest_InheritSameMethodTwice(something); |
| } |
| } |
| |
| @Test |
| public void testInheritSameMethodTwice() { |
| InheritSameMethodTwice x = InheritSameMethodTwice.create(23); |
| assertThat(x.something()).isEqualTo(23); |
| } |
| |
| // Make sure we behave correctly when we inherit the same method definition from more than |
| // one parent interface. We expect methods to appear in the order they are seen, with parents |
| // preceding children, the superclass of a class preceding interfaces that class implements, |
| // and an interface mentioned earlier in the "implements" clause preceding one mentioned later. |
| // https://github.com/google/auto/issues/372 |
| interface OneTwoThreeFour { |
| String one(); |
| |
| String two(); |
| |
| boolean three(); |
| |
| long four(); |
| } |
| |
| interface TwoFour { |
| String two(); |
| |
| long four(); |
| } |
| |
| @AutoValue |
| abstract static class OneTwoThreeFourImpl implements OneTwoThreeFour, TwoFour { |
| static OneTwoThreeFourImpl create(String one, String two, boolean three, long four) { |
| return new AutoValue_AutoValueTest_OneTwoThreeFourImpl(one, two, three, four); |
| } |
| } |
| |
| @Test |
| public void testOneTwoThreeFour() { |
| OneTwoThreeFour x = OneTwoThreeFourImpl.create("one", "two", false, 4); |
| String expectedString = |
| omitIdentifiers |
| ? "{one, two, false, 4}" |
| : "OneTwoThreeFourImpl{one=one, two=two, three=false, four=4}"; |
| assertThat(x.toString()).isEqualTo(expectedString); |
| } |
| |
| @AutoValue |
| abstract static class OuterWithBuilder { |
| abstract String foo(); |
| |
| abstract InnerWithBuilder inner(); |
| |
| abstract Builder toBuilder(); |
| |
| static Builder builder() { |
| return new AutoValue_AutoValueTest_OuterWithBuilder.Builder(); |
| } |
| |
| @AutoValue.Builder |
| abstract static class Builder { |
| abstract Builder foo(String x); |
| |
| abstract Builder inner(InnerWithBuilder x); |
| |
| abstract InnerWithBuilder.Builder innerBuilder(); |
| |
| abstract OuterWithBuilder build(); |
| } |
| } |
| |
| @AutoValue |
| abstract static class InnerWithBuilder { |
| abstract int bar(); |
| |
| abstract Builder toBuilder(); |
| |
| static Builder builder() { |
| return new AutoValue_AutoValueTest_InnerWithBuilder.Builder(); |
| } |
| |
| @AutoValue.Builder |
| abstract static class Builder { |
| abstract Builder setBar(int x); |
| |
| abstract InnerWithBuilder build(); |
| } |
| } |
| |
| @Test |
| public void testBuilderWithinBuilder() { |
| OuterWithBuilder x = |
| OuterWithBuilder.builder() |
| .inner(InnerWithBuilder.builder().setBar(23).build()) |
| .foo("yes") |
| .build(); |
| String expectedStringX = |
| omitIdentifiers |
| ? "{yes, {23}}" |
| : "OuterWithBuilder{foo=yes, inner=InnerWithBuilder{bar=23}}"; |
| assertThat(x.toString()).isEqualTo(expectedStringX); |
| |
| OuterWithBuilder.Builder xBuilder = x.toBuilder(); |
| xBuilder.innerBuilder().setBar(17); |
| OuterWithBuilder y = xBuilder.build(); |
| String expectedStringY = |
| omitIdentifiers |
| ? "{yes, {17}}" |
| : "OuterWithBuilder{foo=yes, inner=InnerWithBuilder{bar=17}}"; |
| assertThat(y.toString()).isEqualTo(expectedStringY); |
| } |
| |
| public static class MyMap<K, V> extends HashMap<K, V> { |
| public MyMap() {} |
| |
| public MyMap(Map<K, V> map) { |
| super(map); |
| } |
| } |
| |
| public static class MyMapBuilder<K, V> extends LinkedHashMap<K, V> { |
| public MyMapBuilder() {} |
| |
| public MyMapBuilder(Map<K, V> map) { |
| super(map); |
| } |
| |
| public MyMap<K, V> build() { |
| return new MyMap<K, V>(this); |
| } |
| } |
| |
| @AutoValue |
| abstract static class BuildMyMap<K, V> { |
| abstract MyMap<K, V> map(); |
| |
| abstract Builder<K, V> toBuilder(); |
| |
| static <K, V> Builder<K, V> builder() { |
| return new AutoValue_AutoValueTest_BuildMyMap.Builder<K, V>(); |
| } |
| |
| @AutoValue.Builder |
| abstract static class Builder<K, V> { |
| abstract MyMapBuilder<K, V> mapBuilder(); |
| |
| abstract BuildMyMap<K, V> build(); |
| } |
| } |
| |
| @Test |
| public void testMyMapBuilder() { |
| BuildMyMap.Builder<String, Integer> builder = BuildMyMap.builder(); |
| MyMapBuilder<String, Integer> mapBuilder = builder.mapBuilder(); |
| mapBuilder.put("23", 23); |
| BuildMyMap<String, Integer> built = builder.build(); |
| assertThat(built.map()).containsExactly("23", 23); |
| |
| BuildMyMap.Builder<String, Integer> builder2 = built.toBuilder(); |
| MyMapBuilder<String, Integer> mapBuilder2 = builder2.mapBuilder(); |
| mapBuilder2.put("17", 17); |
| BuildMyMap<String, Integer> built2 = builder2.build(); |
| assertThat(built2.map()).containsExactly("23", 23, "17", 17); |
| } |
| |
| public static class MyStringMap<V> extends MyMap<String, V> { |
| public MyStringMap() {} |
| |
| public MyStringMap(Map<String, V> map) { |
| super(map); |
| } |
| |
| public MyStringMapBuilder<V> toBuilder() { |
| return new MyStringMapBuilder<V>(this); |
| } |
| } |
| |
| public static class MyStringMapBuilder<V> extends MyMapBuilder<String, V> { |
| public MyStringMapBuilder() {} |
| |
| public MyStringMapBuilder(Map<String, V> map) { |
| super(map); |
| } |
| |
| @Override |
| public MyStringMap<V> build() { |
| return new MyStringMap<V>(this); |
| } |
| } |
| |
| @AutoValue |
| abstract static class BuildMyStringMap<V> { |
| abstract MyStringMap<V> map(); |
| |
| abstract Builder<V> toBuilder(); |
| |
| static <V> Builder<V> builder() { |
| return new AutoValue_AutoValueTest_BuildMyStringMap.Builder<V>(); |
| } |
| |
| @AutoValue.Builder |
| abstract static class Builder<V> { |
| abstract MyStringMapBuilder<V> mapBuilder(); |
| |
| abstract BuildMyStringMap<V> build(); |
| } |
| } |
| |
| @Test |
| public void testMyStringMapBuilder() { |
| BuildMyStringMap.Builder<Integer> builder = BuildMyStringMap.builder(); |
| MyStringMapBuilder<Integer> mapBuilder = builder.mapBuilder(); |
| mapBuilder.put("23", 23); |
| BuildMyStringMap<Integer> built = builder.build(); |
| assertThat(built.map()).containsExactly("23", 23); |
| |
| BuildMyStringMap.Builder<Integer> builder2 = built.toBuilder(); |
| MyStringMapBuilder<Integer> mapBuilder2 = builder2.mapBuilder(); |
| mapBuilder2.put("17", 17); |
| BuildMyStringMap<Integer> built2 = builder2.build(); |
| assertThat(built2.map()).containsExactly("17", 17, "23", 23); |
| } |
| |
| @AutoValue |
| abstract static class BuilderOfManyAccessLevels { |
| public abstract int publicGetterProtectedBuilderGetterPackageProtectedSetterInt(); |
| |
| protected abstract int protectedGetterPackageProtectedBuilderGetterPublicSetterInt(); |
| |
| abstract int packageProtectedGetterPublicBuilderGetterProtectedSetterInt(); |
| |
| @AutoValue.Builder |
| public abstract static class Builder { |
| protected abstract int publicGetterProtectedBuilderGetterPackageProtectedSetterInt(); |
| |
| abstract int protectedGetterPackageProtectedBuilderGetterPublicSetterInt(); |
| |
| public abstract int packageProtectedGetterPublicBuilderGetterProtectedSetterInt(); |
| |
| abstract Builder setPublicGetterProtectedBuilderGetterPackageProtectedSetterInt(int x); |
| |
| public abstract Builder setProtectedGetterPackageProtectedBuilderGetterPublicSetterInt(int x); |
| |
| protected abstract Builder setPackageProtectedGetterPublicBuilderGetterProtectedSetterInt( |
| int x); |
| |
| public abstract BuilderOfManyAccessLevels build(); |
| } |
| } |
| |
| @Test |
| public void testBuilderOfManyAccessLevels_accessLevels() throws NoSuchMethodException { |
| Class<?> builderClass = AutoValue_AutoValueTest_BuilderOfManyAccessLevels.Builder.class; |
| |
| testMethodAccess( |
| Access.PROTECTED, |
| builderClass, |
| "publicGetterProtectedBuilderGetterPackageProtectedSetterInt"); |
| testMethodAccess( |
| Access.PACKAGE, |
| builderClass, |
| "protectedGetterPackageProtectedBuilderGetterPublicSetterInt"); |
| testMethodAccess( |
| Access.PUBLIC, builderClass, "packageProtectedGetterPublicBuilderGetterProtectedSetterInt"); |
| |
| testMethodAccess( |
| Access.PACKAGE, |
| builderClass, |
| "setPublicGetterProtectedBuilderGetterPackageProtectedSetterInt", |
| int.class); |
| testMethodAccess( |
| Access.PUBLIC, |
| builderClass, |
| "setProtectedGetterPackageProtectedBuilderGetterPublicSetterInt", |
| int.class); |
| testMethodAccess( |
| Access.PROTECTED, |
| builderClass, |
| "setPackageProtectedGetterPublicBuilderGetterProtectedSetterInt", |
| int.class); |
| } |
| |
| private enum Access { |
| PRIVATE, |
| PACKAGE, |
| PROTECTED, |
| PUBLIC |
| } |
| |
| private static final ImmutableMap<Integer, Access> MODIFIER_BITS_TO_ACCESS = |
| ImmutableMap.of( |
| Modifier.PUBLIC, |
| Access.PUBLIC, |
| Modifier.PROTECTED, |
| Access.PROTECTED, |
| Modifier.PRIVATE, |
| Access.PRIVATE, |
| 0, |
| Access.PACKAGE); |
| |
| private static void testMethodAccess( |
| Access expectedAccess, Class<?> clazz, String methodName, Class<?>... parameterTypes) |
| throws NoSuchMethodException { |
| Method method = clazz.getDeclaredMethod(methodName, parameterTypes); |
| int modBits = method.getModifiers() & (Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE); |
| Access actualAccess = MODIFIER_BITS_TO_ACCESS.get(modBits); |
| assertWithMessage("Wrong access for %s", methodName) |
| .that(actualAccess) |
| .isEqualTo(expectedAccess); |
| } |
| |
| static class VersionId {} |
| |
| static class ItemVersionId extends VersionId {} |
| |
| interface VersionedPersistent { |
| VersionId getVersionId(); |
| } |
| |
| interface Item extends VersionedPersistent { |
| @Override |
| ItemVersionId getVersionId(); |
| } |
| |
| @AutoValue |
| abstract static class FakeItem implements Item { |
| static Builder builder() { |
| return new AutoValue_AutoValueTest_FakeItem.Builder(); |
| } |
| |
| @AutoValue.Builder |
| abstract static class Builder { |
| abstract Builder setVersionId(ItemVersionId x); |
| |
| abstract FakeItem build(); |
| } |
| } |
| |
| @Test |
| public void testParentInterfaceOverridesGrandparent() { |
| ItemVersionId version = new ItemVersionId(); |
| FakeItem fakeItem = FakeItem.builder().setVersionId(version).build(); |
| assertThat(fakeItem.getVersionId()).isSameInstanceAs(version); |
| } |
| |
| /** Fake ApkVersionCode class. */ |
| public static class ApkVersionCode {} |
| |
| /** |
| * Illustrates a potential problem that showed up while generalizing builders. If our imports are |
| * not accurate we may end up importing ImmutableList.Builder, which won't work because the |
| * generated Builder subclass of ReleaseInfoBuilder will supersede it. Normally we wouldn't import |
| * ImmutableList.Builder because the nested Builder class in the {@code @AutoValue} class would |
| * prevent us trying. But in this case the nested class is called ReleaseInfoBuilder so we might |
| * import anyway if we're not careful. This is one reason why we moved away from importing nested |
| * classes to only importing top-level classes. |
| */ |
| @AutoValue |
| public abstract static class ReleaseInfo { |
| public static ReleaseInfoBuilder newBuilder() { |
| return new AutoValue_AutoValueTest_ReleaseInfo.Builder(); |
| } |
| |
| public abstract ImmutableList<ApkVersionCode> apkVersionCodes(); |
| |
| ReleaseInfo() {} |
| |
| /** Notice that this is called ReleaseInfoBuilder and not Builder. */ |
| @AutoValue.Builder |
| public abstract static class ReleaseInfoBuilder { |
| public ReleaseInfoBuilder addApkVersionCode(ApkVersionCode code) { |
| apkVersionCodesBuilder().add(code); |
| return this; |
| } |
| |
| abstract ImmutableList.Builder<ApkVersionCode> apkVersionCodesBuilder(); |
| |
| public abstract ReleaseInfo build(); |
| } |
| } |
| |
| @Test |
| public void testUnusualBuilderName() { |
| ApkVersionCode apkVersionCode = new ApkVersionCode(); |
| ReleaseInfo x = ReleaseInfo.newBuilder().addApkVersionCode(apkVersionCode).build(); |
| assertThat(x.apkVersionCodes()).containsExactly(apkVersionCode); |
| } |
| |
| @AutoValue |
| public abstract static class OuterWithDefaultableInner { |
| public abstract ImmutableList<String> names(); |
| |
| public abstract DefaultableInner inner(); |
| |
| public static Builder builder() { |
| return new AutoValue_AutoValueTest_OuterWithDefaultableInner.Builder(); |
| } |
| |
| @AutoValue.Builder |
| public abstract static class Builder { |
| public abstract ImmutableList<String> names(); |
| |
| public abstract ImmutableList.Builder<String> namesBuilder(); |
| |
| public abstract DefaultableInner inner(); |
| |
| public abstract DefaultableInner.Builder innerBuilder(); |
| |
| public abstract OuterWithDefaultableInner build(); |
| } |
| } |
| |
| @AutoValue |
| public abstract static class DefaultableInner { |
| public abstract int bar(); |
| |
| public static Builder builder() { |
| return new AutoValue_AutoValueTest_DefaultableInner.Builder().setBar(23); |
| } |
| |
| @AutoValue.Builder |
| public abstract static class Builder { |
| public abstract Builder setBar(int x); |
| |
| public abstract DefaultableInner build(); |
| } |
| } |
| |
| @Test |
| public void testOuterWithDefaultableInner_Defaults() { |
| DefaultableInner defaultInner = DefaultableInner.builder().build(); |
| OuterWithDefaultableInner x = OuterWithDefaultableInner.builder().build(); |
| assertThat(x.names()).isEmpty(); |
| assertThat(x.inner()).isEqualTo(defaultInner); |
| } |
| |
| @Test |
| public void testOuterWithDefaultableInner_Getters() { |
| DefaultableInner defaultInner = DefaultableInner.builder().build(); |
| |
| OuterWithDefaultableInner.Builder builder = OuterWithDefaultableInner.builder(); |
| assertThat(builder.names()).isEmpty(); |
| assertThat(builder.inner()).isEqualTo(defaultInner); |
| |
| OuterWithDefaultableInner x1 = builder.build(); |
| assertThat(x1.names()).isEmpty(); |
| assertThat(x1.inner()).isEqualTo(defaultInner); |
| |
| builder.namesBuilder().add("Fred"); |
| builder.innerBuilder().setBar(17); |
| OuterWithDefaultableInner x2 = builder.build(); |
| assertThat(x2.names()).containsExactly("Fred"); |
| assertThat(x2.inner().bar()).isEqualTo(17); |
| } |
| |
| @AutoValue |
| public abstract static class OuterWithNonDefaultableInner<T> { |
| public abstract int foo(); |
| |
| public abstract NonDefaultableInner<T> inner(); |
| |
| public static <T> Builder<T> builder() { |
| return new AutoValue_AutoValueTest_OuterWithNonDefaultableInner.Builder<T>(); |
| } |
| |
| @AutoValue.Builder |
| public abstract static class Builder<T> { |
| public abstract Builder<T> setFoo(int x); |
| |
| public abstract NonDefaultableInner.Builder<T> innerBuilder(); |
| |
| public abstract OuterWithNonDefaultableInner<T> build(); |
| } |
| } |
| |
| @AutoValue |
| public abstract static class NonDefaultableInner<E> { |
| public abstract E bar(); |
| |
| public static <E> Builder<E> builder() { |
| return new AutoValue_AutoValueTest_NonDefaultableInner.Builder<E>(); |
| } |
| |
| @AutoValue.Builder |
| public abstract static class Builder<E> { |
| public abstract Builder<E> setBar(E x); |
| |
| public abstract NonDefaultableInner<E> build(); |
| } |
| } |
| |
| @Test |
| public void testOuterWithNonDefaultableInner() { |
| OuterWithNonDefaultableInner.Builder<String> builder = OuterWithNonDefaultableInner.builder(); |
| builder.setFoo(23); |
| try { |
| builder.build(); |
| fail("Did not get expected exception for unbuilt inner instance"); |
| } catch (IllegalStateException expected) { |
| } |
| } |
| |
| @SuppressWarnings("JavaLangClash") |
| @AutoValue |
| public abstract static class RedeclareJavaLangClasses { |
| // If you really really want to do this, we have you covered. |
| |
| public static class Object {} |
| |
| public static class String {} |
| |
| public abstract Object alienObject(); |
| |
| public abstract String alienString(); |
| |
| public static Builder builder() { |
| return new AutoValue_AutoValueTest_RedeclareJavaLangClasses.Builder(); |
| } |
| |
| @AutoValue.Builder |
| public abstract static class Builder { |
| public abstract Builder setAlienObject(Object x); |
| |
| public abstract Builder setAlienString(String x); |
| |
| public abstract RedeclareJavaLangClasses build(); |
| } |
| } |
| |
| @Test |
| public void testRedeclareJavaLangClasses() { |
| RedeclareJavaLangClasses x = |
| RedeclareJavaLangClasses.builder() |
| .setAlienObject(new RedeclareJavaLangClasses.Object()) |
| .setAlienString(new RedeclareJavaLangClasses.String()) |
| .build(); |
| assertThat(x).isNotNull(); |
| } |
| |
| // b/28382293 |
| @AutoValue |
| abstract static class GenericExtends { |
| abstract ImmutableSet<Number> metrics(); |
| |
| static Builder builder() { |
| return new AutoValue_AutoValueTest_GenericExtends.Builder(); |
| } |
| |
| @AutoValue.Builder |
| abstract static class Builder { |
| abstract Builder setMetrics(ImmutableSet<? extends Number> metrics); |
| abstract GenericExtends build(); |
| } |
| } |
| |
| @Test |
| public void testGenericExtends() { |
| ImmutableSet<Integer> ints = ImmutableSet.of(1, 2, 3); |
| GenericExtends g = GenericExtends.builder().setMetrics(ints).build(); |
| assertThat(g.metrics()).isEqualTo(ints); |
| } |
| |
| abstract static class Parent<T> { |
| abstract List<T> getList(); |
| } |
| |
| @AutoValue |
| abstract static class Child extends Parent<String> { |
| static Builder builder() { |
| return new AutoValue_AutoValueTest_Child.Builder(); |
| } |
| |
| @AutoValue.Builder |
| abstract static class Builder { |
| abstract Builder setList(List<String> list); |
| abstract Child build(); |
| } |
| } |
| |
| @Test |
| public void nonGenericExtendsGeneric() { |
| List<String> list = ImmutableList.of("foo", "bar", "baz"); |
| Child child = Child.builder().setList(list).build(); |
| assertThat(child.getList()).containsExactlyElementsIn(list).inOrder(); |
| } |
| |
| abstract static class AbstractGenericParentWithBuilder<T> { |
| abstract T foo(); |
| |
| abstract static class Builder<T, B extends Builder<T, B>> { |
| abstract B foo(T s); |
| } |
| } |
| |
| @AutoValue |
| abstract static class ChildOfAbstractGenericParentWithBuilder<T> |
| extends AbstractGenericParentWithBuilder<T> { |
| static <T> Builder<T> builder() { |
| return new AutoValue_AutoValueTest_ChildOfAbstractGenericParentWithBuilder.Builder<T>(); |
| } |
| |
| @AutoValue.Builder |
| abstract static class Builder<T> |
| extends AbstractGenericParentWithBuilder.Builder<T, Builder<T>> { |
| abstract ChildOfAbstractGenericParentWithBuilder<T> build(); |
| } |
| } |
| |
| @Test |
| public void genericExtendsGeneric() { |
| ChildOfAbstractGenericParentWithBuilder<String> child = |
| ChildOfAbstractGenericParentWithBuilder.<String>builder().foo("foo").build(); |
| assertThat(child.foo()).isEqualTo("foo"); |
| } |
| |
| @SuppressWarnings("ClassCanBeStatic") |
| static class OuterWithTypeParam<T extends Number> { |
| class InnerWithTypeParam<U> {} |
| class InnerWithoutTypeParam {} |
| static class Nested {} |
| } |
| |
| @AutoValue |
| abstract static class Nesty { |
| abstract OuterWithTypeParam<Double>.InnerWithTypeParam<String> innerWithTypeParam(); |
| abstract OuterWithTypeParam<Double>.InnerWithoutTypeParam innerWithoutTypeParam(); |
| abstract OuterWithTypeParam.Nested nested(); |
| |
| static Builder builder() { |
| return new AutoValue_AutoValueTest_Nesty.Builder(); |
| } |
| |
| @AutoValue.Builder |
| abstract static class Builder { |
| abstract Builder setInnerWithTypeParam( |
| OuterWithTypeParam<Double>.InnerWithTypeParam<String> x); |
| abstract Builder setInnerWithoutTypeParam(OuterWithTypeParam<Double>.InnerWithoutTypeParam x); |
| abstract Builder setNested(OuterWithTypeParam.Nested x); |
| abstract Nesty build(); |
| } |
| } |
| |
| @Test |
| public void outerWithTypeParam() throws ReflectiveOperationException { |
| @SuppressWarnings("UseDiamond") // Currently we compile this with -source 6 in the Eclipse test. |
| OuterWithTypeParam<Double> outer = new OuterWithTypeParam<Double>(); |
| Nesty nesty = Nesty.builder() |
| .setInnerWithTypeParam(outer.new InnerWithTypeParam<String>()) |
| .setInnerWithoutTypeParam(outer.new InnerWithoutTypeParam()) |
| .setNested(new OuterWithTypeParam.Nested()) |
| .build(); |
| Type originalReturnType = |
| Nesty.class.getDeclaredMethod("innerWithTypeParam").getGenericReturnType(); |
| Type generatedReturnType = |
| nesty.getClass().getDeclaredMethod("innerWithTypeParam").getGenericReturnType(); |
| assertThat(generatedReturnType).isEqualTo(originalReturnType); |
| Type generatedBuilderParamType = |
| Nesty.builder() |
| .getClass() |
| .getDeclaredMethod("setInnerWithTypeParam", OuterWithTypeParam.InnerWithTypeParam.class) |
| .getGenericParameterTypes()[0]; |
| assertThat(generatedBuilderParamType).isEqualTo(originalReturnType); |
| } |
| |
| @AutoValue |
| abstract static class BuilderAnnotationsNotCopied { |
| abstract String foo(); |
| |
| static Builder builder() { |
| return new AutoValue_AutoValueTest_BuilderAnnotationsNotCopied.Builder(); |
| } |
| |
| @AutoValue.Builder |
| @MyAnnotation("thing") |
| abstract static class Builder { |
| abstract Builder setFoo(String x); |
| abstract BuilderAnnotationsNotCopied build(); |
| } |
| } |
| |
| @Test |
| public void builderAnnotationsNotCopiedByDefault() { |
| BuilderAnnotationsNotCopied.Builder builder = BuilderAnnotationsNotCopied.builder(); |
| assertThat(builder.getClass().getAnnotations()).isEmpty(); |
| assertThat(builder.setFoo("foo").build().foo()).isEqualTo("foo"); |
| } |
| |
| @AutoValue |
| abstract static class BuilderAnnotationsCopied { |
| abstract String foo(); |
| |
| static Builder builder() { |
| return new AutoValue_AutoValueTest_BuilderAnnotationsCopied.Builder(); |
| } |
| |
| @AutoValue.Builder |
| @AutoValue.CopyAnnotations |
| @MyAnnotation("thing") |
| abstract static class Builder { |
| abstract Builder setFoo(String x); |
| abstract BuilderAnnotationsCopied build(); |
| } |
| } |
| |
| @Test |
| public void builderAnnotationsCopiedIfRequested() { |
| BuilderAnnotationsCopied.Builder builder = BuilderAnnotationsCopied.builder(); |
| assertThat(builder.getClass().getAnnotations()).asList().containsExactly(myAnnotation("thing")); |
| assertThat(builder.setFoo("foo").build().foo()).isEqualTo("foo"); |
| } |
| } |