1 /* 2 * Copyright (C) 2005 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.checkArgument; 20 import static com.google.common.base.Preconditions.checkNotNull; 21 import static com.google.common.truth.Truth.assertThat; 22 23 import com.google.common.base.Converter; 24 import com.google.common.base.Function; 25 import com.google.common.base.Supplier; 26 import com.google.common.collect.ImmutableList; 27 import com.google.common.collect.ImmutableMap; 28 import com.google.common.collect.ImmutableMultimap; 29 import com.google.common.collect.ImmutableMultiset; 30 import com.google.common.collect.ImmutableSet; 31 import com.google.common.collect.ImmutableSortedSet; 32 import com.google.common.collect.ImmutableTable; 33 import com.google.common.collect.Maps; 34 import com.google.common.collect.Multimap; 35 import com.google.common.collect.Multiset; 36 import com.google.common.collect.Table; 37 import com.google.common.reflect.TypeToken; 38 import com.google.common.testing.NullPointerTester.Visibility; 39 import com.google.common.testing.anotherpackage.SomeClassThatDoesNotUseNullable; 40 41 import junit.framework.AssertionFailedError; 42 import junit.framework.TestCase; 43 44 import java.lang.reflect.Constructor; 45 import java.lang.reflect.Method; 46 import java.util.List; 47 import java.util.Map; 48 import java.util.Set; 49 import java.util.SortedSet; 50 51 import javax.annotation.Nullable; 52 53 /** 54 * Unit test for {@link NullPointerTester}. 55 * 56 * @author Kevin Bourrillion 57 * @author Mick Killianey 58 */ 59 public class NullPointerTesterTest extends TestCase { 60 61 /** Non-NPE RuntimeException. */ 62 public static class FooException extends RuntimeException { 63 private static final long serialVersionUID = 1L; 64 } 65 66 /** 67 * Class for testing all permutations of static/non-static one-argument 68 * methods using methodParameter(). 69 */ 70 @SuppressWarnings("unused") // used by reflection 71 public static class OneArg { 72 staticOneArgCorrectlyThrowsNpe(String s)73 public static void staticOneArgCorrectlyThrowsNpe(String s) { 74 checkNotNull(s); // expect NPE here on null 75 } staticOneArgThrowsOtherThanNpe(String s)76 public static void staticOneArgThrowsOtherThanNpe(String s) { 77 throw new FooException(); // should catch as failure 78 } staticOneArgShouldThrowNpeButDoesnt(String s)79 public static void staticOneArgShouldThrowNpeButDoesnt(String s) { 80 // should catch as failure 81 } 82 public static void staticOneArgNullableCorrectlyDoesNotThrowNPE(@ullable String s)83 staticOneArgNullableCorrectlyDoesNotThrowNPE(@Nullable String s) { 84 // null? no problem 85 } 86 public static void staticOneArgNullableCorrectlyThrowsOtherThanNPE(@ullable String s)87 staticOneArgNullableCorrectlyThrowsOtherThanNPE(@Nullable String s) { 88 throw new FooException(); // ok, as long as it's not NullPointerException 89 } 90 public static void staticOneArgNullableThrowsNPE(@ullable String s)91 staticOneArgNullableThrowsNPE(@Nullable String s) { 92 checkNotNull(s); // doesn't check if you said you'd accept null, but you don't 93 } 94 oneArgCorrectlyThrowsNpe(String s)95 public void oneArgCorrectlyThrowsNpe(String s) { 96 checkNotNull(s); // expect NPE here on null 97 } oneArgThrowsOtherThanNpe(String s)98 public void oneArgThrowsOtherThanNpe(String s) { 99 throw new FooException(); // should catch as failure 100 } oneArgShouldThrowNpeButDoesnt(String s)101 public void oneArgShouldThrowNpeButDoesnt(String s) { 102 // should catch as failure 103 } oneArgNullableCorrectlyDoesNotThrowNPE(@ullable String s)104 public void oneArgNullableCorrectlyDoesNotThrowNPE(@Nullable String s) { 105 // null? no problem 106 } oneArgNullableCorrectlyThrowsOtherThanNPE(@ullable String s)107 public void oneArgNullableCorrectlyThrowsOtherThanNPE(@Nullable String s) { 108 throw new FooException(); // ok, as long as it's not NullPointerException 109 } oneArgNullableThrowsNPE(@ullable String s)110 public void oneArgNullableThrowsNPE(@Nullable String s) { 111 checkNotNull(s); // doesn't check if you said you'd accept null, but you don't 112 } 113 } 114 115 private static final String[] STATIC_ONE_ARG_METHODS_SHOULD_PASS = { 116 "staticOneArgCorrectlyThrowsNpe", 117 "staticOneArgNullableCorrectlyDoesNotThrowNPE", 118 "staticOneArgNullableCorrectlyThrowsOtherThanNPE", 119 "staticOneArgNullableThrowsNPE", 120 }; 121 private static final String[] STATIC_ONE_ARG_METHODS_SHOULD_FAIL = { 122 "staticOneArgThrowsOtherThanNpe", 123 "staticOneArgShouldThrowNpeButDoesnt", 124 }; 125 private static final String[] NONSTATIC_ONE_ARG_METHODS_SHOULD_PASS = { 126 "oneArgCorrectlyThrowsNpe", 127 "oneArgNullableCorrectlyDoesNotThrowNPE", 128 "oneArgNullableCorrectlyThrowsOtherThanNPE", 129 "oneArgNullableThrowsNPE", 130 }; 131 private static final String[] NONSTATIC_ONE_ARG_METHODS_SHOULD_FAIL = { 132 "oneArgThrowsOtherThanNpe", 133 "oneArgShouldThrowNpeButDoesnt", 134 }; 135 136 private static class ThrowsIae { christenPoodle(String name)137 public static void christenPoodle(String name) { 138 checkArgument(name != null); 139 } 140 } 141 142 private static class ThrowsNpe { christenPoodle(String name)143 public static void christenPoodle(String name) { 144 checkNotNull(name); 145 } 146 } 147 148 private static class ThrowsUoe { christenPoodle(String name)149 public static void christenPoodle(String name) { 150 throw new UnsupportedOperationException(); 151 } 152 } 153 154 private static class ThrowsSomethingElse { christenPoodle(String name)155 public static void christenPoodle(String name) { 156 throw new RuntimeException(); 157 } 158 } 159 testDontAcceptIae()160 public void testDontAcceptIae() { 161 NullPointerTester tester = new NullPointerTester(); 162 tester.testAllPublicStaticMethods(ThrowsNpe.class); 163 tester.testAllPublicStaticMethods(ThrowsUoe.class); 164 try { 165 tester.testAllPublicStaticMethods(ThrowsIae.class); 166 } catch (AssertionFailedError expected) { 167 return; 168 } 169 fail(); 170 } 171 testStaticOneArgMethodsThatShouldPass()172 public void testStaticOneArgMethodsThatShouldPass() throws Exception { 173 for (String methodName : STATIC_ONE_ARG_METHODS_SHOULD_PASS) { 174 Method method = OneArg.class.getMethod(methodName, String.class); 175 try { 176 new NullPointerTester().testMethodParameter(new OneArg(), method, 0); 177 } catch (AssertionFailedError unexpected) { 178 fail("Should not have flagged method " + methodName); 179 } 180 } 181 } 182 testStaticOneArgMethodsThatShouldFail()183 public void testStaticOneArgMethodsThatShouldFail() throws Exception { 184 for (String methodName : STATIC_ONE_ARG_METHODS_SHOULD_FAIL) { 185 Method method = OneArg.class.getMethod(methodName, String.class); 186 boolean foundProblem = false; 187 try { 188 new NullPointerTester().testMethodParameter(new OneArg(), method, 0); 189 } catch (AssertionFailedError expected) { 190 foundProblem = true; 191 } 192 assertTrue("Should report error in method " + methodName, foundProblem); 193 } 194 } 195 testNonStaticOneArgMethodsThatShouldPass()196 public void testNonStaticOneArgMethodsThatShouldPass() throws Exception { 197 OneArg foo = new OneArg(); 198 for (String methodName : NONSTATIC_ONE_ARG_METHODS_SHOULD_PASS) { 199 Method method = OneArg.class.getMethod(methodName, String.class); 200 try { 201 new NullPointerTester().testMethodParameter(foo, method, 0); 202 } catch (AssertionFailedError unexpected) { 203 fail("Should not have flagged method " + methodName); 204 } 205 } 206 } 207 testNonStaticOneArgMethodsThatShouldFail()208 public void testNonStaticOneArgMethodsThatShouldFail() throws Exception { 209 OneArg foo = new OneArg(); 210 for (String methodName : NONSTATIC_ONE_ARG_METHODS_SHOULD_FAIL) { 211 Method method = OneArg.class.getMethod(methodName, String.class); 212 boolean foundProblem = false; 213 try { 214 new NullPointerTester().testMethodParameter(foo, method, 0); 215 } catch (AssertionFailedError expected) { 216 foundProblem = true; 217 } 218 assertTrue("Should report error in method " + methodName, foundProblem); 219 } 220 } 221 222 /** 223 * Class for testing all permutations of nullable/non-nullable two-argument 224 * methods using testMethod(). 225 * 226 * normalNormal: two params, neither is Nullable 227 * nullableNormal: only first param is Nullable 228 * normalNullable: only second param is Nullable 229 * nullableNullable: both params are Nullable 230 */ 231 public static class TwoArg { 232 /** Action to take on a null param. */ 233 public enum Action { 234 THROW_A_NPE { act()235 @Override public void act() { 236 throw new NullPointerException(); 237 } 238 }, 239 THROW_OTHER { act()240 @Override public void act() { 241 throw new FooException(); 242 } 243 }, 244 JUST_RETURN { act()245 @Override public void act() {} 246 }; 247 act()248 public abstract void act(); 249 } 250 Action actionWhenFirstParamIsNull; 251 Action actionWhenSecondParamIsNull; 252 TwoArg( Action actionWhenFirstParamIsNull, Action actionWhenSecondParamIsNull)253 public TwoArg( 254 Action actionWhenFirstParamIsNull, 255 Action actionWhenSecondParamIsNull) { 256 this.actionWhenFirstParamIsNull = actionWhenFirstParamIsNull; 257 this.actionWhenSecondParamIsNull = actionWhenSecondParamIsNull; 258 } 259 260 /** Method that decides how to react to parameters. */ reactToNullParameters(Object first, Object second)261 public void reactToNullParameters(Object first, Object second) { 262 if (first == null) { 263 actionWhenFirstParamIsNull.act(); 264 } 265 if (second == null) { 266 actionWhenSecondParamIsNull.act(); 267 } 268 } 269 270 /** Two-arg method with no Nullable params. */ normalNormal(String first, Integer second)271 public void normalNormal(String first, Integer second) { 272 reactToNullParameters(first, second); 273 } 274 275 /** Two-arg method with the second param Nullable. */ normalNullable(String first, @Nullable Integer second)276 public void normalNullable(String first, @Nullable Integer second) { 277 reactToNullParameters(first, second); 278 } 279 280 /** Two-arg method with the first param Nullable. */ nullableNormal(@ullable String first, Integer second)281 public void nullableNormal(@Nullable String first, Integer second) { 282 reactToNullParameters(first, second); 283 } 284 285 /** Two-arg method with the both params Nullable. */ nullableNullable( @ullable String first, @Nullable Integer second)286 public void nullableNullable( 287 @Nullable String first, @Nullable Integer second) { 288 reactToNullParameters(first, second); 289 } 290 291 /** To provide sanity during debugging. */ toString()292 @Override public String toString() { 293 return String.format("Bar(%s, %s)", 294 actionWhenFirstParamIsNull, actionWhenSecondParamIsNull); 295 } 296 } 297 verifyBarPass(Method method, TwoArg bar)298 public void verifyBarPass(Method method, TwoArg bar) { 299 try { 300 new NullPointerTester().testMethod(bar, method); 301 } catch (AssertionFailedError incorrectError) { 302 String errorMessage = String.format( 303 "Should not have flagged method %s for %s", method.getName(), bar); 304 assertNull(errorMessage, incorrectError); 305 } 306 } 307 verifyBarFail(Method method, TwoArg bar)308 public void verifyBarFail(Method method, TwoArg bar) { 309 try { 310 new NullPointerTester().testMethod(bar, method); 311 } catch (AssertionFailedError expected) { 312 return; // good...we wanted a failure 313 } 314 String errorMessage = String.format( 315 "Should have flagged method %s for %s", method.getName(), bar); 316 fail(errorMessage); 317 } 318 testTwoArgNormalNormal()319 public void testTwoArgNormalNormal() throws Exception { 320 Method method = TwoArg.class.getMethod( 321 "normalNormal", String.class, Integer.class); 322 for (TwoArg.Action first : TwoArg.Action.values()) { 323 for (TwoArg.Action second : TwoArg.Action.values()) { 324 TwoArg bar = new TwoArg(first, second); 325 if (first.equals(TwoArg.Action.THROW_A_NPE) 326 && second.equals(TwoArg.Action.THROW_A_NPE)) { 327 verifyBarPass(method, bar); // require both params to throw NPE 328 } else { 329 verifyBarFail(method, bar); 330 } 331 } 332 } 333 } 334 testTwoArgNormalNullable()335 public void testTwoArgNormalNullable() throws Exception { 336 Method method = TwoArg.class.getMethod( 337 "normalNullable", String.class, Integer.class); 338 for (TwoArg.Action first : TwoArg.Action.values()) { 339 for (TwoArg.Action second : TwoArg.Action.values()) { 340 TwoArg bar = new TwoArg(first, second); 341 if (first.equals(TwoArg.Action.THROW_A_NPE)) { 342 verifyBarPass(method, bar); // only pass if 1st param throws NPE 343 } else { 344 verifyBarFail(method, bar); 345 } 346 } 347 } 348 } 349 testTwoArgNullableNormal()350 public void testTwoArgNullableNormal() throws Exception { 351 Method method = TwoArg.class.getMethod( 352 "nullableNormal", String.class, Integer.class); 353 for (TwoArg.Action first : TwoArg.Action.values()) { 354 for (TwoArg.Action second : TwoArg.Action.values()) { 355 TwoArg bar = new TwoArg(first, second); 356 if (second.equals(TwoArg.Action.THROW_A_NPE)) { 357 verifyBarPass(method, bar); // only pass if 2nd param throws NPE 358 } else { 359 verifyBarFail(method, bar); 360 } 361 } 362 } 363 } 364 testTwoArgNullableNullable()365 public void testTwoArgNullableNullable() throws Exception { 366 Method method = TwoArg.class.getMethod( 367 "nullableNullable", String.class, Integer.class); 368 for (TwoArg.Action first : TwoArg.Action.values()) { 369 for (TwoArg.Action second : TwoArg.Action.values()) { 370 TwoArg bar = new TwoArg(first, second); 371 verifyBarPass(method, bar); // All args nullable: anything goes! 372 } 373 } 374 } 375 376 /* 377 * This next part consists of several sample classes that provide 378 * demonstrations of conditions that cause NullPointerTester 379 * to succeed/fail. 380 */ 381 382 /** Lots of well-behaved methods. */ 383 @SuppressWarnings("unused") // used by reflection 384 private static class PassObject extends SomeClassThatDoesNotUseNullable { doThrow(Object arg)385 public static void doThrow(Object arg) { 386 if (arg == null) { 387 throw new FooException(); 388 } 389 } noArg()390 public void noArg() {} oneArg(String s)391 public void oneArg(String s) { checkNotNull(s); } packagePrivateOneArg(String s)392 void packagePrivateOneArg(String s) { checkNotNull(s); } protectedOneArg(String s)393 protected void protectedOneArg(String s) { checkNotNull(s); } oneNullableArg(@ullable String s)394 public void oneNullableArg(@Nullable String s) {} oneNullableArgThrows(@ullable String s)395 public void oneNullableArgThrows(@Nullable String s) { doThrow(s); } 396 twoArg(String s, Integer i)397 public void twoArg(String s, Integer i) { checkNotNull(s); i.intValue(); } twoMixedArgs(String s, @Nullable Integer i)398 public void twoMixedArgs(String s, @Nullable Integer i) { checkNotNull(s); } twoMixedArgsThrows(String s, @Nullable Integer i)399 public void twoMixedArgsThrows(String s, @Nullable Integer i) { 400 checkNotNull(s); doThrow(i); 401 } twoMixedArgs(@ullable Integer i, String s)402 public void twoMixedArgs(@Nullable Integer i, String s) { checkNotNull(s); } twoMixedArgsThrows(@ullable Integer i, String s)403 public void twoMixedArgsThrows(@Nullable Integer i, String s) { 404 checkNotNull(s); doThrow(i); 405 } twoNullableArgs(@ullable String s, @javax.annotation.Nullable Integer i)406 public void twoNullableArgs(@Nullable String s, 407 @javax.annotation.Nullable Integer i) {} twoNullableArgsThrowsFirstArg( @ullable String s, @Nullable Integer i)408 public void twoNullableArgsThrowsFirstArg( 409 @Nullable String s, @Nullable Integer i) { 410 doThrow(s); 411 } twoNullableArgsThrowsSecondArg( @ullable String s, @Nullable Integer i)412 public void twoNullableArgsThrowsSecondArg( 413 @Nullable String s, @Nullable Integer i) { 414 doThrow(i); 415 } staticOneArg(String s)416 public static void staticOneArg(String s) { checkNotNull(s); } staticOneNullableArg(@ullable String s)417 public static void staticOneNullableArg(@Nullable String s) {} staticOneNullableArgThrows(@ullable String s)418 public static void staticOneNullableArgThrows(@Nullable String s) { 419 doThrow(s); 420 } 421 } 422 testGoodClass()423 public void testGoodClass() { 424 shouldPass(new PassObject()); 425 } 426 427 private static class FailOneArgDoesntThrowNPE extends PassObject { oneArg(String s)428 @Override public void oneArg(String s) { 429 // Fail: missing NPE for s 430 } 431 } 432 testFailOneArgDoesntThrowNpe()433 public void testFailOneArgDoesntThrowNpe() { 434 shouldFail(new FailOneArgDoesntThrowNPE()); 435 } 436 437 private static class FailOneArgThrowsWrongType extends PassObject { oneArg(String s)438 @Override public void oneArg(String s) { 439 doThrow(s); // Fail: throwing non-NPE exception for null s 440 } 441 } 442 testFailOneArgThrowsWrongType()443 public void testFailOneArgThrowsWrongType() { 444 shouldFail(new FailOneArgThrowsWrongType()); 445 } 446 447 private static class PassOneNullableArgThrowsNPE extends PassObject { oneNullableArg(@ullable String s)448 @Override public void oneNullableArg(@Nullable String s) { 449 checkNotNull(s); // ok to throw NPE 450 } 451 } 452 testPassOneNullableArgThrowsNPE()453 public void testPassOneNullableArgThrowsNPE() { 454 shouldPass(new PassOneNullableArgThrowsNPE()); 455 } 456 457 private static class FailTwoArgsFirstArgDoesntThrowNPE extends PassObject { twoArg(String s, Integer i)458 @Override public void twoArg(String s, Integer i) { 459 // Fail: missing NPE for s 460 i.intValue(); 461 } 462 } 463 testFailTwoArgsFirstArgDoesntThrowNPE()464 public void testFailTwoArgsFirstArgDoesntThrowNPE() { 465 shouldFail(new FailTwoArgsFirstArgDoesntThrowNPE()); 466 } 467 468 private static class FailTwoArgsFirstArgThrowsWrongType extends PassObject { twoArg(String s, Integer i)469 @Override public void twoArg(String s, Integer i) { 470 doThrow(s); // Fail: throwing non-NPE exception for null s 471 i.intValue(); 472 } 473 } 474 testFailTwoArgsFirstArgThrowsWrongType()475 public void testFailTwoArgsFirstArgThrowsWrongType() { 476 shouldFail(new FailTwoArgsFirstArgThrowsWrongType()); 477 } 478 479 private static class FailTwoArgsSecondArgDoesntThrowNPE extends PassObject { twoArg(String s, Integer i)480 @Override public void twoArg(String s, Integer i) { 481 checkNotNull(s); 482 // Fail: missing NPE for i 483 } 484 } 485 testFailTwoArgsSecondArgDoesntThrowNPE()486 public void testFailTwoArgsSecondArgDoesntThrowNPE() { 487 shouldFail(new FailTwoArgsSecondArgDoesntThrowNPE()); 488 } 489 490 private static class FailTwoArgsSecondArgThrowsWrongType extends PassObject { twoArg(String s, Integer i)491 @Override public void twoArg(String s, Integer i) { 492 checkNotNull(s); 493 doThrow(i); // Fail: throwing non-NPE exception for null i 494 } 495 } 496 testFailTwoArgsSecondArgThrowsWrongType()497 public void testFailTwoArgsSecondArgThrowsWrongType() { 498 shouldFail(new FailTwoArgsSecondArgThrowsWrongType()); 499 } 500 501 private static class FailTwoMixedArgsFirstArgDoesntThrowNPE 502 extends PassObject { twoMixedArgs(String s, @Nullable Integer i)503 @Override public void twoMixedArgs(String s, @Nullable Integer i) { 504 // Fail: missing NPE for s 505 } 506 } 507 testFailTwoMixedArgsFirstArgDoesntThrowNPE()508 public void testFailTwoMixedArgsFirstArgDoesntThrowNPE() { 509 shouldFail(new FailTwoMixedArgsFirstArgDoesntThrowNPE()); 510 } 511 512 private static class FailTwoMixedArgsFirstArgThrowsWrongType 513 extends PassObject { twoMixedArgs(String s, @Nullable Integer i)514 @Override public void twoMixedArgs(String s, @Nullable Integer i) { 515 doThrow(s); // Fail: throwing non-NPE exception for null s 516 } 517 } 518 testFailTwoMixedArgsFirstArgThrowsWrongType()519 public void testFailTwoMixedArgsFirstArgThrowsWrongType() { 520 shouldFail(new FailTwoMixedArgsFirstArgThrowsWrongType()); 521 } 522 523 private static class PassTwoMixedArgsNullableArgThrowsNPE extends PassObject { twoMixedArgs(String s, @Nullable Integer i)524 @Override public void twoMixedArgs(String s, @Nullable Integer i) { 525 checkNotNull(s); 526 i.intValue(); // ok to throw NPE? 527 } 528 } 529 testPassTwoMixedArgsNullableArgThrowsNPE()530 public void testPassTwoMixedArgsNullableArgThrowsNPE() { 531 shouldPass(new PassTwoMixedArgsNullableArgThrowsNPE()); 532 } 533 534 private static class PassTwoMixedArgSecondNullableArgThrowsOther 535 extends PassObject { twoMixedArgs(String s, @Nullable Integer i)536 @Override public void twoMixedArgs(String s, @Nullable Integer i) { 537 checkNotNull(s); 538 doThrow(i); // ok to throw non-NPE exception for null i 539 } 540 } 541 testPassTwoMixedArgSecondNullableArgThrowsOther()542 public void testPassTwoMixedArgSecondNullableArgThrowsOther() { 543 shouldPass(new PassTwoMixedArgSecondNullableArgThrowsOther()); 544 } 545 546 private static class FailTwoMixedArgsSecondArgDoesntThrowNPE 547 extends PassObject { twoMixedArgs(@ullable Integer i, String s)548 @Override public void twoMixedArgs(@Nullable Integer i, String s) { 549 // Fail: missing NPE for null s 550 } 551 } 552 testFailTwoMixedArgsSecondArgDoesntThrowNPE()553 public void testFailTwoMixedArgsSecondArgDoesntThrowNPE() { 554 shouldFail(new FailTwoMixedArgsSecondArgDoesntThrowNPE()); 555 } 556 557 private static class FailTwoMixedArgsSecondArgThrowsWrongType 558 extends PassObject { twoMixedArgs(@ullable Integer i, String s)559 @Override public void twoMixedArgs(@Nullable Integer i, String s) { 560 doThrow(s); // Fail: throwing non-NPE exception for null s 561 } 562 } 563 testFailTwoMixedArgsSecondArgThrowsWrongType()564 public void testFailTwoMixedArgsSecondArgThrowsWrongType() { 565 shouldFail(new FailTwoMixedArgsSecondArgThrowsWrongType()); 566 } 567 568 private static class PassTwoNullableArgsFirstThrowsNPE extends PassObject { twoNullableArgs( @ullable String s, @Nullable Integer i)569 @Override public void twoNullableArgs( 570 @Nullable String s, @Nullable Integer i) { 571 checkNotNull(s); // ok to throw NPE? 572 } 573 } 574 testPassTwoNullableArgsFirstThrowsNPE()575 public void testPassTwoNullableArgsFirstThrowsNPE() { 576 shouldPass(new PassTwoNullableArgsFirstThrowsNPE()); 577 } 578 579 private static class PassTwoNullableArgsFirstThrowsOther extends PassObject { twoNullableArgs( @ullable String s, @Nullable Integer i)580 @Override public void twoNullableArgs( 581 @Nullable String s, @Nullable Integer i) { 582 doThrow(s); // ok to throw non-NPE exception for null s 583 } 584 } 585 testPassTwoNullableArgsFirstThrowsOther()586 public void testPassTwoNullableArgsFirstThrowsOther() { 587 shouldPass(new PassTwoNullableArgsFirstThrowsOther()); 588 } 589 590 private static class PassTwoNullableArgsSecondThrowsNPE extends PassObject { twoNullableArgs( @ullable String s, @Nullable Integer i)591 @Override public void twoNullableArgs( 592 @Nullable String s, @Nullable Integer i) { 593 i.intValue(); // ok to throw NPE? 594 } 595 } 596 testPassTwoNullableArgsSecondThrowsNPE()597 public void testPassTwoNullableArgsSecondThrowsNPE() { 598 shouldPass(new PassTwoNullableArgsSecondThrowsNPE()); 599 } 600 601 private static class PassTwoNullableArgsSecondThrowsOther extends PassObject { twoNullableArgs( @ullable String s, @Nullable Integer i)602 @Override public void twoNullableArgs( 603 @Nullable String s, @Nullable Integer i) { 604 doThrow(i); // ok to throw non-NPE exception for null i 605 } 606 } 607 testPassTwoNullableArgsSecondThrowsOther()608 public void testPassTwoNullableArgsSecondThrowsOther() { 609 shouldPass(new PassTwoNullableArgsSecondThrowsOther()); 610 } 611 612 private static class PassTwoNullableArgsNeitherThrowsAnything 613 extends PassObject { twoNullableArgs( @ullable String s, @Nullable Integer i)614 @Override public void twoNullableArgs( 615 @Nullable String s, @Nullable Integer i) { 616 // ok to do nothing 617 } 618 } 619 testPassTwoNullableArgsNeitherThrowsAnything()620 public void testPassTwoNullableArgsNeitherThrowsAnything() { 621 shouldPass(new PassTwoNullableArgsNeitherThrowsAnything()); 622 } 623 624 @SuppressWarnings("unused") // for NullPointerTester 625 private static abstract class BaseClassThatFailsToThrow { oneArg(String s)626 public void oneArg(String s) {} 627 } 628 629 private static class SubclassWithBadSuperclass 630 extends BaseClassThatFailsToThrow {} 631 testSubclassWithBadSuperclass()632 public void testSubclassWithBadSuperclass() { 633 shouldFail(new SubclassWithBadSuperclass()); 634 } 635 636 @SuppressWarnings("unused") // for NullPointerTester 637 private static abstract class BaseClassThatFailsToThrowForPackagePrivate { packagePrivateOneArg(String s)638 void packagePrivateOneArg(String s) {} 639 } 640 641 private static class SubclassWithBadSuperclassForPackagePrivate 642 extends BaseClassThatFailsToThrowForPackagePrivate {} 643 testSubclassWithBadSuperclassForPackagePrivateMethod()644 public void testSubclassWithBadSuperclassForPackagePrivateMethod() { 645 shouldFail( 646 new SubclassWithBadSuperclassForPackagePrivate(), Visibility.PACKAGE); 647 } 648 649 @SuppressWarnings("unused") // for NullPointerTester 650 private static abstract class BaseClassThatFailsToThrowForProtected { protectedOneArg(String s)651 protected void protectedOneArg(String s) {} 652 } 653 654 private static class SubclassWithBadSuperclassForProtected 655 extends BaseClassThatFailsToThrowForProtected {} 656 testSubclassWithBadSuperclassForPackageProtectedMethod()657 public void testSubclassWithBadSuperclassForPackageProtectedMethod() { 658 shouldFail( 659 new SubclassWithBadSuperclassForProtected(), Visibility.PROTECTED); 660 } 661 662 private static class SubclassThatOverridesBadSuperclassMethod 663 extends BaseClassThatFailsToThrow { oneArg(@ullable String s)664 @Override public void oneArg(@Nullable String s) {} 665 } 666 testSubclassThatOverridesBadSuperclassMethod()667 public void testSubclassThatOverridesBadSuperclassMethod() { 668 shouldPass(new SubclassThatOverridesBadSuperclassMethod()); 669 } 670 671 @SuppressWarnings("unused") // for NullPointerTester 672 private static class SubclassOverridesTheWrongMethod 673 extends BaseClassThatFailsToThrow { oneArg(@ullable CharSequence s)674 public void oneArg(@Nullable CharSequence s) {} 675 } 676 testSubclassOverridesTheWrongMethod()677 public void testSubclassOverridesTheWrongMethod() { 678 shouldFail(new SubclassOverridesTheWrongMethod()); 679 } 680 681 @SuppressWarnings("unused") // for NullPointerTester 682 private static class ClassThatFailsToThrowForStatic { staticOneArg(String s)683 static void staticOneArg(String s) {} 684 } 685 testClassThatFailsToThrowForStatic()686 public void testClassThatFailsToThrowForStatic() { 687 shouldFail(ClassThatFailsToThrowForStatic.class); 688 } 689 690 private static class SubclassThatFailsToThrowForStatic 691 extends ClassThatFailsToThrowForStatic {} 692 testSubclassThatFailsToThrowForStatic()693 public void testSubclassThatFailsToThrowForStatic() { 694 shouldFail(SubclassThatFailsToThrowForStatic.class); 695 } 696 697 private static class SubclassThatTriesToOverrideBadStaticMethod 698 extends ClassThatFailsToThrowForStatic { staticOneArg(@ullable String s)699 static void staticOneArg(@Nullable String s) {} 700 } 701 testSubclassThatTriesToOverrideBadStaticMethod()702 public void testSubclassThatTriesToOverrideBadStaticMethod() { 703 shouldFail(SubclassThatTriesToOverrideBadStaticMethod.class); 704 } 705 706 private static final class HardToCreate { HardToCreate(HardToCreate x)707 private HardToCreate(HardToCreate x) {} 708 } 709 710 @SuppressWarnings("unused") // used by reflection 711 private static class CanCreateDefault { foo(@ullable HardToCreate ignored, String required)712 public void foo(@Nullable HardToCreate ignored, String required) { 713 checkNotNull(required); 714 } 715 } 716 testCanCreateDefault()717 public void testCanCreateDefault() { 718 shouldPass(new CanCreateDefault()); 719 } 720 721 @SuppressWarnings("unused") // used by reflection 722 private static class CannotCreateDefault { foo(HardToCreate ignored, String required)723 public void foo(HardToCreate ignored, String required) { 724 checkNotNull(ignored); 725 checkNotNull(required); 726 } 727 } 728 testCannotCreateDefault()729 public void testCannotCreateDefault() { 730 shouldFail(new CannotCreateDefault()); 731 } 732 shouldPass(Object instance, Visibility visibility)733 private static void shouldPass(Object instance, Visibility visibility) { 734 new NullPointerTester().testInstanceMethods(instance, visibility); 735 } 736 shouldPass(Object instance)737 private static void shouldPass(Object instance) { 738 shouldPass(instance, Visibility.PACKAGE); 739 shouldPass(instance, Visibility.PROTECTED); 740 shouldPass(instance, Visibility.PUBLIC); 741 } 742 743 // TODO(cpovirk): eliminate surprising Object/Class overloading of shouldFail 744 shouldFail(Object instance, Visibility visibility)745 private static void shouldFail(Object instance, Visibility visibility) { 746 try { 747 new NullPointerTester().testInstanceMethods(instance, visibility); 748 } catch (AssertionFailedError expected) { 749 return; 750 } 751 fail("Should detect problem in " + instance.getClass().getSimpleName()); 752 } 753 shouldFail(Object instance)754 private static void shouldFail(Object instance) { 755 shouldFail(instance, Visibility.PACKAGE); 756 shouldFail(instance, Visibility.PROTECTED); 757 shouldFail(instance, Visibility.PUBLIC); 758 } 759 shouldFail(Class<?> cls, Visibility visibility)760 private static void shouldFail(Class<?> cls, Visibility visibility) { 761 try { 762 new NullPointerTester().testStaticMethods(cls, visibility); 763 } catch (AssertionFailedError expected) { 764 return; 765 } 766 fail("Should detect problem in " + cls.getSimpleName()); 767 } 768 shouldFail(Class<?> cls)769 private static void shouldFail(Class<?> cls) { 770 shouldFail(cls, Visibility.PACKAGE); 771 } 772 773 @SuppressWarnings("unused") // used by reflection 774 private static class PrivateClassWithPrivateConstructor { PrivateClassWithPrivateConstructor(@ullable Integer argument)775 private PrivateClassWithPrivateConstructor(@Nullable Integer argument) {} 776 } 777 testPrivateClass()778 public void testPrivateClass() { 779 NullPointerTester tester = new NullPointerTester(); 780 for (Constructor<?> constructor 781 : PrivateClassWithPrivateConstructor.class.getDeclaredConstructors()) { 782 tester.testConstructor(constructor); 783 } 784 } 785 786 private interface Foo<T> { doSomething(T bar, Integer baz)787 void doSomething(T bar, Integer baz); 788 } 789 790 private static class StringFoo implements Foo<String> { 791 doSomething(String bar, Integer baz)792 @Override public void doSomething(String bar, Integer baz) { 793 checkNotNull(bar); 794 checkNotNull(baz); 795 } 796 } 797 testBridgeMethodIgnored()798 public void testBridgeMethodIgnored() { 799 new NullPointerTester().testAllPublicInstanceMethods(new StringFoo()); 800 } 801 802 private static abstract class DefaultValueChecker { 803 804 private final Map<Integer, Object> arguments = Maps.newHashMap(); 805 runTester()806 final DefaultValueChecker runTester() { 807 new NullPointerTester() 808 .testInstanceMethods(this, Visibility.PACKAGE); 809 return this; 810 } 811 assertNonNullValues(Object... expectedValues)812 final void assertNonNullValues(Object... expectedValues) { 813 assertEquals(expectedValues.length, arguments.size()); 814 for (int i = 0; i < expectedValues.length; i++) { 815 assertEquals("Default value for parameter #" + i, 816 expectedValues[i], arguments.get(i)); 817 } 818 } 819 getDefaultParameterValue(int position)820 final Object getDefaultParameterValue(int position) { 821 return arguments.get(position); 822 } 823 calledWith(Object... args)824 final void calledWith(Object... args) { 825 for (int i = 0; i < args.length; i++) { 826 if (args[i] != null) { 827 arguments.put(i, args[i]); 828 } 829 } 830 for (Object arg : args) { 831 checkNotNull(arg); // to fulfill null check 832 } 833 } 834 } 835 836 private enum Gender { 837 MALE, FEMALE 838 } 839 840 private static class AllDefaultValuesChecker extends DefaultValueChecker { 841 842 @SuppressWarnings("unused") // called by NullPointerTester checkDefaultValuesForTheseTypes( Gender gender, Integer integer, int i, String string, CharSequence charSequence, List<String> list, ImmutableList<Integer> immutableList, Map<String, Integer> map, ImmutableMap<String, String> immutableMap, Set<String> set, ImmutableSet<Integer> immutableSet, SortedSet<Number> sortedSet, ImmutableSortedSet<Number> immutableSortedSet, Multiset<String> multiset, ImmutableMultiset<Integer> immutableMultiset, Multimap<String, Integer> multimap, ImmutableMultimap<String, Integer> immutableMultimap, Table<String, Integer, Exception> table, ImmutableTable<Integer, String, Exception> immutableTable)843 public void checkDefaultValuesForTheseTypes( 844 Gender gender, 845 Integer integer, int i, 846 String string, CharSequence charSequence, 847 List<String> list, 848 ImmutableList<Integer> immutableList, 849 Map<String, Integer> map, 850 ImmutableMap<String, String> immutableMap, 851 Set<String> set, 852 ImmutableSet<Integer> immutableSet, 853 SortedSet<Number> sortedSet, 854 ImmutableSortedSet<Number> immutableSortedSet, 855 Multiset<String> multiset, 856 ImmutableMultiset<Integer> immutableMultiset, 857 Multimap<String, Integer> multimap, 858 ImmutableMultimap<String, Integer> immutableMultimap, 859 Table<String, Integer, Exception> table, 860 ImmutableTable<Integer, String, Exception> immutableTable) { 861 calledWith( 862 gender, 863 integer, i, 864 string, charSequence, 865 list, immutableList, 866 map, immutableMap, 867 set, immutableSet, 868 sortedSet, immutableSortedSet, 869 multiset, immutableMultiset, 870 multimap, immutableMultimap, 871 table, immutableTable); 872 } 873 check()874 final void check() { 875 runTester().assertNonNullValues( 876 Gender.MALE, 877 Integer.valueOf(0), 0, 878 "", "", 879 ImmutableList.of(), ImmutableList.of(), 880 ImmutableMap.of(), ImmutableMap.of(), 881 ImmutableSet.of(), ImmutableSet.of(), 882 ImmutableSortedSet.of(), ImmutableSortedSet.of(), 883 ImmutableMultiset.of(), ImmutableMultiset.of(), 884 ImmutableMultimap.of(), ImmutableMultimap.of(), 885 ImmutableTable.of(), ImmutableTable.of()); 886 } 887 } 888 testDefaultValues()889 public void testDefaultValues() { 890 new AllDefaultValuesChecker().check(); 891 } 892 893 private static class ObjectArrayDefaultValueChecker 894 extends DefaultValueChecker { 895 896 @SuppressWarnings("unused") // called by NullPointerTester checkArray(Object[] array, String s)897 public void checkArray(Object[] array, String s) { 898 calledWith(array, s); 899 } 900 check()901 void check() { 902 runTester(); 903 Object[] defaultArray = (Object[]) getDefaultParameterValue(0); 904 assertEquals(0, defaultArray.length); 905 } 906 } 907 testObjectArrayDefaultValue()908 public void testObjectArrayDefaultValue() { 909 new ObjectArrayDefaultValueChecker().check(); 910 } 911 912 private static class StringArrayDefaultValueChecker 913 extends DefaultValueChecker { 914 915 @SuppressWarnings("unused") // called by NullPointerTester checkArray(String[] array, String s)916 public void checkArray(String[] array, String s) { 917 calledWith(array, s); 918 } 919 check()920 void check() { 921 runTester(); 922 String[] defaultArray = (String[]) getDefaultParameterValue(0); 923 assertEquals(0, defaultArray.length); 924 } 925 } 926 testStringArrayDefaultValue()927 public void testStringArrayDefaultValue() { 928 new StringArrayDefaultValueChecker().check(); 929 } 930 931 private static class IntArrayDefaultValueChecker 932 extends DefaultValueChecker { 933 934 @SuppressWarnings("unused") // called by NullPointerTester checkArray(int[] array, String s)935 public void checkArray(int[] array, String s) { 936 calledWith(array, s); 937 } 938 check()939 void check() { 940 runTester(); 941 int[] defaultArray = (int[]) getDefaultParameterValue(0); 942 assertEquals(0, defaultArray.length); 943 } 944 } 945 testIntArrayDefaultValue()946 public void testIntArrayDefaultValue() { 947 new IntArrayDefaultValueChecker().check(); 948 } 949 950 private enum EmptyEnum {} 951 952 private static class EmptyEnumDefaultValueChecker 953 extends DefaultValueChecker { 954 955 @SuppressWarnings("unused") // called by NullPointerTester checkArray(EmptyEnum object, String s)956 public void checkArray(EmptyEnum object, String s) { 957 calledWith(object, s); 958 } 959 check()960 void check() { 961 try { 962 runTester(); 963 } catch (AssertionError expected) { 964 return; 965 } 966 fail("Should have failed because enum has no constant"); 967 } 968 } 969 testEmptyEnumDefaultValue()970 public void testEmptyEnumDefaultValue() { 971 new EmptyEnumDefaultValueChecker().check(); 972 } 973 974 private static class GenericClassTypeDefaultValueChecker 975 extends DefaultValueChecker { 976 977 @SuppressWarnings("unused") // called by NullPointerTester checkArray(Class<? extends List<?>> cls, String s)978 public void checkArray(Class<? extends List<?>> cls, String s) { 979 calledWith(cls, s); 980 } 981 check()982 void check() { 983 runTester(); 984 Class<?> defaultClass = (Class<?>) getDefaultParameterValue(0); 985 assertEquals(List.class, defaultClass); 986 } 987 } 988 testGenericClassDefaultValue()989 public void testGenericClassDefaultValue() { 990 new GenericClassTypeDefaultValueChecker().check(); 991 } 992 993 private static class NonGenericClassTypeDefaultValueChecker 994 extends DefaultValueChecker { 995 996 @SuppressWarnings("unused") // called by NullPointerTester checkArray(@uppressWarnings"rawtypes") Class cls, String s)997 public void checkArray(@SuppressWarnings("rawtypes") Class cls, String s) { 998 calledWith(cls, s); 999 } 1000 check()1001 void check() { 1002 runTester(); 1003 Class<?> defaultClass = (Class<?>) getDefaultParameterValue(0); 1004 assertEquals(Object.class, defaultClass); 1005 } 1006 } 1007 testNonGenericClassDefaultValue()1008 public void testNonGenericClassDefaultValue() { 1009 new NonGenericClassTypeDefaultValueChecker().check(); 1010 } 1011 1012 private static class GenericTypeTokenDefaultValueChecker 1013 extends DefaultValueChecker { 1014 1015 @SuppressWarnings("unused") // called by NullPointerTester checkArray( TypeToken<? extends List<? super Number>> type, String s)1016 public void checkArray( 1017 TypeToken<? extends List<? super Number>> type, String s) { 1018 calledWith(type, s); 1019 } 1020 check()1021 void check() { 1022 runTester(); 1023 TypeToken<?> defaultType = (TypeToken<?>) getDefaultParameterValue(0); 1024 assertTrue(new TypeToken<List<? super Number>>() {} 1025 .isAssignableFrom(defaultType)); 1026 } 1027 } 1028 testGenericTypeTokenDefaultValue()1029 public void testGenericTypeTokenDefaultValue() { 1030 new GenericTypeTokenDefaultValueChecker().check(); 1031 } 1032 1033 private static class NonGenericTypeTokenDefaultValueChecker 1034 extends DefaultValueChecker { 1035 1036 @SuppressWarnings("unused") // called by NullPointerTester checkArray( @uppressWarnings"rawtypes") TypeToken type, String s)1037 public void checkArray( 1038 @SuppressWarnings("rawtypes") TypeToken type, String s) { 1039 calledWith(type, s); 1040 } 1041 check()1042 void check() { 1043 runTester(); 1044 TypeToken<?> defaultType = (TypeToken<?>) getDefaultParameterValue(0); 1045 assertEquals(new TypeToken<Object>() {}, defaultType); 1046 } 1047 } 1048 testNonGenericTypeTokenDefaultValue()1049 public void testNonGenericTypeTokenDefaultValue() { 1050 new NonGenericTypeTokenDefaultValueChecker().check(); 1051 } 1052 1053 private interface FromTo<F, T> extends Function<F, T> {} 1054 1055 private static class GenericInterfaceDefaultValueChecker 1056 extends DefaultValueChecker { 1057 1058 @SuppressWarnings("unused") // called by NullPointerTester checkArray(FromTo<String, Integer> f, String s)1059 public void checkArray(FromTo<String, Integer> f, String s) { 1060 calledWith(f, s); 1061 } 1062 check()1063 void check() { 1064 runTester(); 1065 FromTo<?, ?> defaultFunction = (FromTo<?, ?>) getDefaultParameterValue(0); 1066 assertEquals(0, defaultFunction.apply(null)); 1067 } 1068 } 1069 testGenericInterfaceDefaultValue()1070 public void testGenericInterfaceDefaultValue() { 1071 new GenericInterfaceDefaultValueChecker().check(); 1072 } 1073 1074 private interface NullRejectingFromTo<F, T> extends Function<F, T> { apply(F from)1075 @Override public abstract T apply(F from); 1076 } 1077 1078 private static class NullRejectingInterfaceDefaultValueChecker 1079 extends DefaultValueChecker { 1080 1081 @SuppressWarnings("unused") // called by NullPointerTester checkArray(NullRejectingFromTo<String, Integer> f, String s)1082 public void checkArray(NullRejectingFromTo<String, Integer> f, String s) { 1083 calledWith(f, s); 1084 } 1085 check()1086 void check() { 1087 runTester(); 1088 NullRejectingFromTo<?, ?> defaultFunction = (NullRejectingFromTo<?, ?>) 1089 getDefaultParameterValue(0); 1090 assertNotNull(defaultFunction); 1091 try { 1092 defaultFunction.apply(null); 1093 fail("Proxy Should have rejected null"); 1094 } catch (NullPointerException expected) {} 1095 } 1096 } 1097 testNullRejectingInterfaceDefaultValue()1098 public void testNullRejectingInterfaceDefaultValue() { 1099 new NullRejectingInterfaceDefaultValueChecker().check(); 1100 } 1101 1102 private static class MultipleInterfacesDefaultValueChecker 1103 extends DefaultValueChecker { 1104 1105 @SuppressWarnings("unused") // called by NullPointerTester checkArray( T f, String s)1106 public <T extends FromTo<String, Integer> & Supplier<Long>> void checkArray( 1107 T f, String s) { 1108 calledWith(f, s); 1109 } 1110 check()1111 void check() { 1112 runTester(); 1113 FromTo<?, ?> defaultFunction = (FromTo<?, ?>) getDefaultParameterValue(0); 1114 assertEquals(0, defaultFunction.apply(null)); 1115 Supplier<?> defaultSupplier = (Supplier<?>) defaultFunction; 1116 assertEquals(Long.valueOf(0), defaultSupplier.get()); 1117 } 1118 } 1119 testMultipleInterfacesDefaultValue()1120 public void testMultipleInterfacesDefaultValue() { 1121 new MultipleInterfacesDefaultValueChecker().check(); 1122 } 1123 1124 private static class GenericInterface2DefaultValueChecker 1125 extends DefaultValueChecker { 1126 1127 @SuppressWarnings("unused") // called by NullPointerTester checkArray(FromTo<String, FromTo<Integer, String>> f, String s)1128 public void checkArray(FromTo<String, FromTo<Integer, String>> f, String s) { 1129 calledWith(f, s); 1130 } 1131 check()1132 void check() { 1133 runTester(); 1134 FromTo<?, ?> defaultFunction = (FromTo<?, ?>) getDefaultParameterValue(0); 1135 FromTo<?, ?> returnValue = (FromTo<?, ?>) defaultFunction.apply(null); 1136 assertEquals("", returnValue.apply(null)); 1137 } 1138 } 1139 testGenericInterfaceReturnedByGenericMethod()1140 public void testGenericInterfaceReturnedByGenericMethod() { 1141 new GenericInterface2DefaultValueChecker().check(); 1142 } 1143 1144 private static abstract class AbstractGenericDefaultValueChecker<T> 1145 extends DefaultValueChecker { 1146 1147 @SuppressWarnings("unused") // called by NullPointerTester checkGeneric(T value, String s)1148 public void checkGeneric(T value, String s) { 1149 calledWith(value, s); 1150 } 1151 } 1152 1153 private static class GenericDefaultValueResolvedToStringChecker 1154 extends AbstractGenericDefaultValueChecker<String> { check()1155 void check() { 1156 runTester(); 1157 assertEquals("", getDefaultParameterValue(0)); 1158 } 1159 } 1160 testGenericTypeResolvedForDefaultValue()1161 public void testGenericTypeResolvedForDefaultValue() { 1162 new GenericDefaultValueResolvedToStringChecker().check(); 1163 } 1164 1165 private static abstract 1166 class AbstractGenericDefaultValueForPackagePrivateMethodChecker<T> 1167 extends DefaultValueChecker { 1168 1169 @SuppressWarnings("unused") // called by NullPointerTester checkGeneric(T value, String s)1170 void checkGeneric(T value, String s) { 1171 calledWith(value, s); 1172 } 1173 } 1174 1175 private static 1176 class DefaultValueForPackagePrivateMethodResolvedToStringChecker 1177 extends AbstractGenericDefaultValueForPackagePrivateMethodChecker<String> 1178 { check()1179 void check() { 1180 runTester(); 1181 assertEquals("", getDefaultParameterValue(0)); 1182 } 1183 } 1184 testDefaultValueResolvedForPackagePrivateMethod()1185 public void testDefaultValueResolvedForPackagePrivateMethod() { 1186 new DefaultValueForPackagePrivateMethodResolvedToStringChecker().check(); 1187 } 1188 1189 private static class ConverterDefaultValueChecker 1190 extends DefaultValueChecker { 1191 1192 @SuppressWarnings("unused") // called by NullPointerTester checkArray(Converter<String, Integer> c, String s)1193 public void checkArray(Converter<String, Integer> c, String s) { 1194 calledWith(c, s); 1195 } 1196 check()1197 void check() { 1198 runTester(); 1199 @SuppressWarnings("unchecked") // We are checking it anyway 1200 Converter<String, Integer> defaultConverter = (Converter<String, Integer>) 1201 getDefaultParameterValue(0); 1202 assertEquals(Integer.valueOf(0), defaultConverter.convert("anything")); 1203 assertEquals("", defaultConverter.reverse().convert(123)); 1204 assertNull(defaultConverter.convert(null)); 1205 assertNull(defaultConverter.reverse().convert(null)); 1206 } 1207 } 1208 testConverterDefaultValue()1209 public void testConverterDefaultValue() { 1210 new ConverterDefaultValueChecker().check(); 1211 } 1212 1213 private static class VisibilityMethods { 1214 1215 @SuppressWarnings("unused") // Called by reflection privateMethod()1216 private void privateMethod() {} 1217 1218 @SuppressWarnings("unused") // Called by reflection packagePrivateMethod()1219 void packagePrivateMethod() {} 1220 1221 @SuppressWarnings("unused") // Called by reflection protectedMethod()1222 protected void protectedMethod() {} 1223 1224 @SuppressWarnings("unused") // Called by reflection publicMethod()1225 public void publicMethod() {} 1226 } 1227 testVisibility_public()1228 public void testVisibility_public() throws Exception { 1229 assertFalse(Visibility.PUBLIC.isVisible( 1230 VisibilityMethods.class.getDeclaredMethod("privateMethod"))); 1231 assertFalse(Visibility.PUBLIC.isVisible( 1232 VisibilityMethods.class.getDeclaredMethod("packagePrivateMethod"))); 1233 assertFalse(Visibility.PUBLIC.isVisible( 1234 VisibilityMethods.class.getDeclaredMethod("protectedMethod"))); 1235 assertTrue(Visibility.PUBLIC.isVisible( 1236 VisibilityMethods.class.getDeclaredMethod("publicMethod"))); 1237 } 1238 testVisibility_protected()1239 public void testVisibility_protected() throws Exception { 1240 assertFalse(Visibility.PROTECTED.isVisible( 1241 VisibilityMethods.class.getDeclaredMethod("privateMethod"))); 1242 assertFalse(Visibility.PROTECTED.isVisible( 1243 VisibilityMethods.class.getDeclaredMethod("packagePrivateMethod"))); 1244 assertTrue(Visibility.PROTECTED.isVisible( 1245 VisibilityMethods.class.getDeclaredMethod("protectedMethod"))); 1246 assertTrue(Visibility.PROTECTED.isVisible( 1247 VisibilityMethods.class.getDeclaredMethod("publicMethod"))); 1248 } 1249 testVisibility_package()1250 public void testVisibility_package() throws Exception { 1251 assertFalse(Visibility.PACKAGE.isVisible( 1252 VisibilityMethods.class.getDeclaredMethod("privateMethod"))); 1253 assertTrue(Visibility.PACKAGE.isVisible( 1254 VisibilityMethods.class.getDeclaredMethod("packagePrivateMethod"))); 1255 assertTrue(Visibility.PACKAGE.isVisible( 1256 VisibilityMethods.class.getDeclaredMethod("protectedMethod"))); 1257 assertTrue(Visibility.PACKAGE.isVisible( 1258 VisibilityMethods.class.getDeclaredMethod("publicMethod"))); 1259 } 1260 1261 private class Inner { Inner(String s)1262 public Inner(String s) { 1263 checkNotNull(s); 1264 } 1265 } 1266 testNonStaticInnerClass()1267 public void testNonStaticInnerClass() { 1268 try { 1269 new NullPointerTester().testAllPublicConstructors(Inner.class); 1270 fail(); 1271 } catch (IllegalArgumentException expected) { 1272 assertThat(expected.getMessage()).contains("inner class"); 1273 } 1274 } 1275 } 1276