Skip to content

Commit 889e741

Browse files
SONARJAVA-4446 Check if the parent class or implemented interface symbols of the test class are known. (#4956)
1 parent 2758fee commit 889e741

3 files changed

Lines changed: 27 additions & 4 deletions

File tree

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"ruleKey": "S2187",
33
"hasTruePositives": true,
4-
"falseNegatives": 12,
5-
"falsePositives": 1
4+
"falseNegatives": 13,
5+
"falsePositives": 0
66
}

java-checks-test-sources/default/src/main/files/non-compiling/checks/NoTestInTestClassCheckSample.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import com.googlecode.zohhak.api.TestWith;
2222
import com.googlecode.zohhak.api.runners.ZohhakRunner;
2323

24-
2524
class A extends junit.framework.TestCase {
2625
void testFoo() {
2726
}
@@ -313,3 +312,16 @@ public class MyZohhak4Test { // Compliant
313312
public void testFoo4() {
314313
}
315314
}
315+
316+
class SubclassTest extends UndefinedParent { // Compliant, we cannot know what is in ParentTestClass so we don't raise issues
317+
}
318+
319+
class Subclass2Test extends myPackage.UndefinedParent {
320+
}
321+
322+
class Subclass3Test implements UndefinedInterface {
323+
324+
}
325+
326+
abstract class ResolvedParent {}
327+
class Subclass4Test extends ResolvedParent {} // Noncompliant

java-checks/src/main/java/org/sonar/java/checks/tests/NoTestInTestClassCheck.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.Collections;
2121
import java.util.HashSet;
2222
import java.util.List;
23+
import java.util.Optional;
2324
import java.util.Set;
2425
import java.util.regex.Pattern;
2526
import java.util.stream.Stream;
@@ -78,7 +79,17 @@ private void resetAnnotationCache() {
7879
}
7980

8081
private void checkClass(ClassTree classTree) {
81-
if (!ModifiersUtils.hasModifier(classTree.modifiers(), Modifier.ABSTRACT)) {
82+
boolean hasUnknownParent = Optional.ofNullable(classTree.superClass())
83+
.map(parent -> parent.symbolType().isUnknown())
84+
// If the superClass is null, then the class has no parent, so has no unknownParent.
85+
.orElse(false);
86+
boolean knownImplementedInterfaces = classTree.superInterfaces().stream()
87+
.noneMatch(i -> i.symbolType().isUnknown());
88+
89+
if (!ModifiersUtils.hasModifier(classTree.modifiers(), Modifier.ABSTRACT)
90+
&& !hasUnknownParent
91+
&& knownImplementedInterfaces
92+
) {
8293
Symbol.TypeSymbol classSymbol = classTree.symbol();
8394
Stream<Symbol> members = getAllMembers(classSymbol, checkRunWith(classSymbol, "Enclosed"));
8495
IdentifierTree simpleName = classTree.simpleName();

0 commit comments

Comments
 (0)