Skip to content

Commit

Permalink
Add support for AssertJ (#698)
Browse files Browse the repository at this point in the history
In particular `org.assertj.core.api.Assertions.assertThat(o).isNotNull()`.

Tests included.
  • Loading branch information
Byte27 authored Dec 13, 2022
1 parent ce63224 commit 23dd6cc
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 8 deletions.
1 change: 1 addition & 0 deletions gradle/dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ def test = [
mockito : "org.mockito:mockito-core:4.6.1",
mockitoInline : "org.mockito:mockito-inline:4.6.1",
javaxAnnotationApi : "javax.annotation:javax.annotation-api:1.3.2",
assertJ : "org.assertj:assertj-core:3.23.1",
]

ext.deps = [
Expand Down
1 change: 1 addition & 0 deletions nullaway/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ dependencies {
testImplementation deps.test.mockito
testImplementation deps.test.mockitoInline
testImplementation deps.test.javaxAnnotationApi
testImplementation deps.test.assertJ

// This ends up being resolved to the NullAway jar under nullaway/build/libs
nullawayJar "com.uber.nullaway:nullaway:$VERSION_NAME"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,13 @@ class MethodNameUtil {
// Strings corresponding to the names of the methods (and their owners) used to identify
// assertions in this handler.
private static final String IS_NOT_NULL_METHOD = "isNotNull";
private static final String IS_NOT_NULL_OWNER = "com.google.common.truth.Subject";
private static final String IS_NOT_NULL_OWNER_TRUTH = "com.google.common.truth.Subject";
private static final String IS_NOT_NULL_OWNER_ASSERTJ = "org.assertj.core.api.AbstractAssert";
private static final String IS_TRUE_METHOD = "isTrue";
private static final String IS_TRUE_OWNER = "com.google.common.truth.BooleanSubject";
private static final String ASSERT_THAT_METHOD = "assertThat";
private static final String ASSERT_THAT_OWNER = "com.google.common.truth.Truth";
private static final String ASSERT_THAT_OWNER_TRUTH = "com.google.common.truth.Truth";
private static final String ASSERT_THAT_OWNER_ASSERTJ = "org.assertj.core.api.Assertions";

private static final String HAMCREST_ASSERT_CLASS = "org.hamcrest.MatcherAssert";
private static final String JUNIT_ASSERT_CLASS = "org.junit.Assert";
Expand All @@ -61,13 +63,15 @@ class MethodNameUtil {
// here refers to com.sun.tools.javac.util.Name. Comparing methods using Names is faster than
// comparing using strings.
private Name isNotNull;
private Name isNotNullOwner;
private Name isNotNullOwnerTruth;
private Name isNotNullOwnerAssertJ;

private Name isTrue;
private Name isTrueOwner;

private Name assertThat;
private Name assertThatOwner;
private Name assertThatOwnerTruth;
private Name assertThatOwnerAssertJ;

// Names for junit assertion libraries.
private Name hamcrestAssertClass;
Expand All @@ -85,13 +89,15 @@ class MethodNameUtil {
@Initializer
void initializeMethodNames(Name.Table table) {
isNotNull = table.fromString(IS_NOT_NULL_METHOD);
isNotNullOwner = table.fromString(IS_NOT_NULL_OWNER);
isNotNullOwnerTruth = table.fromString(IS_NOT_NULL_OWNER_TRUTH);
isNotNullOwnerAssertJ = table.fromString(IS_NOT_NULL_OWNER_ASSERTJ);

isTrue = table.fromString(IS_TRUE_METHOD);
isTrueOwner = table.fromString(IS_TRUE_OWNER);

assertThat = table.fromString(ASSERT_THAT_METHOD);
assertThatOwner = table.fromString(ASSERT_THAT_OWNER);
assertThatOwnerTruth = table.fromString(ASSERT_THAT_OWNER_TRUTH);
assertThatOwnerAssertJ = table.fromString(ASSERT_THAT_OWNER_ASSERTJ);

hamcrestAssertClass = table.fromString(HAMCREST_ASSERT_CLASS);
junitAssertClass = table.fromString(JUNIT_ASSERT_CLASS);
Expand All @@ -106,15 +112,17 @@ void initializeMethodNames(Name.Table table) {
}

boolean isMethodIsNotNull(Symbol.MethodSymbol methodSymbol) {
return matchesMethod(methodSymbol, isNotNull, isNotNullOwner);
return matchesMethod(methodSymbol, isNotNull, isNotNullOwnerTruth)
|| matchesMethod(methodSymbol, isNotNull, isNotNullOwnerAssertJ);
}

boolean isMethodIsTrue(Symbol.MethodSymbol methodSymbol) {
return matchesMethod(methodSymbol, isTrue, isTrueOwner);
}

boolean isMethodAssertThat(Symbol.MethodSymbol methodSymbol) {
return matchesMethod(methodSymbol, assertThat, assertThatOwner);
return matchesMethod(methodSymbol, assertThat, assertThatOwnerTruth)
|| matchesMethod(methodSymbol, assertThat, assertThatOwnerAssertJ);
}

boolean isMethodHamcrestAssertThat(Symbol.MethodSymbol methodSymbol) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,4 +260,99 @@ public void doNotSupportJunitAssertThatWhenDisabled() {
"}")
.doTest();
}

@Test
public void supportAssertJAssertThatIsNotNull_Object() {
makeTestHelperWithArgs(
Arrays.asList(
"-d",
temporaryFolder.getRoot().getAbsolutePath(),
"-XepOpt:NullAway:AnnotatedPackages=com.uber",
"-XepOpt:NullAway:HandleTestAssertionLibraries=true"))
.addSourceLines(
"Test.java",
"package com.uber;",
"import java.lang.Object;",
"import java.util.Objects;",
"import javax.annotation.Nullable;",
"import static org.assertj.core.api.Assertions.assertThat;",
"class Test {",
" private void foo(@Nullable Object o) {",
" assertThat(o).isNotNull();",
" o.toString();",
" }",
"}")
.doTest();
}

@Test
public void supportAssertJAssertThatIsNotNull_String() {
makeTestHelperWithArgs(
Arrays.asList(
"-d",
temporaryFolder.getRoot().getAbsolutePath(),
"-XepOpt:NullAway:AnnotatedPackages=com.uber",
"-XepOpt:NullAway:HandleTestAssertionLibraries=true"))
.addSourceLines(
"Test.java",
"package com.uber;",
"import java.util.Objects;",
"import javax.annotation.Nullable;",
"import static org.assertj.core.api.Assertions.assertThat;",
"class Test {",
" private void foo(@Nullable String s) {",
" assertThat(s).isNotNull();",
" s.toString();",
" }",
"}")
.doTest();
}

@Test
public void supportAssertJAssertThatIsNotNull_MapKey() {
makeTestHelperWithArgs(
Arrays.asList(
"-d",
temporaryFolder.getRoot().getAbsolutePath(),
"-XepOpt:NullAway:AnnotatedPackages=com.uber",
"-XepOpt:NullAway:HandleTestAssertionLibraries=true"))
.addSourceLines(
"Test.java",
"package com.uber;",
"import java.util.Map;",
"import javax.annotation.Nullable;",
"import static org.assertj.core.api.Assertions.assertThat;",
"class Test {",
" private void foo(Map<String,Object> m) {",
" assertThat(m.get(\"foo\")).isNotNull();",
" m.get(\"foo\").toString();",
" }",
"}")
.doTest();
}

@Test
public void doNotSupportAssertJAssertThatWhenDisabled() {
makeTestHelperWithArgs(
Arrays.asList(
"-d",
temporaryFolder.getRoot().getAbsolutePath(),
"-XepOpt:NullAway:AnnotatedPackages=com.uber",
"-XepOpt:NullAway:HandleTestAssertionLibraries=false"))
.addSourceLines(
"Test.java",
"package com.uber;",
"import java.lang.Object;",
"import java.util.Objects;",
"import javax.annotation.Nullable;",
"import static org.assertj.core.api.Assertions.assertThat;",
"class Test {",
" private void foo(@Nullable Object a) {",
" assertThat(a).isNotNull();",
" // BUG: Diagnostic contains: dereferenced expression",
" a.toString();",
" }",
"}")
.doTest();
}
}

0 comments on commit 23dd6cc

Please sign in to comment.