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