xref: /aosp_15_r20/external/auto/value/src/it/functional/src/test/java/com/google/auto/value/AutoValueTest.java (revision 1c2bbba85eccddce6de79cbbf1645fda32e723f0)
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 [email protected] (É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   // We use Double.doubleToLongBits in equals and hashCode, so that better be qualified correctly if
1418   // someone has unwisely declared their own Float or Double class.
1419   @SuppressWarnings("JavaLangClash")
1420   @AutoValue
1421   public abstract static class RedeclareFloatAndDouble {
aFloat()1422     public abstract float aFloat();
aDouble()1423     public abstract double aDouble();
1424 
of(float aFloat, double aDouble)1425     public static RedeclareFloatAndDouble of(float aFloat, double aDouble) {
1426       return new AutoValue_AutoValueTest_RedeclareFloatAndDouble(aFloat, aDouble);
1427     }
1428 
1429     static class Float {}
1430     static class Double {}
1431   }
1432 
1433   @SuppressWarnings("TruthSelfEquals")
1434   @Test
testRedeclareFloatAndDouble()1435   public void testRedeclareFloatAndDouble() {
1436     RedeclareFloatAndDouble iEqualMyself = RedeclareFloatAndDouble.of(Float.NaN, Double.NaN);
1437     assertThat(iEqualMyself).isEqualTo(iEqualMyself);
1438   }
1439 
1440   @AutoValue
1441   abstract static class AbstractChild extends AbstractParent {
1442     // The main point of this test is to ensure that we don't try to copy this @Override into the
1443     // generated implementation alongside the @Override that we put on all implementation methods.
1444     @Override
foo()1445     abstract int foo();
1446 
create(int foo)1447     static AbstractChild create(int foo) {
1448       return new AutoValue_AutoValueTest_AbstractChild(foo);
1449     }
1450   }
1451 
1452   @Test
testOverrideNotDuplicated()1453   public void testOverrideNotDuplicated() {
1454     AbstractChild instance = AbstractChild.create(23);
1455     assertEquals(23, instance.foo());
1456   }
1457 
1458   @AutoValue
1459   public abstract static class BasicWithBuilder {
foo()1460     public abstract int foo();
1461 
builder()1462     public static Builder builder() {
1463       return new AutoValue_AutoValueTest_BasicWithBuilder.Builder();
1464     }
1465 
1466     @AutoValue.Builder
1467     public interface Builder {
foo(int foo)1468       Builder foo(int foo);
1469 
build()1470       BasicWithBuilder build();
1471     }
1472   }
1473 
1474   @Test
testBasicWithBuilder()1475   public void testBasicWithBuilder() {
1476     BasicWithBuilder x = BasicWithBuilder.builder().foo(23).build();
1477     assertEquals(23, x.foo());
1478     try {
1479       BasicWithBuilder.builder().build();
1480       fail("Expected exception for missing property");
1481     } catch (IllegalStateException e) {
1482       if (omitIdentifiers) {
1483         assertThat(e).hasMessageThat().isNull();
1484       } else {
1485         assertThat(e).hasMessageThat().contains("foo");
1486       }
1487     }
1488   }
1489 
1490   @Test
testBasicWithBuilderHasOnlyOneConstructor()1491   public void testBasicWithBuilderHasOnlyOneConstructor() throws Exception {
1492     Class<?> builderClass = AutoValue_AutoValueTest_BasicWithBuilder.Builder.class;
1493     Constructor<?>[] constructors = builderClass.getDeclaredConstructors();
1494     assertThat(constructors).hasLength(1);
1495     Constructor<?> constructor = constructors[0];
1496     assertThat(constructor.getParameterTypes()).isEmpty();
1497   }
1498 
1499   @AutoValue
1500   public abstract static class EmptyWithBuilder {
builder()1501     public static Builder builder() {
1502       return new AutoValue_AutoValueTest_EmptyWithBuilder.Builder();
1503     }
1504 
1505     @AutoValue.Builder
1506     public interface Builder {
build()1507       EmptyWithBuilder build();
1508     }
1509   }
1510 
1511   @Test
testEmptyWithBuilder()1512   public void testEmptyWithBuilder() {
1513     EmptyWithBuilder x = EmptyWithBuilder.builder().build();
1514     EmptyWithBuilder y = EmptyWithBuilder.builder().build();
1515     assertEquals(x, y);
1516   }
1517 
1518   @AutoValue
1519   public abstract static class TwoPropertiesWithBuilderClass {
string()1520     public abstract String string();
1521 
integer()1522     public abstract int integer();
1523 
builder()1524     public static Builder builder() {
1525       return new AutoValue_AutoValueTest_TwoPropertiesWithBuilderClass.Builder();
1526     }
1527 
builder(String string)1528     public static Builder builder(String string) {
1529       return new AutoValue_AutoValueTest_TwoPropertiesWithBuilderClass.Builder().string(string);
1530     }
1531 
1532     @AutoValue.Builder
1533     public abstract static class Builder {
string(String x)1534       public abstract Builder string(String x);
1535 
integer(int x)1536       public abstract Builder integer(int x);
1537 
build()1538       public abstract TwoPropertiesWithBuilderClass build();
1539     }
1540   }
1541 
1542   @Test
testTwoPropertiesWithBuilderClass()1543   public void testTwoPropertiesWithBuilderClass() {
1544     TwoPropertiesWithBuilderClass a1 =
1545         TwoPropertiesWithBuilderClass.builder().string("23").integer(17).build();
1546     TwoPropertiesWithBuilderClass a2 =
1547         TwoPropertiesWithBuilderClass.builder("23").integer(17).build();
1548     TwoPropertiesWithBuilderClass a3 =
1549         TwoPropertiesWithBuilderClass.builder().integer(17).string("23").build();
1550     TwoPropertiesWithBuilderClass b =
1551         TwoPropertiesWithBuilderClass.builder().string("17").integer(17).build();
1552     new EqualsTester().addEqualityGroup(a1, a2, a3).addEqualityGroup(b).testEquals();
1553 
1554     try {
1555       TwoPropertiesWithBuilderClass.builder().string(null);
1556       fail("Did not get expected exception");
1557     } catch (NullPointerException expected) {
1558     }
1559   }
1560 
1561   @AutoValue
1562   public abstract static class NullablePropertyWithBuilder {
notNullable()1563     public abstract String notNullable();
1564 
1565     @Nullable
nullable()1566     public abstract String nullable();
1567 
builder()1568     public static Builder builder() {
1569       return new AutoValue_AutoValueTest_NullablePropertyWithBuilder.Builder();
1570     }
1571 
1572     @AutoValue.Builder
1573     public interface Builder {
notNullable(String s)1574       Builder notNullable(String s);
1575 
nullable(@ullable String s)1576       Builder nullable(@Nullable String s);
1577 
build()1578       NullablePropertyWithBuilder build();
1579     }
1580   }
1581 
1582   @Test
testOmitNullableWithBuilder()1583   public void testOmitNullableWithBuilder() {
1584     NullablePropertyWithBuilder instance1 =
1585         NullablePropertyWithBuilder.builder().notNullable("hello").build();
1586     assertThat(instance1.notNullable()).isEqualTo("hello");
1587     assertThat(instance1.nullable()).isNull();
1588 
1589     NullablePropertyWithBuilder instance2 =
1590         NullablePropertyWithBuilder.builder().notNullable("hello").nullable(null).build();
1591     assertThat(instance2.notNullable()).isEqualTo("hello");
1592     assertThat(instance2.nullable()).isNull();
1593     assertThat(instance1).isEqualTo(instance2);
1594 
1595     NullablePropertyWithBuilder instance3 =
1596         NullablePropertyWithBuilder.builder().notNullable("hello").nullable("world").build();
1597     assertThat(instance3.notNullable()).isEqualTo("hello");
1598     assertThat(instance3.nullable()).isEqualTo("world");
1599 
1600     try {
1601       NullablePropertyWithBuilder.builder().build();
1602       fail("Expected IllegalStateException for unset non-@Nullable property");
1603     } catch (IllegalStateException e) {
1604       if (omitIdentifiers) {
1605         assertThat(e).hasMessageThat().isNull();
1606       } else {
1607         assertThat(e).hasMessageThat().contains("notNullable");
1608       }
1609     }
1610   }
1611 
1612   @AutoValue
1613   public abstract static class PrimitiveAndBoxed {
anInt()1614     public abstract int anInt();
1615 
1616     @Nullable
aNullableInteger()1617     public abstract Integer aNullableInteger();
1618 
aNonNullableInteger()1619     public abstract Integer aNonNullableInteger();
1620 
toBuilder()1621     public abstract Builder toBuilder();
1622 
builder()1623     public static Builder builder() {
1624       return new AutoValue_AutoValueTest_PrimitiveAndBoxed.Builder();
1625     }
1626 
1627     @AutoValue.Builder
1628     public interface Builder {
setAnInt(Integer x)1629       Builder setAnInt(Integer x);
1630 
setANullableInteger(int x)1631       Builder setANullableInteger(int x);
1632 
setANonNullableInteger(int x)1633       Builder setANonNullableInteger(int x);
1634 
build()1635       PrimitiveAndBoxed build();
1636     }
1637   }
1638 
1639   @Test
testPrimitiveAndBoxed()1640   public void testPrimitiveAndBoxed() {
1641     PrimitiveAndBoxed instance1 =
1642         PrimitiveAndBoxed.builder().setAnInt(17).setANonNullableInteger(23).build();
1643     assertThat(instance1.anInt()).isEqualTo(17);
1644     assertThat(instance1.aNullableInteger()).isNull();
1645     assertThat(instance1.aNonNullableInteger()).isEqualTo(23);
1646 
1647     PrimitiveAndBoxed instance2 = instance1.toBuilder().setANullableInteger(5).build();
1648     assertThat(instance2.aNullableInteger()).isEqualTo(5);
1649 
1650     try {
1651       instance1.toBuilder().setAnInt(null);
1652       fail();
1653     } catch (NullPointerException expected) {
1654     }
1655   }
1656 
1657   @AutoValue
1658   public abstract static class OptionalPropertiesWithBuilder {
optionalString()1659     public abstract com.google.common.base.Optional<String> optionalString();
1660 
optionalInteger()1661     public abstract com.google.common.base.Optional<Integer> optionalInteger();
1662 
builder()1663     public static Builder builder() {
1664       return new AutoValue_AutoValueTest_OptionalPropertiesWithBuilder.Builder();
1665     }
1666 
1667     @AutoValue.Builder
1668     public interface Builder {
setOptionalString(com.google.common.base.Optional<String> s)1669       Builder setOptionalString(com.google.common.base.Optional<String> s);
1670 
setOptionalString(String s)1671       Builder setOptionalString(String s);
1672 
setOptionalInteger(com.google.common.base.Optional<Integer> i)1673       Builder setOptionalInteger(com.google.common.base.Optional<Integer> i);
1674 
setOptionalInteger(int i)1675       Builder setOptionalInteger(int i);
1676 
build()1677       OptionalPropertiesWithBuilder build();
1678     }
1679   }
1680 
1681   @Test
testOmitOptionalWithBuilder()1682   public void testOmitOptionalWithBuilder() {
1683     OptionalPropertiesWithBuilder omitted = OptionalPropertiesWithBuilder.builder().build();
1684     assertThat(omitted.optionalString()).isAbsent();
1685     assertThat(omitted.optionalInteger()).isAbsent();
1686 
1687     OptionalPropertiesWithBuilder supplied =
1688         OptionalPropertiesWithBuilder.builder()
1689             .setOptionalString(com.google.common.base.Optional.of("foo"))
1690             .build();
1691     assertThat(supplied.optionalString()).hasValue("foo");
1692     assertThat(omitted.optionalInteger()).isAbsent();
1693 
1694     OptionalPropertiesWithBuilder suppliedDirectly =
1695         OptionalPropertiesWithBuilder.builder()
1696             .setOptionalString("foo")
1697             .setOptionalInteger(23)
1698             .build();
1699     assertThat(suppliedDirectly.optionalString()).hasValue("foo");
1700     assertThat(suppliedDirectly.optionalInteger()).hasValue(23);
1701 
1702     try {
1703       // The parameter is not marked @Nullable so this should fail.
1704       OptionalPropertiesWithBuilder.builder().setOptionalString((String) null);
1705       fail();
1706     } catch (NullPointerException expected) {
1707     }
1708   }
1709 
1710   @AutoValue
1711   public abstract static class OptionalPropertyWithNullableBuilder {
notOptional()1712     public abstract String notOptional();
1713 
optional()1714     public abstract com.google.common.base.Optional<String> optional();
1715 
builder()1716     public static Builder builder() {
1717       return new AutoValue_AutoValueTest_OptionalPropertyWithNullableBuilder.Builder();
1718     }
1719 
1720     @AutoValue.Builder
1721     public interface Builder {
notOptional(String s)1722       Builder notOptional(String s);
1723 
optional(@ullable String s)1724       Builder optional(@Nullable String s);
1725 
build()1726       OptionalPropertyWithNullableBuilder build();
1727     }
1728   }
1729 
1730   @Test
testOmitOptionalWithNullableBuilder()1731   public void testOmitOptionalWithNullableBuilder() {
1732     OptionalPropertyWithNullableBuilder instance1 =
1733         OptionalPropertyWithNullableBuilder.builder().notOptional("hello").build();
1734     assertThat(instance1.notOptional()).isEqualTo("hello");
1735     assertThat(instance1.optional()).isAbsent();
1736 
1737     OptionalPropertyWithNullableBuilder instance2 =
1738         OptionalPropertyWithNullableBuilder.builder().notOptional("hello").optional(null).build();
1739     assertThat(instance2.notOptional()).isEqualTo("hello");
1740     assertThat(instance2.optional()).isAbsent();
1741     assertThat(instance1).isEqualTo(instance2);
1742 
1743     OptionalPropertyWithNullableBuilder instance3 =
1744         OptionalPropertyWithNullableBuilder.builder()
1745             .notOptional("hello")
1746             .optional("world")
1747             .build();
1748     assertThat(instance3.notOptional()).isEqualTo("hello");
1749     assertThat(instance3.optional()).hasValue("world");
1750 
1751     try {
1752       OptionalPropertyWithNullableBuilder.builder().build();
1753       fail("Expected IllegalStateException for unset non-Optional property");
1754     } catch (IllegalStateException expected) {
1755     }
1756   }
1757 
1758   @AutoValue
1759   public abstract static class NullableOptionalPropertiesWithBuilder {
1760     @Nullable
optionalString()1761     public abstract com.google.common.base.Optional<String> optionalString();
1762 
builder()1763     public static Builder builder() {
1764       return new AutoValue_AutoValueTest_NullableOptionalPropertiesWithBuilder.Builder();
1765     }
1766 
1767     @AutoValue.Builder
1768     public interface Builder {
setOptionalString(com.google.common.base.Optional<String> s)1769       Builder setOptionalString(com.google.common.base.Optional<String> s);
1770 
build()1771       NullableOptionalPropertiesWithBuilder build();
1772     }
1773   }
1774 
1775   @Test
testOmitNullableOptionalWithBuilder()1776   public void testOmitNullableOptionalWithBuilder() {
1777     NullableOptionalPropertiesWithBuilder omitted =
1778         NullableOptionalPropertiesWithBuilder.builder().build();
1779     assertThat(omitted.optionalString()).isNull();
1780 
1781     NullableOptionalPropertiesWithBuilder supplied =
1782         NullableOptionalPropertiesWithBuilder.builder()
1783             .setOptionalString(com.google.common.base.Optional.of("foo"))
1784             .build();
1785     assertThat(supplied.optionalString()).hasValue("foo");
1786   }
1787 
1788   @AutoValue
1789   public abstract static class OptionalPropertiesWithBuilderSimpleSetter {
optionalString()1790     public abstract com.google.common.base.Optional<String> optionalString();
1791 
builder()1792     public static Builder builder() {
1793       return new AutoValue_AutoValueTest_OptionalPropertiesWithBuilderSimpleSetter.Builder();
1794     }
1795 
1796     @AutoValue.Builder
1797     public interface Builder {
setOptionalString(String s)1798       Builder setOptionalString(String s);
1799 
build()1800       OptionalPropertiesWithBuilderSimpleSetter build();
1801     }
1802   }
1803 
1804   @Test
testOptionalPropertySimpleSetter()1805   public void testOptionalPropertySimpleSetter() {
1806     OptionalPropertiesWithBuilderSimpleSetter omitted =
1807         OptionalPropertiesWithBuilderSimpleSetter.builder().build();
1808     assertThat(omitted.optionalString()).isAbsent();
1809 
1810     OptionalPropertiesWithBuilderSimpleSetter supplied =
1811         OptionalPropertiesWithBuilderSimpleSetter.builder().setOptionalString("foo").build();
1812     assertThat(supplied.optionalString()).hasValue("foo");
1813   }
1814 
1815   @AutoValue
1816   public abstract static class PropertyWithOptionalGetter {
getString()1817     public abstract String getString();
1818 
getInt()1819     public abstract int getInt();
1820 
builder()1821     public static Builder builder() {
1822       return new AutoValue_AutoValueTest_PropertyWithOptionalGetter.Builder();
1823     }
1824 
1825     @AutoValue.Builder
1826     public interface Builder {
setString(String s)1827       Builder setString(String s);
1828 
getString()1829       com.google.common.base.Optional<String> getString();
1830 
setInt(int x)1831       Builder setInt(int x);
1832 
getInt()1833       com.google.common.base.Optional<Integer> getInt();
1834 
build()1835       PropertyWithOptionalGetter build();
1836     }
1837   }
1838 
1839   @Test
testOptionalGetter()1840   public void testOptionalGetter() {
1841     PropertyWithOptionalGetter.Builder omitted = PropertyWithOptionalGetter.builder();
1842     assertThat(omitted.getString()).isAbsent();
1843     assertThat(omitted.getInt()).isAbsent();
1844 
1845     PropertyWithOptionalGetter.Builder supplied =
1846         PropertyWithOptionalGetter.builder().setString("foo").setInt(23);
1847     assertThat(supplied.getString()).hasValue("foo");
1848     assertThat(supplied.getInt()).hasValue(23);
1849   }
1850 
1851   @AutoValue
1852   public abstract static class PropertyNamedMissing {
missing()1853     public abstract String missing();
1854 
builder()1855     public static Builder builder() {
1856       return new AutoValue_AutoValueTest_PropertyNamedMissing.Builder();
1857     }
1858 
1859     @AutoValue.Builder
1860     public abstract static class Builder {
setMissing(String x)1861       public abstract Builder setMissing(String x);
1862 
build()1863       public abstract PropertyNamedMissing build();
1864     }
1865   }
1866 
1867   // https://github.com/google/auto/issues/412
1868   @Test
testPropertyNamedMissing()1869   public void testPropertyNamedMissing() {
1870     try {
1871       PropertyNamedMissing.builder().build();
1872       fail();
1873     } catch (IllegalStateException expected) {
1874     }
1875     PropertyNamedMissing x = PropertyNamedMissing.builder().setMissing("foo").build();
1876     assertThat(x.missing()).isEqualTo("foo");
1877   }
1878 
1879   @AutoValue
1880   public abstract static class GenericsWithBuilder<T extends Number & Comparable<T>, U extends T> {
list()1881     public abstract List<T> list();
1882 
u()1883     public abstract U u();
1884 
builder()1885     public static <T extends Number & Comparable<T>, U extends T> Builder<T, U> builder() {
1886       return new AutoValue_AutoValueTest_GenericsWithBuilder.Builder<T, U>();
1887     }
1888 
toBuilderGenerated()1889     public abstract Builder<T, U> toBuilderGenerated();
1890 
1891     @AutoValue.Builder
1892     public interface Builder<T extends Number & Comparable<T>, U extends T> {
list(List<T> list)1893       Builder<T, U> list(List<T> list);
1894 
u(U u)1895       Builder<T, U> u(U u);
1896 
build()1897       GenericsWithBuilder<T, U> build();
1898     }
1899   }
1900 
1901   @Test
testBuilderGenerics()1902   public void testBuilderGenerics() {
1903     List<Integer> integers = ImmutableList.of(1, 2, 3);
1904     GenericsWithBuilder<Integer, Integer> instance =
1905         GenericsWithBuilder.<Integer, Integer>builder().list(integers).u(23).build();
1906     assertEquals(integers, instance.list());
1907     assertEquals((Integer) 23, instance.u());
1908 
1909     GenericsWithBuilder<Integer, Integer> instance2 = instance.toBuilderGenerated().build();
1910     assertEquals(instance, instance2);
1911     assertNotSame(instance, instance2);
1912 
1913     GenericsWithBuilder<Integer, Integer> instance3 = instance.toBuilderGenerated().u(17).build();
1914     assertEquals(integers, instance3.list());
1915     assertEquals((Integer) 17, instance3.u());
1916   }
1917 
1918   public interface ToBuilder<BuilderT> {
toBuilder()1919     BuilderT toBuilder();
1920   }
1921 
1922   @AutoValue
1923   public abstract static class InheritedToBuilder<T, U>
1924       implements ToBuilder<InheritedToBuilder.Builder<T, U>> {
1925 
t()1926     public abstract T t();
1927 
u()1928     public abstract U u();
1929 
builder()1930     public static <T, U> Builder<T, U> builder() {
1931       return new AutoValue_AutoValueTest_InheritedToBuilder.Builder<T, U>();
1932     }
1933 
1934     @AutoValue.Builder
1935     public abstract static class Builder<T, U> {
setT(T t)1936       public abstract Builder<T, U> setT(T t);
1937 
setU(U u)1938       public abstract Builder<T, U> setU(U u);
1939 
build()1940       public abstract InheritedToBuilder<T, U> build();
1941     }
1942   }
1943 
1944   @Test
testInheritedToBuilder()1945   public void testInheritedToBuilder() {
1946     InheritedToBuilder<Integer, String> x =
1947         InheritedToBuilder.<Integer, String>builder().setT(17).setU("wibble").build();
1948     InheritedToBuilder<Integer, String> y = x.toBuilder().setT(23).build();
1949     assertThat(y.u()).isEqualTo("wibble");
1950   }
1951 
1952   @AutoValue
1953   public abstract static class BuilderWithSet<T extends Comparable<T>> {
list()1954     public abstract List<T> list();
1955 
t()1956     public abstract T t();
1957 
builder()1958     public static <T extends Comparable<T>> Builder<T> builder() {
1959       return new AutoValue_AutoValueTest_BuilderWithSet.Builder<T>();
1960     }
1961 
1962     @AutoValue.Builder
1963     public interface Builder<T extends Comparable<T>> {
setList(List<T> list)1964       Builder<T> setList(List<T> list);
1965 
setT(T t)1966       Builder<T> setT(T t);
1967 
build()1968       BuilderWithSet<T> build();
1969     }
1970   }
1971 
1972   @Test
testBuilderWithSet()1973   public void testBuilderWithSet() {
1974     List<Integer> integers = ImmutableList.of(1, 2, 3);
1975     BuilderWithSet<Integer> instance =
1976         BuilderWithSet.<Integer>builder().setList(integers).setT(23).build();
1977     assertEquals(integers, instance.list());
1978     assertEquals((Integer) 23, instance.t());
1979   }
1980 
1981   @AutoValue
1982   public abstract static class BuilderWithSetAndGet {
getAList()1983     public abstract List<Integer> getAList();
1984 
getAnInt()1985     public abstract int getAnInt();
1986 
builder()1987     public static Builder builder() {
1988       return new AutoValue_AutoValueTest_BuilderWithSetAndGet.Builder();
1989     }
1990 
toBuilder()1991     public abstract Builder toBuilder();
1992 
1993     @AutoValue.Builder
1994     public interface Builder {
setAList(List<Integer> list)1995       Builder setAList(List<Integer> list);
1996 
setAnInt(int i)1997       Builder setAnInt(int i);
1998 
build()1999       BuilderWithSetAndGet build();
2000     }
2001   }
2002 
2003   @Test
testBuilderWithSetAndGet()2004   public void testBuilderWithSetAndGet() {
2005     List<Integer> integers = ImmutableList.of(1, 2, 3);
2006     BuilderWithSetAndGet instance =
2007         BuilderWithSetAndGet.builder().setAList(integers).setAnInt(23).build();
2008     assertEquals(integers, instance.getAList());
2009     assertEquals(23, instance.getAnInt());
2010 
2011     BuilderWithSetAndGet instance2 = instance.toBuilder().build();
2012     assertEquals(instance, instance2);
2013     assertNotSame(instance, instance2);
2014 
2015     BuilderWithSetAndGet instance3 = instance.toBuilder().setAnInt(17).build();
2016     assertEquals(integers, instance3.getAList());
2017     assertEquals(17, instance3.getAnInt());
2018   }
2019 
2020   @AutoValue
2021   public abstract static class BuilderWithUnprefixedGetters<T extends Comparable<T>> {
list()2022     public abstract ImmutableList<T> list();
2023 
2024     @Nullable
t()2025     public abstract T t();
2026 
2027     @SuppressWarnings("mutable")
ints()2028     public abstract int[] ints();
2029 
noGetter()2030     public abstract int noGetter();
2031 
oAuth()2032     public abstract String oAuth();
2033 
oBrien()2034     public abstract String oBrien();
2035 
builder()2036     public static <T extends Comparable<T>> Builder<T> builder() {
2037       return new AutoValue_AutoValueTest_BuilderWithUnprefixedGetters.Builder<T>();
2038     }
2039 
2040     @AutoValue.Builder
2041     public interface Builder<T extends Comparable<T>> {
setList(ImmutableList<T> list)2042       Builder<T> setList(ImmutableList<T> list);
2043 
setT(T t)2044       Builder<T> setT(T t);
2045 
setInts(int[] ints)2046       Builder<T> setInts(int[] ints);
2047 
setNoGetter(int x)2048       Builder<T> setNoGetter(int x);
2049 
setoAuth(String x)2050       Builder<T> setoAuth(String x); // this ugly spelling is for compatibility
2051 
setOBrien(String x)2052       Builder<T> setOBrien(String x);
2053 
list()2054       ImmutableList<T> list();
2055 
t()2056       T t();
2057 
ints()2058       int[] ints();
2059 
oAuth()2060       String oAuth();
2061 
oBrien()2062       String oBrien();
2063 
build()2064       BuilderWithUnprefixedGetters<T> build();
2065     }
2066   }
2067 
2068   @Test
testBuilderWithUnprefixedGetter()2069   public void testBuilderWithUnprefixedGetter() {
2070     ImmutableList<String> names = ImmutableList.of("fred", "jim");
2071     int[] ints = {6, 28, 496, 8128, 33550336};
2072     int noGetter = -1;
2073 
2074     BuilderWithUnprefixedGetters.Builder<String> builder = BuilderWithUnprefixedGetters.builder();
2075     assertNull(builder.t());
2076     try {
2077       builder.list();
2078       fail("Attempt to retrieve unset list property should have failed");
2079     } catch (IllegalStateException e) {
2080       if (omitIdentifiers) {
2081         assertThat(e).hasMessageThat().isNull();
2082       } else {
2083         assertThat(e).hasMessageThat().isEqualTo("Property \"list\" has not been set");
2084       }
2085     }
2086     try {
2087       builder.ints();
2088       fail("Attempt to retrieve unset ints property should have failed");
2089     } catch (IllegalStateException e) {
2090       if (omitIdentifiers) {
2091         assertThat(e).hasMessageThat().isNull();
2092       } else {
2093         assertThat(e).hasMessageThat().isEqualTo("Property \"ints\" has not been set");
2094       }
2095     }
2096 
2097     builder.setList(names);
2098     assertThat(builder.list()).isSameInstanceAs(names);
2099     builder.setInts(ints);
2100     assertThat(builder.ints()).isEqualTo(ints);
2101     builder.setoAuth("OAuth");
2102     assertThat(builder.oAuth()).isEqualTo("OAuth");
2103     builder.setOBrien("Flann");
2104     assertThat(builder.oBrien()).isEqualTo("Flann");
2105     // The array is not cloned by the getter, so the client can modify it (but shouldn't).
2106     ints[0] = 0;
2107     assertThat(builder.ints()[0]).isEqualTo(0);
2108     ints[0] = 6;
2109 
2110     BuilderWithUnprefixedGetters<String> instance = builder.setNoGetter(noGetter).build();
2111     assertThat(instance.list()).isSameInstanceAs(names);
2112     assertThat(instance.t()).isNull();
2113     assertThat(instance.ints()).isEqualTo(ints);
2114     assertThat(instance.noGetter()).isEqualTo(noGetter);
2115     assertThat(instance.oAuth()).isEqualTo("OAuth");
2116     assertThat(instance.oBrien()).isEqualTo("Flann");
2117   }
2118 
2119   @AutoValue
2120   public abstract static class BuilderWithPrefixedGetters<T extends Comparable<T>> {
getList()2121     public abstract ImmutableList<T> getList();
2122 
getT()2123     public abstract T getT();
2124 
2125     @SuppressWarnings("mutable")
2126     @Nullable
getInts()2127     public abstract int[] getInts();
2128 
getOAuths()2129     public abstract ImmutableList<String> getOAuths();
2130 
getNoGetter()2131     public abstract int getNoGetter();
2132 
builder()2133     public static <T extends Comparable<T>> Builder<T> builder() {
2134       return new AutoValue_AutoValueTest_BuilderWithPrefixedGetters.Builder<T>();
2135     }
2136 
2137     @AutoValue.Builder
2138     public abstract static class Builder<T extends Comparable<T>> {
setList(ImmutableList<T> list)2139       public abstract Builder<T> setList(ImmutableList<T> list);
2140 
setT(T t)2141       public abstract Builder<T> setT(T t);
2142 
setInts(int[] ints)2143       public abstract Builder<T> setInts(int[] ints);
2144 
setNoGetter(int x)2145       public abstract Builder<T> setNoGetter(int x);
2146 
setOAuths(List<String> x)2147       public abstract Builder<T> setOAuths(List<String> x);
2148 
oAuthsBuilder()2149       public abstract ImmutableList.Builder<String> oAuthsBuilder();
2150 
getList()2151       abstract ImmutableList<T> getList();
2152 
getT()2153       abstract T getT();
2154 
getInts()2155       abstract int[] getInts();
2156 
build()2157       public abstract BuilderWithPrefixedGetters<T> build();
2158     }
2159   }
2160 
2161   @Test
testBuilderWithPrefixedGetter()2162   public void testBuilderWithPrefixedGetter() {
2163     ImmutableList<String> names = ImmutableList.of("fred", "jim");
2164     String name = "sheila";
2165     int noGetter = -1;
2166 
2167     BuilderWithPrefixedGetters.Builder<String> builder = BuilderWithPrefixedGetters.builder();
2168     assertThat(builder.getInts()).isNull();
2169     try {
2170       builder.getList();
2171       fail("Attempt to retrieve unset list property should have failed");
2172     } catch (IllegalStateException e) {
2173       if (omitIdentifiers) {
2174         assertThat(e).hasMessageThat().isNull();
2175       } else {
2176         assertThat(e).hasMessageThat().isEqualTo("Property \"list\" has not been set");
2177       }
2178     }
2179 
2180     builder.setList(names);
2181     assertThat(builder.getList()).isSameInstanceAs(names);
2182     builder.setT(name);
2183     assertThat(builder.getInts()).isNull();
2184     builder.setOAuths(ImmutableList.of("OAuth"));
2185 
2186     BuilderWithPrefixedGetters<String> instance = builder.setNoGetter(noGetter).build();
2187     assertThat(instance.getList()).isSameInstanceAs(names);
2188     assertThat(instance.getT()).isEqualTo(name);
2189     assertThat(instance.getInts()).isNull();
2190     assertThat(instance.getNoGetter()).isEqualTo(noGetter);
2191     assertThat(instance.getOAuths()).containsExactly("OAuth");
2192 
2193     builder =
2194         BuilderWithPrefixedGetters.<String>builder()
2195             .setList(names)
2196             .setT(name)
2197             .setNoGetter(noGetter);
2198     builder.oAuthsBuilder().add("foo", "bar");
2199     assertThat(builder.build().getOAuths()).containsExactly("foo", "bar").inOrder();
2200   }
2201 
2202   @AutoValue
2203   public abstract static class BuilderWithPrefixedGettersAndUnprefixedSetters {
getOAuth()2204     public abstract String getOAuth();
2205 
getOBrien()2206     public abstract String getOBrien();
2207 
builder()2208     public static Builder builder() {
2209       return new AutoValue_AutoValueTest_BuilderWithPrefixedGettersAndUnprefixedSetters.Builder();
2210     }
2211 
2212     @AutoValue.Builder
2213     public abstract static class Builder {
oAuth(String x)2214       public abstract Builder oAuth(String x);
2215 
OBrien(String x)2216       public abstract Builder OBrien(String x);
2217 
build()2218       public abstract BuilderWithPrefixedGettersAndUnprefixedSetters build();
2219     }
2220   }
2221 
2222   @Test
testBuilderWithPrefixedGetterAndUnprefixedSetter()2223   public void testBuilderWithPrefixedGetterAndUnprefixedSetter() {
2224     BuilderWithPrefixedGettersAndUnprefixedSetters x =
2225         BuilderWithPrefixedGettersAndUnprefixedSetters.builder()
2226             .oAuth("OAuth")
2227             .OBrien("Flann")
2228             .build();
2229     assertThat(x.getOAuth()).isEqualTo("OAuth");
2230     assertThat(x.getOBrien()).isEqualTo("Flann");
2231   }
2232 
2233   @AutoValue
2234   public abstract static class BuilderWithPropertyBuilders<FooT extends Comparable<FooT>> {
getFoos()2235     public abstract ImmutableList<FooT> getFoos();
2236 
getStrings()2237     public abstract ImmutableSet<String> getStrings();
2238 
toBuilder()2239     public abstract BuilderWithPropertyBuilders.Builder<FooT> toBuilder();
2240 
builder()2241     public static <FooT extends Comparable<FooT>> Builder<FooT> builder() {
2242       return new AutoValue_AutoValueTest_BuilderWithPropertyBuilders.Builder<FooT>();
2243     }
2244 
2245     @AutoValue.Builder
2246     public abstract static class Builder<FooT extends Comparable<FooT>> {
getFoos()2247       public abstract ImmutableList<FooT> getFoos();
2248 
addFoos(Iterable<FooT> foos)2249       public Builder<FooT> addFoos(Iterable<FooT> foos) {
2250         foosBuilder().addAll(foos);
2251         return this;
2252       }
2253 
foosBuilder()2254       abstract ImmutableList.Builder<FooT> foosBuilder();
2255 
addToTs(FooT element)2256       public Builder<FooT> addToTs(FooT element) {
2257         foosBuilder().add(element);
2258         return this;
2259       }
2260 
setStrings(ImmutableList<String> strings)2261       abstract Builder<FooT> setStrings(ImmutableList<String> strings);
2262 
stringsBuilder()2263       abstract ImmutableSet.Builder<String> stringsBuilder();
2264 
addToStrings(String element)2265       public Builder<FooT> addToStrings(String element) {
2266         stringsBuilder().add(element);
2267         return this;
2268       }
2269 
build()2270       public abstract BuilderWithPropertyBuilders<FooT> build();
2271     }
2272   }
2273 
2274   @Test
testBuilderWithPropertyBuilders()2275   public void testBuilderWithPropertyBuilders() {
2276     ImmutableList<Integer> numbers = ImmutableList.of(1, 1, 2, 6, 24);
2277     ImmutableSet<String> names = ImmutableSet.of("one", "two", "six", "twenty-four");
2278 
2279     BuilderWithPropertyBuilders<Integer> a =
2280         BuilderWithPropertyBuilders.<Integer>builder()
2281             .addFoos(numbers)
2282             .addToStrings("one")
2283             .addToStrings("two")
2284             .addToStrings("six")
2285             .addToStrings("twenty-four")
2286             .build();
2287 
2288     assertEquals(numbers, a.getFoos());
2289     assertEquals(names, a.getStrings());
2290 
2291     BuilderWithPropertyBuilders.Builder<Integer> bBuilder = BuilderWithPropertyBuilders.builder();
2292     bBuilder.stringsBuilder().addAll(names);
2293     bBuilder.foosBuilder().addAll(numbers);
2294 
2295     assertEquals(numbers, bBuilder.getFoos());
2296 
2297     BuilderWithPropertyBuilders<Integer> b = bBuilder.build();
2298     assertEquals(a, b);
2299 
2300     BuilderWithPropertyBuilders.Builder<Integer> cBuilder = a.toBuilder();
2301     cBuilder.addToStrings("one hundred and twenty");
2302     cBuilder.addToTs(120);
2303     BuilderWithPropertyBuilders<Integer> c = cBuilder.build();
2304     assertEquals(
2305         ImmutableSet.of("one", "two", "six", "twenty-four", "one hundred and twenty"),
2306         c.getStrings());
2307     assertEquals(ImmutableList.of(1, 1, 2, 6, 24, 120), c.getFoos());
2308 
2309     BuilderWithPropertyBuilders.Builder<Integer> dBuilder = a.toBuilder();
2310     dBuilder.addFoos(ImmutableList.of(120, 720));
2311     BuilderWithPropertyBuilders<Integer> d = dBuilder.build();
2312     assertEquals(ImmutableList.of(1, 1, 2, 6, 24, 120, 720), d.getFoos());
2313     assertEquals(names, d.getStrings());
2314 
2315     BuilderWithPropertyBuilders<Integer> empty =
2316         BuilderWithPropertyBuilders.<Integer>builder().build();
2317     assertEquals(ImmutableList.of(), empty.getFoos());
2318     assertEquals(ImmutableSet.of(), empty.getStrings());
2319 
2320     try {
2321       BuilderWithPropertyBuilders.<Integer>builder().setStrings(null).build();
2322       fail("Did not get expected exception");
2323     } catch (RuntimeException expected) {
2324       // We don't specify whether you get the exception on setStrings(null) or on build(), nor
2325       // which exception it is exactly.
2326     }
2327   }
2328 
2329   interface ImmutableListOf<T> {
list()2330     ImmutableList<T> list();
2331   }
2332 
2333   @AutoValue
2334   abstract static class PropertyBuilderInheritsType implements ImmutableListOf<String> {
builder()2335     static Builder builder() {
2336       return new AutoValue_AutoValueTest_PropertyBuilderInheritsType.Builder();
2337     }
2338 
2339     @AutoValue.Builder
2340     abstract static class Builder {
listBuilder()2341       abstract ImmutableList.Builder<String> listBuilder();
2342 
build()2343       abstract PropertyBuilderInheritsType build();
2344     }
2345   }
2346 
2347   @Test
propertyBuilderInheritsType()2348   public void propertyBuilderInheritsType() {
2349     PropertyBuilderInheritsType.Builder builder = PropertyBuilderInheritsType.builder();
2350     builder.listBuilder().add("foo", "bar");
2351     PropertyBuilderInheritsType x = builder.build();
2352     assertThat(x.list()).containsExactly("foo", "bar").inOrder();
2353   }
2354 
2355   @AutoValue
2356   public abstract static class BuilderWithExoticPropertyBuilders<
2357       K extends Number, V extends Comparable<K>> {
map()2358     public abstract ImmutableMap<String, V> map();
2359 
table()2360     public abstract ImmutableTable<String, K, V> table();
2361 
builder()2362     public static <K extends Number, V extends Comparable<K>> Builder<K, V> builder() {
2363       return new AutoValue_AutoValueTest_BuilderWithExoticPropertyBuilders.Builder<K, V>();
2364     }
2365 
2366     @AutoValue.Builder
2367     public abstract static class Builder<K extends Number, V extends Comparable<K>> {
putAll(Map<String, V> map)2368       public Builder<K, V> putAll(Map<String, V> map) {
2369         mapBuilder().putAll(map);
2370         return this;
2371       }
2372 
mapBuilder()2373       public abstract ImmutableMap.Builder<String, V> mapBuilder();
2374 
putAll(ImmutableTable<String, K, V> table)2375       public Builder<K, V> putAll(ImmutableTable<String, K, V> table) {
2376         tableBuilder().putAll(table);
2377         return this;
2378       }
2379 
tableBuilder()2380       public abstract ImmutableTable.Builder<String, K, V> tableBuilder();
2381 
build()2382       public abstract BuilderWithExoticPropertyBuilders<K, V> build();
2383     }
2384   }
2385 
2386   @Test
testBuilderWithExoticPropertyBuilders()2387   public void testBuilderWithExoticPropertyBuilders() {
2388     ImmutableMap<String, Integer> map = ImmutableMap.of("one", 1);
2389     ImmutableTable<String, Integer, Integer> table = ImmutableTable.of("one", 1, -1);
2390 
2391     BuilderWithExoticPropertyBuilders<Integer, Integer> a =
2392         BuilderWithExoticPropertyBuilders.<Integer, Integer>builder()
2393             .putAll(map)
2394             .putAll(table)
2395             .build();
2396     assertEquals(map, a.map());
2397     assertEquals(table, a.table());
2398 
2399     BuilderWithExoticPropertyBuilders.Builder<Integer, Integer> bBuilder =
2400         BuilderWithExoticPropertyBuilders.builder();
2401     bBuilder.mapBuilder().putAll(map);
2402     bBuilder.tableBuilder().putAll(table);
2403     BuilderWithExoticPropertyBuilders<Integer, Integer> b = bBuilder.build();
2404     assertEquals(a, b);
2405 
2406     BuilderWithExoticPropertyBuilders<Integer, Integer> empty =
2407         BuilderWithExoticPropertyBuilders.<Integer, Integer>builder().build();
2408     assertEquals(ImmutableMap.of(), empty.map());
2409     assertEquals(ImmutableTable.of(), empty.table());
2410   }
2411 
2412   @AutoValue
2413   public abstract static class BuilderWithCopyingSetters<T extends Number> {
things()2414     public abstract ImmutableSet<? extends T> things();
2415 
numbers()2416     public abstract ImmutableList<Number> numbers();
2417 
map()2418     public abstract ImmutableMap<String, T> map();
2419 
builder(T value)2420     public static <T extends Number> Builder<T> builder(T value) {
2421       return new AutoValue_AutoValueTest_BuilderWithCopyingSetters.Builder<T>()
2422           .setNumbers(ImmutableSet.of(17, 23.0))
2423           .setMap(Collections.singletonMap("foo", value));
2424     }
2425 
2426     @AutoValue.Builder
2427     public interface Builder<T extends Number> {
setThings(ImmutableSet<T> things)2428       Builder<T> setThings(ImmutableSet<T> things);
2429 
setThings(Iterable<? extends T> things)2430       Builder<T> setThings(Iterable<? extends T> things);
2431 
setThings(T... things)2432       Builder<T> setThings(T... things);
2433 
setNumbers(Collection<? extends Number> strings)2434       Builder<T> setNumbers(Collection<? extends Number> strings);
2435 
setMap(Map<String, T> map)2436       Builder<T> setMap(Map<String, T> map);
2437 
build()2438       BuilderWithCopyingSetters<T> build();
2439     }
2440   }
2441 
2442   @Test
testBuilderWithCopyingSetters()2443   public void testBuilderWithCopyingSetters() {
2444     BuilderWithCopyingSetters.Builder<Integer> builder = BuilderWithCopyingSetters.builder(23);
2445 
2446     BuilderWithCopyingSetters<Integer> a = builder.setThings(ImmutableSet.of(1, 2)).build();
2447     assertThat(a.things()).containsExactly(1, 2);
2448     assertThat(a.numbers()).containsExactly(17, 23.0).inOrder();
2449     assertThat(a.map()).containsExactly("foo", 23);
2450 
2451     BuilderWithCopyingSetters<Integer> b = builder.setThings(Arrays.asList(1, 2)).build();
2452     assertThat(b).isEqualTo(a);
2453 
2454     BuilderWithCopyingSetters<Integer> c = builder.setThings(1, 2).build();
2455     assertThat(c).isEqualTo(a);
2456   }
2457 
2458   @AutoValue
2459   public abstract static class BuilderWithImmutableSorted<T extends Comparable<T>> {
sortedSet()2460     public abstract ImmutableSortedSet<T> sortedSet();
2461 
sortedMap()2462     public abstract ImmutableSortedMap<T, Integer> sortedMap();
2463 
builder()2464     public static <T extends Comparable<T>> Builder<T> builder() {
2465       return new AutoValue_AutoValueTest_BuilderWithImmutableSorted.Builder<T>()
2466           .setSortedSet(new TreeSet<T>())
2467           .setSortedMap(new TreeMap<T, Integer>());
2468     }
2469 
2470     @AutoValue.Builder
2471     public interface Builder<T extends Comparable<T>> {
2472       @SuppressWarnings("unchecked")
setSortedSet(T... x)2473       Builder<T> setSortedSet(T... x);
2474 
setSortedSet(NavigableSet<T> x)2475       Builder<T> setSortedSet(NavigableSet<T> x);
2476 
sortedSetBuilder()2477       ImmutableSortedSet.Builder<T> sortedSetBuilder();
2478 
setSortedMap(SortedMap<T, Integer> x)2479       Builder<T> setSortedMap(SortedMap<T, Integer> x);
2480 
setSortedMap(NavigableMap<T, Integer> x)2481       Builder<T> setSortedMap(NavigableMap<T, Integer> x);
2482 
sortedMapBuilder()2483       ImmutableSortedMap.Builder<T, Integer> sortedMapBuilder();
2484 
build()2485       BuilderWithImmutableSorted<T> build();
2486     }
2487   }
2488 
2489   @Test
testBuilderWithImmutableSorted_Varargs()2490   public void testBuilderWithImmutableSorted_Varargs() {
2491     BuilderWithImmutableSorted<String> x =
2492         BuilderWithImmutableSorted.<String>builder().setSortedSet("foo", "bar", "baz").build();
2493     assertThat(x.sortedSet()).containsExactly("bar", "baz", "foo").inOrder();
2494   }
2495 
2496   @Test
testBuilderWithImmutableSorted_SetSet()2497   public void testBuilderWithImmutableSorted_SetSet() {
2498     BuilderWithImmutableSorted<String> x =
2499         BuilderWithImmutableSorted.<String>builder()
2500             .setSortedSet(new TreeSet<String>(String.CASE_INSENSITIVE_ORDER))
2501             .build();
2502     assertThat(x.sortedSet().comparator()).isEqualTo(String.CASE_INSENSITIVE_ORDER);
2503   }
2504 
2505   @Test
testBuilderWithImmutableSorted_SetMap()2506   public void testBuilderWithImmutableSorted_SetMap() {
2507     BuilderWithImmutableSorted<String> x =
2508         BuilderWithImmutableSorted.<String>builder()
2509             .setSortedMap(new TreeMap<String, Integer>(String.CASE_INSENSITIVE_ORDER))
2510             .build();
2511     assertThat(x.sortedMap().comparator()).isEqualTo(String.CASE_INSENSITIVE_ORDER);
2512   }
2513 
2514   @Test
testBuilderWithImmutableSorted_SetCollectionBuilder()2515   public void testBuilderWithImmutableSorted_SetCollectionBuilder() {
2516     BuilderWithImmutableSorted.Builder<String> builder =
2517         BuilderWithImmutableSorted.<String>builder();
2518     builder.sortedSetBuilder().add("is", "ea", "id");
2519     BuilderWithImmutableSorted<String> x = builder.build();
2520     assertThat(x.sortedSet()).containsExactly("ea", "id", "is").inOrder();
2521   }
2522 
2523   @Test
testBuilderWithImmutableSorted_MapCollectionBuilder()2524   public void testBuilderWithImmutableSorted_MapCollectionBuilder() {
2525     BuilderWithImmutableSorted.Builder<String> builder =
2526         BuilderWithImmutableSorted.<String>builder();
2527     builder.sortedMapBuilder().put("two", 2).put("one", 1);
2528     BuilderWithImmutableSorted<String> x = builder.build();
2529     assertThat(x.sortedMap()).containsExactly("one", 1, "two", 2).inOrder();
2530   }
2531 
2532   @AutoValue
2533   public abstract static class BuilderWithCollectionBuilderAndSetter<T extends Number> {
things()2534     public abstract ImmutableList<T> things();
2535 
builder()2536     public static <T extends Number> Builder<T> builder() {
2537       return new AutoValue_AutoValueTest_BuilderWithCollectionBuilderAndSetter.Builder<T>();
2538     }
2539 
2540     @AutoValue.Builder
2541     public interface Builder<T extends Number> {
setThings(List<T> things)2542       Builder<T> setThings(List<T> things);
2543 
things()2544       ImmutableList<T> things();
2545 
thingsBuilder()2546       ImmutableList.Builder<T> thingsBuilder();
2547 
build()2548       BuilderWithCollectionBuilderAndSetter<T> build();
2549     }
2550   }
2551 
2552   @Test
testBuilderAndSetterDefaultsEmpty()2553   public void testBuilderAndSetterDefaultsEmpty() {
2554     BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder =
2555         BuilderWithCollectionBuilderAndSetter.<Integer>builder();
2556     assertThat(builder.things()).isEmpty();
2557     assertThat(builder.build().things()).isEmpty();
2558   }
2559 
2560   @Test
testBuilderAndSetterUsingBuilder()2561   public void testBuilderAndSetterUsingBuilder() {
2562     BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder =
2563         BuilderWithCollectionBuilderAndSetter.builder();
2564     builder.thingsBuilder().add(17, 23);
2565     BuilderWithCollectionBuilderAndSetter<Integer> x = builder.build();
2566     assertThat(x.things()).isEqualTo(ImmutableList.of(17, 23));
2567   }
2568 
2569   @Test
testBuilderAndSetterUsingSetter()2570   public void testBuilderAndSetterUsingSetter() {
2571     ImmutableList<Integer> things = ImmutableList.of(17, 23);
2572     BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder =
2573         BuilderWithCollectionBuilderAndSetter.<Integer>builder().setThings(things);
2574     assertThat(builder.things()).isSameInstanceAs(things);
2575     assertThat(builder.build().things()).isSameInstanceAs(things);
2576 
2577     List<Integer> moreThings = Arrays.asList(5, 17, 23);
2578     BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder2 =
2579         BuilderWithCollectionBuilderAndSetter.<Integer>builder().setThings(moreThings);
2580     assertThat(builder2.things()).isEqualTo(moreThings);
2581     assertThat(builder2.build().things()).isEqualTo(moreThings);
2582   }
2583 
2584   @Test
testBuilderAndSetterUsingSetterThenBuilder()2585   public void testBuilderAndSetterUsingSetterThenBuilder() {
2586     BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder =
2587         BuilderWithCollectionBuilderAndSetter.builder();
2588     builder.setThings(ImmutableList.of(5));
2589     builder.thingsBuilder().add(17, 23);
2590     List<Integer> expectedThings = ImmutableList.of(5, 17, 23);
2591     assertThat(builder.things()).isEqualTo(expectedThings);
2592     assertThat(builder.build().things()).isEqualTo(expectedThings);
2593   }
2594 
2595   @Test
testBuilderAndSetterCannotSetAfterBuilder()2596   public void testBuilderAndSetterCannotSetAfterBuilder() {
2597     BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder =
2598         BuilderWithCollectionBuilderAndSetter.builder();
2599     builder.setThings(ImmutableList.of(5));
2600     builder.thingsBuilder().add(17, 23);
2601     try {
2602       builder.setThings(ImmutableList.of(1729));
2603       fail("Setting list after retrieving builder should provoke an exception");
2604     } catch (IllegalStateException e) {
2605       if (omitIdentifiers) {
2606         assertThat(e).hasMessageThat().isNull();
2607       } else {
2608         assertThat(e).hasMessageThat().isEqualTo("Cannot set things after calling thingsBuilder()");
2609       }
2610     }
2611   }
2612 
2613   abstract static class AbstractParentWithBuilder {
foo()2614     abstract String foo();
2615 
2616     abstract static class Builder<B extends Builder<B>> {
foo(String s)2617       abstract B foo(String s);
2618     }
2619   }
2620 
2621   @AutoValue
2622   abstract static class ChildWithBuilder extends AbstractParentWithBuilder {
bar()2623     abstract String bar();
2624 
builder()2625     static Builder builder() {
2626       return new AutoValue_AutoValueTest_ChildWithBuilder.Builder();
2627     }
2628 
2629     @AutoValue.Builder
2630     abstract static class Builder extends AbstractParentWithBuilder.Builder<Builder> {
bar(String s)2631       abstract Builder bar(String s);
2632 
build()2633       abstract ChildWithBuilder build();
2634     }
2635   }
2636 
2637   @Test
testInheritedBuilder()2638   public void testInheritedBuilder() {
2639     ChildWithBuilder x = ChildWithBuilder.builder().foo("foo").bar("bar").build();
2640     assertThat(x.foo()).isEqualTo("foo");
2641     assertThat(x.bar()).isEqualTo("bar");
2642   }
2643 
2644   @Retention(RetentionPolicy.RUNTIME)
2645   @interface GwtCompatible {
funky()2646     boolean funky() default false;
2647   }
2648 
2649   @AutoValue
2650   @GwtCompatible(funky = true)
2651   abstract static class GwtCompatibleTest {
foo()2652     abstract int foo();
2653 
create(int foo)2654     static GwtCompatibleTest create(int foo) {
2655       return new AutoValue_AutoValueTest_GwtCompatibleTest(foo);
2656     }
2657   }
2658 
2659   @AutoValue
2660   @GwtCompatible
2661   abstract static class GwtCompatibleTestNoArgs {
bar()2662     abstract String bar();
2663 
create(String bar)2664     static GwtCompatibleTestNoArgs create(String bar) {
2665       return new AutoValue_AutoValueTest_GwtCompatibleTestNoArgs(bar);
2666     }
2667   }
2668 
2669   @Test
testGwtCompatibleInherited()2670   public void testGwtCompatibleInherited() {
2671     GwtCompatibleTest test = GwtCompatibleTest.create(23);
2672     GwtCompatible gwtCompatible = test.getClass().getAnnotation(GwtCompatible.class);
2673     assertNotNull(gwtCompatible);
2674     assertTrue(gwtCompatible.funky());
2675 
2676     GwtCompatibleTestNoArgs testNoArgs = GwtCompatibleTestNoArgs.create("23");
2677     GwtCompatible gwtCompatibleNoArgs = testNoArgs.getClass().getAnnotation(GwtCompatible.class);
2678     assertNotNull(gwtCompatibleNoArgs);
2679     assertFalse(gwtCompatibleNoArgs.funky());
2680   }
2681 
2682   @interface NestedAnnotation {
anInt()2683     int anInt();
2684 
aClassArray()2685     Class<?>[] aClassArray();
2686   }
2687 
2688   @Retention(RetentionPolicy.RUNTIME)
2689   @interface HairyAnnotation {
aString()2690     String aString();
2691 
aClass()2692     Class<? extends Number> aClass();
2693 
anEnum()2694     RetentionPolicy anEnum();
2695 
anAnnotation()2696     NestedAnnotation anAnnotation();
2697   }
2698 
2699   @Retention(RetentionPolicy.RUNTIME)
2700   @interface CopiedAnnotation {}
2701 
2702   @Retention(RetentionPolicy.RUNTIME)
2703   @interface ExcludedAnnotation {}
2704 
2705   @Retention(RetentionPolicy.RUNTIME)
2706   @Inherited
2707   @interface InheritedAnnotation {}
2708 
2709   @CopiedAnnotation
2710   @ExcludedAnnotation
2711   @InheritedAnnotation
2712   @AutoValue
2713   @AutoValue.CopyAnnotations(exclude = {ExcludedAnnotation.class})
2714   abstract static class CopyAnnotation {
2715     @HairyAnnotation(
2716         aString = "hello",
2717         aClass = Integer.class,
2718         anEnum = RetentionPolicy.RUNTIME,
2719         anAnnotation =
2720             @NestedAnnotation(
2721                 anInt = 73,
2722                 aClassArray = {String.class, Object.class}))
field1()2723     abstract String field1();
2724 
2725     @CopiedAnnotation
2726     @ExcludedAnnotation
2727     @InheritedAnnotation
2728     @AutoValue.CopyAnnotations(exclude = {ExcludedAnnotation.class})
field2()2729     abstract String field2();
2730 
create()2731     static CopyAnnotation create() {
2732       return new AutoValue_AutoValueTest_CopyAnnotation("field1", "field2");
2733     }
2734   }
2735 
2736   @Test
testCopyClassAnnotations()2737   public void testCopyClassAnnotations() throws Exception {
2738     CopyAnnotation x = CopyAnnotation.create();
2739     Class<?> c = x.getClass();
2740     assertNotSame(CopyAnnotation.class, c);
2741 
2742     // Sanity check: if these don't appear on CopyAnnotation, it makes no sense to assert that they
2743     // don't appear on the AutoValue_ subclass.
2744     {
2745       List<Class<? extends Annotation>> annotationsOnSuperclass =
2746           new ArrayList<Class<? extends Annotation>>();
2747       for (Annotation annotation : CopyAnnotation.class.getDeclaredAnnotations()) {
2748         annotationsOnSuperclass.add(annotation.annotationType());
2749       }
2750       assertThat(annotationsOnSuperclass)
2751           .containsAtLeast(
2752               CopiedAnnotation.class, ExcludedAnnotation.class, InheritedAnnotation.class);
2753     }
2754 
2755     {
2756       List<Class<? extends Annotation>> annotationsOnSubclass =
2757           new ArrayList<Class<? extends Annotation>>();
2758       for (Annotation annotation : c.getDeclaredAnnotations()) {
2759         annotationsOnSubclass.add(annotation.annotationType());
2760       }
2761       assertThat(annotationsOnSubclass).containsExactly(CopiedAnnotation.class);
2762     }
2763   }
2764 
2765   @Test
testCopyMethodAnnotations()2766   public void testCopyMethodAnnotations() throws Exception {
2767     CopyAnnotation x = CopyAnnotation.create();
2768     Class<?> c = x.getClass();
2769     assertNotSame(CopyAnnotation.class, c);
2770 
2771     Method methodInSubclass = c.getDeclaredMethod("field2");
2772     Method methodInSuperclass = CopyAnnotation.class.getDeclaredMethod("field2");
2773 
2774     // Sanity check: if these don't appear on CopyAnnotation, it makes no sense to assert that they
2775     // don't appear on the AutoValue_ subclass.
2776     assertThat(methodInSuperclass.isAnnotationPresent(CopiedAnnotation.class)).isTrue();
2777     assertThat(methodInSuperclass.isAnnotationPresent(ExcludedAnnotation.class)).isTrue();
2778     assertThat(methodInSuperclass.isAnnotationPresent(InheritedAnnotation.class)).isTrue();
2779 
2780     assertThat(methodInSubclass.isAnnotationPresent(CopiedAnnotation.class)).isTrue();
2781     assertThat(methodInSubclass.isAnnotationPresent(ExcludedAnnotation.class)).isFalse();
2782     assertThat(methodInSubclass.isAnnotationPresent(InheritedAnnotation.class)).isTrue();
2783   }
2784 
2785   @Test
testCopyMethodAnnotationsByDefault()2786   public void testCopyMethodAnnotationsByDefault() throws Exception {
2787     CopyAnnotation x = CopyAnnotation.create();
2788     Class<?> c = x.getClass();
2789     assertNotSame(CopyAnnotation.class, c);
2790     Method methodInSubclass = c.getDeclaredMethod("field1");
2791     Method methodInSuperclass = CopyAnnotation.class.getDeclaredMethod("field1");
2792     assertNotSame(methodInSuperclass, methodInSubclass);
2793     HairyAnnotation annotationInSubclass = methodInSubclass.getAnnotation(HairyAnnotation.class);
2794     HairyAnnotation annotationInSuperclass =
2795         methodInSuperclass.getAnnotation(HairyAnnotation.class);
2796     assertEquals(annotationInSuperclass, annotationInSubclass);
2797   }
2798 
2799   @AutoValue
2800   abstract static class HProperty {
h()2801     public abstract Object h();
2802 
create(Object h)2803     public static HProperty create(Object h) {
2804       return new AutoValue_AutoValueTest_HProperty(h);
2805     }
2806   }
2807 
2808   @Test
testHProperty()2809   public void testHProperty() throws Exception {
2810     // Checks that we can have a property called `h`. The generated hashCode() method has
2811     // a local variable of that name and can cause the error `int cannot be dereferenced`
2812     HProperty.create(new Object());
2813   }
2814 
2815   interface Parent1 {
something()2816     int something();
2817   }
2818 
2819   interface Parent2 {
something()2820     int something();
2821   }
2822 
2823   @AutoValue
2824   abstract static class InheritSameMethodTwice implements Parent1, Parent2 {
create(int something)2825     static InheritSameMethodTwice create(int something) {
2826       return new AutoValue_AutoValueTest_InheritSameMethodTwice(something);
2827     }
2828   }
2829 
2830   @Test
testInheritSameMethodTwice()2831   public void testInheritSameMethodTwice() {
2832     InheritSameMethodTwice x = InheritSameMethodTwice.create(23);
2833     assertThat(x.something()).isEqualTo(23);
2834   }
2835 
2836   // Make sure we behave correctly when we inherit the same method definition from more than
2837   // one parent interface. We expect methods to appear in the order they are seen, with parents
2838   // preceding children, the superclass of a class preceding interfaces that class implements,
2839   // and an interface mentioned earlier in the "implements" clause preceding one mentioned later.
2840   // https://github.com/google/auto/issues/372
2841   interface OneTwoThreeFour {
one()2842     String one();
2843 
two()2844     String two();
2845 
three()2846     boolean three();
2847 
four()2848     long four();
2849   }
2850 
2851   interface TwoFour {
two()2852     String two();
2853 
four()2854     long four();
2855   }
2856 
2857   @AutoValue
2858   abstract static class OneTwoThreeFourImpl implements OneTwoThreeFour, TwoFour {
create(String one, String two, boolean three, long four)2859     static OneTwoThreeFourImpl create(String one, String two, boolean three, long four) {
2860       return new AutoValue_AutoValueTest_OneTwoThreeFourImpl(one, two, three, four);
2861     }
2862   }
2863 
2864   @Test
testOneTwoThreeFour()2865   public void testOneTwoThreeFour() {
2866     OneTwoThreeFour x = OneTwoThreeFourImpl.create("one", "two", false, 4);
2867     String expectedString =
2868         omitIdentifiers
2869             ? "{one, two, false, 4}"
2870             : "OneTwoThreeFourImpl{one=one, two=two, three=false, four=4}";
2871     assertThat(x.toString()).isEqualTo(expectedString);
2872   }
2873 
2874   @AutoValue
2875   abstract static class OuterWithBuilder {
foo()2876     abstract String foo();
2877 
inner()2878     abstract InnerWithBuilder inner();
2879 
toBuilder()2880     abstract Builder toBuilder();
2881 
builder()2882     static Builder builder() {
2883       return new AutoValue_AutoValueTest_OuterWithBuilder.Builder();
2884     }
2885 
2886     @AutoValue.Builder
2887     abstract static class Builder {
foo(String x)2888       abstract Builder foo(String x);
2889 
inner(InnerWithBuilder x)2890       abstract Builder inner(InnerWithBuilder x);
2891 
innerBuilder()2892       abstract InnerWithBuilder.Builder innerBuilder();
2893 
build()2894       abstract OuterWithBuilder build();
2895     }
2896   }
2897 
2898   @AutoValue
2899   abstract static class InnerWithBuilder {
bar()2900     abstract int bar();
2901 
toBuilder()2902     abstract Builder toBuilder();
2903 
builder()2904     static Builder builder() {
2905       return new AutoValue_AutoValueTest_InnerWithBuilder.Builder();
2906     }
2907 
2908     @AutoValue.Builder
2909     abstract static class Builder {
setBar(int x)2910       abstract Builder setBar(int x);
2911 
build()2912       abstract InnerWithBuilder build();
2913     }
2914   }
2915 
2916   @Test
testBuilderWithinBuilder()2917   public void testBuilderWithinBuilder() {
2918     OuterWithBuilder x =
2919         OuterWithBuilder.builder()
2920             .inner(InnerWithBuilder.builder().setBar(23).build())
2921             .foo("yes")
2922             .build();
2923     String expectedStringX =
2924         omitIdentifiers
2925             ? "{yes, {23}}"
2926             : "OuterWithBuilder{foo=yes, inner=InnerWithBuilder{bar=23}}";
2927     assertThat(x.toString()).isEqualTo(expectedStringX);
2928 
2929     OuterWithBuilder.Builder xBuilder = x.toBuilder();
2930     xBuilder.innerBuilder().setBar(17);
2931     OuterWithBuilder y = xBuilder.build();
2932     String expectedStringY =
2933         omitIdentifiers
2934             ? "{yes, {17}}"
2935             : "OuterWithBuilder{foo=yes, inner=InnerWithBuilder{bar=17}}";
2936     assertThat(y.toString()).isEqualTo(expectedStringY);
2937   }
2938 
2939   public static class MyMap<K, V> extends HashMap<K, V> {
2940     private static final long serialVersionUID = 1L;
2941 
MyMap()2942     public MyMap() {}
2943 
MyMap(Map<K, V> map)2944     public MyMap(Map<K, V> map) {
2945       super(map);
2946     }
2947   }
2948 
2949   public static class MyMapBuilder<K, V> extends LinkedHashMap<K, V> {
2950     private static final long serialVersionUID = 1L;
2951 
MyMapBuilder()2952     public MyMapBuilder() {}
2953 
MyMapBuilder(Map<K, V> map)2954     public MyMapBuilder(Map<K, V> map) {
2955       super(map);
2956     }
2957 
build()2958     public MyMap<K, V> build() {
2959       return new MyMap<K, V>(this);
2960     }
2961   }
2962 
2963   @AutoValue
2964   abstract static class BuildMyMap<K, V> {
map()2965     abstract MyMap<K, V> map();
2966 
toBuilder()2967     abstract Builder<K, V> toBuilder();
2968 
builder()2969     static <K, V> Builder<K, V> builder() {
2970       return new AutoValue_AutoValueTest_BuildMyMap.Builder<K, V>();
2971     }
2972 
2973     @AutoValue.Builder
2974     abstract static class Builder<K, V> {
mapBuilder()2975       abstract MyMapBuilder<K, V> mapBuilder();
2976 
build()2977       abstract BuildMyMap<K, V> build();
2978     }
2979   }
2980 
2981   @Test
testMyMapBuilder()2982   public void testMyMapBuilder() {
2983     BuildMyMap.Builder<String, Integer> builder = BuildMyMap.builder();
2984     MyMapBuilder<String, Integer> mapBuilder = builder.mapBuilder();
2985     mapBuilder.put("23", 23);
2986     BuildMyMap<String, Integer> built = builder.build();
2987     assertThat(built.map()).containsExactly("23", 23);
2988 
2989     BuildMyMap.Builder<String, Integer> builder2 = built.toBuilder();
2990     MyMapBuilder<String, Integer> mapBuilder2 = builder2.mapBuilder();
2991     mapBuilder2.put("17", 17);
2992     BuildMyMap<String, Integer> built2 = builder2.build();
2993     assertThat(built2.map()).containsExactly("23", 23, "17", 17);
2994   }
2995 
2996   public static class MyStringMap<V> extends MyMap<String, V> {
2997     private static final long serialVersionUID = 1L;
2998 
MyStringMap()2999     public MyStringMap() {}
3000 
MyStringMap(Map<String, V> map)3001     public MyStringMap(Map<String, V> map) {
3002       super(map);
3003     }
3004 
toBuilder()3005     public MyStringMapBuilder<V> toBuilder() {
3006       return new MyStringMapBuilder<V>(this);
3007     }
3008   }
3009 
3010   public static class MyStringMapBuilder<V> extends MyMapBuilder<String, V> {
3011     private static final long serialVersionUID = 1L;
3012 
MyStringMapBuilder()3013     public MyStringMapBuilder() {}
3014 
MyStringMapBuilder(Map<String, V> map)3015     public MyStringMapBuilder(Map<String, V> map) {
3016       super(map);
3017     }
3018 
3019     @Override
build()3020     public MyStringMap<V> build() {
3021       return new MyStringMap<V>(this);
3022     }
3023   }
3024 
3025   @AutoValue
3026   abstract static class BuildMyStringMap<V> {
map()3027     abstract MyStringMap<V> map();
3028 
toBuilder()3029     abstract Builder<V> toBuilder();
3030 
builder()3031     static <V> Builder<V> builder() {
3032       return new AutoValue_AutoValueTest_BuildMyStringMap.Builder<V>();
3033     }
3034 
3035     @AutoValue.Builder
3036     abstract static class Builder<V> {
mapBuilder()3037       abstract MyStringMapBuilder<V> mapBuilder();
3038 
build()3039       abstract BuildMyStringMap<V> build();
3040     }
3041   }
3042 
3043   @Test
testMyStringMapBuilder()3044   public void testMyStringMapBuilder() {
3045     BuildMyStringMap.Builder<Integer> builder = BuildMyStringMap.builder();
3046     MyStringMapBuilder<Integer> mapBuilder = builder.mapBuilder();
3047     mapBuilder.put("23", 23);
3048     BuildMyStringMap<Integer> built = builder.build();
3049     assertThat(built.map()).containsExactly("23", 23);
3050 
3051     BuildMyStringMap.Builder<Integer> builder2 = built.toBuilder();
3052     MyStringMapBuilder<Integer> mapBuilder2 = builder2.mapBuilder();
3053     mapBuilder2.put("17", 17);
3054     BuildMyStringMap<Integer> built2 = builder2.build();
3055     assertThat(built2.map()).containsExactly("17", 17, "23", 23);
3056   }
3057 
3058   @AutoValue
3059   abstract static class BuilderOfManyAccessLevels {
publicGetterProtectedBuilderGetterPackageProtectedSetterInt()3060     public abstract int publicGetterProtectedBuilderGetterPackageProtectedSetterInt();
3061 
protectedGetterPackageProtectedBuilderGetterPublicSetterInt()3062     protected abstract int protectedGetterPackageProtectedBuilderGetterPublicSetterInt();
3063 
packageProtectedGetterPublicBuilderGetterProtectedSetterInt()3064     abstract int packageProtectedGetterPublicBuilderGetterProtectedSetterInt();
3065 
3066     @AutoValue.Builder
3067     public abstract static class Builder {
publicGetterProtectedBuilderGetterPackageProtectedSetterInt()3068       protected abstract int publicGetterProtectedBuilderGetterPackageProtectedSetterInt();
3069 
protectedGetterPackageProtectedBuilderGetterPublicSetterInt()3070       abstract int protectedGetterPackageProtectedBuilderGetterPublicSetterInt();
3071 
packageProtectedGetterPublicBuilderGetterProtectedSetterInt()3072       public abstract int packageProtectedGetterPublicBuilderGetterProtectedSetterInt();
3073 
setPublicGetterProtectedBuilderGetterPackageProtectedSetterInt(int x)3074       abstract Builder setPublicGetterProtectedBuilderGetterPackageProtectedSetterInt(int x);
3075 
setProtectedGetterPackageProtectedBuilderGetterPublicSetterInt(int x)3076       public abstract Builder setProtectedGetterPackageProtectedBuilderGetterPublicSetterInt(int x);
3077 
setPackageProtectedGetterPublicBuilderGetterProtectedSetterInt( int x)3078       protected abstract Builder setPackageProtectedGetterPublicBuilderGetterProtectedSetterInt(
3079           int x);
3080 
build()3081       public abstract BuilderOfManyAccessLevels build();
3082     }
3083   }
3084 
3085   @Test
testBuilderOfManyAccessLevels_accessLevels()3086   public void testBuilderOfManyAccessLevels_accessLevels() throws NoSuchMethodException {
3087     Class<?> builderClass = AutoValue_AutoValueTest_BuilderOfManyAccessLevels.Builder.class;
3088 
3089     testMethodAccess(
3090         Access.PROTECTED,
3091         builderClass,
3092         "publicGetterProtectedBuilderGetterPackageProtectedSetterInt");
3093     testMethodAccess(
3094         Access.PACKAGE,
3095         builderClass,
3096         "protectedGetterPackageProtectedBuilderGetterPublicSetterInt");
3097     testMethodAccess(
3098         Access.PUBLIC, builderClass, "packageProtectedGetterPublicBuilderGetterProtectedSetterInt");
3099 
3100     testMethodAccess(
3101         Access.PACKAGE,
3102         builderClass,
3103         "setPublicGetterProtectedBuilderGetterPackageProtectedSetterInt",
3104         int.class);
3105     testMethodAccess(
3106         Access.PUBLIC,
3107         builderClass,
3108         "setProtectedGetterPackageProtectedBuilderGetterPublicSetterInt",
3109         int.class);
3110     testMethodAccess(
3111         Access.PROTECTED,
3112         builderClass,
3113         "setPackageProtectedGetterPublicBuilderGetterProtectedSetterInt",
3114         int.class);
3115   }
3116 
3117   private enum Access {
3118     PRIVATE,
3119     PACKAGE,
3120     PROTECTED,
3121     PUBLIC
3122   }
3123 
3124   private static final ImmutableMap<Integer, Access> MODIFIER_BITS_TO_ACCESS =
3125       ImmutableMap.of(
3126           Modifier.PUBLIC,
3127           Access.PUBLIC,
3128           Modifier.PROTECTED,
3129           Access.PROTECTED,
3130           Modifier.PRIVATE,
3131           Access.PRIVATE,
3132           0,
3133           Access.PACKAGE);
3134 
testMethodAccess( Access expectedAccess, Class<?> clazz, String methodName, Class<?>... parameterTypes)3135   private static void testMethodAccess(
3136       Access expectedAccess, Class<?> clazz, String methodName, Class<?>... parameterTypes)
3137       throws NoSuchMethodException {
3138     Method method = clazz.getDeclaredMethod(methodName, parameterTypes);
3139     int modBits = method.getModifiers() & (Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE);
3140     Access actualAccess = MODIFIER_BITS_TO_ACCESS.get(modBits);
3141     assertWithMessage("Wrong access for %s", methodName)
3142         .that(actualAccess)
3143         .isEqualTo(expectedAccess);
3144   }
3145 
3146   static class VersionId {}
3147 
3148   static class ItemVersionId extends VersionId {}
3149 
3150   interface VersionedPersistent {
getVersionId()3151     VersionId getVersionId();
3152   }
3153 
3154   interface Item extends VersionedPersistent {
3155     @Override
getVersionId()3156     ItemVersionId getVersionId();
3157   }
3158 
3159   @AutoValue
3160   abstract static class FakeItem implements Item {
builder()3161     static Builder builder() {
3162       return new AutoValue_AutoValueTest_FakeItem.Builder();
3163     }
3164 
3165     @AutoValue.Builder
3166     abstract static class Builder {
setVersionId(ItemVersionId x)3167       abstract Builder setVersionId(ItemVersionId x);
3168 
build()3169       abstract FakeItem build();
3170     }
3171   }
3172 
3173   @Test
testParentInterfaceOverridesGrandparent()3174   public void testParentInterfaceOverridesGrandparent() {
3175     ItemVersionId version = new ItemVersionId();
3176     FakeItem fakeItem = FakeItem.builder().setVersionId(version).build();
3177     assertThat(fakeItem.getVersionId()).isSameInstanceAs(version);
3178   }
3179 
3180   /** Fake ApkVersionCode class. */
3181   public static class ApkVersionCode {}
3182 
3183   /**
3184    * Illustrates a potential problem that showed up while generalizing builders. If our imports are
3185    * not accurate we may end up importing ImmutableList.Builder, which won't work because the
3186    * generated Builder subclass of ReleaseInfoBuilder will supersede it. Normally we wouldn't import
3187    * ImmutableList.Builder because the nested Builder class in the {@code @AutoValue} class would
3188    * prevent us trying. But in this case the nested class is called ReleaseInfoBuilder so we might
3189    * import anyway if we're not careful. This is one reason why we moved away from importing nested
3190    * classes to only importing top-level classes.
3191    */
3192   @AutoValue
3193   public abstract static class ReleaseInfo {
newBuilder()3194     public static ReleaseInfoBuilder newBuilder() {
3195       return new AutoValue_AutoValueTest_ReleaseInfo.Builder();
3196     }
3197 
apkVersionCodes()3198     public abstract ImmutableList<ApkVersionCode> apkVersionCodes();
3199 
ReleaseInfo()3200     ReleaseInfo() {}
3201 
3202     /** Notice that this is called ReleaseInfoBuilder and not Builder. */
3203     @AutoValue.Builder
3204     public abstract static class ReleaseInfoBuilder {
addApkVersionCode(ApkVersionCode code)3205       public ReleaseInfoBuilder addApkVersionCode(ApkVersionCode code) {
3206         apkVersionCodesBuilder().add(code);
3207         return this;
3208       }
3209 
apkVersionCodesBuilder()3210       abstract ImmutableList.Builder<ApkVersionCode> apkVersionCodesBuilder();
3211 
build()3212       public abstract ReleaseInfo build();
3213     }
3214   }
3215 
3216   @Test
testUnusualBuilderName()3217   public void testUnusualBuilderName() {
3218     ApkVersionCode apkVersionCode = new ApkVersionCode();
3219     ReleaseInfo x = ReleaseInfo.newBuilder().addApkVersionCode(apkVersionCode).build();
3220     assertThat(x.apkVersionCodes()).containsExactly(apkVersionCode);
3221   }
3222 
3223   @AutoValue
3224   public abstract static class OuterWithDefaultableInner {
names()3225     public abstract ImmutableList<String> names();
3226 
inner()3227     public abstract DefaultableInner inner();
3228 
builder()3229     public static Builder builder() {
3230       return new AutoValue_AutoValueTest_OuterWithDefaultableInner.Builder();
3231     }
3232 
3233     @AutoValue.Builder
3234     public abstract static class Builder {
names()3235       public abstract ImmutableList<String> names();
3236 
namesBuilder()3237       public abstract ImmutableList.Builder<String> namesBuilder();
3238 
inner()3239       public abstract DefaultableInner inner();
3240 
innerBuilder()3241       public abstract DefaultableInner.Builder innerBuilder();
3242 
build()3243       public abstract OuterWithDefaultableInner build();
3244     }
3245   }
3246 
3247   @AutoValue
3248   public abstract static class DefaultableInner {
bar()3249     public abstract int bar();
3250 
builder()3251     public static Builder builder() {
3252       return new AutoValue_AutoValueTest_DefaultableInner.Builder().setBar(23);
3253     }
3254 
3255     @AutoValue.Builder
3256     public abstract static class Builder {
setBar(int x)3257       public abstract Builder setBar(int x);
3258 
build()3259       public abstract DefaultableInner build();
3260     }
3261   }
3262 
3263   @Test
testOuterWithDefaultableInner_Defaults()3264   public void testOuterWithDefaultableInner_Defaults() {
3265     DefaultableInner defaultInner = DefaultableInner.builder().build();
3266     OuterWithDefaultableInner x = OuterWithDefaultableInner.builder().build();
3267     assertThat(x.names()).isEmpty();
3268     assertThat(x.inner()).isEqualTo(defaultInner);
3269   }
3270 
3271   @Test
testOuterWithDefaultableInner_Getters()3272   public void testOuterWithDefaultableInner_Getters() {
3273     DefaultableInner defaultInner = DefaultableInner.builder().build();
3274 
3275     OuterWithDefaultableInner.Builder builder = OuterWithDefaultableInner.builder();
3276     assertThat(builder.names()).isEmpty();
3277     assertThat(builder.inner()).isEqualTo(defaultInner);
3278 
3279     OuterWithDefaultableInner x1 = builder.build();
3280     assertThat(x1.names()).isEmpty();
3281     assertThat(x1.inner()).isEqualTo(defaultInner);
3282 
3283     builder.namesBuilder().add("Fred");
3284     builder.innerBuilder().setBar(17);
3285     OuterWithDefaultableInner x2 = builder.build();
3286     assertThat(x2.names()).containsExactly("Fred");
3287     assertThat(x2.inner().bar()).isEqualTo(17);
3288   }
3289 
3290   @AutoValue
3291   public abstract static class OuterWithNonDefaultableInner<T> {
foo()3292     public abstract int foo();
3293 
inner()3294     public abstract NonDefaultableInner<T> inner();
3295 
builder()3296     public static <T> Builder<T> builder() {
3297       return new AutoValue_AutoValueTest_OuterWithNonDefaultableInner.Builder<T>();
3298     }
3299 
3300     @AutoValue.Builder
3301     public abstract static class Builder<T> {
setFoo(int x)3302       public abstract Builder<T> setFoo(int x);
3303 
innerBuilder()3304       public abstract NonDefaultableInner.Builder<T> innerBuilder();
3305 
build()3306       public abstract OuterWithNonDefaultableInner<T> build();
3307     }
3308   }
3309 
3310   @AutoValue
3311   public abstract static class NonDefaultableInner<E> {
bar()3312     public abstract E bar();
3313 
builder()3314     public static <E> Builder<E> builder() {
3315       return new AutoValue_AutoValueTest_NonDefaultableInner.Builder<E>();
3316     }
3317 
3318     @AutoValue.Builder
3319     public abstract static class Builder<E> {
setBar(E x)3320       public abstract Builder<E> setBar(E x);
3321 
build()3322       public abstract NonDefaultableInner<E> build();
3323     }
3324   }
3325 
3326   @Test
testOuterWithNonDefaultableInner()3327   public void testOuterWithNonDefaultableInner() {
3328     OuterWithNonDefaultableInner.Builder<String> builder = OuterWithNonDefaultableInner.builder();
3329     builder.setFoo(23);
3330     try {
3331       builder.build();
3332       fail("Did not get expected exception for unbuilt inner instance");
3333     } catch (IllegalStateException expected) {
3334     }
3335   }
3336 
3337   @SuppressWarnings("JavaLangClash")
3338   @AutoValue
3339   public abstract static class RedeclareJavaLangClasses {
3340     // If you really really want to do this, we have you covered.
3341 
3342     public static class Object {}
3343 
3344     public static class String {}
3345 
alienObject()3346     public abstract Object alienObject();
3347 
alienString()3348     public abstract String alienString();
3349 
builder()3350     public static Builder builder() {
3351       return new AutoValue_AutoValueTest_RedeclareJavaLangClasses.Builder();
3352     }
3353 
3354     @AutoValue.Builder
3355     public abstract static class Builder {
setAlienObject(Object x)3356       public abstract Builder setAlienObject(Object x);
3357 
setAlienString(String x)3358       public abstract Builder setAlienString(String x);
3359 
build()3360       public abstract RedeclareJavaLangClasses build();
3361     }
3362   }
3363 
3364   @Test
testRedeclareJavaLangClasses()3365   public void testRedeclareJavaLangClasses() {
3366     RedeclareJavaLangClasses x =
3367         RedeclareJavaLangClasses.builder()
3368             .setAlienObject(new RedeclareJavaLangClasses.Object())
3369             .setAlienString(new RedeclareJavaLangClasses.String())
3370             .build();
3371     assertThat(x).isNotNull();
3372   }
3373 
3374   // b/28382293
3375   @AutoValue
3376   abstract static class GenericExtends {
metrics()3377     abstract ImmutableSet<Number> metrics();
3378 
builder()3379     static Builder builder() {
3380       return new AutoValue_AutoValueTest_GenericExtends.Builder();
3381     }
3382 
3383     @AutoValue.Builder
3384     abstract static class Builder {
setMetrics(ImmutableSet<? extends Number> metrics)3385       abstract Builder setMetrics(ImmutableSet<? extends Number> metrics);
3386 
build()3387       abstract GenericExtends build();
3388     }
3389   }
3390 
3391   @Test
testGenericExtends()3392   public void testGenericExtends() {
3393     ImmutableSet<Integer> ints = ImmutableSet.of(1, 2, 3);
3394     GenericExtends g = GenericExtends.builder().setMetrics(ints).build();
3395     assertThat(g.metrics()).isEqualTo(ints);
3396   }
3397 
3398   abstract static class Parent<T> {
getList()3399     abstract List<T> getList();
3400   }
3401 
3402   @AutoValue
3403   abstract static class Child extends Parent<String> {
builder()3404     static Builder builder() {
3405       return new AutoValue_AutoValueTest_Child.Builder();
3406     }
3407 
3408     @AutoValue.Builder
3409     abstract static class Builder {
setList(List<String> list)3410       abstract Builder setList(List<String> list);
3411 
build()3412       abstract Child build();
3413     }
3414   }
3415 
3416   @Test
nonGenericExtendsGeneric()3417   public void nonGenericExtendsGeneric() {
3418     List<String> list = ImmutableList.of("foo", "bar", "baz");
3419     Child child = Child.builder().setList(list).build();
3420     assertThat(child.getList()).containsExactlyElementsIn(list).inOrder();
3421   }
3422 
3423   abstract static class AbstractGenericParentWithBuilder<T> {
foo()3424     abstract T foo();
3425 
3426     abstract static class Builder<T, B extends Builder<T, B>> {
foo(T s)3427       abstract B foo(T s);
3428     }
3429   }
3430 
3431   @AutoValue
3432   abstract static class ChildOfAbstractGenericParentWithBuilder<T>
3433       extends AbstractGenericParentWithBuilder<T> {
builder()3434     static <T> Builder<T> builder() {
3435       return new AutoValue_AutoValueTest_ChildOfAbstractGenericParentWithBuilder.Builder<T>();
3436     }
3437 
3438     @AutoValue.Builder
3439     abstract static class Builder<T>
3440         extends AbstractGenericParentWithBuilder.Builder<T, Builder<T>> {
build()3441       abstract ChildOfAbstractGenericParentWithBuilder<T> build();
3442     }
3443   }
3444 
3445   @Test
genericExtendsGeneric()3446   public void genericExtendsGeneric() {
3447     ChildOfAbstractGenericParentWithBuilder<String> child =
3448         ChildOfAbstractGenericParentWithBuilder.<String>builder().foo("foo").build();
3449     assertThat(child.foo()).isEqualTo("foo");
3450   }
3451 
3452   @SuppressWarnings("ClassCanBeStatic")
3453   static class OuterWithTypeParam<T extends Number> {
3454     class InnerWithTypeParam<U> {}
3455 
3456     class InnerWithoutTypeParam {}
3457 
3458     static class Nested {}
3459   }
3460 
3461   @AutoValue
3462   abstract static class Nesty {
innerWithTypeParam()3463     abstract OuterWithTypeParam<Double>.InnerWithTypeParam<String> innerWithTypeParam();
3464 
innerWithoutTypeParam()3465     abstract OuterWithTypeParam<Double>.InnerWithoutTypeParam innerWithoutTypeParam();
3466 
nested()3467     abstract OuterWithTypeParam.Nested nested();
3468 
builder()3469     static Builder builder() {
3470       return new AutoValue_AutoValueTest_Nesty.Builder();
3471     }
3472 
3473     @AutoValue.Builder
3474     abstract static class Builder {
setInnerWithTypeParam( OuterWithTypeParam<Double>.InnerWithTypeParam<String> x)3475       abstract Builder setInnerWithTypeParam(
3476           OuterWithTypeParam<Double>.InnerWithTypeParam<String> x);
3477 
setInnerWithoutTypeParam(OuterWithTypeParam<Double>.InnerWithoutTypeParam x)3478       abstract Builder setInnerWithoutTypeParam(OuterWithTypeParam<Double>.InnerWithoutTypeParam x);
3479 
setNested(OuterWithTypeParam.Nested x)3480       abstract Builder setNested(OuterWithTypeParam.Nested x);
3481 
build()3482       abstract Nesty build();
3483     }
3484   }
3485 
3486   @Test
outerWithTypeParam()3487   public void outerWithTypeParam() throws ReflectiveOperationException {
3488     @SuppressWarnings("UseDiamond") // Currently we compile this with -source 6 in the Eclipse test.
3489     OuterWithTypeParam<Double> outer = new OuterWithTypeParam<Double>();
3490     Nesty nesty =
3491         Nesty.builder()
3492             .setInnerWithTypeParam(outer.new InnerWithTypeParam<String>())
3493             .setInnerWithoutTypeParam(outer.new InnerWithoutTypeParam())
3494             .setNested(new OuterWithTypeParam.Nested())
3495             .build();
3496     Type originalReturnType =
3497         Nesty.class.getDeclaredMethod("innerWithTypeParam").getGenericReturnType();
3498     Type generatedReturnType =
3499         nesty.getClass().getDeclaredMethod("innerWithTypeParam").getGenericReturnType();
3500     assertThat(generatedReturnType).isEqualTo(originalReturnType);
3501     Type generatedBuilderParamType =
3502         Nesty.builder()
3503             .getClass()
3504             .getDeclaredMethod("setInnerWithTypeParam", OuterWithTypeParam.InnerWithTypeParam.class)
3505             .getGenericParameterTypes()[0];
3506     assertThat(generatedBuilderParamType).isEqualTo(originalReturnType);
3507   }
3508 
3509   @AutoValue
3510   abstract static class BuilderAnnotationsNotCopied {
foo()3511     abstract String foo();
3512 
builder()3513     static Builder builder() {
3514       return new AutoValue_AutoValueTest_BuilderAnnotationsNotCopied.Builder();
3515     }
3516 
3517     @AutoValue.Builder
3518     @MyAnnotation("thing")
3519     abstract static class Builder {
setFoo(String x)3520       abstract Builder setFoo(String x);
3521 
build()3522       abstract BuilderAnnotationsNotCopied build();
3523     }
3524   }
3525 
3526   @Test
builderAnnotationsNotCopiedByDefault()3527   public void builderAnnotationsNotCopiedByDefault() {
3528     BuilderAnnotationsNotCopied.Builder builder = BuilderAnnotationsNotCopied.builder();
3529     assertThat(builder.getClass().getAnnotations()).isEmpty();
3530     assertThat(builder.setFoo("foo").build().foo()).isEqualTo("foo");
3531   }
3532 
3533   @AutoValue
3534   abstract static class BuilderAnnotationsCopied {
foo()3535     abstract String foo();
3536 
builder()3537     static Builder builder() {
3538       return new AutoValue_AutoValueTest_BuilderAnnotationsCopied.Builder();
3539     }
3540 
3541     @AutoValue.Builder
3542     @AutoValue.CopyAnnotations
3543     @MyAnnotation("thing")
3544     abstract static class Builder {
setFoo(String x)3545       abstract Builder setFoo(String x);
3546 
build()3547       abstract BuilderAnnotationsCopied build();
3548     }
3549   }
3550 
3551   @Test
builderAnnotationsCopiedIfRequested()3552   public void builderAnnotationsCopiedIfRequested() {
3553     BuilderAnnotationsCopied.Builder builder = BuilderAnnotationsCopied.builder();
3554     assertThat(builder.getClass().getAnnotations()).asList().containsExactly(myAnnotation("thing"));
3555     assertThat(builder.setFoo("foo").build().foo()).isEqualTo("foo");
3556   }
3557 
3558   @AutoValue
3559   @AutoValue.CopyAnnotations
3560   @SuppressWarnings({"rawtypes", "unchecked"}) // deliberately checking handling of raw types
3561   abstract static class DataWithSortedCollectionBuilders<K, V> {
anImmutableSortedMap()3562     abstract ImmutableSortedMap<K, V> anImmutableSortedMap();
3563 
anImmutableSortedSet()3564     abstract ImmutableSortedSet<V> anImmutableSortedSet();
3565 
nonGenericImmutableSortedMap()3566     abstract ImmutableSortedMap<Integer, V> nonGenericImmutableSortedMap();
3567 
rawImmutableSortedSet()3568     abstract ImmutableSortedSet rawImmutableSortedSet();
3569 
toBuilder()3570     abstract DataWithSortedCollectionBuilders.Builder<K, V> toBuilder();
3571 
builder()3572     static <K, V> DataWithSortedCollectionBuilders.Builder<K, V> builder() {
3573       return new AutoValue_AutoValueTest_DataWithSortedCollectionBuilders.Builder<K, V>();
3574     }
3575 
3576     @AutoValue.Builder
3577     abstract static class Builder<K, V> {
anImmutableSortedMap( SortedMap<K, V> anImmutableSortedMap)3578       abstract DataWithSortedCollectionBuilders.Builder<K, V> anImmutableSortedMap(
3579           SortedMap<K, V> anImmutableSortedMap);
3580 
anImmutableSortedMapBuilder( Comparator<K> keyComparator)3581       abstract ImmutableSortedMap.Builder<K, V> anImmutableSortedMapBuilder(
3582           Comparator<K> keyComparator);
3583 
anImmutableSortedSet( SortedSet<V> anImmutableSortedSet)3584       abstract DataWithSortedCollectionBuilders.Builder<K, V> anImmutableSortedSet(
3585           SortedSet<V> anImmutableSortedSet);
3586 
anImmutableSortedSetBuilder(Comparator<V> comparator)3587       abstract ImmutableSortedSet.Builder<V> anImmutableSortedSetBuilder(Comparator<V> comparator);
3588 
nonGenericImmutableSortedMapBuilder( Comparator<Integer> keyComparator)3589       abstract ImmutableSortedMap.Builder<Integer, V> nonGenericImmutableSortedMapBuilder(
3590           Comparator<Integer> keyComparator);
3591 
rawImmutableSortedSetBuilder(Comparator comparator)3592       abstract ImmutableSortedSet.Builder rawImmutableSortedSetBuilder(Comparator comparator);
3593 
build()3594       abstract DataWithSortedCollectionBuilders<K, V> build();
3595     }
3596   }
3597 
3598   @Test
3599   @SuppressWarnings({"rawtypes", "unchecked"}) // deliberately checking handling of raw types
shouldGenerateBuildersWithComparators()3600   public void shouldGenerateBuildersWithComparators() {
3601     Comparator<String> stringComparator =
3602         new Comparator<String>() {
3603           @Override
3604           public int compare(String left, String right) {
3605             return left.compareTo(right);
3606           }
3607         };
3608 
3609     Comparator<Integer> intComparator =
3610         new Comparator<Integer>() {
3611           @Override
3612           public int compare(Integer o1, Integer o2) {
3613             return o1 - o2;
3614           }
3615         };
3616 
3617     Comparator comparator =
3618         new Comparator() {
3619           @Override
3620           public int compare(Object left, Object right) {
3621             return String.valueOf(left).compareTo(String.valueOf(right));
3622           }
3623         };
3624 
3625     AutoValueTest.DataWithSortedCollectionBuilders.Builder<String, Integer> builder =
3626         AutoValueTest.DataWithSortedCollectionBuilders.builder();
3627 
3628     builder
3629         .anImmutableSortedMapBuilder(stringComparator)
3630         .put("Charlie", 1)
3631         .put("Alfa", 2)
3632         .put("Bravo", 3);
3633     builder.anImmutableSortedSetBuilder(intComparator).add(1, 5, 9, 3);
3634     builder.nonGenericImmutableSortedMapBuilder(intComparator).put(9, 99).put(1, 11).put(3, 33);
3635     builder.rawImmutableSortedSetBuilder(comparator).add("Bravo", "Charlie", "Alfa");
3636 
3637     AutoValueTest.DataWithSortedCollectionBuilders<String, Integer> data = builder.build();
3638 
3639     AutoValueTest.DataWithSortedCollectionBuilders.Builder<String, Integer> copiedBuilder =
3640         data.toBuilder();
3641     AutoValueTest.DataWithSortedCollectionBuilders<String, Integer> copiedData =
3642         copiedBuilder.build();
3643 
3644     assertThat(data.anImmutableSortedMap().keySet())
3645         .containsExactly("Alfa", "Bravo", "Charlie")
3646         .inOrder();
3647     assertThat(data.anImmutableSortedSet()).containsExactly(1, 3, 5, 9).inOrder();
3648     assertThat(data.nonGenericImmutableSortedMap().keySet()).containsExactly(1, 3, 9).inOrder();
3649     assertThat(data.rawImmutableSortedSet()).containsExactly("Alfa", "Bravo", "Charlie").inOrder();
3650 
3651     assertThat(copiedData).isEqualTo(data);
3652 
3653     try {
3654       builder.anImmutableSortedMapBuilder(Ordering.from(stringComparator).reverse());
3655       fail("Calling property builder method a second time should have failed");
3656     } catch (IllegalStateException expected) {
3657     }
3658   }
3659 
3660   @AutoValue
3661   public abstract static class Stepped {
one()3662     public abstract String one();
3663 
two()3664     public abstract int two();
3665 
three()3666     public abstract double three();
3667 
3668     public interface StepOne<T> {
setOne(T x)3669       StepTwo setOne(T x);
3670     }
3671 
3672     public interface StepTwo {
setTwo(int x)3673       StepThree setTwo(int x);
3674     }
3675 
3676     public interface StepThree {
setThreeAndBuild(double x)3677       Stepped setThreeAndBuild(double x);
3678     }
3679 
builder()3680     public static StepOne<String> builder() {
3681       return new AutoValue_AutoValueTest_Stepped.Builder();
3682     }
3683 
3684     @AutoValue.Builder
3685     abstract static class Builder implements StepOne<String>, StepTwo, StepThree {
setThree(double x)3686       abstract Builder setThree(double x);
build()3687       abstract Stepped build();
3688 
3689       @Override
setThreeAndBuild(double x)3690       public Stepped setThreeAndBuild(double x) {
3691         return setThree(x).build();
3692       }
3693     }
3694   }
3695 
3696   @Test
stepBuilder()3697   public void stepBuilder() {
3698     Stepped stepped = Stepped.builder().setOne("one").setTwo(2).setThreeAndBuild(3.0);
3699     assertThat(stepped.one()).isEqualTo("one");
3700     assertThat(stepped.two()).isEqualTo(2);
3701     assertThat(stepped.three()).isEqualTo(3.0);
3702   }
3703 
3704   // The code for tracking unset properties with bitmasks is fairly tricky. When there are many
3705   // properties, we use as many ints as needed to track which properties are still unset, with
3706   // 32 properties being tracked per int. So here we test @AutoValue classes with 31, 32, and 33
3707   // required properties, to catch problems at these edge values that we wouldn't see in our smaller
3708   // test classes.
3709   abstract static class Giant {
x1()3710     abstract int x1();
x2()3711     abstract int x2();
x3()3712     abstract int x3();
x4()3713     abstract int x4();
x5()3714     abstract int x5();
x6()3715     abstract int x6();
x7()3716     abstract int x7();
x8()3717     abstract int x8();
x9()3718     abstract int x9();
x10()3719     abstract int x10();
x11()3720     abstract int x11();
x12()3721     abstract int x12();
x13()3722     abstract int x13();
x14()3723     abstract int x14();
x15()3724     abstract int x15();
x16()3725     abstract int x16();
x17()3726     abstract int x17();
x18()3727     abstract int x18();
x19()3728     abstract int x19();
x20()3729     abstract int x20();
x21()3730     abstract int x21();
x22()3731     abstract int x22();
x23()3732     abstract int x23();
x24()3733     abstract int x24();
x25()3734     abstract int x25();
x26()3735     abstract int x26();
x27()3736     abstract int x27();
x28()3737     abstract int x28();
x29()3738     abstract int x29();
x30()3739     abstract int x30();
x31()3740     abstract int x31();
3741 
3742     abstract static class Builder {
x1(int x)3743       abstract Builder x1(int x);
x2(int x)3744       abstract Builder x2(int x);
x3(int x)3745       abstract Builder x3(int x);
x4(int x)3746       abstract Builder x4(int x);
x5(int x)3747       abstract Builder x5(int x);
x6(int x)3748       abstract Builder x6(int x);
x7(int x)3749       abstract Builder x7(int x);
x8(int x)3750       abstract Builder x8(int x);
x9(int x)3751       abstract Builder x9(int x);
x10(int x)3752       abstract Builder x10(int x);
x11(int x)3753       abstract Builder x11(int x);
x12(int x)3754       abstract Builder x12(int x);
x13(int x)3755       abstract Builder x13(int x);
x14(int x)3756       abstract Builder x14(int x);
x15(int x)3757       abstract Builder x15(int x);
x16(int x)3758       abstract Builder x16(int x);
x17(int x)3759       abstract Builder x17(int x);
x18(int x)3760       abstract Builder x18(int x);
x19(int x)3761       abstract Builder x19(int x);
x20(int x)3762       abstract Builder x20(int x);
x21(int x)3763       abstract Builder x21(int x);
x22(int x)3764       abstract Builder x22(int x);
x23(int x)3765       abstract Builder x23(int x);
x24(int x)3766       abstract Builder x24(int x);
x25(int x)3767       abstract Builder x25(int x);
x26(int x)3768       abstract Builder x26(int x);
x27(int x)3769       abstract Builder x27(int x);
x28(int x)3770       abstract Builder x28(int x);
x29(int x)3771       abstract Builder x29(int x);
x30(int x)3772       abstract Builder x30(int x);
x31(int x)3773       abstract Builder x31(int x);
3774 
setFirst30()3775       Builder setFirst30() {
3776         return this.x1(1)
3777             .x2(2)
3778             .x3(3)
3779             .x4(4)
3780             .x5(5)
3781             .x6(6)
3782             .x7(7)
3783             .x8(8)
3784             .x9(9)
3785             .x10(10)
3786             .x11(11)
3787             .x12(12)
3788             .x13(13)
3789             .x14(14)
3790             .x15(15)
3791             .x16(16)
3792             .x17(17)
3793             .x18(18)
3794             .x19(19)
3795             .x20(20)
3796             .x21(21)
3797             .x22(22)
3798             .x23(23)
3799             .x24(24)
3800             .x25(25)
3801             .x26(26)
3802             .x27(27)
3803             .x28(28)
3804             .x29(29)
3805             .x30(30);
3806       }
3807     }
3808   }
3809 
3810   @AutoValue
3811   abstract static class Giant31 extends Giant {
builder()3812     static Builder builder() {
3813       return new AutoValue_AutoValueTest_Giant31.Builder();
3814     }
3815 
3816     @AutoValue.Builder
3817     abstract static class Builder extends Giant.Builder {
build()3818       abstract Giant31 build();
3819     }
3820   }
3821 
3822   @AutoValue
3823   abstract static class Giant32 extends Giant {
x32()3824     abstract int x32();
3825 
builder()3826     static Builder builder() {
3827       return new AutoValue_AutoValueTest_Giant32.Builder();
3828     }
3829 
3830     @AutoValue.Builder
3831     abstract static class Builder extends Giant.Builder {
x32(int x)3832       abstract Builder x32(int x);
build()3833       abstract Giant32 build();
3834     }
3835   }
3836 
3837   @AutoValue
3838   abstract static class Giant33 extends Giant {
x32()3839     abstract int x32();
x33()3840     abstract int x33();
3841 
builder()3842     static Builder builder() {
3843       return new AutoValue_AutoValueTest_Giant33.Builder();
3844     }
3845 
3846     @AutoValue.Builder
3847     abstract static class Builder extends Giant.Builder {
x32(int x)3848       abstract Builder x32(int x);
x33(int x)3849       abstract Builder x33(int x);
build()3850       abstract Giant33 build();
3851     }
3852   }
3853 
3854   @Test
testGiant31()3855   public void testGiant31() {
3856     Giant31.Builder builder = Giant31.builder();
3857     builder.setFirst30();
3858     builder.x31(31);
3859     Giant31 giant = builder.build();
3860     assertThat(giant.x1()).isEqualTo(1);
3861     assertThat(giant.x31()).isEqualTo(31);
3862 
3863     builder = Giant31.builder();
3864     builder.setFirst30();
3865     try {
3866       builder.build();
3867       fail();
3868     } catch (IllegalStateException expected) {
3869       if (omitIdentifiers) {
3870         assertThat(expected).hasMessageThat().isNull();
3871       } else {
3872         assertThat(expected).hasMessageThat().contains("x31");
3873         assertThat(expected).hasMessageThat().doesNotContain("x30");
3874       }
3875     }
3876   }
3877 
3878   @Test
testGiant32()3879   public void testGiant32() {
3880     Giant32.Builder builder = Giant32.builder();
3881     builder.setFirst30();
3882     builder.x31(31);
3883     builder.x32(32);
3884     Giant32 giant = builder.build();
3885     assertThat(giant.x1()).isEqualTo(1);
3886     assertThat(giant.x31()).isEqualTo(31);
3887 
3888     builder = Giant32.builder();
3889     builder.setFirst30();
3890     try {
3891       builder.build();
3892       fail();
3893     } catch (IllegalStateException expected) {
3894       if (omitIdentifiers) {
3895         assertThat(expected).hasMessageThat().isNull();
3896       } else {
3897         assertThat(expected).hasMessageThat().contains("x31");
3898         assertThat(expected).hasMessageThat().contains("x32");
3899         assertThat(expected).hasMessageThat().doesNotContain("x30");
3900       }
3901     }
3902   }
3903 
3904   @Test
testGiant33()3905   public void testGiant33() {
3906     Giant33.Builder builder = Giant33.builder();
3907     builder.setFirst30();
3908     builder.x31(31);
3909     builder.x32(32);
3910     builder.x33(33);
3911     Giant33 giant = builder.build();
3912     assertThat(giant.x1()).isEqualTo(1);
3913     assertThat(giant.x31()).isEqualTo(31);
3914     assertThat(giant.x32()).isEqualTo(32);
3915     assertThat(giant.x33()).isEqualTo(33);
3916 
3917     builder = Giant33.builder();
3918     builder.setFirst30();
3919     try {
3920       builder.build();
3921       fail();
3922     } catch (IllegalStateException expected) {
3923       if (omitIdentifiers) {
3924         assertThat(expected).hasMessageThat().isNull();
3925       } else {
3926         assertThat(expected).hasMessageThat().contains("x31");
3927         assertThat(expected).hasMessageThat().contains("x32");
3928         assertThat(expected).hasMessageThat().contains("x33");
3929         assertThat(expected).hasMessageThat().doesNotContain("x30");
3930       }
3931     }
3932   }
3933 }
3934