From 90e621706c2e49bca69e92dc8410b2c214ce7664 Mon Sep 17 00:00:00 2001 From: Romain Brenguier Date: Thu, 6 Feb 2025 10:25:45 +0100 Subject: [PATCH] SONARJAVA-5256 Generalize the pattern for AssertJ assertions The previous conditions were too restrictive and there are many assertion methods in AssertJ. They generally follow the patterns that are described here. Note that this introduces a false negative in autoscan tests. Co-authored-by: Alban Auzeill --- .../resources/autoscan/diffs/diff_S2699.json | 2 +- .../java/checks/helpers/UnitTestUtils.java | 10 ++++- .../checks/helpers/UnitTestUtilsTest.java | 40 +++++++++++++++++++ 3 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 java-checks/src/test/java/org/sonar/java/checks/helpers/UnitTestUtilsTest.java diff --git a/its/autoscan/src/test/resources/autoscan/diffs/diff_S2699.json b/its/autoscan/src/test/resources/autoscan/diffs/diff_S2699.json index d361a3c2311..e93820e083b 100644 --- a/its/autoscan/src/test/resources/autoscan/diffs/diff_S2699.json +++ b/its/autoscan/src/test/resources/autoscan/diffs/diff_S2699.json @@ -1,6 +1,6 @@ { "ruleKey": "S2699", "hasTruePositives": true, - "falseNegatives": 151, + "falseNegatives": 152, "falsePositives": 1 } diff --git a/java-checks/src/main/java/org/sonar/java/checks/helpers/UnitTestUtils.java b/java-checks/src/main/java/org/sonar/java/checks/helpers/UnitTestUtils.java index 37a046bc564..22d8d565a6a 100644 --- a/java-checks/src/main/java/org/sonar/java/checks/helpers/UnitTestUtils.java +++ b/java-checks/src/main/java/org/sonar/java/checks/helpers/UnitTestUtils.java @@ -22,6 +22,8 @@ import java.util.Set; import java.util.regex.Pattern; import javax.annotation.Nullable; + +import org.sonar.java.annotations.VisibleForTesting; import org.sonar.java.model.ExpressionUtils; import org.sonar.plugins.java.api.semantic.MethodMatchers; import org.sonar.plugins.java.api.semantic.Symbol; @@ -42,6 +44,10 @@ public final class UnitTestUtils { "|laxCheckpoint|succeedingThenComplete"); private static final Pattern TEST_METHODS_PATTERN = Pattern.compile("test.*|.*Test"); + @VisibleForTesting + static final Pattern ASSERTJ_ASSERTION_METHODS_PATTERN = Pattern.compile( + "(allMatch|assert|contains|doesNot|has|is|returns|satisfies)([A-Z].*)?"); + public static final MethodMatchers ASSERTION_INVOCATION_MATCHERS = MethodMatchers.or( // fest 1.x / 2.X MethodMatchers.create().ofSubTypes("org.fest.assertions.GenericAssert", "org.fest.assertions.api.AbstractAssert").anyName().withAnyParameters().build(), @@ -62,8 +68,8 @@ public final class UnitTestUtils { .withAnyParameters() .build(), // assertJ - MethodMatchers.create().ofSubTypes("org.assertj.core.api.AbstractAssert").anyName().withAnyParameters().build(), - MethodMatchers.create().ofSubTypes("org.assertj.core.api.ThrowableTypeAssert").anyName().withAnyParameters().build(), + MethodMatchers.create().ofType(type -> type.fullyQualifiedName().matches("org\\.assertj\\.core\\.api\\.[a-zA-Z]+Assert")) + .name(ASSERTJ_ASSERTION_METHODS_PATTERN.asMatchPredicate()).withAnyParameters().build(), // spring MethodMatchers.create().ofTypes("org.springframework.test.web.servlet.ResultActions").names("andExpect", "andExpectAll").withAnyParameters().build(), // JMockit diff --git a/java-checks/src/test/java/org/sonar/java/checks/helpers/UnitTestUtilsTest.java b/java-checks/src/test/java/org/sonar/java/checks/helpers/UnitTestUtilsTest.java new file mode 100644 index 00000000000..db2f0e56d00 --- /dev/null +++ b/java-checks/src/test/java/org/sonar/java/checks/helpers/UnitTestUtilsTest.java @@ -0,0 +1,40 @@ +/* + * SonarQube Java + * Copyright (C) 2012-2025 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Sonar Source-Available License for more details. + * + * You should have received a copy of the Sonar Source-Available License + * along with this program; if not, see https://sonarsource.com/license/ssal/ + */ +package org.sonar.java.checks.helpers; + +import org.junit.jupiter.api.Test; + +import java.util.function.Predicate; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + + +class UnitTestUtilsTest { + + @Test + void testAssertJAssertionMethodPattern() { + Predicate predicate = UnitTestUtils.ASSERTJ_ASSERTION_METHODS_PATTERN.asMatchPredicate(); + assertTrue(predicate.test("returns")); + assertTrue(predicate.test("contains")); + assertFalse(predicate.test("doesNot")); + assertTrue(predicate.test("containsAString")); + assertTrue(predicate.test("doesNotThrow")); + assertFalse(predicate.test("allMatchFoo")); + assertFalse(predicate.test("hasten")); + } +}