Home | History | Annotate | Download | only in testing
      1 /*
      2  * Copyright (C) 2012 The Guava Authors
      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 
     17 package com.google.common.testing;
     18 
     19 import static com.google.common.base.Preconditions.checkNotNull;
     20 import static org.truth0.Truth.ASSERT;
     21 
     22 import com.google.common.base.Functions;
     23 import com.google.common.base.Optional;
     24 import com.google.common.collect.ImmutableList;
     25 import com.google.common.testing.ClassSanityTester.FactoryMethodReturnsNullException;
     26 import com.google.common.testing.ClassSanityTester.ParameterHasNoDistinctValueException;
     27 import com.google.common.testing.ClassSanityTester.ParameterNotInstantiableException;
     28 import com.google.common.testing.NullPointerTester.Visibility;
     29 
     30 import junit.framework.AssertionFailedError;
     31 import junit.framework.TestCase;
     32 
     33 import java.io.Serializable;
     34 import java.lang.reflect.InvocationTargetException;
     35 import java.util.AbstractList;
     36 import java.util.ArrayList;
     37 import java.util.List;
     38 import java.util.Set;
     39 import java.util.concurrent.TimeUnit;
     40 
     41 import javax.annotation.Nullable;
     42 
     43 /**
     44  * Unit tests for {@link ClassSanityTester}.
     45  *
     46  * @author Ben Yu
     47  */
     48 public class ClassSanityTesterTest extends TestCase {
     49 
     50   private final ClassSanityTester tester = new ClassSanityTester();
     51 
     52   public void testEqualsOnReturnValues_good() throws Exception {
     53     tester.forAllPublicStaticMethods(GoodEqualsFactory.class).testEquals();
     54   }
     55 
     56   public static class GoodEqualsFactory {
     57     public static Object good(String a, int b,
     58         // oneConstantOnly doesn't matter since it's not nullable and can be only 1 value.
     59         @SuppressWarnings("unused") OneConstantEnum oneConstantOnly,
     60         // noConstant doesn't matter since it can only be null
     61         @SuppressWarnings("unused") @Nullable NoConstantEnum noConstant) {
     62       return new GoodEquals(a, b);
     63     }
     64     // instance method ignored
     65     public Object badIgnored() {
     66       return new BadEquals();
     67     }
     68     // primitive ignored
     69     public int returnsInt() {
     70       throw new UnsupportedOperationException();
     71     }
     72     // void ignored
     73     public void voidMethod() {
     74       throw new UnsupportedOperationException();
     75     }
     76     // non-public method ignored
     77     static Object badButNotPublic() {
     78       return new BadEquals();
     79     }
     80   }
     81 
     82   public void testForAllPublicStaticMethods_noPublicStaticMethods() throws Exception {
     83     try {
     84       tester.forAllPublicStaticMethods(NoPublicStaticMethods.class).testEquals();
     85     } catch (AssertionFailedError expected) {
     86       assertEquals(
     87           "No public static methods that return java.lang.Object or subtype are found in "
     88               + NoPublicStaticMethods.class + ".",
     89           expected.getMessage());
     90       return;
     91     }
     92     fail();
     93   }
     94 
     95   public void testEqualsOnReturnValues_bad() throws Exception {
     96     try {
     97       tester.forAllPublicStaticMethods(BadEqualsFactory.class).testEquals();
     98     } catch (AssertionFailedError expected) {
     99       return;
    100     }
    101     fail();
    102   }
    103 
    104   private static class BadEqualsFactory {
    105     /** oneConstantOnly matters now since it can be either null or the constant. */
    106     @SuppressWarnings("unused") // Called by reflection
    107     public static Object bad(String a, int b,
    108         @Nullable OneConstantEnum oneConstantOnly) {
    109       return new GoodEquals(a, b);
    110     }
    111   }
    112 
    113   public void testNullsOnReturnValues_good() throws Exception {
    114     tester.forAllPublicStaticMethods(GoodNullsFactory.class).testNulls();
    115   }
    116 
    117   private static class GoodNullsFactory {
    118     @SuppressWarnings("unused") // Called by reflection
    119     public static Object good(String s) {
    120       return new GoodNulls(s);
    121     }
    122   }
    123 
    124   public void testNullsOnReturnValues_bad() throws Exception {
    125     try {
    126       tester
    127           .forAllPublicStaticMethods(BadNullsFactory.class)
    128           .thatReturn(Object.class)
    129           .testNulls();
    130     } catch (AssertionFailedError expected) {
    131       return;
    132     }
    133     fail();
    134   }
    135 
    136   public void testNullsOnReturnValues_returnTypeFiltered() throws Exception {
    137     try {
    138       tester
    139           .forAllPublicStaticMethods(BadNullsFactory.class)
    140           .thatReturn(Iterable.class)
    141           .testNulls();
    142     } catch (AssertionFailedError expected) {
    143       assertEquals(
    144           "No public static methods that return java.lang.Iterable or subtype are found in "
    145               + BadNullsFactory.class + ".",
    146           expected.getMessage());
    147       return;
    148     }
    149     fail();
    150   }
    151 
    152   public static class BadNullsFactory {
    153     public static Object bad(@SuppressWarnings("unused") String a) {
    154       return new BadNulls();
    155     }
    156   }
    157 
    158   public void testSerializableOnReturnValues_good() throws Exception {
    159     tester.forAllPublicStaticMethods(GoodSerializableFactory.class).testSerializable();
    160   }
    161 
    162   public static class GoodSerializableFactory {
    163     public static Object good(Runnable r) {
    164       return r;
    165     }
    166     public static Object good(AnInterface i) {
    167       return i;
    168     }
    169   }
    170 
    171   public void testSerializableOnReturnValues_bad() throws Exception {
    172     try {
    173       tester.forAllPublicStaticMethods(BadSerializableFactory.class).testSerializable();
    174     } catch (AssertionError expected) {
    175       return;
    176     }
    177     fail();
    178   }
    179 
    180   public static class BadSerializableFactory {
    181     public static Object bad() {
    182       return new Serializable() {
    183         @SuppressWarnings("unused")
    184         private final Object notSerializable = new Object();
    185       };
    186     }
    187   }
    188 
    189   public void testEqualsAndSerializableOnReturnValues_equalsIsGoodButNotSerializable()
    190       throws Exception {
    191     try {
    192       tester.forAllPublicStaticMethods(GoodEqualsFactory.class).testEqualsAndSerializable();
    193     } catch (AssertionError expected) {
    194       return;
    195     }
    196     fail("should have failed");
    197   }
    198 
    199   public void testEqualsAndSerializableOnReturnValues_serializableButNotEquals()
    200       throws Exception {
    201     try {
    202       tester.forAllPublicStaticMethods(GoodSerializableFactory.class).testEqualsAndSerializable();
    203     } catch (AssertionFailedError expected) {
    204       return;
    205     }
    206     fail("should have failed");
    207   }
    208 
    209   public void testEqualsAndSerializableOnReturnValues_good()
    210       throws Exception {
    211     tester.forAllPublicStaticMethods(GoodEqualsAndSerialiableFactory.class)
    212         .testEqualsAndSerializable();
    213   }
    214 
    215   public static class GoodEqualsAndSerialiableFactory {
    216     public static Object good(AnInterface s) {
    217       return Functions.constant(s);
    218     }
    219   }
    220 
    221   public void testEqualsForReturnValues_factoryReturnsNullButNotAnnotated() throws Exception {
    222     try {
    223       tester.forAllPublicStaticMethods(FactoryThatReturnsNullButNotAnnotated.class)
    224           .testEquals();
    225     } catch (AssertionFailedError expected) {
    226       return;
    227     }
    228     fail();
    229   }
    230 
    231   public void testNullsForReturnValues_factoryReturnsNullButNotAnnotated() throws Exception {
    232     try {
    233       tester.forAllPublicStaticMethods(FactoryThatReturnsNullButNotAnnotated.class)
    234           .testNulls();
    235     } catch (AssertionFailedError expected) {
    236       return;
    237     }
    238     fail();
    239   }
    240 
    241   public void testSerializableForReturnValues_factoryReturnsNullButNotAnnotated() throws Exception {
    242     try {
    243       tester.forAllPublicStaticMethods(FactoryThatReturnsNullButNotAnnotated.class)
    244           .testSerializable();
    245     } catch (AssertionFailedError expected) {
    246       return;
    247     }
    248     fail();
    249   }
    250 
    251   public void testEqualsAndSerializableForReturnValues_factoryReturnsNullButNotAnnotated()
    252       throws Exception {
    253     try {
    254       tester.forAllPublicStaticMethods(FactoryThatReturnsNullButNotAnnotated.class)
    255           .testEqualsAndSerializable();
    256     } catch (AssertionFailedError expected) {
    257       return;
    258     }
    259     fail();
    260   }
    261 
    262   public static class FactoryThatReturnsNullButNotAnnotated {
    263     public static Object bad() {
    264       return null;
    265     }
    266   }
    267 
    268   public void testEqualsForReturnValues_factoryReturnsNullAndAnnotated() throws Exception {
    269     tester.forAllPublicStaticMethods(FactoryThatReturnsNullAndAnnotated.class)
    270         .testEquals();
    271   }
    272 
    273   public void testNullsForReturnValues_factoryReturnsNullAndAnnotated() throws Exception {
    274     tester.forAllPublicStaticMethods(FactoryThatReturnsNullAndAnnotated.class)
    275         .testNulls();
    276   }
    277 
    278   public void testSerializableForReturnValues_factoryReturnsNullAndAnnotated() throws Exception {
    279     tester.forAllPublicStaticMethods(FactoryThatReturnsNullAndAnnotated.class)
    280         .testSerializable();
    281   }
    282 
    283   public void testEqualsAndSerializableForReturnValues_factoryReturnsNullAndAnnotated()
    284       throws Exception {
    285     tester.forAllPublicStaticMethods(FactoryThatReturnsNullAndAnnotated.class)
    286         .testEqualsAndSerializable();
    287   }
    288 
    289   public static class FactoryThatReturnsNullAndAnnotated {
    290     @Nullable public static Object bad() {
    291       return null;
    292     }
    293   }
    294 
    295   public void testGoodEquals() throws Exception {
    296     tester.testEquals(GoodEquals.class);
    297   }
    298 
    299   public void testEquals_interface() {
    300     tester.testEquals(AnInterface.class);
    301   }
    302 
    303   public void testEquals_abstractClass() {
    304     tester.testEquals(AnAbstractClass.class);
    305   }
    306 
    307   public void testEquals_enum() {
    308     tester.testEquals(OneConstantEnum.class);
    309   }
    310 
    311   public void testBadEquals() throws Exception {
    312     try {
    313       tester.testEquals(BadEquals.class);
    314     } catch (AssertionFailedError expected) {
    315       ASSERT.that(expected.getMessage()).contains("create(null)");
    316       return;
    317     }
    318     fail("should have failed");
    319   }
    320 
    321   public void testBadEquals_withParameterizedType() throws Exception {
    322     try {
    323       tester.testEquals(BadEqualsWithParameterizedType.class);
    324     } catch (AssertionFailedError expected) {
    325       ASSERT.that(expected.getMessage()).contains("create([[1]])");
    326       return;
    327     }
    328     fail("should have failed");
    329   }
    330 
    331   public void testBadEquals_withSingleParameterValue() throws Exception {
    332     try {
    333       tester.doTestEquals(ConstructorParameterWithOptionalNotInstantiable.class);
    334       fail();
    335     } catch (ParameterHasNoDistinctValueException expected) {}
    336   }
    337 
    338   public void testGoodReferentialEqualityComparison() throws Exception {
    339     tester.testEquals(UsesEnum.class);
    340     tester.testEquals(UsesReferentialEquality.class);
    341     tester.testEquals(SameListInstance.class);
    342   }
    343 
    344   public void testEqualsUsingReferentialEquality() throws Exception {
    345     assertBadUseOfReferentialEquality(SameIntegerInstance.class);
    346     assertBadUseOfReferentialEquality(SameLongInstance.class);
    347     assertBadUseOfReferentialEquality(SameFloatInstance.class);
    348     assertBadUseOfReferentialEquality(SameDoubleInstance.class);
    349     assertBadUseOfReferentialEquality(SameShortInstance.class);
    350     assertBadUseOfReferentialEquality(SameByteInstance.class);
    351     assertBadUseOfReferentialEquality(SameCharacterInstance.class);
    352     assertBadUseOfReferentialEquality(SameBooleanInstance.class);
    353     assertBadUseOfReferentialEquality(SameObjectInstance.class);
    354     assertBadUseOfReferentialEquality(SameStringInstance.class);
    355     assertBadUseOfReferentialEquality(SameInterfaceInstance.class);
    356   }
    357 
    358   private void assertBadUseOfReferentialEquality(Class<?> cls) throws Exception {
    359     try {
    360       tester.testEquals(cls);
    361     } catch (AssertionFailedError expected) {
    362       ASSERT.that(expected.getMessage()).contains(cls.getSimpleName() + "(");
    363       return;
    364     }
    365     fail("should have failed");
    366   }
    367 
    368   public void testParameterNotInstantiableForEqualsTest() throws Exception {
    369     try {
    370       tester.doTestEquals(ConstructorParameterNotInstantiable.class);
    371       fail("should have failed");
    372     } catch (ParameterNotInstantiableException expected) {}
    373   }
    374 
    375   public void testNoDistinctValueForEqualsTest() throws Exception {
    376     try {
    377       tester.doTestEquals(ConstructorParameterSingleValue.class);
    378       fail("should have failed");
    379     } catch (ParameterHasNoDistinctValueException expected) {}
    380   }
    381 
    382   public void testConstructorThrowsForEqualsTest() throws Exception {
    383     try {
    384       tester.doTestEquals(ConstructorThrows.class);
    385       fail("should have failed");
    386     } catch (InvocationTargetException expected) {}
    387   }
    388 
    389   public void testFactoryMethodReturnsNullForEqualsTest() throws Exception {
    390     try {
    391       tester.doTestEquals(FactoryMethodReturnsNullAndAnnotated.class);
    392       fail("should have failed");
    393     } catch (FactoryMethodReturnsNullException expected) {}
    394   }
    395 
    396   public void testFactoryMethodReturnsNullButNotAnnotatedInEqualsTest() throws Exception {
    397     try {
    398       tester.testEquals(FactoryMethodReturnsNullButNotAnnotated.class);
    399     } catch (AssertionFailedError expected) {
    400       return;
    401     }
    402     fail("should have failed");
    403   }
    404 
    405   public void testNoEqualsChecksOnEnum() throws Exception {
    406     tester.testEquals(OneConstantEnum.class);
    407     tester.testEquals(NoConstantEnum.class);
    408     tester.testEquals(TimeUnit.class);
    409   }
    410 
    411   public void testNoEqualsChecksOnInterface() throws Exception {
    412     tester.testEquals(Runnable.class);
    413   }
    414 
    415   public void testNoEqualsChecksOnAnnotation() throws Exception {
    416     tester.testEquals(Nullable.class);
    417   }
    418 
    419   public void testGoodNulls() throws Exception {
    420     tester.testNulls(GoodNulls.class);
    421   }
    422 
    423   public void testNoNullCheckNeededDespitNotInstantiable() throws Exception {
    424     tester.doTestNulls(NoNullCheckNeededDespitNotInstantiable.class, Visibility.PACKAGE);
    425   }
    426 
    427   public void testNulls_interface() {
    428     tester.testNulls(AnInterface.class);
    429   }
    430 
    431   public void testNulls_abstractClass() {
    432     tester.testNulls(AnAbstractClass.class);
    433   }
    434 
    435   public void testNulls_enum() throws Exception {
    436     tester.testNulls(OneConstantEnum.class);
    437     tester.testNulls(NoConstantEnum.class);
    438     tester.testNulls(TimeUnit.class);
    439   }
    440 
    441   public void testNulls_parameterOptionalNotInstantiable() throws Exception {
    442     tester.testNulls(ConstructorParameterWithOptionalNotInstantiable.class);
    443   }
    444 
    445   public void testEnumFailsToCheckNull() throws Exception {
    446     try {
    447       tester.testNulls(EnumFailsToCheckNull.class);
    448     } catch (AssertionFailedError expected) {
    449       return;
    450     }
    451     fail("should have failed");
    452   }
    453 
    454   public void testNoNullChecksOnInterface() throws Exception {
    455     tester.testNulls(Runnable.class);
    456   }
    457 
    458   public void testNoNullChecksOnAnnotation() throws Exception {
    459     tester.testNulls(Nullable.class);
    460   }
    461 
    462   public void testBadNulls() throws Exception {
    463     try {
    464       tester.testNulls(BadNulls.class);
    465     } catch (AssertionFailedError expected) {
    466       return;
    467     }
    468     fail("should have failed");
    469   }
    470 
    471   public void testInstantiate_factoryMethodReturnsNullButNotAnnotated() throws Exception {
    472     try {
    473       tester.instantiate(FactoryMethodReturnsNullButNotAnnotated.class);
    474     } catch (AssertionFailedError expected) {
    475       ASSERT.that(expected.getMessage()).contains("@Nullable");
    476       return;
    477     }
    478     fail("should have failed");
    479   }
    480 
    481   public void testInstantiate_factoryMethodReturnsNullAndAnnotated() throws Exception {
    482     try {
    483       tester.instantiate(FactoryMethodReturnsNullAndAnnotated.class);
    484       fail("should have failed");
    485     } catch (FactoryMethodReturnsNullException expected) {}
    486   }
    487 
    488   public void testInstantiate_factoryMethodAcceptsNull() throws Exception {
    489     assertNull(tester.instantiate(FactoryMethodAcceptsNull.class).name);
    490   }
    491 
    492   public void testInstantiate_factoryMethodDoesNotAcceptNull() throws Exception {
    493     assertNotNull(tester.instantiate(FactoryMethodDoesNotAcceptNull.class).name);
    494   }
    495 
    496   public void testInstantiate_constructorAcceptsNull() throws Exception {
    497     assertNull(tester.instantiate(ConstructorAcceptsNull.class).name);
    498   }
    499 
    500   public void testInstantiate_constructorDoesNotAcceptNull() throws Exception {
    501     assertNotNull(tester.instantiate(ConstructorDoesNotAcceptNull.class).name);
    502   }
    503 
    504   public void testInstantiate_notInstantiable() throws Exception {
    505     assertNull(tester.instantiate(NotInstantiable.class));
    506   }
    507 
    508   public void testInstantiate_noConstantEnum() throws Exception {
    509     assertNull(tester.instantiate(NoConstantEnum.class));
    510   }
    511 
    512   public void testInstantiate_oneConstantEnum() throws Exception {
    513     assertEquals(OneConstantEnum.A, tester.instantiate(OneConstantEnum.class));
    514   }
    515 
    516   public void testInstantiate_interface() throws Exception {
    517     assertNull(tester.instantiate(Runnable.class));
    518   }
    519 
    520   public void testInstantiate_abstractClass() throws Exception {
    521     assertNull(tester.instantiate(AbstractList.class));
    522   }
    523 
    524   public void testInstantiate_annotation() throws Exception {
    525     assertNull(tester.instantiate(Nullable.class));
    526   }
    527 
    528   public void testInstantiate_setDefault() throws Exception {
    529     NotInstantiable x = new NotInstantiable();
    530     tester.setDefault(NotInstantiable.class, x);
    531     assertNotNull(tester.instantiate(ConstructorParameterNotInstantiable.class));
    532   }
    533 
    534   public void testSetDistinctValues_equalInstances() {
    535     try {
    536       tester.setDistinctValues(String.class, "", "");
    537       fail();
    538     } catch (IllegalArgumentException expected) {}
    539   }
    540 
    541   public void testInstantiate_setDistinctValues() throws Exception {
    542     NotInstantiable x = new NotInstantiable();
    543     NotInstantiable y = new NotInstantiable();
    544     tester.setDistinctValues(NotInstantiable.class, x, y);
    545     assertNotNull(tester.instantiate(ConstructorParameterNotInstantiable.class));
    546   }
    547 
    548   public void testInstantiate_setSampleInstances_empty() throws Exception {
    549     tester.setSampleInstances(NotInstantiable.class, ImmutableList.<NotInstantiable>of());
    550     try {
    551       tester.instantiate(ConstructorParameterNotInstantiable.class);
    552       fail();
    553     } catch (ParameterNotInstantiableException expected) {}
    554   }
    555 
    556   public void testInstantiate_constructorThrows() throws Exception {
    557     try {
    558       tester.instantiate(ConstructorThrows.class);
    559       fail();
    560     } catch (InvocationTargetException expected) {}
    561   }
    562 
    563   public void testInstantiate_factoryMethodThrows() throws Exception {
    564     try {
    565       tester.instantiate(FactoryMethodThrows.class);
    566       fail();
    567     } catch (InvocationTargetException expected) {}
    568   }
    569 
    570   public void testInstantiate_constructorParameterNotInstantiable() throws Exception {
    571     try {
    572       tester.instantiate(ConstructorParameterNotInstantiable.class);
    573       fail();
    574     } catch (ParameterNotInstantiableException expected) {}
    575   }
    576 
    577   public void testInstantiate_factoryMethodParameterNotInstantiable() throws Exception {
    578     try {
    579       tester.instantiate(FactoryMethodParameterNotInstantiable.class);
    580       fail();
    581     } catch (ParameterNotInstantiableException expected) {}
    582   }
    583 
    584   public void testInstantiate_instantiableFactoryMethodChosen() throws Exception {
    585     assertEquals("good", tester.instantiate(InstantiableFactoryMethodChosen.class).name);
    586   }
    587 
    588   public void testInterfaceProxySerializable() throws Exception {
    589     SerializableTester.reserializeAndAssert(tester.instantiate(HasAnInterface.class));
    590   }
    591 
    592   public void testReturnValuesFromAnotherPackageIgnoredForNullTests() throws Exception {
    593     new ClassSanityTester().forAllPublicStaticMethods(JdkObjectFactory.class).testNulls();
    594   }
    595 
    596   /** String doesn't check nulls as we expect. But the framework should ignore. */
    597   private static class JdkObjectFactory {
    598     @SuppressWarnings("unused") // Called by reflection
    599     public static Object create() {
    600       return new ArrayList<String>();
    601     }
    602   }
    603 
    604   static class HasAnInterface implements Serializable {
    605     private final AnInterface i;
    606 
    607     public HasAnInterface(AnInterface i) {
    608       this.i = i;
    609     }
    610 
    611     @Override public boolean equals(@Nullable Object obj) {
    612       if (obj instanceof HasAnInterface) {
    613         HasAnInterface that = (HasAnInterface) obj;
    614         return i.equals(that.i);
    615       } else {
    616         return false;
    617       }
    618     }
    619 
    620     @Override public int hashCode() {
    621       return i.hashCode();
    622     }
    623   }
    624 
    625   static class InstantiableFactoryMethodChosen {
    626     final String name;
    627 
    628     private InstantiableFactoryMethodChosen(String name) {
    629       this.name = name;
    630     }
    631 
    632     public InstantiableFactoryMethodChosen(NotInstantiable x) {
    633       checkNotNull(x);
    634       this.name = "x1";
    635     }
    636 
    637     public static InstantiableFactoryMethodChosen create(NotInstantiable x) {
    638       return new InstantiableFactoryMethodChosen(x);
    639     }
    640 
    641     public static InstantiableFactoryMethodChosen create(String s) {
    642       checkNotNull(s);
    643       return new InstantiableFactoryMethodChosen("good");
    644     }
    645   }
    646 
    647   public void testInstantiate_instantiableConstructorChosen() throws Exception {
    648     assertEquals("good", tester.instantiate(InstantiableConstructorChosen.class).name);
    649   }
    650 
    651   public void testEquals_setOfNonInstantiable() throws Exception {
    652     try {
    653       new ClassSanityTester().doTestEquals(SetWrapper.class);
    654       fail();
    655     } catch (ParameterNotInstantiableException expected) {}
    656   }
    657 
    658   private abstract static class Wrapper {
    659     private final Object wrapped;
    660 
    661     Wrapper(Object wrapped) {
    662       this.wrapped = checkNotNull(wrapped);
    663     }
    664 
    665     @Override public boolean equals(@Nullable Object obj) {
    666       // In general getClass().isInstance() is bad for equals.
    667       // But here we fully control the subclasses to ensure symmetry.
    668       if (getClass().isInstance(obj)) {
    669         Wrapper that = (Wrapper) obj;
    670         return wrapped.equals(that.wrapped);
    671       }
    672       return false;
    673     }
    674 
    675     @Override public int hashCode() {
    676       return wrapped.hashCode();
    677     }
    678 
    679     @Override public String toString() {
    680       return wrapped.toString();
    681     }
    682   }
    683 
    684   private static class SetWrapper extends Wrapper {
    685     public SetWrapper(Set<NotInstantiable> wrapped) {
    686       super(wrapped);
    687     }
    688   }
    689 
    690   static class InstantiableConstructorChosen {
    691     final String name;
    692 
    693     public InstantiableConstructorChosen(String name) {
    694       checkNotNull(name);
    695       this.name = "good";
    696     }
    697 
    698     public InstantiableConstructorChosen(NotInstantiable x) {
    699       checkNotNull(x);
    700       this.name = "x1";
    701     }
    702 
    703     public static InstantiableFactoryMethodChosen create(NotInstantiable x) {
    704       return new InstantiableFactoryMethodChosen(x);
    705     }
    706   }
    707 
    708   static class GoodEquals {
    709 
    710     private final String a;
    711     private final int b;
    712 
    713     private GoodEquals(String a, int b) {
    714       this.a = checkNotNull(a);
    715       this.b = b;
    716     }
    717 
    718     // ignored by testEquals()
    719     GoodEquals(@SuppressWarnings("unused") NotInstantiable x) {
    720       this.a = "x";
    721       this.b = -1;
    722     }
    723 
    724     // will keep trying
    725     public GoodEquals(@SuppressWarnings("unused") NotInstantiable x, int b) {
    726       this.a = "x";
    727       this.b = b;
    728     }
    729 
    730     // keep trying
    731     @SuppressWarnings("unused")
    732     static GoodEquals create(int a, int b) {
    733       throw new RuntimeException();
    734     }
    735 
    736     // keep trying
    737     @SuppressWarnings("unused")
    738     @Nullable public static GoodEquals createMayReturnNull(int a, int b) {
    739       return null;
    740     }
    741 
    742     // Good!
    743     static GoodEquals create(String a, int b) {
    744       return new GoodEquals(a, b);
    745     }
    746 
    747     @Override public boolean equals(@Nullable Object obj) {
    748       if (obj instanceof GoodEquals) {
    749         GoodEquals that = (GoodEquals) obj;
    750         return a.equals(that.a) && b == that.b;
    751       } else {
    752         return false;
    753       }
    754     }
    755 
    756     @Override public int hashCode() {
    757       return 0;
    758     }
    759   }
    760 
    761   static class BadEquals {
    762 
    763     public BadEquals() {} // ignored by testEquals() since it has less parameters.
    764 
    765     public static BadEquals create(@SuppressWarnings("unused") @Nullable String s) {
    766       return new BadEquals();
    767     }
    768 
    769     @Override public boolean equals(@Nullable Object obj) {
    770       return obj instanceof BadEquals;
    771     }
    772 
    773     @Override public int hashCode() {
    774       return 0;
    775     }
    776   }
    777 
    778   static class SameIntegerInstance {
    779     private final Integer i;
    780 
    781     public SameIntegerInstance(Integer i) {
    782       this.i = checkNotNull(i);
    783     }
    784 
    785     @Override public int hashCode() {
    786       return i.hashCode();
    787     }
    788 
    789     @Override
    790     @SuppressWarnings("NumericEquality")
    791     public boolean equals(Object obj) {
    792       if (obj instanceof SameIntegerInstance) {
    793         SameIntegerInstance that = (SameIntegerInstance) obj;
    794         return i == that.i;
    795       }
    796       return false;
    797     }
    798   }
    799 
    800   static class SameLongInstance {
    801     private final Long i;
    802 
    803     public SameLongInstance(Long i) {
    804       this.i = checkNotNull(i);
    805     }
    806 
    807     @Override public int hashCode() {
    808       return i.hashCode();
    809     }
    810 
    811     @Override
    812     @SuppressWarnings("NumericEquality")
    813     public boolean equals(Object obj) {
    814       if (obj instanceof SameLongInstance) {
    815         SameLongInstance that = (SameLongInstance) obj;
    816         return i == that.i;
    817       }
    818       return false;
    819     }
    820   }
    821 
    822   static class SameFloatInstance {
    823     private final Float i;
    824 
    825     public SameFloatInstance(Float i) {
    826       this.i = checkNotNull(i);
    827     }
    828 
    829     @Override public int hashCode() {
    830       return i.hashCode();
    831     }
    832 
    833     @Override
    834     @SuppressWarnings("NumericEquality")
    835     public boolean equals(Object obj) {
    836       if (obj instanceof SameFloatInstance) {
    837         SameFloatInstance that = (SameFloatInstance) obj;
    838         return i == that.i;
    839       }
    840       return false;
    841     }
    842   }
    843 
    844   static class SameDoubleInstance {
    845     private final Double i;
    846 
    847     public SameDoubleInstance(Double i) {
    848       this.i = checkNotNull(i);
    849     }
    850 
    851     @Override public int hashCode() {
    852       return i.hashCode();
    853     }
    854 
    855     @Override
    856     @SuppressWarnings("NumericEquality")
    857     public boolean equals(Object obj) {
    858       if (obj instanceof SameDoubleInstance) {
    859         SameDoubleInstance that = (SameDoubleInstance) obj;
    860         return i == that.i;
    861       }
    862       return false;
    863     }
    864   }
    865 
    866   static class SameShortInstance {
    867     private final Short i;
    868 
    869     public SameShortInstance(Short i) {
    870       this.i = checkNotNull(i);
    871     }
    872 
    873     @Override public int hashCode() {
    874       return i.hashCode();
    875     }
    876 
    877     @Override
    878     @SuppressWarnings("NumericEquality")
    879     public boolean equals(Object obj) {
    880       if (obj instanceof SameShortInstance) {
    881         SameShortInstance that = (SameShortInstance) obj;
    882         return i == that.i;
    883       }
    884       return false;
    885     }
    886   }
    887 
    888   static class SameByteInstance {
    889     private final Byte i;
    890 
    891     public SameByteInstance(Byte i) {
    892       this.i = checkNotNull(i);
    893     }
    894 
    895     @Override public int hashCode() {
    896       return i.hashCode();
    897     }
    898 
    899     @Override
    900     @SuppressWarnings("NumericEquality")
    901     public boolean equals(Object obj) {
    902       if (obj instanceof SameByteInstance) {
    903         SameByteInstance that = (SameByteInstance) obj;
    904         return i == that.i;
    905       }
    906       return false;
    907     }
    908   }
    909 
    910   static class SameCharacterInstance {
    911     private final Character i;
    912 
    913     public SameCharacterInstance(Character i) {
    914       this.i = checkNotNull(i);
    915     }
    916 
    917     @Override public int hashCode() {
    918       return i.hashCode();
    919     }
    920 
    921     @Override public boolean equals(Object obj) {
    922       if (obj instanceof SameCharacterInstance) {
    923         SameCharacterInstance that = (SameCharacterInstance) obj;
    924         return i == that.i;
    925       }
    926       return false;
    927     }
    928   }
    929 
    930   static class SameBooleanInstance {
    931     private final Boolean i;
    932 
    933     public SameBooleanInstance(Boolean i) {
    934       this.i = checkNotNull(i);
    935     }
    936 
    937     @Override public int hashCode() {
    938       return i.hashCode();
    939     }
    940 
    941     @Override public boolean equals(Object obj) {
    942       if (obj instanceof SameBooleanInstance) {
    943         SameBooleanInstance that = (SameBooleanInstance) obj;
    944         return i == that.i;
    945       }
    946       return false;
    947     }
    948   }
    949 
    950   static class SameStringInstance {
    951     private final String s;
    952 
    953     public SameStringInstance(String s) {
    954       this.s = checkNotNull(s);
    955     }
    956 
    957     @Override public int hashCode() {
    958       return s.hashCode();
    959     }
    960 
    961     @Override public boolean equals(Object obj) {
    962       if (obj instanceof SameStringInstance) {
    963         SameStringInstance that = (SameStringInstance) obj;
    964         return s == that.s;
    965       }
    966       return false;
    967     }
    968   }
    969 
    970   static class SameObjectInstance {
    971     private final Object s;
    972 
    973     public SameObjectInstance(Object s) {
    974       this.s = checkNotNull(s);
    975     }
    976 
    977     @Override public int hashCode() {
    978       return s.hashCode();
    979     }
    980 
    981     @Override public boolean equals(Object obj) {
    982       if (obj instanceof SameObjectInstance) {
    983         SameObjectInstance that = (SameObjectInstance) obj;
    984         return s == that.s;
    985       }
    986       return false;
    987     }
    988   }
    989 
    990   static class SameInterfaceInstance {
    991     private final Runnable s;
    992 
    993     public SameInterfaceInstance(Runnable s) {
    994       this.s = checkNotNull(s);
    995     }
    996 
    997     @Override public int hashCode() {
    998       return s.hashCode();
    999     }
   1000 
   1001     @Override public boolean equals(Object obj) {
   1002       if (obj instanceof SameInterfaceInstance) {
   1003         SameInterfaceInstance that = (SameInterfaceInstance) obj;
   1004         return s == that.s;
   1005       }
   1006       return false;
   1007     }
   1008   }
   1009 
   1010   static class SameListInstance {
   1011     private final List<?> s;
   1012 
   1013     public SameListInstance(List<?> s) {
   1014       this.s = checkNotNull(s);
   1015     }
   1016 
   1017     @Override public int hashCode() {
   1018       return System.identityHashCode(s);
   1019     }
   1020 
   1021     @Override public boolean equals(Object obj) {
   1022       if (obj instanceof SameListInstance) {
   1023         SameListInstance that = (SameListInstance) obj;
   1024         return s == that.s;
   1025       }
   1026       return false;
   1027     }
   1028   }
   1029 
   1030   static class UsesReferentialEquality {
   1031     private final ReferentialEquality s;
   1032 
   1033     public UsesReferentialEquality(ReferentialEquality s) {
   1034       this.s = checkNotNull(s);
   1035     }
   1036 
   1037     @Override public int hashCode() {
   1038       return s.hashCode();
   1039     }
   1040 
   1041     @Override public boolean equals(Object obj) {
   1042       if (obj instanceof UsesReferentialEquality) {
   1043         UsesReferentialEquality that = (UsesReferentialEquality) obj;
   1044         return s == that.s;
   1045       }
   1046       return false;
   1047     }
   1048   }
   1049 
   1050   static class UsesEnum {
   1051     private final TimeUnit s;
   1052 
   1053     public UsesEnum(TimeUnit s) {
   1054       this.s = checkNotNull(s);
   1055     }
   1056 
   1057     @Override public int hashCode() {
   1058       return s.hashCode();
   1059     }
   1060 
   1061     @Override public boolean equals(Object obj) {
   1062       if (obj instanceof UsesEnum) {
   1063         UsesEnum that = (UsesEnum) obj;
   1064         return s == that.s;
   1065       }
   1066       return false;
   1067     }
   1068   }
   1069 
   1070   public static class ReferentialEquality {
   1071     public ReferentialEquality() {}
   1072   }
   1073 
   1074   static class BadEqualsWithParameterizedType {
   1075 
   1076     // ignored by testEquals() since it has less parameters.
   1077     public BadEqualsWithParameterizedType() {}
   1078 
   1079     public static BadEqualsWithParameterizedType create(
   1080         @SuppressWarnings("unused") ImmutableList<Iterable<? extends String>> s) {
   1081       return new BadEqualsWithParameterizedType();
   1082     }
   1083 
   1084     @Override public boolean equals(@Nullable Object obj) {
   1085       return obj instanceof BadEqualsWithParameterizedType;
   1086     }
   1087 
   1088     @Override public int hashCode() {
   1089       return 0;
   1090     }
   1091   }
   1092 
   1093   static class GoodNulls {
   1094     public GoodNulls(String s) {
   1095       checkNotNull(s);
   1096     }
   1097 
   1098     public void rejectNull(String s) {
   1099       checkNotNull(s);
   1100     }
   1101   }
   1102 
   1103   public static class BadNulls {
   1104     public void failsToRejectNull(@SuppressWarnings("unused") String s) {}
   1105   }
   1106 
   1107   public static class NoNullCheckNeededDespitNotInstantiable {
   1108 
   1109     public NoNullCheckNeededDespitNotInstantiable(NotInstantiable x) {
   1110       checkNotNull(x);
   1111     }
   1112 
   1113     @SuppressWarnings("unused") // reflected
   1114     void primitiveOnly(int i) {}
   1115 
   1116     @SuppressWarnings("unused") //reflected
   1117     void nullableOnly(@Nullable String s) {}
   1118     public void noParameter() {}
   1119 
   1120     @SuppressWarnings("unused") //reflected
   1121     void primitiveAndNullable(@Nullable String s, int i) {}
   1122   }
   1123 
   1124   static class FactoryMethodReturnsNullButNotAnnotated {
   1125     private FactoryMethodReturnsNullButNotAnnotated() {}
   1126 
   1127     static FactoryMethodReturnsNullButNotAnnotated returnsNull() {
   1128       return null;
   1129     }
   1130   }
   1131 
   1132   static class FactoryMethodReturnsNullAndAnnotated {
   1133     private FactoryMethodReturnsNullAndAnnotated() {}
   1134 
   1135     @Nullable public static FactoryMethodReturnsNullAndAnnotated returnsNull() {
   1136       return null;
   1137     }
   1138   }
   1139 
   1140   static class FactoryMethodAcceptsNull {
   1141 
   1142     final String name;
   1143 
   1144     private FactoryMethodAcceptsNull(String name) {
   1145       this.name = name;
   1146     }
   1147 
   1148     static FactoryMethodAcceptsNull create(@Nullable String name) {
   1149       return new FactoryMethodAcceptsNull(name);
   1150     }
   1151   }
   1152 
   1153   static class FactoryMethodDoesNotAcceptNull {
   1154 
   1155     final String name;
   1156 
   1157     private FactoryMethodDoesNotAcceptNull(String name) {
   1158       this.name = checkNotNull(name);
   1159     }
   1160 
   1161     public static FactoryMethodDoesNotAcceptNull create(String name) {
   1162       return new FactoryMethodDoesNotAcceptNull(name);
   1163     }
   1164   }
   1165 
   1166   static class ConstructorAcceptsNull {
   1167 
   1168     final String name;
   1169 
   1170     public ConstructorAcceptsNull(@Nullable String name) {
   1171       this.name = name;
   1172     }
   1173   }
   1174 
   1175   static class ConstructorDoesNotAcceptNull {
   1176 
   1177     final String name;
   1178 
   1179     ConstructorDoesNotAcceptNull(String name) {
   1180       this.name = checkNotNull(name);
   1181     }
   1182   }
   1183 
   1184   static class ConstructorParameterNotInstantiable {
   1185     public ConstructorParameterNotInstantiable(@SuppressWarnings("unused") NotInstantiable x) {}
   1186   }
   1187 
   1188   // Test that we should get a distinct parameter error when doing equals test.
   1189   static class ConstructorParameterWithOptionalNotInstantiable {
   1190     public ConstructorParameterWithOptionalNotInstantiable(Optional<NotInstantiable> x) {
   1191       checkNotNull(x);
   1192     }
   1193     @Override public boolean equals(@Nullable Object obj) {
   1194       throw new UnsupportedOperationException();
   1195     }
   1196     @Override public int hashCode() {
   1197       throw new UnsupportedOperationException();
   1198     }
   1199   }
   1200 
   1201   static class ConstructorParameterSingleValue {
   1202     public ConstructorParameterSingleValue(@SuppressWarnings("unused") Singleton s) {}
   1203     @Override public boolean equals(Object obj) {
   1204       return obj instanceof ConstructorParameterSingleValue;
   1205     }
   1206     @Override public int hashCode() {
   1207       return 1;
   1208     }
   1209 
   1210     public static class Singleton {
   1211       public static final Singleton INSTANCE = new Singleton();
   1212       private Singleton() {}
   1213     }
   1214   }
   1215 
   1216   static class FactoryMethodParameterNotInstantiable {
   1217 
   1218     private FactoryMethodParameterNotInstantiable() {}
   1219 
   1220     static FactoryMethodParameterNotInstantiable create(
   1221         @SuppressWarnings("unused") NotInstantiable x) {
   1222       return new FactoryMethodParameterNotInstantiable();
   1223     }
   1224   }
   1225 
   1226   static class ConstructorThrows {
   1227     public ConstructorThrows() {
   1228       throw new RuntimeException();
   1229     }
   1230   }
   1231 
   1232   static class FactoryMethodThrows {
   1233     private FactoryMethodThrows() {}
   1234 
   1235     public static FactoryMethodThrows create() {
   1236       throw new RuntimeException();
   1237     }
   1238   }
   1239 
   1240   static class NotInstantiable {
   1241     private NotInstantiable() {}
   1242   }
   1243 
   1244   private enum NoConstantEnum {}
   1245 
   1246   private enum OneConstantEnum {
   1247     A
   1248   }
   1249 
   1250   private enum EnumFailsToCheckNull {
   1251     A;
   1252 
   1253     @SuppressWarnings("unused")
   1254     public void failToCheckNull(String s) {}
   1255   }
   1256 
   1257   private interface AnInterface {}
   1258 
   1259   private static abstract class AnAbstractClass {
   1260     @SuppressWarnings("unused")
   1261     public AnAbstractClass(String s) {}
   1262 
   1263     @SuppressWarnings("unused")
   1264     public void failsToCheckNull(String s) {}
   1265   }
   1266 
   1267   private static class NoPublicStaticMethods {
   1268     @SuppressWarnings("unused") // To test non-public factory isn't used.
   1269     static String notPublic() {
   1270       return "";
   1271     }
   1272   }
   1273 }
   1274