11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2005 The Guava Authors
31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License");
51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * you may not use this file except in compliance with the License.
61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * You may obtain a copy of the License at
71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0
91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software
111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS,
121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the License for the specific language governing permissions and
141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License.
151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.testing;
181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkNotNull;
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.Lists;
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.Sets;
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport junit.framework.AssertionFailedError;
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport junit.framework.TestCase;
261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.lang.reflect.Constructor;
281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.lang.reflect.Method;
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.List;
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Set;
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport javax.annotation.Nullable;
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unit test for {@link NullPointerTester}.
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Kevin Bourrillion
381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Mick Killianey
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic class NullPointerTesterTest extends TestCase {
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private NullPointerTester tester;
431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override protected void setUp() throws Exception {
451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    super.setUp();
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    tester = new NullPointerTester();
471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** Non-NPE RuntimeException. */
501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static class FooException extends RuntimeException {
511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private static final long serialVersionUID = 1L;
521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Class for testing all permutations of static/non-static one-argument
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * methods using methodParameter().
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static class OneArg {
591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public static void staticOneArgCorrectlyThrowsNpe(String s) {
611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      checkNotNull(s); // expect NPE here on null
621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public static void staticOneArgThrowsOtherThanNpe(String s) {
641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new FooException();  // should catch as failure
651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public static void staticOneArgShouldThrowNpeButDoesnt(String s) {
671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // should catch as failure
681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public static void
701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    staticOneArgNullableCorrectlyDoesNotThrowNPE(@Nullable String s) {
711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // null?  no problem
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public static void
741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    staticOneArgNullableCorrectlyThrowsOtherThanNPE(@Nullable String s) {
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new FooException(); // ok, as long as it's not NullPointerException
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public static void
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    staticOneArgNullableThrowsNPE(@Nullable String s) {
791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      checkNotNull(s); // doesn't check if you said you'd accept null, but you don't
801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public void oneArgCorrectlyThrowsNpe(String s) {
831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      checkNotNull(s); // expect NPE here on null
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public void oneArgThrowsOtherThanNpe(String s) {
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new FooException();  // should catch as failure
871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public void oneArgShouldThrowNpeButDoesnt(String s) {
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // should catch as failure
901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public void oneArgNullableCorrectlyDoesNotThrowNPE(@Nullable String s) {
921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // null?  no problem
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public void oneArgNullableCorrectlyThrowsOtherThanNPE(@Nullable String s) {
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new FooException(); // ok, as long as it's not NullPointerException
961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public void oneArgNullableThrowsNPE(@Nullable String s) {
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      checkNotNull(s); // doesn't check if you said you'd accept null, but you don't
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final String[] STATIC_ONE_ARG_METHODS_SHOULD_PASS = {
1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    "staticOneArgCorrectlyThrowsNpe",
1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    "staticOneArgNullableCorrectlyDoesNotThrowNPE",
1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    "staticOneArgNullableCorrectlyThrowsOtherThanNPE",
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    "staticOneArgNullableThrowsNPE",
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  };
1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final String[] STATIC_ONE_ARG_METHODS_SHOULD_FAIL = {
1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    "staticOneArgThrowsOtherThanNpe",
1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    "staticOneArgShouldThrowNpeButDoesnt",
1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  };
1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final String[] NONSTATIC_ONE_ARG_METHODS_SHOULD_PASS = {
1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    "oneArgCorrectlyThrowsNpe",
1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    "oneArgNullableCorrectlyDoesNotThrowNPE",
1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    "oneArgNullableCorrectlyThrowsOtherThanNPE",
1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    "oneArgNullableThrowsNPE",
1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  };
1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final String[] NONSTATIC_ONE_ARG_METHODS_SHOULD_FAIL = {
1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    "oneArgThrowsOtherThanNpe",
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    "oneArgShouldThrowNpeButDoesnt",
1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  };
1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testStaticOneArgMethodsThatShouldPass() throws Exception {
1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (String methodName : STATIC_ONE_ARG_METHODS_SHOULD_PASS) {
1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Method method = OneArg.class.getMethod(methodName, String.class);
1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        tester.testMethodParameter(OneArg.class, method, 0);
1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (AssertionFailedError unexpected) {
1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        fail("Should not have flagged method " + methodName);
1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testStaticOneArgMethodsThatShouldFail() throws Exception {
1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (String methodName : STATIC_ONE_ARG_METHODS_SHOULD_FAIL) {
1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Method method = OneArg.class.getMethod(methodName, String.class);
1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      boolean foundProblem = false;
1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        tester.testMethodParameter(OneArg.class, method, 0);
1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (AssertionFailedError expected) {
1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        foundProblem = true;
1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue("Should report error in method " + methodName, foundProblem);
1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testNonStaticOneArgMethodsThatShouldPass() throws Exception {
1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    OneArg foo = new OneArg();
1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (String methodName : NONSTATIC_ONE_ARG_METHODS_SHOULD_PASS) {
1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Method method = OneArg.class.getMethod(methodName, String.class);
1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        tester.testMethodParameter(foo, method, 0);
1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (AssertionFailedError unexpected) {
1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        fail("Should not have flagged method " + methodName);
1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testNonStaticOneArgMethodsThatShouldFail() throws Exception {
1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    OneArg foo = new OneArg();
1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (String methodName : NONSTATIC_ONE_ARG_METHODS_SHOULD_FAIL) {
1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Method method = OneArg.class.getMethod(methodName, String.class);
1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      boolean foundProblem = false;
1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        tester.testMethodParameter(foo, method, 0);
1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (AssertionFailedError expected) {
1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        foundProblem = true;
1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue("Should report error in method " + methodName, foundProblem);
1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Class for testing all permutations of nullable/non-nullable two-argument
1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * methods using testMethod().
1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   normalNormal:  two params, neither is Nullable
1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   nullableNormal:  only first param is Nullable
1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   normalNullable:  only second param is Nullable
1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   nullableNullable:  both params are Nullable
1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static class TwoArg {
1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /** Action to take on a null param. */
1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public enum Action {
1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      THROW_A_NPE {
1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public void act() {
1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          throw new NullPointerException();
1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      },
1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      THROW_OTHER {
1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public void act() {
1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          throw new FooException();
1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      },
1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      JUST_RETURN {
1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public void act() {}
1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      };
1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      public abstract void act();
2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Action actionWhenFirstParamIsNull;
2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Action actionWhenSecondParamIsNull;
2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public TwoArg(
2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Action actionWhenFirstParamIsNull,
2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Action actionWhenSecondParamIsNull) {
2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.actionWhenFirstParamIsNull = actionWhenFirstParamIsNull;
2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.actionWhenSecondParamIsNull = actionWhenSecondParamIsNull;
2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /** Method that decides how to react to parameters. */
2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public void reactToNullParameters(Object first, Object second) {
2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (first == null) {
2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        actionWhenFirstParamIsNull.act();
2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (second == null) {
2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        actionWhenSecondParamIsNull.act();
2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /** Two-arg method with no Nullable params. */
2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public void normalNormal(String first, Integer second) {
2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      reactToNullParameters(first, second);
2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /** Two-arg method with the second param Nullable. */
2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public void normalNullable(String first, @Nullable Integer second) {
2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      reactToNullParameters(first, second);
2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /** Two-arg method with the first param Nullable. */
2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public void nullableNormal(@Nullable String first, Integer second) {
2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      reactToNullParameters(first, second);
2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /** Two-arg method with the both params Nullable. */
2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public void nullableNullable(
2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Nullable String first, @Nullable Integer second) {
2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      reactToNullParameters(first, second);
2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /** To provide sanity during debugging. */
2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public String toString() {
2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return String.format("Bar(%s, %s)",
2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          actionWhenFirstParamIsNull, actionWhenSecondParamIsNull);
2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void verifyBarPass(Method method, TwoArg bar) throws Exception {
2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      tester.testMethod(bar, method);
2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (AssertionFailedError incorrectError) {
2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      String errorMessage = String.format(
2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          "Should not have flagged method %s for %s", method.getName(), bar);
2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertNull(errorMessage, incorrectError);
2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void verifyBarFail(Method method, TwoArg bar) throws Exception {
2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      tester.testMethod(bar, method);
2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (AssertionFailedError expected) {
2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return; // good...we wanted a failure
2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    String errorMessage = String.format(
2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        "Should have flagged method %s for %s", method.getName(), bar);
2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    fail(errorMessage);
2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTwoArgNormalNormal() throws Exception {
2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Method method = TwoArg.class.getMethod(
2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        "normalNormal", String.class, Integer.class);
2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (TwoArg.Action first : TwoArg.Action.values()) {
2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (TwoArg.Action second : TwoArg.Action.values()) {
2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        TwoArg bar = new TwoArg(first, second);
2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        if (first.equals(TwoArg.Action.THROW_A_NPE)
2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            && second.equals(TwoArg.Action.THROW_A_NPE)) {
2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          verifyBarPass(method, bar); // require both params to throw NPE
2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        } else {
2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          verifyBarFail(method, bar);
2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTwoArgNormalNullable() throws Exception {
2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Method method = TwoArg.class.getMethod(
2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        "normalNullable", String.class, Integer.class);
2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (TwoArg.Action first : TwoArg.Action.values()) {
2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (TwoArg.Action second : TwoArg.Action.values()) {
2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        TwoArg bar = new TwoArg(first, second);
2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        if (first.equals(TwoArg.Action.THROW_A_NPE)) {
2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          verifyBarPass(method, bar); // only pass if 1st param throws NPE
2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        } else {
2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          verifyBarFail(method, bar);
2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTwoArgNullableNormal() throws Exception {
3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Method method = TwoArg.class.getMethod(
3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        "nullableNormal", String.class, Integer.class);
3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (TwoArg.Action first : TwoArg.Action.values()) {
3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (TwoArg.Action second : TwoArg.Action.values()) {
3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        TwoArg bar = new TwoArg(first, second);
3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        if (second.equals(TwoArg.Action.THROW_A_NPE)) {
3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          verifyBarPass(method, bar); // only pass if 2nd param throws NPE
3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        } else {
3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          verifyBarFail(method, bar);
3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
3121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
3131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTwoArgNullableNullable() throws Exception {
3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Method method = TwoArg.class.getMethod(
3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        "nullableNullable", String.class, Integer.class);
3191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (TwoArg.Action first : TwoArg.Action.values()) {
3201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (TwoArg.Action second : TwoArg.Action.values()) {
3211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        TwoArg bar = new TwoArg(first, second);
3221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        verifyBarPass(method, bar); // All args nullable:  anything goes!
3231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
3241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /*
3281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * This next part consists of several sample classes that provide
3291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * demonstrations of conditions that cause NullPointerTester
3301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * to succeed/fail.
3311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Add naughty classes to failClasses to verify that NullPointerTest
3331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * raises an AssertionFailedError.
3341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Add acceptable classes to passClasses to verify that NullPointerTest
3361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * doesn't complain.
3371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
3381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** List of classes that NullPointerTester should pass as acceptable. */
3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static List<Class<?>> failClasses = Lists.newArrayList();
3411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** List of classes that NullPointerTester should flag as problematic. */
3431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static List<Class<?>> passClasses = Lists.newArrayList();
3441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** Lots of well-behaved methods. */
3461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static class PassObject {
3471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public static void doThrow(Object arg) {
3481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (arg == null) {
3491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        throw new FooException();
3501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
3511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public void noArg() {}
3531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public void oneArg(String s) { checkNotNull(s); }
3541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public void oneNullableArg(@Nullable String s) {}
3551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public void oneNullableArgThrows(@Nullable String s) { doThrow(s); }
3561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public void twoArg(String s, Integer i) { checkNotNull(s); i.intValue(); }
3581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public void twoMixedArgs(String s, @Nullable Integer i) { checkNotNull(s); }
3591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public void twoMixedArgsThrows(String s, @Nullable Integer i) {
3601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      checkNotNull(s); doThrow(i);
3611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public void twoMixedArgs(@Nullable Integer i, String s) { checkNotNull(s); }
3631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public void twoMixedArgsThrows(@Nullable Integer i, String s) {
3641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      checkNotNull(s); doThrow(i);
3651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public void twoNullableArgs(@Nullable String s,
3671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @javax.annotation.Nullable Integer i) { }
3681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public void twoNullableArgsThrowsFirstArg(
3691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Nullable String s, @Nullable Integer i) {
3701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      doThrow(s);
3711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public void twoNullableArgsThrowsSecondArg(
3731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Nullable String s, @Nullable Integer i) {
3741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      doThrow(i);
3751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public static void staticOneArg(String s) { checkNotNull(s); }
3771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public static void staticOneNullableArg(@Nullable String s) { }
3781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public static void staticOneNullableArgThrows(@Nullable String s) {
3791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      doThrow(s);
3801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static { passClasses.add(PassObject.class); }
3831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static class FailOneArgDoesntThrowNPE extends PassObject {
3851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void oneArg(String s) {
3861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // Fail:  missing NPE for s
3871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static { failClasses.add(FailOneArgDoesntThrowNPE.class); }
3901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static class FailOneArgThrowsWrongType extends PassObject {
3921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void oneArg(String s) {
3931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      doThrow(s); // Fail:  throwing non-NPE exception for null s
3941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static { failClasses.add(FailOneArgThrowsWrongType.class); }
3971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static class PassOneNullableArgThrowsNPE extends PassObject {
3991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void oneNullableArg(@Nullable String s) {
4001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      checkNotNull(s); // ok to throw NPE
4011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static { passClasses.add(PassOneNullableArgThrowsNPE.class); }
4041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static class FailTwoArgsFirstArgDoesntThrowNPE extends PassObject {
4061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void twoArg(String s, Integer i) {
4071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // Fail: missing NPE for s
4081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      i.intValue();
4091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static { failClasses.add(FailTwoArgsFirstArgDoesntThrowNPE.class); }
4121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static class FailTwoArgsFirstArgThrowsWrongType extends PassObject {
4141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void twoArg(String s, Integer i) {
4151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      doThrow(s); // Fail:  throwing non-NPE exception for null s
4161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      i.intValue();
4171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static { failClasses.add(FailTwoArgsFirstArgThrowsWrongType.class); }
4201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static class FailTwoArgsSecondArgDoesntThrowNPE extends PassObject {
4221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void twoArg(String s, Integer i) {
4231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      checkNotNull(s);
4241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // Fail: missing NPE for i
4251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static { failClasses.add(FailTwoArgsSecondArgDoesntThrowNPE.class); }
4281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static class FailTwoArgsSecondArgThrowsWrongType extends PassObject {
4301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void twoArg(String s, Integer i) {
4311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      checkNotNull(s);
4321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      doThrow(i); // Fail:  throwing non-NPE exception for null i
4331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static { failClasses.add(FailTwoArgsSecondArgThrowsWrongType.class); }
4361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static class FailTwoMixedArgsFirstArgDoesntThrowNPE extends PassObject {
4381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void twoMixedArgs(String s, @Nullable Integer i) {
4391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // Fail: missing NPE for s
4401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static { failClasses.add(FailTwoMixedArgsFirstArgDoesntThrowNPE.class); }
4431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static class FailTwoMixedArgsFirstArgThrowsWrongType extends PassObject {
4451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void twoMixedArgs(String s, @Nullable Integer i) {
4461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      doThrow(s); // Fail:  throwing non-NPE exception for null s
4471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static { failClasses.add(FailTwoMixedArgsFirstArgThrowsWrongType.class); }
4501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static class PassTwoMixedArgsNullableArgThrowsNPE extends PassObject {
4521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void twoMixedArgs(String s, @Nullable Integer i) {
4531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      checkNotNull(s);
4541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      i.intValue(); // ok to throw NPE?
4551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static { passClasses.add(PassTwoMixedArgsNullableArgThrowsNPE.class); }
4581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static class PassTwoMixedArgSecondNullableArgThrowsOther extends PassObject {
4601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void twoMixedArgs(String s, @Nullable Integer i) {
4611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      checkNotNull(s);
4621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      doThrow(i); // ok to throw non-NPE exception for null i
4631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static { passClasses.add(PassTwoMixedArgSecondNullableArgThrowsOther.class); }
4661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static class FailTwoMixedArgsSecondArgDoesntThrowNPE extends PassObject {
4681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void twoMixedArgs(@Nullable Integer i, String s) {
4691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // Fail: missing NPE for null s
4701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static { failClasses.add(FailTwoMixedArgsSecondArgDoesntThrowNPE.class); }
4731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static class FailTwoMixedArgsSecondArgThrowsWrongType extends PassObject {
4751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void twoMixedArgs(@Nullable Integer i, String s) {
4761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      doThrow(s); // Fail:  throwing non-NPE exception for null s
4771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static { failClasses.add(FailTwoMixedArgsSecondArgThrowsWrongType.class); }
4801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static class PassTwoNullableArgsFirstThrowsNPE extends PassObject {
4821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void twoNullableArgs(
4831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Nullable String s, @Nullable Integer i) {
4841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      checkNotNull(s); // ok to throw NPE?
4851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static { passClasses.add(PassTwoNullableArgsFirstThrowsNPE.class); }
4881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static class PassTwoNullableArgsFirstThrowsOther extends PassObject {
4901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void twoNullableArgs(
4911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Nullable String s, @Nullable Integer i) {
4921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      doThrow(s); // ok to throw non-NPE exception for null s
4931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static { passClasses.add(PassTwoNullableArgsFirstThrowsOther.class); }
4961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static class PassTwoNullableArgsSecondThrowsNPE extends PassObject {
4981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void twoNullableArgs(
4991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Nullable String s, @Nullable Integer i) {
5001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      i.intValue(); // ok to throw NPE?
5011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static { passClasses.add(PassTwoNullableArgsSecondThrowsNPE.class); }
5041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static class PassTwoNullableArgsSecondThrowsOther extends PassObject {
5061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void twoNullableArgs(
5071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Nullable String s, @Nullable Integer i) {
5081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      doThrow(i); // ok to throw non-NPE exception for null i
5091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static { passClasses.add(PassTwoNullableArgsSecondThrowsOther.class); }
5121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static class PassTwoNullableArgsNeitherThrowsAnything extends PassObject {
5141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void twoNullableArgs(
5151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Nullable String s, @Nullable Integer i) {
5161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // ok to do nothing
5171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static { passClasses.add(PassTwoNullableArgsNeitherThrowsAnything.class); }
5201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** Sanity check:  it's easy to make typos. */
5221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private void checkClasses(String message, List<Class<?>> classes) {
5231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Set<Class<?>> set = Sets.newHashSet(classes);
5241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (Class<?> clazz : classes) {
5251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (!set.remove(clazz)) {
5261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        fail(String.format("%s: %s appears twice. Typo?",
5271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            message, clazz.getSimpleName()));
5281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
5291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testDidntMakeTypoInTestCases() {
5331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    checkClasses("passClass", passClasses);
5341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    checkClasses("failClasses", failClasses);
5351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    List<Class<?>> allClasses = Lists.newArrayList(passClasses);
5361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    allClasses.addAll(failClasses);
5371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    checkClasses("allClasses", allClasses);
5381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testShouldNotFindProblemInPassClass() throws Exception {
5411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (Class<?> passClass : passClasses) {
5421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Object instance = passClass.newInstance();
5431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
5441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        tester.testAllPublicInstanceMethods(instance);
5451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (AssertionFailedError e) {
5461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        assertNull("Should not detect problem in " + passClass.getSimpleName(),
5471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            e);
5481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
5491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testShouldFindProblemInFailClass() throws Exception {
5531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (Class<?> failClass : failClasses) {
5541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Object instance = failClass.newInstance();
5551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      boolean foundProblem = false;
5561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      try {
5571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        tester.testAllPublicInstanceMethods(instance);
5581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } catch (AssertionFailedError e) {
5591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        foundProblem = true;
5601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
5611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      assertTrue("Should detect problem in " + failClass.getSimpleName(),
5621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          foundProblem);
5631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static class PrivateClassWithPrivateConstructor {
5671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private PrivateClassWithPrivateConstructor(@Nullable Integer argument) {}
5681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testPrivateClass() throws Exception {
5711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    NullPointerTester tester = new NullPointerTester();
5721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (Constructor<?> constructor
5731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        : PrivateClassWithPrivateConstructor.class.getDeclaredConstructors()) {
5741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      tester.testConstructor(constructor);
5751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private interface Foo<T> {
5791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    void doSomething(T bar, Integer baz);
5801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static class StringFoo implements Foo<String> {
5831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void doSomething(String bar, Integer baz) {
5851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      checkNotNull(bar);
5861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      checkNotNull(baz);
5871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testBidgeMethodIgnored() throws Exception {
5911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    new NullPointerTester().testAllPublicInstanceMethods(new StringFoo());
5921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /*
5951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
5961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * TODO(kevinb): This is only a very small start.
5971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Must come back and finish.
5981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
5991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
6001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
602