17
package com.google.common.testing;
19
import static com.google.common.base.Preconditions.checkArgument;
20
import static com.google.common.base.Preconditions.checkNotNull;
21
import static com.google.common.truth.Truth.assertThat;
22
import static org.junit.Assert.assertThrows;
24
import com.google.common.base.Converter;
25
import com.google.common.base.Function;
26
import com.google.common.base.Supplier;
27
import com.google.common.collect.ImmutableList;
28
import com.google.common.collect.ImmutableMap;
29
import com.google.common.collect.ImmutableMultimap;
30
import com.google.common.collect.ImmutableMultiset;
31
import com.google.common.collect.ImmutableSet;
32
import com.google.common.collect.ImmutableSortedSet;
33
import com.google.common.collect.ImmutableTable;
34
import com.google.common.collect.Maps;
35
import com.google.common.collect.Multimap;
36
import com.google.common.collect.Multiset;
37
import com.google.common.collect.Table;
38
import com.google.common.reflect.TypeToken;
39
import com.google.common.testing.NullPointerTester.Visibility;
40
import com.google.common.testing.anotherpackage.SomeClassThatDoesNotUseNullable;
41
import com.google.errorprone.annotations.CanIgnoreReturnValue;
42
import java.lang.reflect.Constructor;
43
import java.lang.reflect.Method;
45
import java.util.Locale;
48
import java.util.SortedSet;
49
import javax.annotation.CheckForNull;
50
import junit.framework.TestCase;
51
import org.checkerframework.checker.nullness.qual.Nullable;
59
@SuppressWarnings("CheckReturnValue")
60
public class NullPointerTesterTest extends TestCase {
63
public static class FooException extends RuntimeException {
64
private static final long serialVersionUID = 1L;
71
@SuppressWarnings("unused")
72
public static class OneArg {
74
public static void staticOneArgCorrectlyThrowsNpe(String s) {
78
public static void staticOneArgThrowsOtherThanNpe(String s) {
79
throw new FooException();
82
public static void staticOneArgShouldThrowNpeButDoesnt(String s) {
86
public static void staticOneArgCheckForNullCorrectlyDoesNotThrowNPE(@CheckForNull String s) {
90
public static void staticOneArgJsr305NullableCorrectlyDoesNotThrowNPE(
91
@javax.annotation.Nullable String s) {
95
public static void staticOneArgNullableCorrectlyDoesNotThrowNPE(@Nullable String s) {
99
public static void staticOneArgCheckForNullCorrectlyThrowsOtherThanNPE(@CheckForNull String s) {
100
throw new FooException();
103
public static void staticOneArgNullableCorrectlyThrowsOtherThanNPE(@Nullable String s) {
104
throw new FooException();
107
public static void staticOneArgCheckForNullThrowsNPE(@CheckForNull String s) {
111
public static void staticOneArgNullableThrowsNPE(@Nullable String s) {
115
public void oneArgCorrectlyThrowsNpe(String s) {
119
public void oneArgThrowsOtherThanNpe(String s) {
120
throw new FooException();
123
public void oneArgShouldThrowNpeButDoesnt(String s) {
127
public void oneArgCheckForNullCorrectlyDoesNotThrowNPE(@CheckForNull String s) {
131
public void oneArgNullableCorrectlyDoesNotThrowNPE(@Nullable String s) {
135
public void oneArgCheckForNullCorrectlyThrowsOtherThanNPE(@CheckForNull String s) {
136
throw new FooException();
139
public void oneArgNullableCorrectlyThrowsOtherThanNPE(@Nullable String s) {
140
throw new FooException();
143
public void oneArgCheckForNullThrowsNPE(@CheckForNull String s) {
147
public void oneArgNullableThrowsNPE(@Nullable String s) {
152
private static final String[] STATIC_ONE_ARG_METHODS_SHOULD_PASS = {
153
"staticOneArgCorrectlyThrowsNpe",
154
"staticOneArgCheckForNullCorrectlyDoesNotThrowNPE",
155
"staticOneArgCheckForNullCorrectlyThrowsOtherThanNPE",
156
"staticOneArgCheckForNullThrowsNPE",
157
"staticOneArgNullableCorrectlyDoesNotThrowNPE",
158
"staticOneArgNullableCorrectlyThrowsOtherThanNPE",
159
"staticOneArgNullableThrowsNPE",
161
private static final String[] STATIC_ONE_ARG_METHODS_SHOULD_FAIL = {
162
"staticOneArgThrowsOtherThanNpe", "staticOneArgShouldThrowNpeButDoesnt",
164
private static final String[] NONSTATIC_ONE_ARG_METHODS_SHOULD_PASS = {
165
"oneArgCorrectlyThrowsNpe",
166
"oneArgCheckForNullCorrectlyDoesNotThrowNPE",
167
"oneArgCheckForNullCorrectlyThrowsOtherThanNPE",
168
"oneArgCheckForNullThrowsNPE",
169
"oneArgNullableCorrectlyDoesNotThrowNPE",
170
"oneArgNullableCorrectlyThrowsOtherThanNPE",
171
"oneArgNullableThrowsNPE",
173
private static final String[] NONSTATIC_ONE_ARG_METHODS_SHOULD_FAIL = {
174
"oneArgThrowsOtherThanNpe", "oneArgShouldThrowNpeButDoesnt",
177
private static class ThrowsIae {
178
public static void christenPoodle(String name) {
179
checkArgument(name != null);
183
private static class ThrowsNpe {
184
public static void christenPoodle(String name) {
189
private static class ThrowsUoe {
190
public static void christenPoodle(String unused) {
191
throw new UnsupportedOperationException();
195
private static class ThrowsSomethingElse {
196
public static void christenPoodle(String unused) {
197
throw new RuntimeException();
201
private interface InterfaceStaticMethodFailsToCheckNull {
202
static String create(String unused) {
203
return "I don't check";
207
private interface InterfaceStaticMethodChecksNull {
208
static String create(String s) {
209
return checkNotNull(s);
213
private interface InterfaceDefaultMethodFailsToCheckNull {
214
static InterfaceDefaultMethodFailsToCheckNull create() {
215
return new InterfaceDefaultMethodFailsToCheckNull() {};
218
default void doNotCheckNull(String unused) {}
221
private interface InterfaceDefaultMethodChecksNull {
222
static InterfaceDefaultMethodChecksNull create() {
223
return new InterfaceDefaultMethodChecksNull() {};
226
default void checksNull(String s) {
231
public void testInterfaceStaticMethod() {
232
NullPointerTester tester = new NullPointerTester();
233
tester.testAllPublicStaticMethods(InterfaceStaticMethodChecksNull.class);
235
tester.testAllPublicStaticMethods(InterfaceStaticMethodFailsToCheckNull.class);
236
} catch (AssertionError expected) {
242
public void testInterfaceDefaultMethod() {
243
NullPointerTester tester = new NullPointerTester();
244
tester.testAllPublicInstanceMethods(InterfaceDefaultMethodChecksNull.create());
246
tester.testAllPublicInstanceMethods(InterfaceDefaultMethodFailsToCheckNull.create());
247
} catch (AssertionError expected) {
253
public void testDontAcceptIae() {
254
NullPointerTester tester = new NullPointerTester();
255
tester.testAllPublicStaticMethods(ThrowsNpe.class);
256
tester.testAllPublicStaticMethods(ThrowsUoe.class);
258
tester.testAllPublicStaticMethods(ThrowsIae.class);
259
} catch (AssertionError expected) {
265
public void testStaticOneArgMethodsThatShouldPass() throws Exception {
266
for (String methodName : STATIC_ONE_ARG_METHODS_SHOULD_PASS) {
267
Method method = OneArg.class.getMethod(methodName, String.class);
269
new NullPointerTester().testMethodParameter(new OneArg(), method, 0);
270
} catch (AssertionError unexpected) {
271
fail("Should not have flagged method " + methodName);
276
public void testStaticOneArgMethodsThatShouldFail() throws Exception {
277
for (String methodName : STATIC_ONE_ARG_METHODS_SHOULD_FAIL) {
278
Method method = OneArg.class.getMethod(methodName, String.class);
279
boolean foundProblem = false;
281
new NullPointerTester().testMethodParameter(new OneArg(), method, 0);
282
} catch (AssertionError expected) {
285
assertTrue("Should report error in method " + methodName, foundProblem);
289
public void testNonStaticOneArgMethodsThatShouldPass() throws Exception {
290
OneArg foo = new OneArg();
291
for (String methodName : NONSTATIC_ONE_ARG_METHODS_SHOULD_PASS) {
292
Method method = OneArg.class.getMethod(methodName, String.class);
294
new NullPointerTester().testMethodParameter(foo, method, 0);
295
} catch (AssertionError unexpected) {
296
fail("Should not have flagged method " + methodName);
301
public void testNonStaticOneArgMethodsThatShouldFail() throws Exception {
302
OneArg foo = new OneArg();
303
for (String methodName : NONSTATIC_ONE_ARG_METHODS_SHOULD_FAIL) {
304
Method method = OneArg.class.getMethod(methodName, String.class);
305
boolean foundProblem = false;
307
new NullPointerTester().testMethodParameter(foo, method, 0);
308
} catch (AssertionError expected) {
311
assertTrue("Should report error in method " + methodName, foundProblem);
315
public void testMessageOtherException() throws Exception {
316
Method method = OneArg.class.getMethod("staticOneArgThrowsOtherThanNpe", String.class);
317
boolean foundProblem = false;
319
new NullPointerTester().testMethodParameter(new OneArg(), method, 0);
320
} catch (AssertionError expected) {
321
assertThat(expected.getMessage()).contains("index 0");
322
assertThat(expected.getMessage()).contains("[null]");
325
assertTrue("Should report error when different exception is thrown", foundProblem);
328
public void testMessageNoException() throws Exception {
329
Method method = OneArg.class.getMethod("staticOneArgShouldThrowNpeButDoesnt", String.class);
330
boolean foundProblem = false;
332
new NullPointerTester().testMethodParameter(new OneArg(), method, 0);
333
} catch (AssertionError expected) {
334
assertThat(expected.getMessage()).contains("index 0");
335
assertThat(expected.getMessage()).contains("[null]");
338
assertTrue("Should report error when no exception is thrown", foundProblem);
352
public static class TwoArg {
358
throw new NullPointerException();
364
throw new FooException();
372
public abstract void act();
375
Action actionWhenFirstParamIsNull;
376
Action actionWhenSecondParamIsNull;
378
public TwoArg(Action actionWhenFirstParamIsNull, Action actionWhenSecondParamIsNull) {
379
this.actionWhenFirstParamIsNull = actionWhenFirstParamIsNull;
380
this.actionWhenSecondParamIsNull = actionWhenSecondParamIsNull;
384
public void reactToNullParameters(@Nullable Object first, @Nullable Object second) {
386
actionWhenFirstParamIsNull.act();
388
if (second == null) {
389
actionWhenSecondParamIsNull.act();
394
@SuppressWarnings("GoodTime")
395
public void normalNormal(String first, Integer second) {
396
reactToNullParameters(first, second);
400
@SuppressWarnings("GoodTime")
401
public void normalNullable(String first, @Nullable Integer second) {
402
reactToNullParameters(first, second);
406
@SuppressWarnings("GoodTime")
407
public void nullableNormal(@Nullable String first, Integer second) {
408
reactToNullParameters(first, second);
412
@SuppressWarnings("GoodTime")
413
public void nullableNullable(@Nullable String first, @Nullable Integer second) {
414
reactToNullParameters(first, second);
419
public String toString() {
420
return rootLocaleFormat(
421
"Bar(%s, %s)", actionWhenFirstParamIsNull, actionWhenSecondParamIsNull);
425
public void verifyBarPass(Method method, TwoArg bar) {
427
new NullPointerTester().testMethod(bar, method);
428
} catch (AssertionError incorrectError) {
429
String errorMessage =
430
rootLocaleFormat("Should not have flagged method %s for %s", method.getName(), bar);
431
assertNull(errorMessage, incorrectError);
435
public void verifyBarFail(Method method, TwoArg bar) {
437
new NullPointerTester().testMethod(bar, method);
438
} catch (AssertionError expected) {
441
String errorMessage =
442
rootLocaleFormat("Should have flagged method %s for %s", method.getName(), bar);
446
public void testTwoArgNormalNormal() throws Exception {
447
Method method = TwoArg.class.getMethod("normalNormal", String.class, Integer.class);
448
for (TwoArg.Action first : TwoArg.Action.values()) {
449
for (TwoArg.Action second : TwoArg.Action.values()) {
450
TwoArg bar = new TwoArg(first, second);
451
if (first.equals(TwoArg.Action.THROW_A_NPE) && second.equals(TwoArg.Action.THROW_A_NPE)) {
452
verifyBarPass(method, bar);
454
verifyBarFail(method, bar);
460
public void testTwoArgNormalNullable() throws Exception {
461
Method method = TwoArg.class.getMethod("normalNullable", String.class, Integer.class);
462
for (TwoArg.Action first : TwoArg.Action.values()) {
463
for (TwoArg.Action second : TwoArg.Action.values()) {
464
TwoArg bar = new TwoArg(first, second);
465
if (first.equals(TwoArg.Action.THROW_A_NPE)) {
466
verifyBarPass(method, bar);
468
verifyBarFail(method, bar);
474
public void testTwoArgNullableNormal() throws Exception {
475
Method method = TwoArg.class.getMethod("nullableNormal", String.class, Integer.class);
476
for (TwoArg.Action first : TwoArg.Action.values()) {
477
for (TwoArg.Action second : TwoArg.Action.values()) {
478
TwoArg bar = new TwoArg(first, second);
479
if (second.equals(TwoArg.Action.THROW_A_NPE)) {
480
verifyBarPass(method, bar);
482
verifyBarFail(method, bar);
488
public void testTwoArgNullableNullable() throws Exception {
489
Method method = TwoArg.class.getMethod("nullableNullable", String.class, Integer.class);
490
for (TwoArg.Action first : TwoArg.Action.values()) {
491
for (TwoArg.Action second : TwoArg.Action.values()) {
492
TwoArg bar = new TwoArg(first, second);
493
verifyBarPass(method, bar);
505
@SuppressWarnings("unused")
506
private static class PassObject extends SomeClassThatDoesNotUseNullable {
507
public static void doThrow(Object arg) {
509
throw new FooException();
513
public void noArg() {}
515
public void oneArg(String s) {
519
void packagePrivateOneArg(String s) {
523
protected void protectedOneArg(String s) {
527
public void oneNullableArg(@Nullable String s) {}
529
public void oneNullableArgThrows(@Nullable String s) {
533
public void twoArg(String s, Integer i) {
538
public void twoMixedArgs(String s, @Nullable Integer i) {
542
public void twoMixedArgs(@Nullable Integer i, String s) {
546
public void twoMixedArgsThrows(String s, @Nullable Integer i) {
551
public void twoMixedArgsThrows(@Nullable Integer i, String s) {
556
public void twoNullableArgs(@Nullable String s, @javax.annotation.Nullable Integer i) {}
558
public void twoNullableArgsThrowsFirstArg(@Nullable String s, @Nullable Integer i) {
562
public void twoNullableArgsThrowsSecondArg(@Nullable String s, @Nullable Integer i) {
566
public static void staticOneArg(String s) {
570
public static void staticOneNullableArg(@Nullable String s) {}
572
public static void staticOneNullableArgThrows(@Nullable String s) {
577
public void testGoodClass() {
578
shouldPass(new PassObject());
581
private static class FailOneArgDoesntThrowNPE extends PassObject {
583
public void oneArg(String s) {
588
public void testFailOneArgDoesntThrowNpe() {
589
shouldFail(new FailOneArgDoesntThrowNPE());
592
private static class FailOneArgThrowsWrongType extends PassObject {
594
public void oneArg(String s) {
599
public void testFailOneArgThrowsWrongType() {
600
shouldFail(new FailOneArgThrowsWrongType());
603
private static class PassOneNullableArgThrowsNPE extends PassObject {
605
public void oneNullableArg(@Nullable String s) {
610
public void testPassOneNullableArgThrowsNPE() {
611
shouldPass(new PassOneNullableArgThrowsNPE());
614
private static class FailTwoArgsFirstArgDoesntThrowNPE extends PassObject {
616
public void twoArg(String s, Integer i) {
622
public void testFailTwoArgsFirstArgDoesntThrowNPE() {
623
shouldFail(new FailTwoArgsFirstArgDoesntThrowNPE());
626
private static class FailTwoArgsFirstArgThrowsWrongType extends PassObject {
628
public void twoArg(String s, Integer i) {
634
public void testFailTwoArgsFirstArgThrowsWrongType() {
635
shouldFail(new FailTwoArgsFirstArgThrowsWrongType());
638
private static class FailTwoArgsSecondArgDoesntThrowNPE extends PassObject {
640
public void twoArg(String s, Integer i) {
646
public void testFailTwoArgsSecondArgDoesntThrowNPE() {
647
shouldFail(new FailTwoArgsSecondArgDoesntThrowNPE());
650
private static class FailTwoArgsSecondArgThrowsWrongType extends PassObject {
652
public void twoArg(String s, Integer i) {
658
public void testFailTwoArgsSecondArgThrowsWrongType() {
659
shouldFail(new FailTwoArgsSecondArgThrowsWrongType());
662
private static class FailTwoMixedArgsFirstArgDoesntThrowNPE extends PassObject {
664
public void twoMixedArgs(String s, @Nullable Integer i) {
669
public void testFailTwoMixedArgsFirstArgDoesntThrowNPE() {
670
shouldFail(new FailTwoMixedArgsFirstArgDoesntThrowNPE());
673
private static class FailTwoMixedArgsFirstArgThrowsWrongType extends PassObject {
675
public void twoMixedArgs(String s, @Nullable Integer i) {
680
public void testFailTwoMixedArgsFirstArgThrowsWrongType() {
681
shouldFail(new FailTwoMixedArgsFirstArgThrowsWrongType());
684
private static class PassTwoMixedArgsNullableArgThrowsNPE extends PassObject {
686
public void twoMixedArgs(String s, @Nullable Integer i) {
692
public void testPassTwoMixedArgsNullableArgThrowsNPE() {
693
shouldPass(new PassTwoMixedArgsNullableArgThrowsNPE());
696
private static class PassTwoMixedArgSecondNullableArgThrowsOther extends PassObject {
698
public void twoMixedArgs(String s, @Nullable Integer i) {
704
public void testPassTwoMixedArgSecondNullableArgThrowsOther() {
705
shouldPass(new PassTwoMixedArgSecondNullableArgThrowsOther());
708
private static class FailTwoMixedArgsSecondArgDoesntThrowNPE extends PassObject {
710
public void twoMixedArgs(@Nullable Integer i, String s) {
715
public void testFailTwoMixedArgsSecondArgDoesntThrowNPE() {
716
shouldFail(new FailTwoMixedArgsSecondArgDoesntThrowNPE());
719
private static class FailTwoMixedArgsSecondArgThrowsWrongType extends PassObject {
721
public void twoMixedArgs(@Nullable Integer i, String s) {
726
public void testFailTwoMixedArgsSecondArgThrowsWrongType() {
727
shouldFail(new FailTwoMixedArgsSecondArgThrowsWrongType());
730
private static class PassTwoNullableArgsFirstThrowsNPE extends PassObject {
732
public void twoNullableArgs(@Nullable String s, @Nullable Integer i) {
737
public void testPassTwoNullableArgsFirstThrowsNPE() {
738
shouldPass(new PassTwoNullableArgsFirstThrowsNPE());
741
private static class PassTwoNullableArgsFirstThrowsOther extends PassObject {
743
public void twoNullableArgs(@Nullable String s, @Nullable Integer i) {
748
public void testPassTwoNullableArgsFirstThrowsOther() {
749
shouldPass(new PassTwoNullableArgsFirstThrowsOther());
752
private static class PassTwoNullableArgsSecondThrowsNPE extends PassObject {
754
public void twoNullableArgs(@Nullable String s, @Nullable Integer i) {
759
public void testPassTwoNullableArgsSecondThrowsNPE() {
760
shouldPass(new PassTwoNullableArgsSecondThrowsNPE());
763
private static class PassTwoNullableArgsSecondThrowsOther extends PassObject {
765
public void twoNullableArgs(@Nullable String s, @Nullable Integer i) {
770
public void testPassTwoNullableArgsSecondThrowsOther() {
771
shouldPass(new PassTwoNullableArgsSecondThrowsOther());
774
private static class PassTwoNullableArgsNeitherThrowsAnything extends PassObject {
776
public void twoNullableArgs(@Nullable String s, @Nullable Integer i) {
781
public void testPassTwoNullableArgsNeitherThrowsAnything() {
782
shouldPass(new PassTwoNullableArgsNeitherThrowsAnything());
785
@SuppressWarnings("unused")
786
private abstract static class BaseClassThatFailsToThrow {
787
public void oneArg(String s) {}
790
private static class SubclassWithBadSuperclass extends BaseClassThatFailsToThrow {}
792
public void testSubclassWithBadSuperclass() {
793
shouldFail(new SubclassWithBadSuperclass());
796
@SuppressWarnings("unused")
797
private abstract static class BaseClassThatFailsToThrowForPackagePrivate {
798
void packagePrivateOneArg(String s) {}
801
private static class SubclassWithBadSuperclassForPackagePrivate
802
extends BaseClassThatFailsToThrowForPackagePrivate {}
804
public void testSubclassWithBadSuperclassForPackagePrivateMethod() {
805
shouldFail(new SubclassWithBadSuperclassForPackagePrivate(), Visibility.PACKAGE);
808
@SuppressWarnings("unused")
809
private abstract static class BaseClassThatFailsToThrowForProtected {
810
protected void protectedOneArg(String s) {}
813
private static class SubclassWithBadSuperclassForProtected
814
extends BaseClassThatFailsToThrowForProtected {}
816
public void testSubclassWithBadSuperclassForPackageProtectedMethod() {
817
shouldFail(new SubclassWithBadSuperclassForProtected(), Visibility.PROTECTED);
820
private static class SubclassThatOverridesBadSuperclassMethod extends BaseClassThatFailsToThrow {
822
public void oneArg(@Nullable String s) {}
825
public void testSubclassThatOverridesBadSuperclassMethod() {
826
shouldPass(new SubclassThatOverridesBadSuperclassMethod());
829
@SuppressWarnings("unused")
830
private static class SubclassOverridesTheWrongMethod extends BaseClassThatFailsToThrow {
831
public void oneArg(@Nullable CharSequence s) {}
834
public void testSubclassOverridesTheWrongMethod() {
835
shouldFail(new SubclassOverridesTheWrongMethod());
838
@SuppressWarnings("unused")
839
private static class ClassThatFailsToThrowForStatic {
840
static void staticOneArg(String s) {}
843
public void testClassThatFailsToThrowForStatic() {
844
shouldFail(ClassThatFailsToThrowForStatic.class);
847
private static class SubclassThatFailsToThrowForStatic extends ClassThatFailsToThrowForStatic {}
849
public void testSubclassThatFailsToThrowForStatic() {
850
shouldFail(SubclassThatFailsToThrowForStatic.class);
853
private static class SubclassThatTriesToOverrideBadStaticMethod
854
extends ClassThatFailsToThrowForStatic {
855
static void staticOneArg(String unused) {}
858
public void testSubclassThatTriesToOverrideBadStaticMethod() {
859
shouldFail(SubclassThatTriesToOverrideBadStaticMethod.class);
862
private static final class HardToCreate {
863
private HardToCreate(String unused) {}
866
@SuppressWarnings("unused")
867
private static class CanCreateDefault {
868
public void foo(@Nullable HardToCreate ignored, String required) {
869
checkNotNull(required);
873
public void testCanCreateDefault() {
874
shouldPass(new CanCreateDefault());
877
@SuppressWarnings("unused")
878
private static class CannotCreateDefault {
879
public void foo(HardToCreate ignored, String required) {
880
checkNotNull(ignored);
881
checkNotNull(required);
885
public void testCannotCreateDefault() {
886
shouldFail(new CannotCreateDefault());
889
private static void shouldPass(Object instance, Visibility visibility) {
890
new NullPointerTester().testInstanceMethods(instance, visibility);
893
private static void shouldPass(Object instance) {
894
shouldPass(instance, Visibility.PACKAGE);
895
shouldPass(instance, Visibility.PROTECTED);
896
shouldPass(instance, Visibility.PUBLIC);
901
private static void shouldFail(Object instance, Visibility visibility) {
903
new NullPointerTester().testInstanceMethods(instance, visibility);
904
} catch (AssertionError expected) {
907
fail("Should detect problem in " + instance.getClass().getSimpleName());
910
private static void shouldFail(Object instance) {
911
shouldFail(instance, Visibility.PACKAGE);
912
shouldFail(instance, Visibility.PROTECTED);
913
shouldFail(instance, Visibility.PUBLIC);
916
private static void shouldFail(Class<?> cls, Visibility visibility) {
918
new NullPointerTester().testStaticMethods(cls, visibility);
919
} catch (AssertionError expected) {
922
fail("Should detect problem in " + cls.getSimpleName());
925
private static void shouldFail(Class<?> cls) {
926
shouldFail(cls, Visibility.PACKAGE);
929
@SuppressWarnings("unused")
930
private static class PrivateClassWithPrivateConstructor {
931
private PrivateClassWithPrivateConstructor(@Nullable Integer argument) {}
934
public void testPrivateClass() {
935
NullPointerTester tester = new NullPointerTester();
936
for (Constructor<?> constructor :
937
PrivateClassWithPrivateConstructor.class.getDeclaredConstructors()) {
938
tester.testConstructor(constructor);
942
private interface Foo<T> {
943
void doSomething(T bar, Integer baz);
946
private static class StringFoo implements Foo<String> {
949
public void doSomething(String bar, Integer baz) {
955
public void testBridgeMethodIgnored() {
956
new NullPointerTester().testAllPublicInstanceMethods(new StringFoo());
959
private abstract static class DefaultValueChecker {
961
private final Map<Integer, Object> arguments = Maps.newHashMap();
963
@CanIgnoreReturnValue
964
final DefaultValueChecker runTester() {
965
new NullPointerTester().testInstanceMethods(this, Visibility.PACKAGE);
969
final void assertNonNullValues(Object... expectedValues) {
970
assertEquals(expectedValues.length, arguments.size());
971
for (int i = 0; i < expectedValues.length; i++) {
972
assertEquals("Default value for parameter #" + i, expectedValues[i], arguments.get(i));
976
final Object getDefaultParameterValue(int position) {
977
return arguments.get(position);
980
final void calledWith(Object... args) {
981
for (int i = 0; i < args.length; i++) {
982
if (args[i] != null) {
983
arguments.put(i, args[i]);
986
for (Object arg : args) {
992
private enum Gender {
997
private static class AllDefaultValuesChecker extends DefaultValueChecker {
999
@SuppressWarnings("unused")
1000
public void checkDefaultValuesForTheseTypes(
1005
CharSequence charSequence,
1007
ImmutableList<Integer> immutableList,
1008
Map<String, Integer> map,
1009
ImmutableMap<String, String> immutableMap,
1011
ImmutableSet<Integer> immutableSet,
1012
SortedSet<Number> sortedSet,
1013
ImmutableSortedSet<Number> immutableSortedSet,
1014
Multiset<String> multiset,
1015
ImmutableMultiset<Integer> immutableMultiset,
1016
Multimap<String, Integer> multimap,
1017
ImmutableMultimap<String, Integer> immutableMultimap,
1018
Table<String, Integer, Exception> table,
1019
ImmutableTable<Integer, String, Exception> immutableTable) {
1042
final void check() {
1044
.assertNonNullValues(
1056
ImmutableSortedSet.of(),
1057
ImmutableSortedSet.of(),
1058
ImmutableMultiset.of(),
1059
ImmutableMultiset.of(),
1060
ImmutableMultimap.of(),
1061
ImmutableMultimap.of(),
1062
ImmutableTable.of(),
1063
ImmutableTable.of());
1067
public void testDefaultValues() {
1068
new AllDefaultValuesChecker().check();
1071
private static class ObjectArrayDefaultValueChecker extends DefaultValueChecker {
1073
@SuppressWarnings("unused")
1074
public void checkArray(Object[] array, String s) {
1075
calledWith(array, s);
1080
Object[] defaultArray = (Object[]) getDefaultParameterValue(0);
1081
assertThat(defaultArray).isEmpty();
1085
public void testObjectArrayDefaultValue() {
1086
new ObjectArrayDefaultValueChecker().check();
1089
private static class StringArrayDefaultValueChecker extends DefaultValueChecker {
1091
@SuppressWarnings("unused")
1092
public void checkArray(String[] array, String s) {
1093
calledWith(array, s);
1098
String[] defaultArray = (String[]) getDefaultParameterValue(0);
1099
assertThat(defaultArray).isEmpty();
1103
public void testStringArrayDefaultValue() {
1104
new StringArrayDefaultValueChecker().check();
1107
private static class IntArrayDefaultValueChecker extends DefaultValueChecker {
1109
@SuppressWarnings("unused")
1110
public void checkArray(int[] array, String s) {
1111
calledWith(array, s);
1116
int[] defaultArray = (int[]) getDefaultParameterValue(0);
1117
assertEquals(0, defaultArray.length);
1121
public void testIntArrayDefaultValue() {
1122
new IntArrayDefaultValueChecker().check();
1125
private enum EmptyEnum {}
1127
private static class EmptyEnumDefaultValueChecker extends DefaultValueChecker {
1129
@SuppressWarnings("unused")
1130
public void checkArray(EmptyEnum object, String s) {
1131
calledWith(object, s);
1137
} catch (AssertionError expected) {
1140
fail("Should have failed because enum has no constant");
1144
public void testEmptyEnumDefaultValue() {
1145
new EmptyEnumDefaultValueChecker().check();
1148
private static class GenericClassTypeDefaultValueChecker extends DefaultValueChecker {
1150
@SuppressWarnings("unused")
1151
public void checkArray(Class<? extends List<?>> cls, String s) {
1157
Class<?> defaultClass = (Class<?>) getDefaultParameterValue(0);
1158
assertEquals(List.class, defaultClass);
1162
public void testGenericClassDefaultValue() {
1163
new GenericClassTypeDefaultValueChecker().check();
1166
private static class NonGenericClassTypeDefaultValueChecker extends DefaultValueChecker {
1168
@SuppressWarnings("unused")
1169
public void checkArray(@SuppressWarnings("rawtypes") Class cls, String s) {
1175
Class<?> defaultClass = (Class<?>) getDefaultParameterValue(0);
1176
assertEquals(Object.class, defaultClass);
1180
public void testNonGenericClassDefaultValue() {
1181
new NonGenericClassTypeDefaultValueChecker().check();
1184
private static class GenericTypeTokenDefaultValueChecker extends DefaultValueChecker {
1186
@SuppressWarnings("unused")
1187
public void checkArray(TypeToken<? extends List<? super Number>> type, String s) {
1188
calledWith(type, s);
1193
TypeToken<?> defaultType = (TypeToken<?>) getDefaultParameterValue(0);
1194
assertTrue(new TypeToken<List<? super Number>>() {}.isSupertypeOf(defaultType));
1198
public void testGenericTypeTokenDefaultValue() {
1199
new GenericTypeTokenDefaultValueChecker().check();
1202
private static class NonGenericTypeTokenDefaultValueChecker extends DefaultValueChecker {
1204
@SuppressWarnings("unused")
1205
public void checkArray(@SuppressWarnings("rawtypes") TypeToken type, String s) {
1206
calledWith(type, s);
1211
TypeToken<?> defaultType = (TypeToken<?>) getDefaultParameterValue(0);
1212
assertEquals(new TypeToken<Object>() {}, defaultType);
1216
public void testNonGenericTypeTokenDefaultValue() {
1217
new NonGenericTypeTokenDefaultValueChecker().check();
1220
private interface FromTo<F, T> extends Function<F, T> {}
1222
private static class GenericInterfaceDefaultValueChecker extends DefaultValueChecker {
1224
@SuppressWarnings("unused")
1225
public void checkArray(FromTo<String, Integer> f, String s) {
1231
FromTo<?, ?> defaultFunction = (FromTo<?, ?>) getDefaultParameterValue(0);
1232
assertEquals(0, defaultFunction.apply(null));
1236
public void testGenericInterfaceDefaultValue() {
1237
new GenericInterfaceDefaultValueChecker().check();
1240
private interface NullRejectingFromTo<F, T> extends Function<F, T> {
1242
public abstract T apply(F from);
1245
private static class NullRejectingInterfaceDefaultValueChecker extends DefaultValueChecker {
1247
@SuppressWarnings("unused")
1248
public void checkArray(NullRejectingFromTo<String, Integer> f, String s) {
1254
NullRejectingFromTo<?, ?> defaultFunction =
1255
(NullRejectingFromTo<?, ?>) getDefaultParameterValue(0);
1256
assertNotNull(defaultFunction);
1258
defaultFunction.apply(null);
1259
fail("Proxy Should have rejected null");
1260
} catch (NullPointerException expected) {
1265
public void testNullRejectingInterfaceDefaultValue() {
1266
new NullRejectingInterfaceDefaultValueChecker().check();
1269
private static class MultipleInterfacesDefaultValueChecker extends DefaultValueChecker {
1271
@SuppressWarnings("unused")
1272
public <T extends FromTo<String, Integer> & Supplier<Long>> void checkArray(T f, String s) {
1278
FromTo<?, ?> defaultFunction = (FromTo<?, ?>) getDefaultParameterValue(0);
1279
assertEquals(0, defaultFunction.apply(null));
1280
Supplier<?> defaultSupplier = (Supplier<?>) defaultFunction;
1281
assertEquals(Long.valueOf(0), defaultSupplier.get());
1285
public void testMultipleInterfacesDefaultValue() {
1286
new MultipleInterfacesDefaultValueChecker().check();
1289
private static class GenericInterface2DefaultValueChecker extends DefaultValueChecker {
1291
@SuppressWarnings("unused")
1292
public void checkArray(FromTo<String, FromTo<Integer, String>> f, String s) {
1298
FromTo<?, ?> defaultFunction = (FromTo<?, ?>) getDefaultParameterValue(0);
1299
FromTo<?, ?> returnValue = (FromTo<?, ?>) defaultFunction.apply(null);
1300
assertEquals("", returnValue.apply(null));
1304
public void testGenericInterfaceReturnedByGenericMethod() {
1305
new GenericInterface2DefaultValueChecker().check();
1308
private abstract static class AbstractGenericDefaultValueChecker<T> extends DefaultValueChecker {
1310
@SuppressWarnings("unused")
1311
public void checkGeneric(T value, String s) {
1312
calledWith(value, s);
1316
private static class GenericDefaultValueResolvedToStringChecker
1317
extends AbstractGenericDefaultValueChecker<String> {
1320
assertEquals("", getDefaultParameterValue(0));
1324
public void testGenericTypeResolvedForDefaultValue() {
1325
new GenericDefaultValueResolvedToStringChecker().check();
1328
private abstract static class AbstractGenericDefaultValueForPackagePrivateMethodChecker<T>
1329
extends DefaultValueChecker {
1331
@SuppressWarnings("unused")
1332
void checkGeneric(T value, String s) {
1333
calledWith(value, s);
1337
private static class DefaultValueForPackagePrivateMethodResolvedToStringChecker
1338
extends AbstractGenericDefaultValueForPackagePrivateMethodChecker<String> {
1341
assertEquals("", getDefaultParameterValue(0));
1345
public void testDefaultValueResolvedForPackagePrivateMethod() {
1346
new DefaultValueForPackagePrivateMethodResolvedToStringChecker().check();
1349
private static class ConverterDefaultValueChecker extends DefaultValueChecker {
1351
@SuppressWarnings("unused")
1352
public void checkArray(Converter<String, Integer> c, String s) {
1358
@SuppressWarnings("unchecked")
1359
Converter<String, Integer> defaultConverter =
1360
(Converter<String, Integer>) getDefaultParameterValue(0);
1361
assertEquals(Integer.valueOf(0), defaultConverter.convert("anything"));
1362
assertEquals("", defaultConverter.reverse().convert(123));
1363
assertNull(defaultConverter.convert(null));
1364
assertNull(defaultConverter.reverse().convert(null));
1368
public void testConverterDefaultValue() {
1369
new ConverterDefaultValueChecker().check();
1372
private static class VisibilityMethods {
1374
@SuppressWarnings("unused")
1375
private void privateMethod() {}
1377
@SuppressWarnings("unused")
1378
void packagePrivateMethod() {}
1380
@SuppressWarnings("unused")
1381
protected void protectedMethod() {}
1383
@SuppressWarnings("unused")
1384
public void publicMethod() {}
1387
public void testVisibility_public() throws Exception {
1389
Visibility.PUBLIC.isVisible(VisibilityMethods.class.getDeclaredMethod("privateMethod")));
1391
Visibility.PUBLIC.isVisible(
1392
VisibilityMethods.class.getDeclaredMethod("packagePrivateMethod")));
1394
Visibility.PUBLIC.isVisible(VisibilityMethods.class.getDeclaredMethod("protectedMethod")));
1396
Visibility.PUBLIC.isVisible(VisibilityMethods.class.getDeclaredMethod("publicMethod")));
1399
public void testVisibility_protected() throws Exception {
1401
Visibility.PROTECTED.isVisible(VisibilityMethods.class.getDeclaredMethod("privateMethod")));
1403
Visibility.PROTECTED.isVisible(
1404
VisibilityMethods.class.getDeclaredMethod("packagePrivateMethod")));
1406
Visibility.PROTECTED.isVisible(
1407
VisibilityMethods.class.getDeclaredMethod("protectedMethod")));
1409
Visibility.PROTECTED.isVisible(VisibilityMethods.class.getDeclaredMethod("publicMethod")));
1412
public void testVisibility_package() throws Exception {
1414
Visibility.PACKAGE.isVisible(VisibilityMethods.class.getDeclaredMethod("privateMethod")));
1416
Visibility.PACKAGE.isVisible(
1417
VisibilityMethods.class.getDeclaredMethod("packagePrivateMethod")));
1419
Visibility.PACKAGE.isVisible(VisibilityMethods.class.getDeclaredMethod("protectedMethod")));
1421
Visibility.PACKAGE.isVisible(VisibilityMethods.class.getDeclaredMethod("publicMethod")));
1424
private class Inner {
1425
public Inner(String s) {
1430
public void testNonStaticInnerClass() {
1431
IllegalArgumentException expected =
1433
IllegalArgumentException.class,
1434
() -> new NullPointerTester().testAllPublicConstructors(Inner.class));
1435
assertThat(expected.getMessage()).contains("inner class");
1438
private static String rootLocaleFormat(String format, Object... args) {
1439
return String.format(Locale.ROOT, format, args);
1442
static class OverridesEquals {
1443
@SuppressWarnings("EqualsHashCode")
1445
public boolean equals(@Nullable Object o) {
1450
static class DoesNotOverrideEquals {
1451
public boolean equals(Object a, Object b) {
1456
public void testEqualsMethod() {
1457
shouldPass(new OverridesEquals());
1458
shouldFail(new DoesNotOverrideEquals());
1461
private static final class FailOnOneOfTwoConstructors {
1462
@SuppressWarnings("unused")
1463
public FailOnOneOfTwoConstructors(String s) {}
1465
@SuppressWarnings("unused")
1466
public FailOnOneOfTwoConstructors(Object o) {
1471
public void testConstructor_ignored_shouldPass() throws Exception {
1472
new NullPointerTester()
1473
.ignore(FailOnOneOfTwoConstructors.class.getDeclaredConstructor(String.class))
1474
.testAllPublicConstructors(FailOnOneOfTwoConstructors.class);
1477
public void testConstructor_shouldFail() throws Exception {
1479
new NullPointerTester().testAllPublicConstructors(FailOnOneOfTwoConstructors.class);
1480
} catch (AssertionError expected) {
1483
fail("Should detect problem in " + FailOnOneOfTwoConstructors.class.getSimpleName());
1486
public static class NullBounds<T extends @Nullable Object, U extends T, X> {
1489
@SuppressWarnings("unused")
1490
public void x(X x) {
1495
@SuppressWarnings("unused")
1496
public void t(T t) {
1497
fail("Method with parameter <T extends @Nullable Object> should not be called");
1500
@SuppressWarnings("unused")
1501
public void u(U u) {
1503
"Method with parameter <U extends T> where <T extends @Nullable Object> should not be"
1507
@SuppressWarnings("unused")
1508
public <A extends @Nullable Object> void a(A a) {
1509
fail("Method with parameter <A extends @Nullable Object> should not be called");
1512
@SuppressWarnings("unused")
1513
public <A extends B, B extends @Nullable Object> void b(A a) {
1515
"Method with parameter <A extends B> where <B extends @Nullable Object> should not be"
1520
public void testNullBounds() {
1524
NullBounds<?, ?, ?> nullBounds = new NullBounds<>();
1525
new NullPointerTester().testAllPublicInstanceMethods(nullBounds);
1526
assertThat(nullBounds.xWasCalled).isTrue();