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