• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2012 Google LLC
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.google.auto.value;
17 
18 import static com.google.common.truth.Truth.assertThat;
19 import static com.google.common.truth.Truth.assertWithMessage;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertNotNull;
23 import static org.junit.Assert.assertNotSame;
24 import static org.junit.Assert.assertNull;
25 import static org.junit.Assert.assertSame;
26 import static org.junit.Assert.assertTrue;
27 import static org.junit.Assert.fail;
28 
29 import com.google.common.base.MoreObjects;
30 import com.google.common.collect.ComparisonChain;
31 import com.google.common.collect.ImmutableList;
32 import com.google.common.collect.ImmutableMap;
33 import com.google.common.collect.ImmutableSet;
34 import com.google.common.collect.ImmutableSortedMap;
35 import com.google.common.collect.ImmutableSortedSet;
36 import com.google.common.collect.ImmutableTable;
37 import com.google.common.testing.EqualsTester;
38 import com.google.common.testing.SerializableTester;
39 import java.io.ObjectStreamClass;
40 import java.io.Serializable;
41 import java.lang.annotation.Annotation;
42 import java.lang.annotation.Inherited;
43 import java.lang.annotation.Retention;
44 import java.lang.annotation.RetentionPolicy;
45 import java.lang.reflect.Constructor;
46 import java.lang.reflect.Method;
47 import java.lang.reflect.Modifier;
48 import java.lang.reflect.Type;
49 import java.math.BigInteger;
50 import java.util.AbstractList;
51 import java.util.ArrayList;
52 import java.util.Arrays;
53 import java.util.Collection;
54 import java.util.Collections;
55 import java.util.HashMap;
56 import java.util.LinkedHashMap;
57 import java.util.List;
58 import java.util.Map;
59 import java.util.NavigableMap;
60 import java.util.NavigableSet;
61 import java.util.NoSuchElementException;
62 import java.util.SortedMap;
63 import java.util.TreeMap;
64 import java.util.TreeSet;
65 import javax.annotation.Nullable;
66 import org.junit.BeforeClass;
67 import org.junit.Test;
68 import org.junit.runner.RunWith;
69 import org.junit.runners.JUnit4;
70 
71 /** @author emcmanus@google.com (Éamonn McManus) */
72 @RunWith(JUnit4.class)
73 public class AutoValueTest {
74   private static boolean omitIdentifiers;
75 
76   @BeforeClass
initOmitIdentifiers()77   public static void initOmitIdentifiers() {
78     omitIdentifiers = System.getProperty("OmitIdentifiers") != null;
79   }
80 
81   @AutoValue
82   abstract static class Simple {
publicString()83     public abstract String publicString();
84 
protectedInt()85     protected abstract int protectedInt();
86 
packageMap()87     abstract Map<String, Long> packageMap();
88 
create(String s, int i, Map<String, Long> m)89     public static Simple create(String s, int i, Map<String, Long> m) {
90       return new AutoValue_AutoValueTest_Simple(s, i, m);
91     }
92   }
93 
94   @Test
testSimple()95   public void testSimple() throws Exception {
96     Simple instance1a = Simple.create("example", 23, ImmutableMap.of("twenty-three", 23L));
97     Simple instance1b = Simple.create("example", 23, ImmutableMap.of("twenty-three", 23L));
98     Simple instance2 = Simple.create("", 0, ImmutableMap.<String, Long>of());
99     assertEquals("example", instance1a.publicString());
100     assertEquals(23, instance1a.protectedInt());
101     assertEquals(ImmutableMap.of("twenty-three", 23L), instance1a.packageMap());
102     MoreObjects.ToStringHelper toStringHelper = MoreObjects.toStringHelper(Simple.class);
103     toStringHelper.add("publicString", "example");
104     toStringHelper.add("protectedInt", 23);
105     toStringHelper.add("packageMap", ImmutableMap.of("twenty-three", 23L));
106     String expectedString =
107         omitIdentifiers ? "{example, 23, {twenty-three=23}}" : toStringHelper.toString();
108     assertThat(instance1a.toString()).isEqualTo(expectedString);
109     new EqualsTester()
110         .addEqualityGroup(instance1a, instance1b)
111         .addEqualityGroup(instance2)
112         .testEquals();
113   }
114 
115   @AutoValue
116   abstract static class Empty {
create()117     public static Empty create() {
118       return new AutoValue_AutoValueTest_Empty();
119     }
120   }
121 
122   @Test
testEmpty()123   public void testEmpty() throws Exception {
124     Empty instance = Empty.create();
125     String expectedString = omitIdentifiers ? "{}" : "Empty{}";
126     assertThat(instance.toString()).isEqualTo(expectedString);
127     assertEquals(instance, instance);
128     assertEquals(instance, Empty.create());
129   }
130 
131   @AutoValue
132   abstract static class SimpleWithGetters {
getFoo()133     abstract int getFoo();
134 
isBar()135     abstract boolean isBar();
136 
getOtherBar()137     abstract boolean getOtherBar();
138 
getPackage()139     abstract String getPackage(); // package is a reserved word
140 
getPackage0()141     abstract String getPackage0();
142 
getHTMLPage()143     abstract String getHTMLPage();
144 
create( int foo, boolean bar, boolean otherBar, String pkg, String pkg0, String htmlPage)145     static SimpleWithGetters create(
146         int foo, boolean bar, boolean otherBar, String pkg, String pkg0, String htmlPage) {
147       return new AutoValue_AutoValueTest_SimpleWithGetters(foo, bar, otherBar, pkg, pkg0, htmlPage);
148     }
149   }
150 
151   @Test
testGetters()152   public void testGetters() {
153     SimpleWithGetters instance = SimpleWithGetters.create(23, true, false, "foo", "bar", "<html>");
154     String expectedString =
155         omitIdentifiers
156             ? "{23, true, false, foo, bar, <html>}"
157             : "SimpleWithGetters{"
158                 + "foo=23, bar=true, otherBar=false, package=foo, package0=bar, HTMLPage=<html>}";
159     assertThat(instance.toString()).isEqualTo(expectedString);
160   }
161 
162   @AutoValue
163   abstract static class NotAllGetters {
getFoo()164     abstract int getFoo();
165 
bar()166     abstract boolean bar();
167 
create(int foo, boolean bar)168     static NotAllGetters create(int foo, boolean bar) {
169       return new AutoValue_AutoValueTest_NotAllGetters(foo, bar);
170     }
171   }
172 
173   @Test
testNotGetters()174   public void testNotGetters() {
175     NotAllGetters instance = NotAllGetters.create(23, true);
176     String expectedString = omitIdentifiers ? "{23, true}" : "NotAllGetters{getFoo=23, bar=true}";
177     assertThat(instance.toString()).isEqualTo(expectedString);
178   }
179 
180   @AutoValue
181   abstract static class StrangeGetters {
get1st()182     abstract int get1st();
get_1st()183     abstract int get_1st(); // by default we'll use _1st where identifiers are needed, so foil that.
184 
185     @AutoValue.Builder
186     abstract static class Builder {
set1st(int x)187       abstract Builder set1st(int x);
set_1st(int x)188       abstract Builder set_1st(int x);
build()189       abstract StrangeGetters build();
190     }
191 
builder()192     static Builder builder() {
193       return new AutoValue_AutoValueTest_StrangeGetters.Builder();
194     }
195   }
196 
197   @Test
testStrangeGetters()198   public void testStrangeGetters() {
199     StrangeGetters instance = StrangeGetters.builder().set1st(17).set_1st(23).build();
200     String expectedString = omitIdentifiers ? "{17, 23}" : "StrangeGetters{1st=17, _1st=23}";
201     assertThat(instance.toString()).isEqualTo(expectedString);
202   }
203 
204   @AutoValue
205   abstract static class GettersAndConcreteNonGetters {
getFoo()206     abstract int getFoo();
207 
208     @SuppressWarnings("mutable")
getBytes()209     abstract byte[] getBytes();
210 
hasNoBytes()211     boolean hasNoBytes() {
212       return getBytes().length == 0;
213     }
214 
create(int foo, byte[] bytes)215     static GettersAndConcreteNonGetters create(int foo, byte[] bytes) {
216       return new AutoValue_AutoValueTest_GettersAndConcreteNonGetters(foo, bytes);
217     }
218   }
219 
220   @Test
testGettersAndConcreteNonGetters()221   public void testGettersAndConcreteNonGetters() {
222     GettersAndConcreteNonGetters instance = GettersAndConcreteNonGetters.create(23, new byte[] {1});
223     assertFalse(instance.hasNoBytes());
224     String expectedString =
225         omitIdentifiers ? "{23, [1]}" : "GettersAndConcreteNonGetters{foo=23, bytes=[1]}";
226     assertThat(instance.toString()).isEqualTo(expectedString);
227   }
228 
229   @AutoValue
230   abstract static class ClassProperty {
theClass()231     abstract Class<?> theClass();
232 
create(Class<?> theClass)233     static ClassProperty create(Class<?> theClass) {
234       return new AutoValue_AutoValueTest_ClassProperty(theClass);
235     }
236   }
237 
238   @Test
testClassProperty()239   public void testClassProperty() {
240     ClassProperty instance = ClassProperty.create(Thread.class);
241     assertThat(instance.theClass()).isEqualTo(Thread.class);
242 
243     try {
244       ClassProperty.create(null);
245       fail();
246     } catch (NullPointerException expected) {
247     }
248   }
249 
250   @AutoValue
251   abstract static class ClassPropertyWithBuilder {
numberClass()252     abstract Class<? extends Number> numberClass();
253 
builder()254     static Builder builder() {
255       return new AutoValue_AutoValueTest_ClassPropertyWithBuilder.Builder();
256     }
257 
258     @AutoValue.Builder
259     abstract static class Builder {
setNumberClass(Class<? extends Number> x)260       abstract Builder setNumberClass(Class<? extends Number> x);
261 
build()262       abstract ClassPropertyWithBuilder build();
263     }
264   }
265 
266   @Test
testClassPropertyWithBuilder()267   public void testClassPropertyWithBuilder() {
268     ClassPropertyWithBuilder instance =
269         ClassPropertyWithBuilder.builder().setNumberClass(Integer.class).build();
270     assertThat(instance.numberClass()).isEqualTo(Integer.class);
271 
272     try {
273       ClassPropertyWithBuilder.builder().build();
274       fail();
275     } catch (IllegalStateException expected) {
276     }
277 
278     try {
279       ClassPropertyWithBuilder.builder().setNumberClass(null);
280       fail();
281     } catch (NullPointerException expected) {
282     }
283   }
284 
285   @AutoValue
286   public abstract static class Serialize implements Serializable {
integer()287     public abstract int integer();
288 
string()289     public abstract String string();
290 
bigInteger()291     public abstract BigInteger bigInteger();
292 
create(int integer, String string, BigInteger bigInteger)293     public static Serialize create(int integer, String string, BigInteger bigInteger) {
294       return new AutoValue_AutoValueTest_Serialize(integer, string, bigInteger);
295     }
296   }
297 
298   @Test
testSerialize()299   public void testSerialize() throws Exception {
300     Serialize instance = Serialize.create(23, "23", BigInteger.valueOf(23));
301     assertEquals(instance, SerializableTester.reserialize(instance));
302   }
303 
304   @AutoValue
305   public abstract static class SerializeWithVersionUID implements Serializable {
306     private static final long serialVersionUID = 4294967297L;
307 
integer()308     public abstract int integer();
309 
string()310     public abstract String string();
311 
create(int integer, String string)312     public static SerializeWithVersionUID create(int integer, String string) {
313       return new AutoValue_AutoValueTest_SerializeWithVersionUID(integer, string);
314     }
315   }
316 
317   @Test
testSerializeWithVersionUID()318   public void testSerializeWithVersionUID() throws Exception {
319     SerializeWithVersionUID instance = SerializeWithVersionUID.create(23, "23");
320     assertEquals(instance, SerializableTester.reserialize(instance));
321 
322     long serialVersionUID =
323         ObjectStreamClass.lookup(AutoValue_AutoValueTest_SerializeWithVersionUID.class)
324             .getSerialVersionUID();
325     assertEquals(4294967297L, serialVersionUID);
326   }
327 
328   @AutoValue
329   abstract static class LongProperty {
longProperty()330     public abstract long longProperty();
331 
create(long longProperty)332     public static LongProperty create(long longProperty) {
333       return new AutoValue_AutoValueTest_LongProperty(longProperty);
334     }
335   }
336 
337   @Test
testLongHashCode()338   public void testLongHashCode() {
339     long longValue = 0x1234567887654321L;
340     LongProperty longProperty = LongProperty.create(longValue);
341     assertEquals(singlePropertyHash(longValue), longProperty.hashCode());
342   }
343 
344   @AutoValue
345   abstract static class IntProperty {
intProperty()346     public abstract int intProperty();
347 
create(int intProperty)348     public static IntProperty create(int intProperty) {
349       return new AutoValue_AutoValueTest_IntProperty(intProperty);
350     }
351   }
352 
353   @Test
testIntHashCode()354   public void testIntHashCode() {
355     int intValue = 0x12345678;
356     IntProperty intProperty = IntProperty.create(intValue);
357     assertEquals(singlePropertyHash(intValue), intProperty.hashCode());
358   }
359 
360   @AutoValue
361   abstract static class ShortProperty {
shortProperty()362     public abstract short shortProperty();
363 
create(short shortProperty)364     public static ShortProperty create(short shortProperty) {
365       return new AutoValue_AutoValueTest_ShortProperty(shortProperty);
366     }
367   }
368 
369   @Test
testShortHashCode()370   public void testShortHashCode() {
371     short shortValue = 0x1234;
372     ShortProperty shortProperty = ShortProperty.create(shortValue);
373     assertEquals(singlePropertyHash(shortValue), shortProperty.hashCode());
374   }
375 
376   @AutoValue
377   abstract static class ByteProperty {
byteProperty()378     public abstract byte byteProperty();
379 
create(byte byteProperty)380     public static ByteProperty create(byte byteProperty) {
381       return new AutoValue_AutoValueTest_ByteProperty(byteProperty);
382     }
383   }
384 
385   @Test
testByteHashCode()386   public void testByteHashCode() {
387     byte byteValue = 123;
388     ByteProperty byteProperty = ByteProperty.create(byteValue);
389     assertEquals(singlePropertyHash(byteValue), byteProperty.hashCode());
390   }
391 
392   @AutoValue
393   abstract static class CharProperty {
charProperty()394     public abstract char charProperty();
395 
create(char charProperty)396     public static CharProperty create(char charProperty) {
397       return new AutoValue_AutoValueTest_CharProperty(charProperty);
398     }
399   }
400 
401   @Test
testCharHashCode()402   public void testCharHashCode() {
403     char charValue = 123;
404     CharProperty charProperty = CharProperty.create(charValue);
405     assertEquals(singlePropertyHash(charValue), charProperty.hashCode());
406   }
407 
408   @AutoValue
409   abstract static class BooleanProperty {
booleanProperty()410     public abstract boolean booleanProperty();
411 
create(boolean booleanProperty)412     public static BooleanProperty create(boolean booleanProperty) {
413       return new AutoValue_AutoValueTest_BooleanProperty(booleanProperty);
414     }
415   }
416 
417   @Test
testBooleanHashCode()418   public void testBooleanHashCode() {
419     for (boolean booleanValue : new boolean[] {false, true}) {
420       BooleanProperty booleanProperty = BooleanProperty.create(booleanValue);
421       assertEquals(singlePropertyHash(booleanValue), booleanProperty.hashCode());
422     }
423   }
424 
425   @AutoValue
426   abstract static class FloatProperty {
floatProperty()427     public abstract float floatProperty();
428 
create(float floatProperty)429     public static FloatProperty create(float floatProperty) {
430       return new AutoValue_AutoValueTest_FloatProperty(floatProperty);
431     }
432   }
433 
434   @Test
testFloatHashCode()435   public void testFloatHashCode() {
436     float floatValue = 123456f;
437     FloatProperty floatProperty = FloatProperty.create(floatValue);
438     assertEquals(singlePropertyHash(floatValue), floatProperty.hashCode());
439   }
440 
441   @AutoValue
442   abstract static class DoubleProperty {
doubleProperty()443     public abstract double doubleProperty();
444 
create(double doubleProperty)445     public static DoubleProperty create(double doubleProperty) {
446       return new AutoValue_AutoValueTest_DoubleProperty(doubleProperty);
447     }
448   }
449 
450   @Test
testDoubleHashCode()451   public void testDoubleHashCode() {
452     double doubleValue = 1234567890123456d;
453     DoubleProperty doubleProperty = DoubleProperty.create(doubleValue);
454     assertEquals(singlePropertyHash(doubleValue), doubleProperty.hashCode());
455   }
456 
457   @Test
testFloatingEquality()458   public void testFloatingEquality() {
459     FloatProperty floatZero = FloatProperty.create(0.0f);
460     FloatProperty floatMinusZero = FloatProperty.create(-0.0f);
461     FloatProperty floatNaN = FloatProperty.create(Float.NaN);
462     DoubleProperty doubleZero = DoubleProperty.create(0.0);
463     DoubleProperty doubleMinusZero = DoubleProperty.create(-0.0);
464     DoubleProperty doubleNaN = DoubleProperty.create(Double.NaN);
465     new EqualsTester()
466         .addEqualityGroup(floatZero)
467         .addEqualityGroup(floatMinusZero)
468         .addEqualityGroup(floatNaN)
469         .addEqualityGroup(doubleZero)
470         .addEqualityGroup(doubleMinusZero)
471         .addEqualityGroup(doubleNaN)
472         .testEquals();
473   }
474 
singlePropertyHash(Object property)475   private static int singlePropertyHash(Object property) {
476     return 1000003 ^ property.hashCode();
477   }
478 
479   abstract static class Super {
superObject()480     public abstract Object superObject();
481 
superBoolean()482     public abstract boolean superBoolean();
483     // The above two are out of alphabetical order to test EclipseHack.
484   }
485 
486   @AutoValue
487   public abstract static class Sub extends Super {
subInt()488     public abstract int subInt();
489 
create(Object superObject, boolean superBoolean, int subInt)490     public static Sub create(Object superObject, boolean superBoolean, int subInt) {
491       return new AutoValue_AutoValueTest_Sub(superObject, superBoolean, subInt);
492     }
493   }
494 
495   // The @AutoValue class can inherit abstract methods from its superclass.
496   @Test
testSuperclass()497   public void testSuperclass() throws Exception {
498     Sub instance = Sub.create("blim", true, 1729);
499     assertEquals("blim", instance.superObject());
500     assertTrue(instance.superBoolean());
501     assertEquals(1729, instance.subInt());
502     assertEquals(instance, instance);
503     assertEqualsNullIsFalse(instance);
504   }
505 
506   abstract static class NonPublicSuper {
superObject()507     abstract Object superObject();
508   }
509 
510   // The properties in this subclass are not in alphabetical order, which enables us to test that
511   // everything works correctly when Eclipse sorts them into the order
512   // [superObject, subInt, subString], since it sorts per class.
513   @AutoValue
514   abstract static class NonPublicSub extends NonPublicSuper {
subString()515     abstract String subString();
516 
subInt()517     abstract int subInt();
518 
create(Object superObject, String subString, int subInt)519     static NonPublicSub create(Object superObject, String subString, int subInt) {
520       return new AutoValue_AutoValueTest_NonPublicSub(superObject, subString, subInt);
521     }
522   }
523 
524   @Test
testNonPublicInheritedGetters()525   public void testNonPublicInheritedGetters() throws Exception {
526     NonPublicSub instance = NonPublicSub.create("blim", "blam", 1729);
527     assertEquals("blim", instance.superObject());
528     assertEquals("blam", instance.subString());
529     assertEquals(1729, instance.subInt());
530     assertEquals(instance, instance);
531     assertEqualsNullIsFalse(instance);
532   }
533 
534   @SuppressWarnings("ObjectEqualsNull")
assertEqualsNullIsFalse(Object instance)535   private void assertEqualsNullIsFalse(Object instance) {
536     assertFalse(instance.equals(null));
537   }
538 
539   @AutoValue
540   abstract static class NullableProperties {
541     @Nullable
nullableString()542     abstract String nullableString();
543 
randomInt()544     abstract int randomInt();
545 
create(@ullable String nullableString, int randomInt)546     static NullableProperties create(@Nullable String nullableString, int randomInt) {
547       return new AutoValue_AutoValueTest_NullableProperties(nullableString, randomInt);
548     }
549   }
550 
551   @Test
testNullablePropertiesCanBeNull()552   public void testNullablePropertiesCanBeNull() {
553     NullableProperties instance = NullableProperties.create(null, 23);
554     assertNull(instance.nullableString());
555     assertThat(instance.randomInt()).isEqualTo(23);
556     String expectedString =
557         omitIdentifiers ? "{null, 23}" : "NullableProperties{nullableString=null, randomInt=23}";
558     assertThat(instance.toString()).isEqualTo(expectedString);
559   }
560 
561   @AutoAnnotation
nullable()562   static Nullable nullable() {
563     return new AutoAnnotation_AutoValueTest_nullable();
564   }
565 
566   @Test
testNullablePropertyConstructorParameterIsNullable()567   public void testNullablePropertyConstructorParameterIsNullable() throws NoSuchMethodException {
568     Constructor<?> constructor =
569         AutoValue_AutoValueTest_NullableProperties.class.getDeclaredConstructor(
570             String.class, int.class);
571     assertThat(constructor.getParameterAnnotations()[0]).asList().contains(nullable());
572   }
573 
574   @AutoValue
575   abstract static class AlternativeNullableProperties {
576     @interface Nullable {}
577 
578     @AlternativeNullableProperties.Nullable
nullableString()579     abstract String nullableString();
580 
randomInt()581     abstract int randomInt();
582 
create(@ullable String nullableString, int randomInt)583     static AlternativeNullableProperties create(@Nullable String nullableString, int randomInt) {
584       return new AutoValue_AutoValueTest_AlternativeNullableProperties(nullableString, randomInt);
585     }
586   }
587 
588   @Test
testNullableCanBeFromElsewhere()589   public void testNullableCanBeFromElsewhere() throws Exception {
590     AlternativeNullableProperties instance = AlternativeNullableProperties.create(null, 23);
591     assertNull(instance.nullableString());
592     assertThat(instance.randomInt()).isEqualTo(23);
593     String expectedString =
594         omitIdentifiers
595             ? "{null, 23}"
596             : "AlternativeNullableProperties{nullableString=null, randomInt=23}";
597     assertThat(instance.toString()).isEqualTo(expectedString);
598   }
599 
600   @AutoValue
601   abstract static class NonNullableProperties {
nonNullableString()602     abstract String nonNullableString();
603 
randomInt()604     abstract int randomInt();
605 
create(String nonNullableString, int randomInt)606     static NonNullableProperties create(String nonNullableString, int randomInt) {
607       return new AutoValue_AutoValueTest_NonNullableProperties(nonNullableString, randomInt);
608     }
609   }
610 
611   @Test
testNonNullablePropertiesCannotBeNull()612   public void testNonNullablePropertiesCannotBeNull() throws Exception {
613     try {
614       NonNullableProperties.create(null, 23);
615       fail("Object creation succeeded but should not have");
616     } catch (NullPointerException expected) {
617     }
618     NonNullableProperties instance = NonNullableProperties.create("nonnull", 23);
619     assertEquals("nonnull", instance.nonNullableString());
620     assertEquals(23, instance.randomInt());
621   }
622 
623   @AutoValue
624   abstract static class NullableListProperties {
625     @Nullable
nullableStringList()626     abstract ImmutableList<String> nullableStringList();
627 
create(@ullable ImmutableList<String> nullableStringList)628     static NullableListProperties create(@Nullable ImmutableList<String> nullableStringList) {
629       return new AutoValue_AutoValueTest_NullableListProperties(nullableStringList);
630     }
631   }
632 
633   @Test
testNullableListPropertiesCanBeNonNull()634   public void testNullableListPropertiesCanBeNonNull() {
635     NullableListProperties instance = NullableListProperties.create(ImmutableList.of("foo", "bar"));
636     assertEquals(ImmutableList.of("foo", "bar"), instance.nullableStringList());
637   }
638 
639   @Test
testNullableListPropertiesCanBeNull()640   public void testNullableListPropertiesCanBeNull() {
641     NullableListProperties instance = NullableListProperties.create(null);
642     assertNull(instance.nullableStringList());
643   }
644 
645   @AutoValue
646   abstract static class NullableListPropertiesWithBuilder {
647     @Nullable
nullableStringList()648     abstract ImmutableList<String> nullableStringList();
649 
builder()650     static Builder builder() {
651       return new AutoValue_AutoValueTest_NullableListPropertiesWithBuilder.Builder();
652     }
653 
654     @AutoValue.Builder
655     interface Builder {
nullableStringList(List<String> nullableStringList)656       Builder nullableStringList(List<String> nullableStringList);
657 
build()658       NullableListPropertiesWithBuilder build();
659     }
660   }
661 
662   @Test
testNullableListPropertiesWithBuilderCanBeNonNull()663   public void testNullableListPropertiesWithBuilderCanBeNonNull() {
664     NullableListPropertiesWithBuilder instance =
665         NullableListPropertiesWithBuilder.builder()
666             .nullableStringList(ImmutableList.of("foo", "bar"))
667             .build();
668     assertEquals(ImmutableList.of("foo", "bar"), instance.nullableStringList());
669   }
670 
671   @Test
testNullableListPropertiesWithBuilderCanBeUnset()672   public void testNullableListPropertiesWithBuilderCanBeUnset() {
673     NullableListPropertiesWithBuilder instance =
674         NullableListPropertiesWithBuilder.builder().build();
675     assertNull(instance.nullableStringList());
676   }
677 
678   @Test
testNullableListPropertiesWithBuilderCanBeNull()679   public void testNullableListPropertiesWithBuilderCanBeNull() {
680     NullableListPropertiesWithBuilder instance =
681         NullableListPropertiesWithBuilder.builder().nullableStringList(null).build();
682     assertNull(instance.nullableStringList());
683   }
684 
685   static class Nested {
686     @AutoValue
687     abstract static class Doubly {
688       @Nullable
nullableString()689       abstract String nullableString();
690 
randomInt()691       abstract int randomInt();
692 
create(String nullableString, int randomInt)693       static Doubly create(String nullableString, int randomInt) {
694         return new AutoValue_AutoValueTest_Nested_Doubly(nullableString, randomInt);
695       }
696     }
697   }
698 
699   @Test
testDoublyNestedClass()700   public void testDoublyNestedClass() throws Exception {
701     Nested.Doubly instance = Nested.Doubly.create(null, 23);
702     assertNull(instance.nullableString());
703     assertThat(instance.randomInt()).isEqualTo(23);
704     String expectedString =
705         omitIdentifiers ? "{null, 23}" : "Doubly{nullableString=null, randomInt=23}";
706     assertThat(instance.toString()).isEqualTo(expectedString);
707   }
708 
709   static interface NestedInInterface {
710     @AutoValue
711     abstract class Doubly {
string()712       abstract String string();
713 
map()714       abstract Map<String, Integer> map();
715 
create(String string, Map<String, Integer> map)716       static Doubly create(String string, Map<String, Integer> map) {
717         return new AutoValue_AutoValueTest_NestedInInterface_Doubly(string, map);
718       }
719     }
720   }
721 
722   @Test
testClassNestedInInterface()723   public void testClassNestedInInterface() throws Exception {
724     Map<String, Integer> map = ImmutableMap.of("vingt-et-un", 21);
725     NestedInInterface.Doubly instance = NestedInInterface.Doubly.create("foo", map);
726     assertEquals("foo", instance.string());
727     assertEquals(map, instance.map());
728   }
729 
730   @AutoValue
731   abstract static class NullableNonNullable {
732     @Nullable
nullableString()733     abstract String nullableString();
734 
735     @Nullable
otherNullableString()736     abstract String otherNullableString();
737 
nonNullableString()738     abstract String nonNullableString();
739 
create( String nullableString, String otherNullableString, String nonNullableString)740     static NullableNonNullable create(
741         String nullableString, String otherNullableString, String nonNullableString) {
742       return new AutoValue_AutoValueTest_NullableNonNullable(
743           nullableString, otherNullableString, nonNullableString);
744     }
745   }
746 
747   @Test
testEqualsWithNullable()748   public void testEqualsWithNullable() throws Exception {
749     NullableNonNullable everythingNull =
750         NullableNonNullable.create(null, null, "nonNullableString");
751     NullableNonNullable somethingNull =
752         NullableNonNullable.create(null, "otherNullableString", "nonNullableString");
753     NullableNonNullable nothingNull =
754         NullableNonNullable.create("nullableString", "otherNullableString", "nonNullableString");
755     NullableNonNullable nothingNullAgain =
756         NullableNonNullable.create("nullableString", "otherNullableString", "nonNullableString");
757     new EqualsTester()
758         .addEqualityGroup(everythingNull)
759         .addEqualityGroup(somethingNull)
760         .addEqualityGroup(nothingNull, nothingNullAgain)
761         .testEquals();
762   }
763 
764   @AutoValue
765   abstract static class GenericProperties {
simpleMap()766     abstract Map<String, Integer> simpleMap();
767 
hairyMap()768     abstract Map<String, Map<String, Integer>> hairyMap();
769 
create( Map<String, Integer> simpleMap, Map<String, Map<String, Integer>> hairyMap)770     static GenericProperties create(
771         Map<String, Integer> simpleMap, Map<String, Map<String, Integer>> hairyMap) {
772       return new AutoValue_AutoValueTest_GenericProperties(simpleMap, hairyMap);
773     }
774   }
775 
776   @Test
testGenericProperties()777   public void testGenericProperties() throws Exception {
778     GenericProperties instance1 =
779         GenericProperties.create(
780             ImmutableMap.of("twenty-three", 23),
781             ImmutableMap.of("very", (Map<String, Integer>) ImmutableMap.of("hairy", 17)));
782     GenericProperties instance2 =
783         GenericProperties.create(
784             ImmutableMap.of("seventeen", 17),
785             ImmutableMap.of("very", (Map<String, Integer>) ImmutableMap.of("hairy", 23)));
786     new EqualsTester().addEqualityGroup(instance1).addEqualityGroup(instance2).testEquals();
787     assertEquals(
788         ImmutableMap.of("very", (Map<String, Integer>) ImmutableMap.of("hairy", 23)),
789         instance2.hairyMap());
790   }
791 
792   @AutoValue
793   abstract static class GenericClass<K, V> {
key()794     abstract K key();
795 
map()796     abstract Map<K, V> map();
797 
create(K key, Map<K, V> map)798     static <K, V> GenericClass<K, V> create(K key, Map<K, V> map) {
799       return new AutoValue_AutoValueTest_GenericClass<K, V>(key, map);
800     }
801   }
802 
803   @Test
testGenericClass()804   public void testGenericClass() throws Exception {
805     GenericClass<String, Boolean> instance =
806         GenericClass.create("whatever", ImmutableMap.of("no", false));
807     assertEquals(instance, instance);
808     assertEquals("whatever", instance.key());
809     assertEquals(ImmutableMap.of("no", false), instance.map());
810   }
811 
812   @AutoValue
813   abstract static class GenericClassSimpleBounds<K extends Number, V extends K> {
key()814     abstract K key();
815 
map()816     abstract Map<K, V> map();
817 
create( K key, Map<K, V> map)818     static <K extends Number, V extends K> GenericClassSimpleBounds<K, V> create(
819         K key, Map<K, V> map) {
820       return new AutoValue_AutoValueTest_GenericClassSimpleBounds<K, V>(key, map);
821     }
822   }
823 
824   @Test
testGenericClassWithSimpleBounds()825   public void testGenericClassWithSimpleBounds() throws Exception {
826     GenericClassSimpleBounds<Integer, Integer> instance =
827         GenericClassSimpleBounds.create(23, ImmutableMap.of(17, 23));
828     assertEquals(instance, instance);
829     assertEquals(23, (int) instance.key());
830     assertEquals(ImmutableMap.of(17, 23), instance.map());
831   }
832 
833   @AutoValue
834   abstract static class GenericClassHairyBounds<K extends List<V> & Comparable<K>, V> {
key()835     abstract K key();
836 
map()837     abstract Map<K, V> map();
838 
create( K key, Map<K, V> map)839     static <K extends List<V> & Comparable<K>, V> GenericClassHairyBounds<K, V> create(
840         K key, Map<K, V> map) {
841       return new AutoValue_AutoValueTest_GenericClassHairyBounds<K, V>(key, map);
842     }
843   }
844 
845   @Test
testGenericClassWithHairyBounds()846   public void testGenericClassWithHairyBounds() throws Exception {
847     class ComparableList<E> extends ArrayList<E> implements Comparable<ComparableList<E>> {
848       @Override
849       public int compareTo(ComparableList<E> list) {
850         throw new UnsupportedOperationException();
851       }
852     }
853     ComparableList<String> emptyList = new ComparableList<String>();
854     GenericClassHairyBounds<ComparableList<String>, String> instance =
855         GenericClassHairyBounds.create(emptyList, ImmutableMap.of(emptyList, "23"));
856     assertEquals(instance, instance);
857     assertEquals(emptyList, instance.key());
858     assertEquals(ImmutableMap.of(emptyList, "23"), instance.map());
859   }
860 
861   interface Mergeable<M extends Mergeable<M>> {
merge(M other)862     M merge(M other);
863   }
864 
865   @AutoValue
866   abstract static class Delta<M extends Mergeable<M>> {
meta()867     abstract M meta();
868 
create(M meta)869     static <M extends Mergeable<M>> Delta<M> create(M meta) {
870       return new AutoValue_AutoValueTest_Delta<M>(meta);
871     }
872   }
873 
874   @Test
testRecursiveGeneric()875   public void testRecursiveGeneric() {
876     class MergeableImpl implements Mergeable<MergeableImpl> {
877       @Override
878       public MergeableImpl merge(MergeableImpl other) {
879         return this;
880       }
881     }
882     MergeableImpl mergeable = new MergeableImpl();
883     Delta<MergeableImpl> instance = Delta.create(mergeable);
884     assertSame(mergeable, instance.meta());
885   }
886 
887   static class NodeType<O> {}
888 
889   abstract static class NodeExpressionClass<O> {
getType()890     abstract NodeType<O> getType();
891   }
892 
893   @AutoValue
894   abstract static class NotNodeExpression extends NodeExpressionClass<Boolean> {
create()895     static NotNodeExpression create() {
896       return new AutoValue_AutoValueTest_NotNodeExpression(new NodeType<Boolean>());
897     }
898   }
899 
900   interface NodeExpressionInterface<O> {
getType()901     NodeType<O> getType();
902   }
903 
904   @AutoValue
905   abstract static class NotNodeExpression2 implements NodeExpressionInterface<Boolean> {
create()906     static NotNodeExpression2 create() {
907       return new AutoValue_AutoValueTest_NotNodeExpression2(new NodeType<Boolean>());
908     }
909   }
910 
911   @Test
testConcreteWithGenericParent()912   public void testConcreteWithGenericParent() {
913     NotNodeExpression instance = NotNodeExpression.create();
914     assertThat(instance.getType()).isInstanceOf(NodeType.class);
915     NotNodeExpression2 instance2 = NotNodeExpression2.create();
916     assertThat(instance2.getType()).isInstanceOf(NodeType.class);
917   }
918 
919   @AutoValue
920   abstract static class ExplicitToString {
string()921     abstract String string();
922 
create(String string)923     static ExplicitToString create(String string) {
924       return new AutoValue_AutoValueTest_ExplicitToString(string);
925     }
926 
927     @Override
toString()928     public String toString() {
929       return "Bazinga{" + string() + "}";
930     }
931   }
932 
933   // We should not generate a toString() method if there already is a non-default one.
934   @Test
testExplicitToString()935   public void testExplicitToString() throws Exception {
936     ExplicitToString instance = ExplicitToString.create("foo");
937     assertEquals("Bazinga{foo}", instance.toString());
938   }
939 
940   abstract static class NonAutoExplicitToString {
string()941     abstract String string();
942 
943     @Override
toString()944     public String toString() {
945       return "Bazinga{" + string() + "}";
946     }
947   }
948 
949   @AutoValue
950   abstract static class InheritedExplicitToString extends NonAutoExplicitToString {
create(String string)951     static InheritedExplicitToString create(String string) {
952       return new AutoValue_AutoValueTest_InheritedExplicitToString(string);
953     }
954   }
955 
956   // We should not generate a toString() method if we already inherit a non-default one.
957   @Test
testInheritedExplicitToString()958   public void testInheritedExplicitToString() throws Exception {
959     InheritedExplicitToString instance = InheritedExplicitToString.create("foo");
960     assertEquals("Bazinga{foo}", instance.toString());
961   }
962 
963   @AutoValue
964   abstract static class AbstractToString {
string()965     abstract String string();
966 
create(String string)967     static AbstractToString create(String string) {
968       return new AutoValue_AutoValueTest_AbstractToString(string);
969     }
970 
971     @Override
toString()972     public abstract String toString();
973   }
974 
975   // We should generate a toString() method if the parent class has an abstract one.
976   // That allows users to cancel a toString() from a parent class if they want.
977   @Test
testAbstractToString()978   public void testAbstractToString() throws Exception {
979     AbstractToString instance = AbstractToString.create("foo");
980     String expectedString = omitIdentifiers ? "{foo}" : "AbstractToString{string=foo}";
981     assertThat(instance.toString()).isEqualTo(expectedString);
982   }
983 
984   abstract static class NonAutoAbstractToString {
string()985     abstract String string();
986 
987     @Override
toString()988     public abstract String toString();
989   }
990 
991   @AutoValue
992   abstract static class SubAbstractToString extends NonAutoAbstractToString {
create(String string)993     static SubAbstractToString create(String string) {
994       return new AutoValue_AutoValueTest_SubAbstractToString(string);
995     }
996   }
997 
998   // We should generate a toString() method if the parent class inherits an abstract one.
999   @Test
testInheritedAbstractToString()1000   public void testInheritedAbstractToString() throws Exception {
1001     SubAbstractToString instance = SubAbstractToString.create("foo");
1002     String expectedString = omitIdentifiers ? "{foo}" : "SubAbstractToString{string=foo}";
1003     assertThat(instance.toString()).isEqualTo(expectedString);
1004   }
1005 
1006   @AutoValue
1007   abstract static class ExplicitHashCode {
string()1008     abstract String string();
1009 
create(String string)1010     static ExplicitHashCode create(String string) {
1011       return new AutoValue_AutoValueTest_ExplicitHashCode(string);
1012     }
1013 
1014     @Override
hashCode()1015     public int hashCode() {
1016       return 1234;
1017     }
1018   }
1019 
1020   @Test
testExplicitHashCode()1021   public void testExplicitHashCode() throws Exception {
1022     ExplicitHashCode instance = ExplicitHashCode.create("foo");
1023     assertEquals(1234, instance.hashCode());
1024   }
1025 
1026   @AutoValue
1027   @SuppressWarnings("EqualsHashCode")
1028   abstract static class ExplicitEquals {
1029     int equalsCount;
1030 
create()1031     static ExplicitEquals create() {
1032       return new AutoValue_AutoValueTest_ExplicitEquals();
1033     }
1034 
1035     @Override
equals(Object o)1036     public boolean equals(Object o) {
1037       equalsCount++;
1038       return super.equals(o);
1039     }
1040   }
1041 
1042   @SuppressWarnings("SelfEquals")
1043   @Test
testExplicitEquals()1044   public void testExplicitEquals() throws Exception {
1045     ExplicitEquals instance = ExplicitEquals.create();
1046     assertEquals(0, instance.equalsCount);
1047     assertTrue(instance.equals(instance));
1048     assertEquals(1, instance.equalsCount);
1049     Method equals = instance.getClass().getMethod("equals", Object.class);
1050     assertNotSame(ExplicitEquals.class, instance.getClass());
1051     assertSame(ExplicitEquals.class, equals.getDeclaringClass());
1052   }
1053 
1054   @Retention(RetentionPolicy.RUNTIME)
1055   @interface MyAnnotation {
value()1056     String value();
1057   }
1058 
1059   @AutoAnnotation
myAnnotation(String value)1060   private static MyAnnotation myAnnotation(String value) {
1061     return new AutoAnnotation_AutoValueTest_myAnnotation(value);
1062   }
1063 
1064   @AutoValue
1065   abstract static class PrimitiveArrays {
1066     @SuppressWarnings("mutable")
booleans()1067     abstract boolean[] booleans();
1068 
1069     @SuppressWarnings("mutable")
1070     @Nullable
ints()1071     abstract int[] ints();
1072 
create(boolean[] booleans, int[] ints)1073     static PrimitiveArrays create(boolean[] booleans, int[] ints) {
1074       // Real code would likely clone these parameters, but here we want to check that the
1075       // generated constructor rejects a null value for booleans.
1076       return new AutoValue_AutoValueTest_PrimitiveArrays(booleans, ints);
1077     }
1078   }
1079 
1080   @Test
testPrimitiveArrays()1081   public void testPrimitiveArrays() {
1082     PrimitiveArrays object0 = PrimitiveArrays.create(new boolean[0], new int[0]);
1083     boolean[] booleans = {false, true, true, false};
1084     int[] ints = {6, 28, 496, 8128, 33550336};
1085     PrimitiveArrays object1 = PrimitiveArrays.create(booleans.clone(), ints.clone());
1086     PrimitiveArrays object2 = PrimitiveArrays.create(booleans.clone(), ints.clone());
1087     new EqualsTester().addEqualityGroup(object1, object2).addEqualityGroup(object0).testEquals();
1088     // EqualsTester also exercises hashCode(). We clone the arrays above to ensure that using the
1089     // default Object.hashCode() will fail.
1090 
1091     String expectedString =
1092         omitIdentifiers
1093             ? ("{" + Arrays.toString(booleans) + ", " + Arrays.toString(ints) + "}")
1094             : ("PrimitiveArrays{booleans="
1095                 + Arrays.toString(booleans)
1096                 + ", "
1097                 + "ints="
1098                 + Arrays.toString(ints)
1099                 + "}");
1100     assertThat(object1.toString()).isEqualTo(expectedString);
1101     assertThat(object1.ints()).isSameInstanceAs(object1.ints());
1102   }
1103 
1104   @Test
testNullablePrimitiveArrays()1105   public void testNullablePrimitiveArrays() {
1106     PrimitiveArrays object0 = PrimitiveArrays.create(new boolean[0], null);
1107     boolean[] booleans = {false, true, true, false};
1108     PrimitiveArrays object1 = PrimitiveArrays.create(booleans.clone(), null);
1109     PrimitiveArrays object2 = PrimitiveArrays.create(booleans.clone(), null);
1110     new EqualsTester().addEqualityGroup(object1, object2).addEqualityGroup(object0).testEquals();
1111 
1112     String expectedString =
1113         omitIdentifiers
1114             ? ("{" + Arrays.toString(booleans) + ", null}")
1115             : ("PrimitiveArrays{booleans=" + Arrays.toString(booleans) + ", " + "ints=null}");
1116     assertThat(object1.toString()).isEqualTo(expectedString);
1117 
1118     assertThat(object1.booleans()).isSameInstanceAs(object1.booleans());
1119     assertThat(object1.booleans()).isEqualTo(booleans);
1120     object1.booleans()[0] ^= true;
1121     assertThat(object1.booleans()).isNotEqualTo(booleans);
1122   }
1123 
1124   @Test
testNotNullablePrimitiveArrays()1125   public void testNotNullablePrimitiveArrays() {
1126     try {
1127       PrimitiveArrays.create(null, new int[0]);
1128       fail("Construction with null value for non-@Nullable array should have failed");
1129     } catch (NullPointerException e) {
1130       if (omitIdentifiers) {
1131         assertThat(e).hasMessageThat().isNull();
1132       } else {
1133         assertThat(e).hasMessageThat().contains("booleans");
1134       }
1135     }
1136   }
1137 
1138   // If users are mad enough to define their own Arrays class and have some properties of that
1139   // class and others of primitive array type, then we can't import java.util.Arrays.
1140   // This is unlikely.
1141   @AutoValue
1142   abstract static class AmbiguousArrays {
1143     static class Arrays {}
1144 
arrays()1145     abstract Arrays arrays();
1146 
1147     @SuppressWarnings("mutable")
ints()1148     abstract int[] ints();
1149 
create(Arrays arrays, int[] ints)1150     static AmbiguousArrays create(Arrays arrays, int[] ints) {
1151       return new AutoValue_AutoValueTest_AmbiguousArrays(arrays, ints);
1152     }
1153   }
1154 
1155   @Test
testAmbiguousArrays()1156   public void testAmbiguousArrays() {
1157     // If this test compiles at all then we presumably don't have the import problem above.
1158     AmbiguousArrays object1 = AmbiguousArrays.create(new AmbiguousArrays.Arrays(), new int[0]);
1159     assertNotNull(object1.arrays());
1160     assertEquals(0, object1.ints().length);
1161   }
1162 
1163   static final class HashCodeObserver {
1164     int hashCodeCount;
1165 
1166     @Override
equals(Object obj)1167     public boolean equals(Object obj) {
1168       return obj instanceof HashCodeObserver;
1169     }
1170 
1171     @Override
hashCode()1172     public int hashCode() {
1173       hashCodeCount++;
1174       return 23;
1175     }
1176   }
1177 
1178   @AutoValue
1179   abstract static class MaybeCachedHashCode {
hashCodeObserver()1180     abstract HashCodeObserver hashCodeObserver();
1181 
randomInt()1182     abstract int randomInt();
1183 
create(HashCodeObserver hashCodeObserver, int randomInt)1184     static MaybeCachedHashCode create(HashCodeObserver hashCodeObserver, int randomInt) {
1185       return new AutoValue_AutoValueTest_MaybeCachedHashCode(hashCodeObserver, randomInt);
1186     }
1187   }
1188 
1189   @Test
testHashCodeNotCached()1190   public void testHashCodeNotCached() {
1191     HashCodeObserver observer = new HashCodeObserver();
1192     MaybeCachedHashCode maybeCached = MaybeCachedHashCode.create(observer, 17);
1193     int hash1 = maybeCached.hashCode();
1194     int hash2 = maybeCached.hashCode();
1195     assertEquals(hash1, hash2);
1196     assertEquals(2, observer.hashCodeCount);
1197   }
1198 
1199   @AutoValue
1200   abstract static class Version implements Comparable<Version> {
major()1201     abstract int major();
1202 
minor()1203     abstract int minor();
1204 
create(int major, int minor)1205     static Version create(int major, int minor) {
1206       return new AutoValue_AutoValueTest_Version(major, minor);
1207     }
1208 
1209     @Override
compareTo(Version that)1210     public int compareTo(Version that) {
1211       return ComparisonChain.start()
1212           .compare(this.major(), that.major())
1213           .compare(this.minor(), that.minor())
1214           .result();
1215     }
1216   }
1217 
1218   @Test
testComparisonChain()1219   public void testComparisonChain() {
1220     assertEquals(Version.create(1, 2), Version.create(1, 2));
1221     Version[] versions = {Version.create(1, 2), Version.create(1, 3), Version.create(2, 1)};
1222     for (int i = 0; i < versions.length; i++) {
1223       for (int j = 0; j < versions.length; j++) {
1224         int actual = Integer.signum(versions[i].compareTo(versions[j]));
1225         int expected = Integer.signum(i - j);
1226         assertEquals(expected, actual);
1227       }
1228     }
1229   }
1230 
1231   abstract static class LukesBase {
1232     interface LukesVisitor<T> {
visit(LukesSub s)1233       T visit(LukesSub s);
1234     }
1235 
accept(LukesVisitor<T> visitor)1236     abstract <T> T accept(LukesVisitor<T> visitor);
1237 
1238     @AutoValue
1239     abstract static class LukesSub extends LukesBase {
create()1240       static LukesSub create() {
1241         return new AutoValue_AutoValueTest_LukesBase_LukesSub();
1242       }
1243 
1244       @Override
accept(LukesVisitor<T> visitor)1245       <T> T accept(LukesVisitor<T> visitor) {
1246         return visitor.visit(this);
1247       }
1248     }
1249   }
1250 
1251   @Test
testVisitor()1252   public void testVisitor() {
1253     LukesBase.LukesVisitor<String> visitor =
1254         new LukesBase.LukesVisitor<String>() {
1255           @Override
1256           public String visit(LukesBase.LukesSub s) {
1257             return s.toString();
1258           }
1259         };
1260     LukesBase.LukesSub sub = LukesBase.LukesSub.create();
1261     assertEquals(sub.toString(), sub.accept(visitor));
1262   }
1263 
1264   @AutoValue
1265   public abstract static class ComplexInheritance extends AbstractBase implements A, B {
create(String name)1266     public static ComplexInheritance create(String name) {
1267       return new AutoValue_AutoValueTest_ComplexInheritance(name);
1268     }
1269 
name()1270     abstract String name();
1271   }
1272 
1273   static class AbstractBase implements Base {
1274     @Override
answer()1275     public int answer() {
1276       return 42;
1277     }
1278   }
1279 
1280   interface A extends Base {}
1281 
1282   interface B extends Base {}
1283 
1284   interface Base {
answer()1285     int answer();
1286   }
1287 
1288   @Test
testComplexInheritance()1289   public void testComplexInheritance() {
1290     ComplexInheritance complex = ComplexInheritance.create("fred");
1291     assertEquals("fred", complex.name());
1292     assertEquals(42, complex.answer());
1293   }
1294 
1295   // This tests the case where we inherit abstract methods on more than one path. AbstractList
1296   // extends AbstractCollection, which implements Collection; and AbstractList also implements List,
1297   // which extends Collection. So the class here inherits the methods of Collection on more than
1298   // one path. In an earlier version of the logic for handling inheritance, this confused us into
1299   // thinking that the methods from Collection were still abstract and therefore candidates for
1300   // implementation, even though we inherit concrete implementations of them from AbstractList.
1301   @AutoValue
1302   public static class MoreComplexInheritance extends AbstractList<String> {
1303     @Override
get(int index)1304     public String get(int index) {
1305       throw new NoSuchElementException(String.valueOf(index));
1306     }
1307 
1308     @Override
size()1309     public int size() {
1310       return 0;
1311     }
1312 
create()1313     public static MoreComplexInheritance create() {
1314       return new AutoValue_AutoValueTest_MoreComplexInheritance();
1315     }
1316   }
1317 
1318   @Test
testMoreComplexInheritance()1319   public void testMoreComplexInheritance() {
1320     MoreComplexInheritance instance1 = MoreComplexInheritance.create();
1321     MoreComplexInheritance instance2 = MoreComplexInheritance.create();
1322     assertThat(instance1).isEqualTo(instance2);
1323     assertThat(instance1).isNotSameInstanceAs(instance2);
1324   }
1325 
1326   // Test that we are not misled by the privateness of an ancestor into thinking that its methods
1327   // are invisible to descendants.
1328   public abstract static class PublicGrandparent {
foo()1329     public abstract String foo();
1330   }
1331 
1332   private static class PrivateParent extends PublicGrandparent {
1333     @Override
foo()1334     public String foo() {
1335       return "foo";
1336     }
1337   }
1338 
1339   @AutoValue
1340   static class EffectiveVisibility extends PrivateParent {
create()1341     static EffectiveVisibility create() {
1342       return new AutoValue_AutoValueTest_EffectiveVisibility();
1343     }
1344   }
1345 
1346   @Test
testEffectiveVisibility()1347   public void testEffectiveVisibility() {
1348     EffectiveVisibility instance1 = EffectiveVisibility.create();
1349     EffectiveVisibility instance2 = EffectiveVisibility.create();
1350     assertThat(instance1).isEqualTo(instance2);
1351     assertThat(instance1).isNotSameInstanceAs(instance2);
1352   }
1353 
1354   @AutoValue
1355   public abstract static class InheritTwice implements A, B {
create(int answer)1356     public static InheritTwice create(int answer) {
1357       return new AutoValue_AutoValueTest_InheritTwice(answer);
1358     }
1359   }
1360 
1361   @Test
testInheritTwice()1362   public void testInheritTwice() {
1363     InheritTwice inheritTwice = InheritTwice.create(42);
1364     assertEquals(42, inheritTwice.answer());
1365   }
1366 
1367   @AutoValue
1368   public abstract static class Optional {
getOptional()1369     public abstract com.google.common.base.Optional<Object> getOptional();
1370 
create(com.google.common.base.Optional<Object> opt)1371     public static Optional create(com.google.common.base.Optional<Object> opt) {
1372       return new AutoValue_AutoValueTest_Optional(opt);
1373     }
1374   }
1375 
1376   @Test
testAmbiguityFromAutoValueType()1377   public void testAmbiguityFromAutoValueType() {
1378     Optional autoOptional = Optional.create(com.google.common.base.Optional.absent());
1379     assertEquals(com.google.common.base.Optional.absent(), autoOptional.getOptional());
1380   }
1381 
1382   static class BaseWithNestedType {
1383     static class Optional {}
1384   }
1385 
1386   @AutoValue
1387   public abstract static class InheritsNestedType extends BaseWithNestedType {
getOptional()1388     public abstract com.google.common.base.Optional<Object> getOptional();
1389 
create(com.google.common.base.Optional<Object> opt)1390     public static InheritsNestedType create(com.google.common.base.Optional<Object> opt) {
1391       return new AutoValue_AutoValueTest_InheritsNestedType(opt);
1392     }
1393   }
1394 
1395   @Test
testAmbiguityFromInheritedType()1396   public void testAmbiguityFromInheritedType() {
1397     InheritsNestedType inheritsNestedType =
1398         InheritsNestedType.create(com.google.common.base.Optional.absent());
1399     assertEquals(com.google.common.base.Optional.absent(), inheritsNestedType.getOptional());
1400   }
1401 
1402   abstract static class AbstractParent {
foo()1403     abstract int foo();
1404   }
1405 
1406   @AutoValue
1407   abstract static class AbstractChild extends AbstractParent {
1408     // The main point of this test is to ensure that we don't try to copy this @Override into the
1409     // generated implementation alongside the @Override that we put on all implementation methods.
1410     @Override
foo()1411     abstract int foo();
1412 
create(int foo)1413     static AbstractChild create(int foo) {
1414       return new AutoValue_AutoValueTest_AbstractChild(foo);
1415     }
1416   }
1417 
1418   @Test
testOverrideNotDuplicated()1419   public void testOverrideNotDuplicated() {
1420     AbstractChild instance = AbstractChild.create(23);
1421     assertEquals(23, instance.foo());
1422   }
1423 
1424   @AutoValue
1425   public abstract static class BasicWithBuilder {
foo()1426     public abstract int foo();
1427 
builder()1428     public static Builder builder() {
1429       return new AutoValue_AutoValueTest_BasicWithBuilder.Builder();
1430     }
1431 
1432     @AutoValue.Builder
1433     public interface Builder {
foo(int foo)1434       Builder foo(int foo);
1435 
build()1436       BasicWithBuilder build();
1437     }
1438   }
1439 
1440   @Test
testBasicWithBuilder()1441   public void testBasicWithBuilder() {
1442     BasicWithBuilder x = BasicWithBuilder.builder().foo(23).build();
1443     assertEquals(23, x.foo());
1444     try {
1445       BasicWithBuilder.builder().build();
1446       fail("Expected exception for missing property");
1447     } catch (IllegalStateException e) {
1448       if (omitIdentifiers) {
1449         assertThat(e).hasMessageThat().isNull();
1450       } else {
1451         assertThat(e).hasMessageThat().contains("foo");
1452       }
1453     }
1454   }
1455 
1456   @Test
testBasicWithBuilderHasOnlyOneConstructor()1457   public void testBasicWithBuilderHasOnlyOneConstructor() throws Exception {
1458     Class<?> builderClass = AutoValue_AutoValueTest_BasicWithBuilder.Builder.class;
1459     Constructor<?>[] constructors = builderClass.getDeclaredConstructors();
1460     assertThat(constructors).hasLength(1);
1461     Constructor<?> constructor = constructors[0];
1462     assertThat(constructor.getParameterTypes()).isEmpty();
1463   }
1464 
1465   @AutoValue
1466   public abstract static class EmptyWithBuilder {
builder()1467     public static Builder builder() {
1468       return new AutoValue_AutoValueTest_EmptyWithBuilder.Builder();
1469     }
1470 
1471     @AutoValue.Builder
1472     public interface Builder {
build()1473       EmptyWithBuilder build();
1474     }
1475   }
1476 
1477   @Test
testEmptyWithBuilder()1478   public void testEmptyWithBuilder() {
1479     EmptyWithBuilder x = EmptyWithBuilder.builder().build();
1480     EmptyWithBuilder y = EmptyWithBuilder.builder().build();
1481     assertEquals(x, y);
1482   }
1483 
1484   @AutoValue
1485   public abstract static class TwoPropertiesWithBuilderClass {
string()1486     public abstract String string();
1487 
integer()1488     public abstract int integer();
1489 
builder()1490     public static Builder builder() {
1491       return new AutoValue_AutoValueTest_TwoPropertiesWithBuilderClass.Builder();
1492     }
1493 
builder(String string)1494     public static Builder builder(String string) {
1495       return new AutoValue_AutoValueTest_TwoPropertiesWithBuilderClass.Builder().string(string);
1496     }
1497 
1498     @AutoValue.Builder
1499     public abstract static class Builder {
string(String x)1500       public abstract Builder string(String x);
1501 
integer(int x)1502       public abstract Builder integer(int x);
1503 
build()1504       public abstract TwoPropertiesWithBuilderClass build();
1505     }
1506   }
1507 
1508   @Test
testTwoPropertiesWithBuilderClass()1509   public void testTwoPropertiesWithBuilderClass() {
1510     TwoPropertiesWithBuilderClass a1 =
1511         TwoPropertiesWithBuilderClass.builder().string("23").integer(17).build();
1512     TwoPropertiesWithBuilderClass a2 =
1513         TwoPropertiesWithBuilderClass.builder("23").integer(17).build();
1514     TwoPropertiesWithBuilderClass a3 =
1515         TwoPropertiesWithBuilderClass.builder().integer(17).string("23").build();
1516     TwoPropertiesWithBuilderClass b =
1517         TwoPropertiesWithBuilderClass.builder().string("17").integer(17).build();
1518     new EqualsTester().addEqualityGroup(a1, a2, a3).addEqualityGroup(b).testEquals();
1519 
1520     try {
1521       TwoPropertiesWithBuilderClass.builder().string(null);
1522       fail("Did not get expected exception");
1523     } catch (NullPointerException expected) {
1524     }
1525   }
1526 
1527   @AutoValue
1528   public abstract static class NullablePropertyWithBuilder {
notNullable()1529     public abstract String notNullable();
1530 
1531     @Nullable
nullable()1532     public abstract String nullable();
1533 
builder()1534     public static Builder builder() {
1535       return new AutoValue_AutoValueTest_NullablePropertyWithBuilder.Builder();
1536     }
1537 
1538     @AutoValue.Builder
1539     public interface Builder {
notNullable(String s)1540       Builder notNullable(String s);
1541 
nullable(@ullable String s)1542       Builder nullable(@Nullable String s);
1543 
build()1544       NullablePropertyWithBuilder build();
1545     }
1546   }
1547 
1548   @Test
testOmitNullableWithBuilder()1549   public void testOmitNullableWithBuilder() {
1550     NullablePropertyWithBuilder instance1 =
1551         NullablePropertyWithBuilder.builder().notNullable("hello").build();
1552     assertThat(instance1.notNullable()).isEqualTo("hello");
1553     assertThat(instance1.nullable()).isNull();
1554 
1555     NullablePropertyWithBuilder instance2 =
1556         NullablePropertyWithBuilder.builder().notNullable("hello").nullable(null).build();
1557     assertThat(instance2.notNullable()).isEqualTo("hello");
1558     assertThat(instance2.nullable()).isNull();
1559     assertThat(instance1).isEqualTo(instance2);
1560 
1561     NullablePropertyWithBuilder instance3 =
1562         NullablePropertyWithBuilder.builder().notNullable("hello").nullable("world").build();
1563     assertThat(instance3.notNullable()).isEqualTo("hello");
1564     assertThat(instance3.nullable()).isEqualTo("world");
1565 
1566     try {
1567       NullablePropertyWithBuilder.builder().build();
1568       fail("Expected IllegalStateException for unset non-@Nullable property");
1569     } catch (IllegalStateException e) {
1570       if (omitIdentifiers) {
1571         assertThat(e).hasMessageThat().isNull();
1572       } else {
1573         assertThat(e).hasMessageThat().contains("notNullable");
1574       }
1575     }
1576   }
1577 
1578   @AutoValue
1579   public abstract static class PrimitiveAndBoxed {
anInt()1580     public abstract int anInt();
1581 
1582     @Nullable
aNullableInteger()1583     public abstract Integer aNullableInteger();
1584 
aNonNullableInteger()1585     public abstract Integer aNonNullableInteger();
1586 
toBuilder()1587     public abstract Builder toBuilder();
1588 
builder()1589     public static Builder builder() {
1590       return new AutoValue_AutoValueTest_PrimitiveAndBoxed.Builder();
1591     }
1592 
1593     @AutoValue.Builder
1594     public interface Builder {
setAnInt(Integer x)1595       Builder setAnInt(Integer x);
1596 
setANullableInteger(int x)1597       Builder setANullableInteger(int x);
1598 
setANonNullableInteger(int x)1599       Builder setANonNullableInteger(int x);
1600 
build()1601       PrimitiveAndBoxed build();
1602     }
1603   }
1604 
1605   @Test
testPrimitiveAndBoxed()1606   public void testPrimitiveAndBoxed() {
1607     PrimitiveAndBoxed instance1 =
1608         PrimitiveAndBoxed.builder().setAnInt(17).setANonNullableInteger(23).build();
1609     assertThat(instance1.anInt()).isEqualTo(17);
1610     assertThat(instance1.aNullableInteger()).isNull();
1611     assertThat(instance1.aNonNullableInteger()).isEqualTo(23);
1612 
1613     PrimitiveAndBoxed instance2 = instance1.toBuilder().setANullableInteger(5).build();
1614     assertThat(instance2.aNullableInteger()).isEqualTo(5);
1615 
1616     try {
1617       instance1.toBuilder().setAnInt(null);
1618       fail();
1619     } catch (NullPointerException expected) {
1620     }
1621   }
1622 
1623   @AutoValue
1624   public abstract static class OptionalPropertiesWithBuilder {
optionalString()1625     public abstract com.google.common.base.Optional<String> optionalString();
1626 
optionalInteger()1627     public abstract com.google.common.base.Optional<Integer> optionalInteger();
1628 
builder()1629     public static Builder builder() {
1630       return new AutoValue_AutoValueTest_OptionalPropertiesWithBuilder.Builder();
1631     }
1632 
1633     @AutoValue.Builder
1634     public interface Builder {
setOptionalString(com.google.common.base.Optional<String> s)1635       Builder setOptionalString(com.google.common.base.Optional<String> s);
1636 
setOptionalString(String s)1637       Builder setOptionalString(String s);
1638 
setOptionalInteger(com.google.common.base.Optional<Integer> i)1639       Builder setOptionalInteger(com.google.common.base.Optional<Integer> i);
1640 
setOptionalInteger(int i)1641       Builder setOptionalInteger(int i);
1642 
build()1643       OptionalPropertiesWithBuilder build();
1644     }
1645   }
1646 
1647   @Test
testOmitOptionalWithBuilder()1648   public void testOmitOptionalWithBuilder() {
1649     OptionalPropertiesWithBuilder omitted = OptionalPropertiesWithBuilder.builder().build();
1650     assertThat(omitted.optionalString()).isAbsent();
1651     assertThat(omitted.optionalInteger()).isAbsent();
1652 
1653     OptionalPropertiesWithBuilder supplied =
1654         OptionalPropertiesWithBuilder.builder()
1655             .setOptionalString(com.google.common.base.Optional.of("foo"))
1656             .build();
1657     assertThat(supplied.optionalString()).hasValue("foo");
1658     assertThat(omitted.optionalInteger()).isAbsent();
1659 
1660     OptionalPropertiesWithBuilder suppliedDirectly =
1661         OptionalPropertiesWithBuilder.builder()
1662             .setOptionalString("foo")
1663             .setOptionalInteger(23)
1664             .build();
1665     assertThat(suppliedDirectly.optionalString()).hasValue("foo");
1666     assertThat(suppliedDirectly.optionalInteger()).hasValue(23);
1667   }
1668 
1669   @AutoValue
1670   public abstract static class OptionalPropertyWithNullableBuilder {
notOptional()1671     public abstract String notOptional();
1672 
optional()1673     public abstract com.google.common.base.Optional<String> optional();
1674 
builder()1675     public static Builder builder() {
1676       return new AutoValue_AutoValueTest_OptionalPropertyWithNullableBuilder.Builder();
1677     }
1678 
1679     @AutoValue.Builder
1680     public interface Builder {
notOptional(String s)1681       Builder notOptional(String s);
1682 
optional(@ullable String s)1683       Builder optional(@Nullable String s);
1684 
build()1685       OptionalPropertyWithNullableBuilder build();
1686     }
1687   }
1688 
1689   @Test
testOmitOptionalWithNullableBuilder()1690   public void testOmitOptionalWithNullableBuilder() {
1691     OptionalPropertyWithNullableBuilder instance1 =
1692         OptionalPropertyWithNullableBuilder.builder().notOptional("hello").build();
1693     assertThat(instance1.notOptional()).isEqualTo("hello");
1694     assertThat(instance1.optional()).isAbsent();
1695 
1696     OptionalPropertyWithNullableBuilder instance2 =
1697         OptionalPropertyWithNullableBuilder.builder().notOptional("hello").optional(null).build();
1698     assertThat(instance2.notOptional()).isEqualTo("hello");
1699     assertThat(instance2.optional()).isAbsent();
1700     assertThat(instance1).isEqualTo(instance2);
1701 
1702     OptionalPropertyWithNullableBuilder instance3 =
1703         OptionalPropertyWithNullableBuilder.builder()
1704             .notOptional("hello")
1705             .optional("world")
1706             .build();
1707     assertThat(instance3.notOptional()).isEqualTo("hello");
1708     assertThat(instance3.optional()).hasValue("world");
1709 
1710     try {
1711       OptionalPropertyWithNullableBuilder.builder().build();
1712       fail("Expected IllegalStateException for unset non-Optional property");
1713     } catch (IllegalStateException expected) {
1714     }
1715   }
1716 
1717   @AutoValue
1718   public abstract static class NullableOptionalPropertiesWithBuilder {
1719     @Nullable
optionalString()1720     public abstract com.google.common.base.Optional<String> optionalString();
1721 
builder()1722     public static Builder builder() {
1723       return new AutoValue_AutoValueTest_NullableOptionalPropertiesWithBuilder.Builder();
1724     }
1725 
1726     @AutoValue.Builder
1727     public interface Builder {
setOptionalString(com.google.common.base.Optional<String> s)1728       Builder setOptionalString(com.google.common.base.Optional<String> s);
1729 
build()1730       NullableOptionalPropertiesWithBuilder build();
1731     }
1732   }
1733 
1734   @Test
testOmitNullableOptionalWithBuilder()1735   public void testOmitNullableOptionalWithBuilder() {
1736     NullableOptionalPropertiesWithBuilder omitted =
1737         NullableOptionalPropertiesWithBuilder.builder().build();
1738     assertThat(omitted.optionalString()).isNull();
1739 
1740     NullableOptionalPropertiesWithBuilder supplied =
1741         NullableOptionalPropertiesWithBuilder.builder()
1742             .setOptionalString(com.google.common.base.Optional.of("foo"))
1743             .build();
1744     assertThat(supplied.optionalString()).hasValue("foo");
1745   }
1746 
1747   @AutoValue
1748   public abstract static class OptionalPropertiesWithBuilderSimpleSetter {
optionalString()1749     public abstract com.google.common.base.Optional<String> optionalString();
1750 
builder()1751     public static Builder builder() {
1752       return new AutoValue_AutoValueTest_OptionalPropertiesWithBuilderSimpleSetter.Builder();
1753     }
1754 
1755     @AutoValue.Builder
1756     public interface Builder {
setOptionalString(String s)1757       Builder setOptionalString(String s);
1758 
build()1759       OptionalPropertiesWithBuilderSimpleSetter build();
1760     }
1761   }
1762 
1763   @Test
testOptionalPropertySimpleSetter()1764   public void testOptionalPropertySimpleSetter() {
1765     OptionalPropertiesWithBuilderSimpleSetter omitted =
1766         OptionalPropertiesWithBuilderSimpleSetter.builder().build();
1767     assertThat(omitted.optionalString()).isAbsent();
1768 
1769     OptionalPropertiesWithBuilderSimpleSetter supplied =
1770         OptionalPropertiesWithBuilderSimpleSetter.builder().setOptionalString("foo").build();
1771     assertThat(supplied.optionalString()).hasValue("foo");
1772   }
1773 
1774   @AutoValue
1775   public abstract static class PropertyWithOptionalGetter {
getString()1776     public abstract String getString();
1777 
getInt()1778     public abstract int getInt();
1779 
builder()1780     public static Builder builder() {
1781       return new AutoValue_AutoValueTest_PropertyWithOptionalGetter.Builder();
1782     }
1783 
1784     @AutoValue.Builder
1785     public interface Builder {
setString(String s)1786       Builder setString(String s);
1787 
getString()1788       com.google.common.base.Optional<String> getString();
1789 
setInt(int x)1790       Builder setInt(int x);
1791 
getInt()1792       com.google.common.base.Optional<Integer> getInt();
1793 
build()1794       PropertyWithOptionalGetter build();
1795     }
1796   }
1797 
1798   @Test
testOptionalGetter()1799   public void testOptionalGetter() {
1800     PropertyWithOptionalGetter.Builder omitted = PropertyWithOptionalGetter.builder();
1801     assertThat(omitted.getString()).isAbsent();
1802     assertThat(omitted.getInt()).isAbsent();
1803 
1804     PropertyWithOptionalGetter.Builder supplied =
1805         PropertyWithOptionalGetter.builder().setString("foo").setInt(23);
1806     assertThat(supplied.getString()).hasValue("foo");
1807     assertThat(supplied.getInt()).hasValue(23);
1808   }
1809 
1810   @AutoValue
1811   public abstract static class PropertyNamedMissing {
missing()1812     public abstract String missing();
1813 
builder()1814     public static Builder builder() {
1815       return new AutoValue_AutoValueTest_PropertyNamedMissing.Builder();
1816     }
1817 
1818     @AutoValue.Builder
1819     public abstract static class Builder {
setMissing(String x)1820       public abstract Builder setMissing(String x);
1821 
build()1822       public abstract PropertyNamedMissing build();
1823     }
1824   }
1825 
1826   // https://github.com/google/auto/issues/412
1827   @Test
testPropertyNamedMissing()1828   public void testPropertyNamedMissing() {
1829     try {
1830       PropertyNamedMissing.builder().build();
1831       fail();
1832     } catch (IllegalStateException expected) {
1833     }
1834     PropertyNamedMissing x = PropertyNamedMissing.builder().setMissing("foo").build();
1835     assertThat(x.missing()).isEqualTo("foo");
1836   }
1837 
1838   @AutoValue
1839   public abstract static class GenericsWithBuilder<T extends Number & Comparable<T>, U extends T> {
list()1840     public abstract List<T> list();
1841 
u()1842     public abstract U u();
1843 
builder()1844     public static <T extends Number & Comparable<T>, U extends T> Builder<T, U> builder() {
1845       return new AutoValue_AutoValueTest_GenericsWithBuilder.Builder<T, U>();
1846     }
1847 
toBuilderGenerated()1848     public abstract Builder<T, U> toBuilderGenerated();
1849 
1850     @AutoValue.Builder
1851     public interface Builder<T extends Number & Comparable<T>, U extends T> {
list(List<T> list)1852       Builder<T, U> list(List<T> list);
1853 
u(U u)1854       Builder<T, U> u(U u);
1855 
build()1856       GenericsWithBuilder<T, U> build();
1857     }
1858   }
1859 
1860   @Test
testBuilderGenerics()1861   public void testBuilderGenerics() {
1862     List<Integer> integers = ImmutableList.of(1, 2, 3);
1863     GenericsWithBuilder<Integer, Integer> instance =
1864         GenericsWithBuilder.<Integer, Integer>builder().list(integers).u(23).build();
1865     assertEquals(integers, instance.list());
1866     assertEquals((Integer) 23, instance.u());
1867 
1868     GenericsWithBuilder<Integer, Integer> instance2 = instance.toBuilderGenerated().build();
1869     assertEquals(instance, instance2);
1870     assertNotSame(instance, instance2);
1871 
1872     GenericsWithBuilder<Integer, Integer> instance3 = instance.toBuilderGenerated().u(17).build();
1873     assertEquals(integers, instance3.list());
1874     assertEquals((Integer) 17, instance3.u());
1875   }
1876 
1877   @AutoValue
1878   public abstract static class BuilderWithSet<T extends Comparable<T>> {
list()1879     public abstract List<T> list();
1880 
t()1881     public abstract T t();
1882 
builder()1883     public static <T extends Comparable<T>> Builder<T> builder() {
1884       return new AutoValue_AutoValueTest_BuilderWithSet.Builder<T>();
1885     }
1886 
1887     @AutoValue.Builder
1888     public interface Builder<T extends Comparable<T>> {
setList(List<T> list)1889       Builder<T> setList(List<T> list);
1890 
setT(T t)1891       Builder<T> setT(T t);
1892 
build()1893       BuilderWithSet<T> build();
1894     }
1895   }
1896 
1897   @Test
testBuilderWithSet()1898   public void testBuilderWithSet() {
1899     List<Integer> integers = ImmutableList.of(1, 2, 3);
1900     BuilderWithSet<Integer> instance =
1901         BuilderWithSet.<Integer>builder().setList(integers).setT(23).build();
1902     assertEquals(integers, instance.list());
1903     assertEquals((Integer) 23, instance.t());
1904   }
1905 
1906   @AutoValue
1907   public abstract static class BuilderWithSetAndGet {
getAList()1908     public abstract List<Integer> getAList();
1909 
getAnInt()1910     public abstract int getAnInt();
1911 
builder()1912     public static Builder builder() {
1913       return new AutoValue_AutoValueTest_BuilderWithSetAndGet.Builder();
1914     }
1915 
toBuilder()1916     public abstract Builder toBuilder();
1917 
1918     @AutoValue.Builder
1919     public interface Builder {
setAList(List<Integer> list)1920       Builder setAList(List<Integer> list);
1921 
setAnInt(int i)1922       Builder setAnInt(int i);
1923 
build()1924       BuilderWithSetAndGet build();
1925     }
1926   }
1927 
1928   @Test
testBuilderWithSetAndGet()1929   public void testBuilderWithSetAndGet() {
1930     List<Integer> integers = ImmutableList.of(1, 2, 3);
1931     BuilderWithSetAndGet instance =
1932         BuilderWithSetAndGet.builder().setAList(integers).setAnInt(23).build();
1933     assertEquals(integers, instance.getAList());
1934     assertEquals(23, instance.getAnInt());
1935 
1936     BuilderWithSetAndGet instance2 = instance.toBuilder().build();
1937     assertEquals(instance, instance2);
1938     assertNotSame(instance, instance2);
1939 
1940     BuilderWithSetAndGet instance3 = instance.toBuilder().setAnInt(17).build();
1941     assertEquals(integers, instance3.getAList());
1942     assertEquals(17, instance3.getAnInt());
1943   }
1944 
1945   @AutoValue
1946   public abstract static class BuilderWithUnprefixedGetters<T extends Comparable<T>> {
list()1947     public abstract ImmutableList<T> list();
1948 
1949     @Nullable
t()1950     public abstract T t();
1951 
1952     @SuppressWarnings("mutable")
ints()1953     public abstract int[] ints();
1954 
noGetter()1955     public abstract int noGetter();
1956 
oAuth()1957     public abstract String oAuth();
1958 
oBrien()1959     public abstract String oBrien();
1960 
builder()1961     public static <T extends Comparable<T>> Builder<T> builder() {
1962       return new AutoValue_AutoValueTest_BuilderWithUnprefixedGetters.Builder<T>();
1963     }
1964 
1965     @AutoValue.Builder
1966     public interface Builder<T extends Comparable<T>> {
setList(ImmutableList<T> list)1967       Builder<T> setList(ImmutableList<T> list);
1968 
setT(T t)1969       Builder<T> setT(T t);
1970 
setInts(int[] ints)1971       Builder<T> setInts(int[] ints);
1972 
setNoGetter(int x)1973       Builder<T> setNoGetter(int x);
1974 
setoAuth(String x)1975       Builder<T> setoAuth(String x); // this ugly spelling is for compatibility
1976 
setOBrien(String x)1977       Builder<T> setOBrien(String x);
1978 
list()1979       ImmutableList<T> list();
1980 
t()1981       T t();
1982 
ints()1983       int[] ints();
1984 
oAuth()1985       String oAuth();
1986 
oBrien()1987       String oBrien();
1988 
build()1989       BuilderWithUnprefixedGetters<T> build();
1990     }
1991   }
1992 
1993   @Test
testBuilderWithUnprefixedGetter()1994   public void testBuilderWithUnprefixedGetter() {
1995     ImmutableList<String> names = ImmutableList.of("fred", "jim");
1996     int[] ints = {6, 28, 496, 8128, 33550336};
1997     int noGetter = -1;
1998 
1999     BuilderWithUnprefixedGetters.Builder<String> builder = BuilderWithUnprefixedGetters.builder();
2000     assertNull(builder.t());
2001     try {
2002       builder.list();
2003       fail("Attempt to retrieve unset list property should have failed");
2004     } catch (IllegalStateException e) {
2005       if (omitIdentifiers) {
2006         assertThat(e).hasMessageThat().isNull();
2007       } else {
2008         assertThat(e).hasMessageThat().isEqualTo("Property \"list\" has not been set");
2009       }
2010     }
2011     try {
2012       builder.ints();
2013       fail("Attempt to retrieve unset ints property should have failed");
2014     } catch (IllegalStateException e) {
2015       if (omitIdentifiers) {
2016         assertThat(e).hasMessageThat().isNull();
2017       } else {
2018         assertThat(e).hasMessageThat().isEqualTo("Property \"ints\" has not been set");
2019       }
2020     }
2021 
2022     builder.setList(names);
2023     assertThat(builder.list()).isSameInstanceAs(names);
2024     builder.setInts(ints);
2025     assertThat(builder.ints()).isEqualTo(ints);
2026     builder.setoAuth("OAuth");
2027     assertThat(builder.oAuth()).isEqualTo("OAuth");
2028     builder.setOBrien("Flann");
2029     assertThat(builder.oBrien()).isEqualTo("Flann");
2030     // The array is not cloned by the getter, so the client can modify it (but shouldn't).
2031     ints[0] = 0;
2032     assertThat(builder.ints()[0]).isEqualTo(0);
2033     ints[0] = 6;
2034 
2035     BuilderWithUnprefixedGetters<String> instance = builder.setNoGetter(noGetter).build();
2036     assertThat(instance.list()).isSameInstanceAs(names);
2037     assertThat(instance.t()).isNull();
2038     assertThat(instance.ints()).isEqualTo(ints);
2039     assertThat(instance.noGetter()).isEqualTo(noGetter);
2040     assertThat(instance.oAuth()).isEqualTo("OAuth");
2041     assertThat(instance.oBrien()).isEqualTo("Flann");
2042   }
2043 
2044   @AutoValue
2045   public abstract static class BuilderWithPrefixedGetters<T extends Comparable<T>> {
getList()2046     public abstract ImmutableList<T> getList();
2047 
getT()2048     public abstract T getT();
2049 
2050     @SuppressWarnings("mutable")
2051     @Nullable
getInts()2052     public abstract int[] getInts();
2053 
getOAuth()2054     public abstract String getOAuth();
2055 
getNoGetter()2056     public abstract int getNoGetter();
2057 
builder()2058     public static <T extends Comparable<T>> Builder<T> builder() {
2059       return new AutoValue_AutoValueTest_BuilderWithPrefixedGetters.Builder<T>();
2060     }
2061 
2062     @AutoValue.Builder
2063     public abstract static class Builder<T extends Comparable<T>> {
setList(ImmutableList<T> list)2064       public abstract Builder<T> setList(ImmutableList<T> list);
2065 
setT(T t)2066       public abstract Builder<T> setT(T t);
2067 
setInts(int[] ints)2068       public abstract Builder<T> setInts(int[] ints);
2069 
setNoGetter(int x)2070       public abstract Builder<T> setNoGetter(int x);
2071 
setOAuth(String x)2072       public abstract Builder<T> setOAuth(String x);
2073 
getList()2074       abstract ImmutableList<T> getList();
2075 
getT()2076       abstract T getT();
2077 
getInts()2078       abstract int[] getInts();
2079 
build()2080       public abstract BuilderWithPrefixedGetters<T> build();
2081     }
2082   }
2083 
2084   @Test
testBuilderWithPrefixedGetter()2085   public void testBuilderWithPrefixedGetter() {
2086     ImmutableList<String> names = ImmutableList.of("fred", "jim");
2087     String name = "sheila";
2088     int noGetter = -1;
2089 
2090     BuilderWithPrefixedGetters.Builder<String> builder = BuilderWithPrefixedGetters.builder();
2091     assertThat(builder.getInts()).isNull();
2092     try {
2093       builder.getList();
2094       fail("Attempt to retrieve unset list property should have failed");
2095     } catch (IllegalStateException e) {
2096       if (omitIdentifiers) {
2097         assertThat(e).hasMessageThat().isNull();
2098       } else {
2099         assertThat(e).hasMessageThat().isEqualTo("Property \"list\" has not been set");
2100       }
2101     }
2102 
2103     builder.setList(names);
2104     assertThat(builder.getList()).isSameInstanceAs(names);
2105     builder.setT(name);
2106     assertThat(builder.getInts()).isNull();
2107     builder.setOAuth("OAuth");
2108 
2109     BuilderWithPrefixedGetters<String> instance = builder.setNoGetter(noGetter).build();
2110     assertThat(instance.getList()).isSameInstanceAs(names);
2111     assertThat(instance.getT()).isEqualTo(name);
2112     assertThat(instance.getInts()).isNull();
2113     assertThat(instance.getNoGetter()).isEqualTo(noGetter);
2114     assertThat(instance.getOAuth()).isEqualTo("OAuth");
2115   }
2116 
2117   @AutoValue
2118   public abstract static class BuilderWithPropertyBuilders<FooT extends Comparable<FooT>> {
getFoos()2119     public abstract ImmutableList<FooT> getFoos();
2120 
getStrings()2121     public abstract ImmutableSet<String> getStrings();
2122 
toBuilder()2123     public abstract BuilderWithPropertyBuilders.Builder<FooT> toBuilder();
2124 
builder()2125     public static <FooT extends Comparable<FooT>> Builder<FooT> builder() {
2126       return new AutoValue_AutoValueTest_BuilderWithPropertyBuilders.Builder<FooT>();
2127     }
2128 
2129     @AutoValue.Builder
2130     public abstract static class Builder<FooT extends Comparable<FooT>> {
getFoos()2131       public abstract ImmutableList<FooT> getFoos();
2132 
addFoos(Iterable<FooT> foos)2133       public Builder<FooT> addFoos(Iterable<FooT> foos) {
2134         foosBuilder().addAll(foos);
2135         return this;
2136       }
2137 
foosBuilder()2138       abstract ImmutableList.Builder<FooT> foosBuilder();
2139 
addToTs(FooT element)2140       public Builder<FooT> addToTs(FooT element) {
2141         foosBuilder().add(element);
2142         return this;
2143       }
2144 
setStrings(ImmutableList<String> strings)2145       abstract Builder<FooT> setStrings(ImmutableList<String> strings);
2146 
stringsBuilder()2147       abstract ImmutableSet.Builder<String> stringsBuilder();
2148 
addToStrings(String element)2149       public Builder<FooT> addToStrings(String element) {
2150         stringsBuilder().add(element);
2151         return this;
2152       }
2153 
build()2154       public abstract BuilderWithPropertyBuilders<FooT> build();
2155     }
2156   }
2157 
2158   @Test
testBuilderWithPropertyBuilders()2159   public void testBuilderWithPropertyBuilders() {
2160     ImmutableList<Integer> numbers = ImmutableList.of(1, 1, 2, 6, 24);
2161     ImmutableSet<String> names = ImmutableSet.of("one", "two", "six", "twenty-four");
2162 
2163     BuilderWithPropertyBuilders<Integer> a =
2164         BuilderWithPropertyBuilders.<Integer>builder()
2165             .addFoos(numbers)
2166             .addToStrings("one")
2167             .addToStrings("two")
2168             .addToStrings("six")
2169             .addToStrings("twenty-four")
2170             .build();
2171 
2172     assertEquals(numbers, a.getFoos());
2173     assertEquals(names, a.getStrings());
2174 
2175     BuilderWithPropertyBuilders.Builder<Integer> bBuilder = BuilderWithPropertyBuilders.builder();
2176     bBuilder.stringsBuilder().addAll(names);
2177     bBuilder.foosBuilder().addAll(numbers);
2178 
2179     assertEquals(numbers, bBuilder.getFoos());
2180 
2181     BuilderWithPropertyBuilders<Integer> b = bBuilder.build();
2182     assertEquals(a, b);
2183 
2184     BuilderWithPropertyBuilders.Builder<Integer> cBuilder = a.toBuilder();
2185     cBuilder.addToStrings("one hundred and twenty");
2186     cBuilder.addToTs(120);
2187     BuilderWithPropertyBuilders<Integer> c = cBuilder.build();
2188     assertEquals(
2189         ImmutableSet.of("one", "two", "six", "twenty-four", "one hundred and twenty"),
2190         c.getStrings());
2191     assertEquals(ImmutableList.of(1, 1, 2, 6, 24, 120), c.getFoos());
2192 
2193     BuilderWithPropertyBuilders.Builder<Integer> dBuilder = a.toBuilder();
2194     dBuilder.addFoos(ImmutableList.of(120, 720));
2195     BuilderWithPropertyBuilders<Integer> d = dBuilder.build();
2196     assertEquals(ImmutableList.of(1, 1, 2, 6, 24, 120, 720), d.getFoos());
2197     assertEquals(names, d.getStrings());
2198 
2199     BuilderWithPropertyBuilders<Integer> empty =
2200         BuilderWithPropertyBuilders.<Integer>builder().build();
2201     assertEquals(ImmutableList.of(), empty.getFoos());
2202     assertEquals(ImmutableSet.of(), empty.getStrings());
2203 
2204     try {
2205       BuilderWithPropertyBuilders.<Integer>builder().setStrings(null).build();
2206       fail("Did not get expected exception");
2207     } catch (RuntimeException expected) {
2208       // We don't specify whether you get the exception on setStrings(null) or on build(), nor
2209       // which exception it is exactly.
2210     }
2211   }
2212 
2213   interface ImmutableListOf<T> {
list()2214     ImmutableList<T> list();
2215   }
2216 
2217   @AutoValue
2218   abstract static class PropertyBuilderInheritsType implements ImmutableListOf<String> {
builder()2219     static Builder builder() {
2220       return new AutoValue_AutoValueTest_PropertyBuilderInheritsType.Builder();
2221     }
2222 
2223     @AutoValue.Builder
2224     abstract static class Builder {
listBuilder()2225       abstract ImmutableList.Builder<String> listBuilder();
build()2226       abstract PropertyBuilderInheritsType build();
2227     }
2228   }
2229 
2230   @Test
propertyBuilderInheritsType()2231   public void propertyBuilderInheritsType() {
2232     PropertyBuilderInheritsType.Builder builder = PropertyBuilderInheritsType.builder();
2233     builder.listBuilder().add("foo", "bar");
2234     PropertyBuilderInheritsType x = builder.build();
2235     assertThat(x.list()).containsExactly("foo", "bar").inOrder();
2236   }
2237 
2238   @AutoValue
2239   public abstract static class BuilderWithExoticPropertyBuilders<
2240       K extends Number, V extends Comparable<K>> {
map()2241     public abstract ImmutableMap<String, V> map();
2242 
table()2243     public abstract ImmutableTable<String, K, V> table();
2244 
builder()2245     public static <K extends Number, V extends Comparable<K>> Builder<K, V> builder() {
2246       return new AutoValue_AutoValueTest_BuilderWithExoticPropertyBuilders.Builder<K, V>();
2247     }
2248 
2249     @AutoValue.Builder
2250     public abstract static class Builder<K extends Number, V extends Comparable<K>> {
putAll(Map<String, V> map)2251       public Builder<K, V> putAll(Map<String, V> map) {
2252         mapBuilder().putAll(map);
2253         return this;
2254       }
2255 
mapBuilder()2256       public abstract ImmutableMap.Builder<String, V> mapBuilder();
2257 
putAll(ImmutableTable<String, K, V> table)2258       public Builder<K, V> putAll(ImmutableTable<String, K, V> table) {
2259         tableBuilder().putAll(table);
2260         return this;
2261       }
2262 
tableBuilder()2263       public abstract ImmutableTable.Builder<String, K, V> tableBuilder();
2264 
build()2265       public abstract BuilderWithExoticPropertyBuilders<K, V> build();
2266     }
2267   }
2268 
2269   @Test
testBuilderWithExoticPropertyBuilders()2270   public void testBuilderWithExoticPropertyBuilders() {
2271     ImmutableMap<String, Integer> map = ImmutableMap.of("one", 1);
2272     ImmutableTable<String, Integer, Integer> table = ImmutableTable.of("one", 1, -1);
2273 
2274     BuilderWithExoticPropertyBuilders<Integer, Integer> a =
2275         BuilderWithExoticPropertyBuilders.<Integer, Integer>builder()
2276             .putAll(map)
2277             .putAll(table)
2278             .build();
2279     assertEquals(map, a.map());
2280     assertEquals(table, a.table());
2281 
2282     BuilderWithExoticPropertyBuilders.Builder<Integer, Integer> bBuilder =
2283         BuilderWithExoticPropertyBuilders.builder();
2284     bBuilder.mapBuilder().putAll(map);
2285     bBuilder.tableBuilder().putAll(table);
2286     BuilderWithExoticPropertyBuilders<Integer, Integer> b = bBuilder.build();
2287     assertEquals(a, b);
2288 
2289     BuilderWithExoticPropertyBuilders<Integer, Integer> empty =
2290         BuilderWithExoticPropertyBuilders.<Integer, Integer>builder().build();
2291     assertEquals(ImmutableMap.of(), empty.map());
2292     assertEquals(ImmutableTable.of(), empty.table());
2293   }
2294 
2295   @AutoValue
2296   public abstract static class BuilderWithCopyingSetters<T extends Number> {
things()2297     public abstract ImmutableSet<? extends T> things();
2298 
numbers()2299     public abstract ImmutableList<Number> numbers();
2300 
map()2301     public abstract ImmutableMap<String, T> map();
2302 
builder(T value)2303     public static <T extends Number> Builder<T> builder(T value) {
2304       return new AutoValue_AutoValueTest_BuilderWithCopyingSetters.Builder<T>()
2305           .setNumbers(ImmutableSet.of(17, 23.0))
2306           .setMap(Collections.singletonMap("foo", value));
2307     }
2308 
2309     @AutoValue.Builder
2310     public interface Builder<T extends Number> {
setThings(ImmutableSet<T> things)2311       Builder<T> setThings(ImmutableSet<T> things);
2312 
setThings(Iterable<? extends T> things)2313       Builder<T> setThings(Iterable<? extends T> things);
2314 
setThings(T... things)2315       Builder<T> setThings(T... things);
2316 
setNumbers(Collection<? extends Number> strings)2317       Builder<T> setNumbers(Collection<? extends Number> strings);
2318 
setMap(Map<String, T> map)2319       Builder<T> setMap(Map<String, T> map);
2320 
build()2321       BuilderWithCopyingSetters<T> build();
2322     }
2323   }
2324 
2325   @Test
testBuilderWithCopyingSetters()2326   public void testBuilderWithCopyingSetters() {
2327     BuilderWithCopyingSetters.Builder<Integer> builder = BuilderWithCopyingSetters.builder(23);
2328 
2329     BuilderWithCopyingSetters<Integer> a = builder.setThings(ImmutableSet.of(1, 2)).build();
2330     assertThat(a.things()).containsExactly(1, 2);
2331     assertThat(a.numbers()).containsExactly(17, 23.0).inOrder();
2332     assertThat(a.map()).containsExactly("foo", 23);
2333 
2334     BuilderWithCopyingSetters<Integer> b = builder.setThings(Arrays.asList(1, 2)).build();
2335     assertThat(b).isEqualTo(a);
2336 
2337     BuilderWithCopyingSetters<Integer> c = builder.setThings(1, 2).build();
2338     assertThat(c).isEqualTo(a);
2339   }
2340 
2341   @AutoValue
2342   public abstract static class BuilderWithImmutableSorted<T extends Comparable<T>> {
sortedSet()2343     public abstract ImmutableSortedSet<T> sortedSet();
2344 
sortedMap()2345     public abstract ImmutableSortedMap<T, Integer> sortedMap();
2346 
builder()2347     public static <T extends Comparable<T>> Builder<T> builder() {
2348       return new AutoValue_AutoValueTest_BuilderWithImmutableSorted.Builder<T>()
2349           .setSortedSet(new TreeSet<T>())
2350           .setSortedMap(new TreeMap<T, Integer>());
2351     }
2352 
2353     @AutoValue.Builder
2354     public interface Builder<T extends Comparable<T>> {
2355       @SuppressWarnings("unchecked")
setSortedSet(T... x)2356       Builder<T> setSortedSet(T... x);
2357 
setSortedSet(NavigableSet<T> x)2358       Builder<T> setSortedSet(NavigableSet<T> x);
2359 
sortedSetBuilder()2360       ImmutableSortedSet.Builder<T> sortedSetBuilder();
2361 
setSortedMap(SortedMap<T, Integer> x)2362       Builder<T> setSortedMap(SortedMap<T, Integer> x);
2363 
setSortedMap(NavigableMap<T, Integer> x)2364       Builder<T> setSortedMap(NavigableMap<T, Integer> x);
2365 
sortedMapBuilder()2366       ImmutableSortedMap.Builder<T, Integer> sortedMapBuilder();
2367 
build()2368       BuilderWithImmutableSorted<T> build();
2369     }
2370   }
2371 
2372   @Test
testBuilderWithImmutableSorted_Varargs()2373   public void testBuilderWithImmutableSorted_Varargs() {
2374     BuilderWithImmutableSorted<String> x =
2375         BuilderWithImmutableSorted.<String>builder().setSortedSet("foo", "bar", "baz").build();
2376     assertThat(x.sortedSet()).containsExactly("bar", "baz", "foo").inOrder();
2377   }
2378 
2379   @Test
testBuilderWithImmutableSorted_SetSet()2380   public void testBuilderWithImmutableSorted_SetSet() {
2381     BuilderWithImmutableSorted<String> x =
2382         BuilderWithImmutableSorted.<String>builder()
2383             .setSortedSet(new TreeSet<String>(String.CASE_INSENSITIVE_ORDER))
2384             .build();
2385     assertThat(x.sortedSet().comparator()).isEqualTo(String.CASE_INSENSITIVE_ORDER);
2386   }
2387 
2388   @Test
testBuilderWithImmutableSorted_SetMap()2389   public void testBuilderWithImmutableSorted_SetMap() {
2390     BuilderWithImmutableSorted<String> x =
2391         BuilderWithImmutableSorted.<String>builder()
2392             .setSortedMap(new TreeMap<String, Integer>(String.CASE_INSENSITIVE_ORDER))
2393             .build();
2394     assertThat(x.sortedMap().comparator()).isEqualTo(String.CASE_INSENSITIVE_ORDER);
2395   }
2396 
2397   @Test
testBuilderWithImmutableSorted_SetCollectionBuilder()2398   public void testBuilderWithImmutableSorted_SetCollectionBuilder() {
2399     BuilderWithImmutableSorted.Builder<String> builder =
2400         BuilderWithImmutableSorted.<String>builder();
2401     builder.sortedSetBuilder().add("is", "ea", "id");
2402     BuilderWithImmutableSorted<String> x = builder.build();
2403     assertThat(x.sortedSet()).containsExactly("ea", "id", "is").inOrder();
2404   }
2405 
2406   @Test
testBuilderWithImmutableSorted_MapCollectionBuilder()2407   public void testBuilderWithImmutableSorted_MapCollectionBuilder() {
2408     BuilderWithImmutableSorted.Builder<String> builder =
2409         BuilderWithImmutableSorted.<String>builder();
2410     builder.sortedMapBuilder().put("two", 2).put("one", 1);
2411     BuilderWithImmutableSorted<String> x = builder.build();
2412     assertThat(x.sortedMap()).containsExactly("one", 1, "two", 2).inOrder();
2413   }
2414 
2415   @AutoValue
2416   public abstract static class BuilderWithCollectionBuilderAndSetter<T extends Number> {
things()2417     public abstract ImmutableList<T> things();
2418 
builder()2419     public static <T extends Number> Builder<T> builder() {
2420       return new AutoValue_AutoValueTest_BuilderWithCollectionBuilderAndSetter.Builder<T>();
2421     }
2422 
2423     @AutoValue.Builder
2424     public interface Builder<T extends Number> {
setThings(List<T> things)2425       Builder<T> setThings(List<T> things);
2426 
things()2427       ImmutableList<T> things();
2428 
thingsBuilder()2429       ImmutableList.Builder<T> thingsBuilder();
2430 
build()2431       BuilderWithCollectionBuilderAndSetter<T> build();
2432     }
2433   }
2434 
2435   @Test
testBuilderAndSetterDefaultsEmpty()2436   public void testBuilderAndSetterDefaultsEmpty() {
2437     BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder =
2438         BuilderWithCollectionBuilderAndSetter.<Integer>builder();
2439     assertThat(builder.things()).isEmpty();
2440     assertThat(builder.build().things()).isEmpty();
2441   }
2442 
2443   @Test
testBuilderAndSetterUsingBuilder()2444   public void testBuilderAndSetterUsingBuilder() {
2445     BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder =
2446         BuilderWithCollectionBuilderAndSetter.builder();
2447     builder.thingsBuilder().add(17, 23);
2448     BuilderWithCollectionBuilderAndSetter<Integer> x = builder.build();
2449     assertThat(x.things()).isEqualTo(ImmutableList.of(17, 23));
2450   }
2451 
2452   @Test
testBuilderAndSetterUsingSetter()2453   public void testBuilderAndSetterUsingSetter() {
2454     ImmutableList<Integer> things = ImmutableList.of(17, 23);
2455     BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder =
2456         BuilderWithCollectionBuilderAndSetter.<Integer>builder().setThings(things);
2457     assertThat(builder.things()).isSameInstanceAs(things);
2458     assertThat(builder.build().things()).isSameInstanceAs(things);
2459 
2460     List<Integer> moreThings = Arrays.asList(5, 17, 23);
2461     BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder2 =
2462         BuilderWithCollectionBuilderAndSetter.<Integer>builder().setThings(moreThings);
2463     assertThat(builder2.things()).isEqualTo(moreThings);
2464     assertThat(builder2.build().things()).isEqualTo(moreThings);
2465   }
2466 
2467   @Test
testBuilderAndSetterUsingSetterThenBuilder()2468   public void testBuilderAndSetterUsingSetterThenBuilder() {
2469     BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder =
2470         BuilderWithCollectionBuilderAndSetter.builder();
2471     builder.setThings(ImmutableList.of(5));
2472     builder.thingsBuilder().add(17, 23);
2473     List<Integer> expectedThings = ImmutableList.of(5, 17, 23);
2474     assertThat(builder.things()).isEqualTo(expectedThings);
2475     assertThat(builder.build().things()).isEqualTo(expectedThings);
2476   }
2477 
2478   @Test
testBuilderAndSetterCannotSetAfterBuilder()2479   public void testBuilderAndSetterCannotSetAfterBuilder() {
2480     BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder =
2481         BuilderWithCollectionBuilderAndSetter.builder();
2482     builder.setThings(ImmutableList.of(5));
2483     builder.thingsBuilder().add(17, 23);
2484     try {
2485       builder.setThings(ImmutableList.of(1729));
2486       fail("Setting list after retrieving builder should provoke an exception");
2487     } catch (IllegalStateException e) {
2488       if (omitIdentifiers) {
2489         assertThat(e).hasMessageThat().isNull();
2490       } else {
2491         assertThat(e).hasMessageThat().isEqualTo("Cannot set things after calling thingsBuilder()");
2492       }
2493     }
2494   }
2495 
2496   abstract static class AbstractParentWithBuilder {
foo()2497     abstract String foo();
2498 
2499     abstract static class Builder<B extends Builder<B>> {
foo(String s)2500       abstract B foo(String s);
2501     }
2502   }
2503 
2504   @AutoValue
2505   abstract static class ChildWithBuilder extends AbstractParentWithBuilder {
bar()2506     abstract String bar();
2507 
builder()2508     static Builder builder() {
2509       return new AutoValue_AutoValueTest_ChildWithBuilder.Builder();
2510     }
2511 
2512     @AutoValue.Builder
2513     abstract static class Builder extends AbstractParentWithBuilder.Builder<Builder> {
bar(String s)2514       abstract Builder bar(String s);
2515 
build()2516       abstract ChildWithBuilder build();
2517     }
2518   }
2519 
2520   @Test
testInheritedBuilder()2521   public void testInheritedBuilder() {
2522     ChildWithBuilder x = ChildWithBuilder.builder().foo("foo").bar("bar").build();
2523     assertThat(x.foo()).isEqualTo("foo");
2524     assertThat(x.bar()).isEqualTo("bar");
2525   }
2526 
2527   @Retention(RetentionPolicy.RUNTIME)
2528   @interface GwtCompatible {
funky()2529     boolean funky() default false;
2530   }
2531 
2532   @AutoValue
2533   @GwtCompatible(funky = true)
2534   abstract static class GwtCompatibleTest {
foo()2535     abstract int foo();
2536 
create(int foo)2537     static GwtCompatibleTest create(int foo) {
2538       return new AutoValue_AutoValueTest_GwtCompatibleTest(foo);
2539     }
2540   }
2541 
2542   @AutoValue
2543   @GwtCompatible
2544   abstract static class GwtCompatibleTestNoArgs {
bar()2545     abstract String bar();
2546 
create(String bar)2547     static GwtCompatibleTestNoArgs create(String bar) {
2548       return new AutoValue_AutoValueTest_GwtCompatibleTestNoArgs(bar);
2549     }
2550   }
2551 
2552   @Test
testGwtCompatibleInherited()2553   public void testGwtCompatibleInherited() {
2554     GwtCompatibleTest test = GwtCompatibleTest.create(23);
2555     GwtCompatible gwtCompatible = test.getClass().getAnnotation(GwtCompatible.class);
2556     assertNotNull(gwtCompatible);
2557     assertTrue(gwtCompatible.funky());
2558 
2559     GwtCompatibleTestNoArgs testNoArgs = GwtCompatibleTestNoArgs.create("23");
2560     GwtCompatible gwtCompatibleNoArgs = testNoArgs.getClass().getAnnotation(GwtCompatible.class);
2561     assertNotNull(gwtCompatibleNoArgs);
2562     assertFalse(gwtCompatibleNoArgs.funky());
2563   }
2564 
2565   @interface NestedAnnotation {
anInt()2566     int anInt();
2567 
aClassArray()2568     Class<?>[] aClassArray();
2569   }
2570 
2571   @Retention(RetentionPolicy.RUNTIME)
2572   @interface HairyAnnotation {
aString()2573     String aString();
2574 
aClass()2575     Class<? extends Number> aClass();
2576 
anEnum()2577     RetentionPolicy anEnum();
2578 
anAnnotation()2579     NestedAnnotation anAnnotation();
2580   }
2581 
2582   @Retention(RetentionPolicy.RUNTIME)
2583   @interface CopiedAnnotation {}
2584 
2585   @Retention(RetentionPolicy.RUNTIME)
2586   @interface ExcludedAnnotation {}
2587 
2588   @Retention(RetentionPolicy.RUNTIME)
2589   @Inherited
2590   @interface InheritedAnnotation {}
2591 
2592   @CopiedAnnotation
2593   @ExcludedAnnotation
2594   @InheritedAnnotation
2595   @AutoValue
2596   @AutoValue.CopyAnnotations(exclude = {ExcludedAnnotation.class})
2597   abstract static class CopyAnnotation {
2598     @HairyAnnotation(
2599         aString = "hello",
2600         aClass = Integer.class,
2601         anEnum = RetentionPolicy.RUNTIME,
2602         anAnnotation =
2603             @NestedAnnotation(
2604                 anInt = 73,
2605                 aClassArray = {String.class, Object.class}))
field1()2606     abstract String field1();
2607 
2608     @CopiedAnnotation
2609     @ExcludedAnnotation
2610     @InheritedAnnotation
2611     @AutoValue.CopyAnnotations(exclude = {ExcludedAnnotation.class})
field2()2612     abstract String field2();
2613 
create()2614     static CopyAnnotation create() {
2615       return new AutoValue_AutoValueTest_CopyAnnotation("field1", "field2");
2616     }
2617   }
2618 
2619   @Test
testCopyClassAnnotations()2620   public void testCopyClassAnnotations() throws Exception {
2621     CopyAnnotation x = CopyAnnotation.create();
2622     Class<?> c = x.getClass();
2623     assertNotSame(CopyAnnotation.class, c);
2624 
2625     // Sanity check: if these don't appear on CopyAnnotation, it makes no sense to assert that they
2626     // don't appear on the AutoValue_ subclass.
2627     {
2628       List<Class<? extends Annotation>> annotationsOnSuperclass =
2629           new ArrayList<Class<? extends Annotation>>();
2630       for (Annotation annotation : CopyAnnotation.class.getDeclaredAnnotations()) {
2631         annotationsOnSuperclass.add(annotation.annotationType());
2632       }
2633       assertThat(annotationsOnSuperclass)
2634           .containsAtLeast(
2635               CopiedAnnotation.class, ExcludedAnnotation.class, InheritedAnnotation.class);
2636     }
2637 
2638     {
2639       List<Class<? extends Annotation>> annotationsOnSubclass =
2640           new ArrayList<Class<? extends Annotation>>();
2641       for (Annotation annotation : c.getDeclaredAnnotations()) {
2642         annotationsOnSubclass.add(annotation.annotationType());
2643       }
2644       assertThat(annotationsOnSubclass).containsExactly(CopiedAnnotation.class);
2645     }
2646   }
2647 
2648   @Test
testCopyMethodAnnotations()2649   public void testCopyMethodAnnotations() throws Exception {
2650     CopyAnnotation x = CopyAnnotation.create();
2651     Class<?> c = x.getClass();
2652     assertNotSame(CopyAnnotation.class, c);
2653 
2654     Method methodInSubclass = c.getDeclaredMethod("field2");
2655     Method methodInSuperclass = CopyAnnotation.class.getDeclaredMethod("field2");
2656 
2657     // Sanity check: if these don't appear on CopyAnnotation, it makes no sense to assert that they
2658     // don't appear on the AutoValue_ subclass.
2659     assertThat(methodInSuperclass.isAnnotationPresent(CopiedAnnotation.class)).isTrue();
2660     assertThat(methodInSuperclass.isAnnotationPresent(ExcludedAnnotation.class)).isTrue();
2661     assertThat(methodInSuperclass.isAnnotationPresent(InheritedAnnotation.class)).isTrue();
2662 
2663     assertThat(methodInSubclass.isAnnotationPresent(CopiedAnnotation.class)).isTrue();
2664     assertThat(methodInSubclass.isAnnotationPresent(ExcludedAnnotation.class)).isFalse();
2665     assertThat(methodInSubclass.isAnnotationPresent(InheritedAnnotation.class)).isTrue();
2666   }
2667 
2668   @Test
testCopyMethodAnnotationsByDefault()2669   public void testCopyMethodAnnotationsByDefault() throws Exception {
2670     CopyAnnotation x = CopyAnnotation.create();
2671     Class<?> c = x.getClass();
2672     assertNotSame(CopyAnnotation.class, c);
2673     Method methodInSubclass = c.getDeclaredMethod("field1");
2674     Method methodInSuperclass = CopyAnnotation.class.getDeclaredMethod("field1");
2675     assertNotSame(methodInSuperclass, methodInSubclass);
2676     HairyAnnotation annotationInSubclass = methodInSubclass.getAnnotation(HairyAnnotation.class);
2677     HairyAnnotation annotationInSuperclass =
2678         methodInSuperclass.getAnnotation(HairyAnnotation.class);
2679     assertEquals(annotationInSuperclass, annotationInSubclass);
2680   }
2681 
2682   @AutoValue
2683   abstract static class HProperty {
h()2684     public abstract Object h();
2685 
create(Object h)2686     public static HProperty create(Object h) {
2687       return new AutoValue_AutoValueTest_HProperty(h);
2688     }
2689   }
2690 
2691   @Test
testHProperty()2692   public void testHProperty() throws Exception {
2693     // Checks that we can have a property called `h`. The generated hashCode() method has
2694     // a local variable of that name and can cause the error `int cannot be dereferenced`
2695     HProperty.create(new Object());
2696   }
2697 
2698   interface Parent1 {
something()2699     int something();
2700   }
2701 
2702   interface Parent2 {
something()2703     int something();
2704   }
2705 
2706   @AutoValue
2707   abstract static class InheritSameMethodTwice implements Parent1, Parent2 {
create(int something)2708     static InheritSameMethodTwice create(int something) {
2709       return new AutoValue_AutoValueTest_InheritSameMethodTwice(something);
2710     }
2711   }
2712 
2713   @Test
testInheritSameMethodTwice()2714   public void testInheritSameMethodTwice() {
2715     InheritSameMethodTwice x = InheritSameMethodTwice.create(23);
2716     assertThat(x.something()).isEqualTo(23);
2717   }
2718 
2719   // Make sure we behave correctly when we inherit the same method definition from more than
2720   // one parent interface. We expect methods to appear in the order they are seen, with parents
2721   // preceding children, the superclass of a class preceding interfaces that class implements,
2722   // and an interface mentioned earlier in the "implements" clause preceding one mentioned later.
2723   // https://github.com/google/auto/issues/372
2724   interface OneTwoThreeFour {
one()2725     String one();
2726 
two()2727     String two();
2728 
three()2729     boolean three();
2730 
four()2731     long four();
2732   }
2733 
2734   interface TwoFour {
two()2735     String two();
2736 
four()2737     long four();
2738   }
2739 
2740   @AutoValue
2741   abstract static class OneTwoThreeFourImpl implements OneTwoThreeFour, TwoFour {
create(String one, String two, boolean three, long four)2742     static OneTwoThreeFourImpl create(String one, String two, boolean three, long four) {
2743       return new AutoValue_AutoValueTest_OneTwoThreeFourImpl(one, two, three, four);
2744     }
2745   }
2746 
2747   @Test
testOneTwoThreeFour()2748   public void testOneTwoThreeFour() {
2749     OneTwoThreeFour x = OneTwoThreeFourImpl.create("one", "two", false, 4);
2750     String expectedString =
2751         omitIdentifiers
2752             ? "{one, two, false, 4}"
2753             : "OneTwoThreeFourImpl{one=one, two=two, three=false, four=4}";
2754     assertThat(x.toString()).isEqualTo(expectedString);
2755   }
2756 
2757   @AutoValue
2758   abstract static class OuterWithBuilder {
foo()2759     abstract String foo();
2760 
inner()2761     abstract InnerWithBuilder inner();
2762 
toBuilder()2763     abstract Builder toBuilder();
2764 
builder()2765     static Builder builder() {
2766       return new AutoValue_AutoValueTest_OuterWithBuilder.Builder();
2767     }
2768 
2769     @AutoValue.Builder
2770     abstract static class Builder {
foo(String x)2771       abstract Builder foo(String x);
2772 
inner(InnerWithBuilder x)2773       abstract Builder inner(InnerWithBuilder x);
2774 
innerBuilder()2775       abstract InnerWithBuilder.Builder innerBuilder();
2776 
build()2777       abstract OuterWithBuilder build();
2778     }
2779   }
2780 
2781   @AutoValue
2782   abstract static class InnerWithBuilder {
bar()2783     abstract int bar();
2784 
toBuilder()2785     abstract Builder toBuilder();
2786 
builder()2787     static Builder builder() {
2788       return new AutoValue_AutoValueTest_InnerWithBuilder.Builder();
2789     }
2790 
2791     @AutoValue.Builder
2792     abstract static class Builder {
setBar(int x)2793       abstract Builder setBar(int x);
2794 
build()2795       abstract InnerWithBuilder build();
2796     }
2797   }
2798 
2799   @Test
testBuilderWithinBuilder()2800   public void testBuilderWithinBuilder() {
2801     OuterWithBuilder x =
2802         OuterWithBuilder.builder()
2803             .inner(InnerWithBuilder.builder().setBar(23).build())
2804             .foo("yes")
2805             .build();
2806     String expectedStringX =
2807         omitIdentifiers
2808             ? "{yes, {23}}"
2809             : "OuterWithBuilder{foo=yes, inner=InnerWithBuilder{bar=23}}";
2810     assertThat(x.toString()).isEqualTo(expectedStringX);
2811 
2812     OuterWithBuilder.Builder xBuilder = x.toBuilder();
2813     xBuilder.innerBuilder().setBar(17);
2814     OuterWithBuilder y = xBuilder.build();
2815     String expectedStringY =
2816         omitIdentifiers
2817             ? "{yes, {17}}"
2818             : "OuterWithBuilder{foo=yes, inner=InnerWithBuilder{bar=17}}";
2819     assertThat(y.toString()).isEqualTo(expectedStringY);
2820   }
2821 
2822   public static class MyMap<K, V> extends HashMap<K, V> {
MyMap()2823     public MyMap() {}
2824 
MyMap(Map<K, V> map)2825     public MyMap(Map<K, V> map) {
2826       super(map);
2827     }
2828   }
2829 
2830   public static class MyMapBuilder<K, V> extends LinkedHashMap<K, V> {
MyMapBuilder()2831     public MyMapBuilder() {}
2832 
MyMapBuilder(Map<K, V> map)2833     public MyMapBuilder(Map<K, V> map) {
2834       super(map);
2835     }
2836 
build()2837     public MyMap<K, V> build() {
2838       return new MyMap<K, V>(this);
2839     }
2840   }
2841 
2842   @AutoValue
2843   abstract static class BuildMyMap<K, V> {
map()2844     abstract MyMap<K, V> map();
2845 
toBuilder()2846     abstract Builder<K, V> toBuilder();
2847 
builder()2848     static <K, V> Builder<K, V> builder() {
2849       return new AutoValue_AutoValueTest_BuildMyMap.Builder<K, V>();
2850     }
2851 
2852     @AutoValue.Builder
2853     abstract static class Builder<K, V> {
mapBuilder()2854       abstract MyMapBuilder<K, V> mapBuilder();
2855 
build()2856       abstract BuildMyMap<K, V> build();
2857     }
2858   }
2859 
2860   @Test
testMyMapBuilder()2861   public void testMyMapBuilder() {
2862     BuildMyMap.Builder<String, Integer> builder = BuildMyMap.builder();
2863     MyMapBuilder<String, Integer> mapBuilder = builder.mapBuilder();
2864     mapBuilder.put("23", 23);
2865     BuildMyMap<String, Integer> built = builder.build();
2866     assertThat(built.map()).containsExactly("23", 23);
2867 
2868     BuildMyMap.Builder<String, Integer> builder2 = built.toBuilder();
2869     MyMapBuilder<String, Integer> mapBuilder2 = builder2.mapBuilder();
2870     mapBuilder2.put("17", 17);
2871     BuildMyMap<String, Integer> built2 = builder2.build();
2872     assertThat(built2.map()).containsExactly("23", 23, "17", 17);
2873   }
2874 
2875   public static class MyStringMap<V> extends MyMap<String, V> {
MyStringMap()2876     public MyStringMap() {}
2877 
MyStringMap(Map<String, V> map)2878     public MyStringMap(Map<String, V> map) {
2879       super(map);
2880     }
2881 
toBuilder()2882     public MyStringMapBuilder<V> toBuilder() {
2883       return new MyStringMapBuilder<V>(this);
2884     }
2885   }
2886 
2887   public static class MyStringMapBuilder<V> extends MyMapBuilder<String, V> {
MyStringMapBuilder()2888     public MyStringMapBuilder() {}
2889 
MyStringMapBuilder(Map<String, V> map)2890     public MyStringMapBuilder(Map<String, V> map) {
2891       super(map);
2892     }
2893 
2894     @Override
build()2895     public MyStringMap<V> build() {
2896       return new MyStringMap<V>(this);
2897     }
2898   }
2899 
2900   @AutoValue
2901   abstract static class BuildMyStringMap<V> {
map()2902     abstract MyStringMap<V> map();
2903 
toBuilder()2904     abstract Builder<V> toBuilder();
2905 
builder()2906     static <V> Builder<V> builder() {
2907       return new AutoValue_AutoValueTest_BuildMyStringMap.Builder<V>();
2908     }
2909 
2910     @AutoValue.Builder
2911     abstract static class Builder<V> {
mapBuilder()2912       abstract MyStringMapBuilder<V> mapBuilder();
2913 
build()2914       abstract BuildMyStringMap<V> build();
2915     }
2916   }
2917 
2918   @Test
testMyStringMapBuilder()2919   public void testMyStringMapBuilder() {
2920     BuildMyStringMap.Builder<Integer> builder = BuildMyStringMap.builder();
2921     MyStringMapBuilder<Integer> mapBuilder = builder.mapBuilder();
2922     mapBuilder.put("23", 23);
2923     BuildMyStringMap<Integer> built = builder.build();
2924     assertThat(built.map()).containsExactly("23", 23);
2925 
2926     BuildMyStringMap.Builder<Integer> builder2 = built.toBuilder();
2927     MyStringMapBuilder<Integer> mapBuilder2 = builder2.mapBuilder();
2928     mapBuilder2.put("17", 17);
2929     BuildMyStringMap<Integer> built2 = builder2.build();
2930     assertThat(built2.map()).containsExactly("17", 17, "23", 23);
2931   }
2932 
2933   @AutoValue
2934   abstract static class BuilderOfManyAccessLevels {
publicGetterProtectedBuilderGetterPackageProtectedSetterInt()2935     public abstract int publicGetterProtectedBuilderGetterPackageProtectedSetterInt();
2936 
protectedGetterPackageProtectedBuilderGetterPublicSetterInt()2937     protected abstract int protectedGetterPackageProtectedBuilderGetterPublicSetterInt();
2938 
packageProtectedGetterPublicBuilderGetterProtectedSetterInt()2939     abstract int packageProtectedGetterPublicBuilderGetterProtectedSetterInt();
2940 
2941     @AutoValue.Builder
2942     public abstract static class Builder {
publicGetterProtectedBuilderGetterPackageProtectedSetterInt()2943       protected abstract int publicGetterProtectedBuilderGetterPackageProtectedSetterInt();
2944 
protectedGetterPackageProtectedBuilderGetterPublicSetterInt()2945       abstract int protectedGetterPackageProtectedBuilderGetterPublicSetterInt();
2946 
packageProtectedGetterPublicBuilderGetterProtectedSetterInt()2947       public abstract int packageProtectedGetterPublicBuilderGetterProtectedSetterInt();
2948 
setPublicGetterProtectedBuilderGetterPackageProtectedSetterInt(int x)2949       abstract Builder setPublicGetterProtectedBuilderGetterPackageProtectedSetterInt(int x);
2950 
setProtectedGetterPackageProtectedBuilderGetterPublicSetterInt(int x)2951       public abstract Builder setProtectedGetterPackageProtectedBuilderGetterPublicSetterInt(int x);
2952 
setPackageProtectedGetterPublicBuilderGetterProtectedSetterInt( int x)2953       protected abstract Builder setPackageProtectedGetterPublicBuilderGetterProtectedSetterInt(
2954           int x);
2955 
build()2956       public abstract BuilderOfManyAccessLevels build();
2957     }
2958   }
2959 
2960   @Test
testBuilderOfManyAccessLevels_accessLevels()2961   public void testBuilderOfManyAccessLevels_accessLevels() throws NoSuchMethodException {
2962     Class<?> builderClass = AutoValue_AutoValueTest_BuilderOfManyAccessLevels.Builder.class;
2963 
2964     testMethodAccess(
2965         Access.PROTECTED,
2966         builderClass,
2967         "publicGetterProtectedBuilderGetterPackageProtectedSetterInt");
2968     testMethodAccess(
2969         Access.PACKAGE,
2970         builderClass,
2971         "protectedGetterPackageProtectedBuilderGetterPublicSetterInt");
2972     testMethodAccess(
2973         Access.PUBLIC, builderClass, "packageProtectedGetterPublicBuilderGetterProtectedSetterInt");
2974 
2975     testMethodAccess(
2976         Access.PACKAGE,
2977         builderClass,
2978         "setPublicGetterProtectedBuilderGetterPackageProtectedSetterInt",
2979         int.class);
2980     testMethodAccess(
2981         Access.PUBLIC,
2982         builderClass,
2983         "setProtectedGetterPackageProtectedBuilderGetterPublicSetterInt",
2984         int.class);
2985     testMethodAccess(
2986         Access.PROTECTED,
2987         builderClass,
2988         "setPackageProtectedGetterPublicBuilderGetterProtectedSetterInt",
2989         int.class);
2990   }
2991 
2992   private enum Access {
2993     PRIVATE,
2994     PACKAGE,
2995     PROTECTED,
2996     PUBLIC
2997   }
2998 
2999   private static final ImmutableMap<Integer, Access> MODIFIER_BITS_TO_ACCESS =
3000       ImmutableMap.of(
3001           Modifier.PUBLIC,
3002           Access.PUBLIC,
3003           Modifier.PROTECTED,
3004           Access.PROTECTED,
3005           Modifier.PRIVATE,
3006           Access.PRIVATE,
3007           0,
3008           Access.PACKAGE);
3009 
testMethodAccess( Access expectedAccess, Class<?> clazz, String methodName, Class<?>... parameterTypes)3010   private static void testMethodAccess(
3011       Access expectedAccess, Class<?> clazz, String methodName, Class<?>... parameterTypes)
3012       throws NoSuchMethodException {
3013     Method method = clazz.getDeclaredMethod(methodName, parameterTypes);
3014     int modBits = method.getModifiers() & (Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE);
3015     Access actualAccess = MODIFIER_BITS_TO_ACCESS.get(modBits);
3016     assertWithMessage("Wrong access for %s", methodName)
3017         .that(actualAccess)
3018         .isEqualTo(expectedAccess);
3019   }
3020 
3021   static class VersionId {}
3022 
3023   static class ItemVersionId extends VersionId {}
3024 
3025   interface VersionedPersistent {
getVersionId()3026     VersionId getVersionId();
3027   }
3028 
3029   interface Item extends VersionedPersistent {
3030     @Override
getVersionId()3031     ItemVersionId getVersionId();
3032   }
3033 
3034   @AutoValue
3035   abstract static class FakeItem implements Item {
builder()3036     static Builder builder() {
3037       return new AutoValue_AutoValueTest_FakeItem.Builder();
3038     }
3039 
3040     @AutoValue.Builder
3041     abstract static class Builder {
setVersionId(ItemVersionId x)3042       abstract Builder setVersionId(ItemVersionId x);
3043 
build()3044       abstract FakeItem build();
3045     }
3046   }
3047 
3048   @Test
testParentInterfaceOverridesGrandparent()3049   public void testParentInterfaceOverridesGrandparent() {
3050     ItemVersionId version = new ItemVersionId();
3051     FakeItem fakeItem = FakeItem.builder().setVersionId(version).build();
3052     assertThat(fakeItem.getVersionId()).isSameInstanceAs(version);
3053   }
3054 
3055   /** Fake ApkVersionCode class. */
3056   public static class ApkVersionCode {}
3057 
3058   /**
3059    * Illustrates a potential problem that showed up while generalizing builders. If our imports are
3060    * not accurate we may end up importing ImmutableList.Builder, which won't work because the
3061    * generated Builder subclass of ReleaseInfoBuilder will supersede it. Normally we wouldn't import
3062    * ImmutableList.Builder because the nested Builder class in the {@code @AutoValue} class would
3063    * prevent us trying. But in this case the nested class is called ReleaseInfoBuilder so we might
3064    * import anyway if we're not careful. This is one reason why we moved away from importing nested
3065    * classes to only importing top-level classes.
3066    */
3067   @AutoValue
3068   public abstract static class ReleaseInfo {
newBuilder()3069     public static ReleaseInfoBuilder newBuilder() {
3070       return new AutoValue_AutoValueTest_ReleaseInfo.Builder();
3071     }
3072 
apkVersionCodes()3073     public abstract ImmutableList<ApkVersionCode> apkVersionCodes();
3074 
ReleaseInfo()3075     ReleaseInfo() {}
3076 
3077     /** Notice that this is called ReleaseInfoBuilder and not Builder. */
3078     @AutoValue.Builder
3079     public abstract static class ReleaseInfoBuilder {
addApkVersionCode(ApkVersionCode code)3080       public ReleaseInfoBuilder addApkVersionCode(ApkVersionCode code) {
3081         apkVersionCodesBuilder().add(code);
3082         return this;
3083       }
3084 
apkVersionCodesBuilder()3085       abstract ImmutableList.Builder<ApkVersionCode> apkVersionCodesBuilder();
3086 
build()3087       public abstract ReleaseInfo build();
3088     }
3089   }
3090 
3091   @Test
testUnusualBuilderName()3092   public void testUnusualBuilderName() {
3093     ApkVersionCode apkVersionCode = new ApkVersionCode();
3094     ReleaseInfo x = ReleaseInfo.newBuilder().addApkVersionCode(apkVersionCode).build();
3095     assertThat(x.apkVersionCodes()).containsExactly(apkVersionCode);
3096   }
3097 
3098   @AutoValue
3099   public abstract static class OuterWithDefaultableInner {
names()3100     public abstract ImmutableList<String> names();
3101 
inner()3102     public abstract DefaultableInner inner();
3103 
builder()3104     public static Builder builder() {
3105       return new AutoValue_AutoValueTest_OuterWithDefaultableInner.Builder();
3106     }
3107 
3108     @AutoValue.Builder
3109     public abstract static class Builder {
names()3110       public abstract ImmutableList<String> names();
3111 
namesBuilder()3112       public abstract ImmutableList.Builder<String> namesBuilder();
3113 
inner()3114       public abstract DefaultableInner inner();
3115 
innerBuilder()3116       public abstract DefaultableInner.Builder innerBuilder();
3117 
build()3118       public abstract OuterWithDefaultableInner build();
3119     }
3120   }
3121 
3122   @AutoValue
3123   public abstract static class DefaultableInner {
bar()3124     public abstract int bar();
3125 
builder()3126     public static Builder builder() {
3127       return new AutoValue_AutoValueTest_DefaultableInner.Builder().setBar(23);
3128     }
3129 
3130     @AutoValue.Builder
3131     public abstract static class Builder {
setBar(int x)3132       public abstract Builder setBar(int x);
3133 
build()3134       public abstract DefaultableInner build();
3135     }
3136   }
3137 
3138   @Test
testOuterWithDefaultableInner_Defaults()3139   public void testOuterWithDefaultableInner_Defaults() {
3140     DefaultableInner defaultInner = DefaultableInner.builder().build();
3141     OuterWithDefaultableInner x = OuterWithDefaultableInner.builder().build();
3142     assertThat(x.names()).isEmpty();
3143     assertThat(x.inner()).isEqualTo(defaultInner);
3144   }
3145 
3146   @Test
testOuterWithDefaultableInner_Getters()3147   public void testOuterWithDefaultableInner_Getters() {
3148     DefaultableInner defaultInner = DefaultableInner.builder().build();
3149 
3150     OuterWithDefaultableInner.Builder builder = OuterWithDefaultableInner.builder();
3151     assertThat(builder.names()).isEmpty();
3152     assertThat(builder.inner()).isEqualTo(defaultInner);
3153 
3154     OuterWithDefaultableInner x1 = builder.build();
3155     assertThat(x1.names()).isEmpty();
3156     assertThat(x1.inner()).isEqualTo(defaultInner);
3157 
3158     builder.namesBuilder().add("Fred");
3159     builder.innerBuilder().setBar(17);
3160     OuterWithDefaultableInner x2 = builder.build();
3161     assertThat(x2.names()).containsExactly("Fred");
3162     assertThat(x2.inner().bar()).isEqualTo(17);
3163   }
3164 
3165   @AutoValue
3166   public abstract static class OuterWithNonDefaultableInner<T> {
foo()3167     public abstract int foo();
3168 
inner()3169     public abstract NonDefaultableInner<T> inner();
3170 
builder()3171     public static <T> Builder<T> builder() {
3172       return new AutoValue_AutoValueTest_OuterWithNonDefaultableInner.Builder<T>();
3173     }
3174 
3175     @AutoValue.Builder
3176     public abstract static class Builder<T> {
setFoo(int x)3177       public abstract Builder<T> setFoo(int x);
3178 
innerBuilder()3179       public abstract NonDefaultableInner.Builder<T> innerBuilder();
3180 
build()3181       public abstract OuterWithNonDefaultableInner<T> build();
3182     }
3183   }
3184 
3185   @AutoValue
3186   public abstract static class NonDefaultableInner<E> {
bar()3187     public abstract E bar();
3188 
builder()3189     public static <E> Builder<E> builder() {
3190       return new AutoValue_AutoValueTest_NonDefaultableInner.Builder<E>();
3191     }
3192 
3193     @AutoValue.Builder
3194     public abstract static class Builder<E> {
setBar(E x)3195       public abstract Builder<E> setBar(E x);
3196 
build()3197       public abstract NonDefaultableInner<E> build();
3198     }
3199   }
3200 
3201   @Test
testOuterWithNonDefaultableInner()3202   public void testOuterWithNonDefaultableInner() {
3203     OuterWithNonDefaultableInner.Builder<String> builder = OuterWithNonDefaultableInner.builder();
3204     builder.setFoo(23);
3205     try {
3206       builder.build();
3207       fail("Did not get expected exception for unbuilt inner instance");
3208     } catch (IllegalStateException expected) {
3209     }
3210   }
3211 
3212   @SuppressWarnings("JavaLangClash")
3213   @AutoValue
3214   public abstract static class RedeclareJavaLangClasses {
3215     // If you really really want to do this, we have you covered.
3216 
3217     public static class Object {}
3218 
3219     public static class String {}
3220 
alienObject()3221     public abstract Object alienObject();
3222 
alienString()3223     public abstract String alienString();
3224 
builder()3225     public static Builder builder() {
3226       return new AutoValue_AutoValueTest_RedeclareJavaLangClasses.Builder();
3227     }
3228 
3229     @AutoValue.Builder
3230     public abstract static class Builder {
setAlienObject(Object x)3231       public abstract Builder setAlienObject(Object x);
3232 
setAlienString(String x)3233       public abstract Builder setAlienString(String x);
3234 
build()3235       public abstract RedeclareJavaLangClasses build();
3236     }
3237   }
3238 
3239   @Test
testRedeclareJavaLangClasses()3240   public void testRedeclareJavaLangClasses() {
3241     RedeclareJavaLangClasses x =
3242         RedeclareJavaLangClasses.builder()
3243             .setAlienObject(new RedeclareJavaLangClasses.Object())
3244             .setAlienString(new RedeclareJavaLangClasses.String())
3245             .build();
3246     assertThat(x).isNotNull();
3247   }
3248 
3249   // b/28382293
3250   @AutoValue
3251   abstract static class GenericExtends {
metrics()3252     abstract ImmutableSet<Number> metrics();
3253 
builder()3254     static Builder builder() {
3255       return new AutoValue_AutoValueTest_GenericExtends.Builder();
3256     }
3257 
3258     @AutoValue.Builder
3259     abstract static class Builder {
setMetrics(ImmutableSet<? extends Number> metrics)3260       abstract Builder setMetrics(ImmutableSet<? extends Number> metrics);
build()3261       abstract GenericExtends build();
3262     }
3263   }
3264 
3265   @Test
testGenericExtends()3266   public void testGenericExtends() {
3267     ImmutableSet<Integer> ints = ImmutableSet.of(1, 2, 3);
3268     GenericExtends g = GenericExtends.builder().setMetrics(ints).build();
3269     assertThat(g.metrics()).isEqualTo(ints);
3270   }
3271 
3272   abstract static class Parent<T> {
getList()3273     abstract List<T> getList();
3274   }
3275 
3276   @AutoValue
3277   abstract static class Child extends Parent<String> {
builder()3278     static Builder builder() {
3279       return new AutoValue_AutoValueTest_Child.Builder();
3280     }
3281 
3282     @AutoValue.Builder
3283     abstract static class Builder {
setList(List<String> list)3284       abstract Builder setList(List<String> list);
build()3285       abstract Child build();
3286     }
3287   }
3288 
3289   @Test
nonGenericExtendsGeneric()3290   public void nonGenericExtendsGeneric() {
3291     List<String> list = ImmutableList.of("foo", "bar", "baz");
3292     Child child = Child.builder().setList(list).build();
3293     assertThat(child.getList()).containsExactlyElementsIn(list).inOrder();
3294   }
3295 
3296   abstract static class AbstractGenericParentWithBuilder<T> {
foo()3297     abstract T foo();
3298 
3299     abstract static class Builder<T, B extends Builder<T, B>> {
foo(T s)3300       abstract B foo(T s);
3301     }
3302   }
3303 
3304   @AutoValue
3305   abstract static class ChildOfAbstractGenericParentWithBuilder<T>
3306       extends AbstractGenericParentWithBuilder<T> {
builder()3307     static <T> Builder<T> builder() {
3308       return new AutoValue_AutoValueTest_ChildOfAbstractGenericParentWithBuilder.Builder<T>();
3309     }
3310 
3311     @AutoValue.Builder
3312     abstract static class Builder<T>
3313         extends AbstractGenericParentWithBuilder.Builder<T, Builder<T>> {
build()3314       abstract ChildOfAbstractGenericParentWithBuilder<T> build();
3315     }
3316   }
3317 
3318   @Test
genericExtendsGeneric()3319   public void genericExtendsGeneric() {
3320     ChildOfAbstractGenericParentWithBuilder<String> child =
3321         ChildOfAbstractGenericParentWithBuilder.<String>builder().foo("foo").build();
3322     assertThat(child.foo()).isEqualTo("foo");
3323   }
3324 
3325   @SuppressWarnings("ClassCanBeStatic")
3326   static class OuterWithTypeParam<T extends Number> {
3327     class InnerWithTypeParam<U> {}
3328     class InnerWithoutTypeParam {}
3329     static class Nested {}
3330   }
3331 
3332   @AutoValue
3333   abstract static class Nesty {
innerWithTypeParam()3334     abstract OuterWithTypeParam<Double>.InnerWithTypeParam<String> innerWithTypeParam();
innerWithoutTypeParam()3335     abstract OuterWithTypeParam<Double>.InnerWithoutTypeParam innerWithoutTypeParam();
nested()3336     abstract OuterWithTypeParam.Nested nested();
3337 
builder()3338     static Builder builder() {
3339       return new AutoValue_AutoValueTest_Nesty.Builder();
3340     }
3341 
3342     @AutoValue.Builder
3343     abstract static class Builder {
setInnerWithTypeParam( OuterWithTypeParam<Double>.InnerWithTypeParam<String> x)3344       abstract Builder setInnerWithTypeParam(
3345           OuterWithTypeParam<Double>.InnerWithTypeParam<String> x);
setInnerWithoutTypeParam(OuterWithTypeParam<Double>.InnerWithoutTypeParam x)3346       abstract Builder setInnerWithoutTypeParam(OuterWithTypeParam<Double>.InnerWithoutTypeParam x);
setNested(OuterWithTypeParam.Nested x)3347       abstract Builder setNested(OuterWithTypeParam.Nested x);
build()3348       abstract Nesty build();
3349     }
3350   }
3351 
3352   @Test
outerWithTypeParam()3353   public void outerWithTypeParam() throws ReflectiveOperationException {
3354     @SuppressWarnings("UseDiamond") // Currently we compile this with -source 6 in the Eclipse test.
3355     OuterWithTypeParam<Double> outer = new OuterWithTypeParam<Double>();
3356     Nesty nesty = Nesty.builder()
3357         .setInnerWithTypeParam(outer.new InnerWithTypeParam<String>())
3358         .setInnerWithoutTypeParam(outer.new InnerWithoutTypeParam())
3359         .setNested(new OuterWithTypeParam.Nested())
3360         .build();
3361     Type originalReturnType =
3362         Nesty.class.getDeclaredMethod("innerWithTypeParam").getGenericReturnType();
3363     Type generatedReturnType =
3364         nesty.getClass().getDeclaredMethod("innerWithTypeParam").getGenericReturnType();
3365     assertThat(generatedReturnType).isEqualTo(originalReturnType);
3366     Type generatedBuilderParamType =
3367         Nesty.builder()
3368             .getClass()
3369             .getDeclaredMethod("setInnerWithTypeParam", OuterWithTypeParam.InnerWithTypeParam.class)
3370             .getGenericParameterTypes()[0];
3371     assertThat(generatedBuilderParamType).isEqualTo(originalReturnType);
3372   }
3373 
3374   @AutoValue
3375   abstract static class BuilderAnnotationsNotCopied {
foo()3376     abstract String foo();
3377 
builder()3378     static Builder builder() {
3379       return new AutoValue_AutoValueTest_BuilderAnnotationsNotCopied.Builder();
3380     }
3381 
3382     @AutoValue.Builder
3383     @MyAnnotation("thing")
3384     abstract static class Builder {
setFoo(String x)3385       abstract Builder setFoo(String x);
build()3386       abstract BuilderAnnotationsNotCopied build();
3387     }
3388   }
3389 
3390   @Test
builderAnnotationsNotCopiedByDefault()3391   public void builderAnnotationsNotCopiedByDefault() {
3392     BuilderAnnotationsNotCopied.Builder builder = BuilderAnnotationsNotCopied.builder();
3393     assertThat(builder.getClass().getAnnotations()).isEmpty();
3394     assertThat(builder.setFoo("foo").build().foo()).isEqualTo("foo");
3395   }
3396 
3397   @AutoValue
3398   abstract static class BuilderAnnotationsCopied {
foo()3399     abstract String foo();
3400 
builder()3401     static Builder builder() {
3402       return new AutoValue_AutoValueTest_BuilderAnnotationsCopied.Builder();
3403     }
3404 
3405     @AutoValue.Builder
3406     @AutoValue.CopyAnnotations
3407     @MyAnnotation("thing")
3408     abstract static class Builder {
setFoo(String x)3409       abstract Builder setFoo(String x);
build()3410       abstract BuilderAnnotationsCopied build();
3411     }
3412   }
3413 
3414   @Test
builderAnnotationsCopiedIfRequested()3415   public void builderAnnotationsCopiedIfRequested() {
3416     BuilderAnnotationsCopied.Builder builder = BuilderAnnotationsCopied.builder();
3417     assertThat(builder.getClass().getAnnotations()).asList().containsExactly(myAnnotation("thing"));
3418     assertThat(builder.setFoo("foo").build().foo()).isEqualTo("foo");
3419   }
3420 }
3421