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