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