@Before public void setup() { compilationHelper = CompilationTestHelper.newInstance(NullAway.class, getClass()); compilationHelper.setArgs( Arrays.asList( "-d", temporaryFolder.getRoot().getAbsolutePath(), "-XepOpt:NullAway:AnnotatedPackages=com.uber,com.ubercab,io.reactivex")); }
@Test public void test_autodisposePositiveCasesWithDefaultClassGivenCustomTypes() { compilationHelper.setArgs(ImmutableList.of("-XepOpt:TypesWithScope" + "=com.uber.autodispose.errorprone.ComponentWithLifecycle")); compilationHelper.addSourceFile("UseAutoDisposeDefaultClassPositiveCases.java").doTest(); }
@Test public void test_autodisposeNegativeCasesWithDefaultClassGivenExclusiveScope() { compilationHelper.setArgs(ImmutableList.of("-XepOpt:TypesWithScope" + "=com.uber.autodispose.errorprone.ComponentWithLifecycle", "-XepOpt:OverrideScopes")); compilationHelper.addSourceFile("UseAutoDisposeNegativeCasesExcluded.java").doTest(); }
@Test public void assertSupportNegativeCases() { compilationHelper .setArgs( Arrays.asList( "-d", temporaryFolder.getRoot().getAbsolutePath(), "-XepOpt:NullAway:AnnotatedPackages=com.uber", "-XepOpt:NullAway:AssertsEnabled=true")) .addSourceFile("CheckAssertSupportNegativeCases.java") .doTest(); }
@Test public void test_autodisposePositiveCasesWithDefaultClassLenient() { compilationHelper.setArgs(ImmutableList.of("-XepOpt:Lenient=true")); compilationHelper.addSourceFile("UseAutoDisposeDefaultClassPositiveCasesLenient.java").doTest(); }
@Before public void setup() { compilationHelper = CompilationTestHelper.newInstance(NullAway.class, getClass()); compilationHelper.setArgs( Arrays.asList( "-d", temporaryFolder.getRoot().getAbsolutePath(), "-XepOpt:NullAway:KnownInitializers=" + "com.uber.nullaway.testdata.CheckFieldInitNegativeCases.Super.doInit," + "com.uber.nullaway.testdata.CheckFieldInitNegativeCases" + ".SuperInterface.doInit2", "-XepOpt:NullAway:AnnotatedPackages=com.uber,com.ubercab,io.reactivex", // We give the following in Regexp format to test that support "-XepOpt:NullAway:UnannotatedSubPackages=com.uber.nullaway.[a-zA-Z0-9.]+.unannotated", "-XepOpt:NullAway:ExcludedClasses=" + "com.uber.nullaway.testdata.Shape_Stuff," + "com.uber.nullaway.testdata.excluded", "-XepOpt:NullAway:ExcludedClassAnnotations=com.uber.nullaway.testdata.TestAnnot", "-XepOpt:NullAway:CastToNonNullMethod=com.uber.nullaway.testdata.Util.castToNonNull", "-XepOpt:NullAway:ExternalInitAnnotations=com.uber.ExternalInit", "-XepOpt:NullAway:ExcludedFieldAnnotations=com.uber.ExternalFieldInit")); }
@Test public void test_autodisposePositiveCasesWithCustomClass() { compilationHelper.setArgs(ImmutableList.of("-XepOpt:TypesWithScope" + "=com.uber.autodispose.errorprone.ComponentWithLifecycle")); compilationHelper.addSourceFile("UseAutoDisposeCustomClassPositiveCases.java").doTest(); }
@Test public void test_autodisposeNegativeCasesLenient() { compilationHelper.setArgs(ImmutableList.of("-XepOpt:Lenient=true")); compilationHelper.addSourceFile("UseAutoDisposeNegativeCasesLenient.java").doTest(); } }
@Test public void defaultURL() { compilationHelper .setArgs( Arrays.asList( "-d", temporaryFolder.getRoot().getAbsolutePath(), "-XepOpt:NullAway:AnnotatedPackages=com.uber")) .addSourceLines( "Test.java", "package com.uber;", "class Test {", " static void foo() {", " // BUG: Diagnostic contains: t.uber.com/nullaway", " Object x = null; x.toString();", " }", "}") .doTest(); }
@Test public void generatedAsUnannotated() { String generatedAnnot = (Double.parseDouble(System.getProperty("java.specification.version")) >= 11) ? "@javax.annotation.processing.Generated" : "@javax.annotation.Generated"; System.err.println(); compilationHelper .setArgs( Arrays.asList( "-d", temporaryFolder.getRoot().getAbsolutePath(), "-XepOpt:NullAway:AnnotatedPackages=com.uber", "-XepOpt:NullAway:TreatGeneratedAsUnannotated=true")) .addSourceLines( "Generated.java", "package com.uber;", generatedAnnot + "(\"foo\")", "public class Generated { public void takeObj(Object o) {} }") .addSourceLines( "Test.java", "package com.uber;", "class Test {", " void foo() { (new Generated()).takeObj(null); }", "}") .doTest(); }
@Test public void customErrorURL() { compilationHelper .setArgs( Arrays.asList( "-d", temporaryFolder.getRoot().getAbsolutePath(), "-XepOpt:NullAway:AnnotatedPackages=com.uber", "-XepOpt:NullAway:ErrorURL=http://mydomain.com/nullaway")) .addSourceLines( "Test.java", "package com.uber;", "class Test {", " static void foo() {", " // BUG: Diagnostic contains: mydomain.com", " Object x = null; x.toString();", " }", "}") .doTest(); }
@Test public void lambdaPlusRestrictiveNegative() { compilationHelper .setArgs( Arrays.asList( "-d", temporaryFolder.getRoot().getAbsolutePath(), "-XepOpt:NullAway:AnnotatedPackages=com.uber", "-XepOpt:NullAway:UnannotatedSubPackages=com.uber.lib.unannotated")) .addSourceLines( "Test.java", "package com.uber;", "import com.uber.lib.unannotated.RestrictivelyAnnotatedFI;", "import javax.annotation.Nullable;", "public class Test {", " void foo() {", " RestrictivelyAnnotatedFI func = (x) -> {", " // no error since AcknowledgeRestrictiveAnnotations disabled", " x.toString();", " return new Object();", " };", " }", "}") .doTest(); }
@Test public void lambdaPlusRestrictivePositive() { compilationHelper .setArgs( Arrays.asList( "-d", temporaryFolder.getRoot().getAbsolutePath(), "-XepOpt:NullAway:AnnotatedPackages=com.uber", "-XepOpt:NullAway:UnannotatedSubPackages=com.uber.lib.unannotated", "-XepOpt:NullAway:AcknowledgeRestrictiveAnnotations=true")) .addSourceLines( "Test.java", "package com.uber;", "import com.uber.lib.unannotated.RestrictivelyAnnotatedFI;", "import javax.annotation.Nullable;", "public class Test {", " void foo() {", " RestrictivelyAnnotatedFI func = (x) -> {", " // BUG: Diagnostic contains: dereferenced expression x is @Nullable", " x.toString();", " return new Object();", " };", " }", "}") .doTest(); }
@Test public void jarinferNullableReturnsTest() { compilationHelper .setArgs( Arrays.asList( "-d", temporaryFolder.getRoot().getAbsolutePath(), "-XepOpt:NullAway:AnnotatedPackages=com.uber", "-XepOpt:NullAway:UnannotatedSubPackages=com.uber.nullaway.[a-zA-Z0-9.]+.unannotated", "-XepOpt:NullAway:JarInferEnabled=true", "-XepOpt:NullAway:JarInferUseReturnAnnotations=true")) .addSourceLines( "Test.java", "package com.uber;", "import javax.annotation.Nullable;", "import com.uber.nullaway.jarinfer.toys.unannotated.Toys;", "class Test {", " void test1(@Nullable String s) {", " // BUG: Diagnostic contains: passing @Nullable parameter 'Toys.getString(false, s)'", " Toys.test1(Toys.getString(false, s), \"let's\", \"try\");", " }", "}") .doTest(); } }
@Test public void jarinferLoadStubsTest() { compilationHelper .setArgs( Arrays.asList( "-d", temporaryFolder.getRoot().getAbsolutePath(), "-XepOpt:NullAway:AnnotatedPackages=com.uber", "-XepOpt:NullAway:JarInferEnabled=true", "-XepOpt:NullAway:UnannotatedSubPackages=com.uber.nullaway.[a-zA-Z0-9.]+.unannotated")) .addSourceLines( "Test.java", "package com.uber;", "import javax.annotation.Nullable;", "import com.uber.nullaway.jarinfer.toys.unannotated.Toys;", "class Test {", " void test1(@Nullable String s) {", " // BUG: Diagnostic contains: passing @Nullable parameter 's'", " Toys.test1(s, \"let's\", \"try\");", " }", "}") .doTest(); }
@Test public void skipNestedClass() { compilationHelper .setArgs( Arrays.asList( "-d", temporaryFolder.getRoot().getAbsolutePath(), "-XepOpt:NullAway:AnnotatedPackages=com.uber", "-XepOpt:NullAway:ExcludedClassAnnotations=com.uber.lib.MyExcluded")) .addSourceLines( "Test.java", "package com.uber;", "import javax.annotation.Nullable;", "public class Test {", " @com.uber.lib.MyExcluded", " static class Inner {", " @Nullable", " static Object foo() {", " Object x = null; x.toString();", " return x;", " }", " }", " static void bar() {", " // BUG: Diagnostic contains: dereferenced expression Inner.foo()", " Inner.foo().toString();", " }", "}") .doTest(); }
@Test public void defaultPermissiveOnUnannotated() { compilationHelper .setArgs( Arrays.asList( "-d", temporaryFolder.getRoot().getAbsolutePath(), "-XepOpt:NullAway:AnnotatedPackages=com.uber", "-XepOpt:NullAway:UnannotatedSubPackages=com.uber.lib.unannotated", "-XepOpt:NullAway:AcknowledgeRestrictiveAnnotations=false")) .addSourceLines( "Test.java", "package com.uber;", "import javax.annotation.Nullable;", "import com.uber.lib.unannotated.RestrictivelyAnnotatedClass;", "class Test {", " Object test() {", " // Assume methods take @Nullable, even if annotated otherwise", " RestrictivelyAnnotatedClass.consumesObjectUnannotated(null);", " RestrictivelyAnnotatedClass.consumesObjectNonNull(null);", " // Ignore explict @Nullable return", " return RestrictivelyAnnotatedClass.returnsNull();", " }", "}") .doTest(); }
@Test public void restrictivelyAnnotatedMethodsWorkWithNullnessFromDataflow2() { compilationHelper .setArgs( Arrays.asList( "-d", temporaryFolder.getRoot().getAbsolutePath(), "-XepOpt:NullAway:AnnotatedPackages=com.uber", "-XepOpt:NullAway:UnannotatedSubPackages=com.uber.lib.unannotated", "-XepOpt:NullAway:AcknowledgeRestrictiveAnnotations=true")) .addSourceLines( "Test.java", "package com.uber;", "import javax.annotation.Nullable;", "import com.uber.lib.unannotated.RestrictivelyAnnotatedGenericContainer;", "class Test {", " String test(RestrictivelyAnnotatedGenericContainer<Integer> instance) {", " if (instance.getField() == null) {", " return \"\";", " }", " return instance.getField().toString();", " }", "}") .doTest(); }
@Test public void restrictivelyAnnotatedMethodsWorkWithNullnessFromDataflow() { compilationHelper .setArgs( Arrays.asList( "-d",
@Test public void unannotatedClass() { compilationHelper .setArgs( Arrays.asList( "-d",