View Javadoc
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 com.google.common.truth.Truth.assertThat;
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       assertThat(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       assertThat(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       assertThat(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       assertThat(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 }