Skip to content

Commit 12b7ef1

Browse files
SONARJAVA-4520 Rule S3655: False Positive with JUnit assertions (#4769)
1 parent 92f27d6 commit 12b7ef1

8 files changed

Lines changed: 442 additions & 9 deletions

File tree

its/autoscan/src/test/resources/autoscan/autoscan-diff-by-rules.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1706,7 +1706,7 @@
17061706
{
17071707
"ruleKey": "S3655",
17081708
"hasTruePositives": true,
1709-
"falseNegatives": 0,
1709+
"falseNegatives": 8,
17101710
"falsePositives": 0
17111711
},
17121712
{
@@ -2492,7 +2492,7 @@
24922492
{
24932493
"ruleKey": "S5960",
24942494
"hasTruePositives": false,
2495-
"falseNegatives": 3,
2495+
"falseNegatives": 4,
24962496
"falsePositives": 0
24972497
},
24982498
{
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"ruleKey": "S3655",
33
"hasTruePositives": true,
4-
"falseNegatives": 0,
4+
"falseNegatives": 8,
55
"falsePositives": 0
6-
}
6+
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"ruleKey": "S5960",
33
"hasTruePositives": false,
4-
"falseNegatives": 3,
4+
"falseNegatives": 4,
55
"falsePositives": 0
6-
}
6+
}

java-checks-test-sources/default/src/main/java/symbolicexecution/checks/OptionalGetBeforeIsPresentCheck_jdk11.java

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package symbolicexecution.checks;
22

33
import java.util.Optional;
4+
import org.junit.Assert;
5+
import org.junit.jupiter.api.Assertions;
46

57
abstract class OptionalGetBeforeIsPresentCheck_jdk11 {
68

@@ -49,4 +51,125 @@ private void usingIsEmpty5() {
4951
}
5052
op.get(); // Noncompliant {{Call "op.isPresent()" or "!op.isEmpty()" before accessing the value.}}
5153
}
54+
55+
void test_junit5_1(Optional<String> op){
56+
Assertions.assertTrue(op.isPresent(), "Hello");
57+
op.get(); // Compliant
58+
}
59+
60+
void test_junit5_2(Optional<String> op){
61+
Assertions.assertTrue(op.isEmpty(), "Hello");
62+
op.get(); // Noncompliant {{Call "op.isPresent()" or "!op.isEmpty()" before accessing the value.}}
63+
}
64+
65+
void test_junit5_3(Optional<String> op){
66+
Assertions.assertFalse(op.isPresent());
67+
op.get(); // Noncompliant {{Call "op.isPresent()" or "!op.isEmpty()" before accessing the value.}}
68+
}
69+
70+
void test_junit5_4(Optional<String> op){
71+
Assertions.assertFalse(op.isEmpty());
72+
op.get(); // Compliant
73+
}
74+
75+
void test_junit5_5(Optional<String> op, int i){
76+
Assertions.assertFalse(i < 0);
77+
op.get(); // Noncompliant {{Call "op.isPresent()" or "!op.isEmpty()" before accessing the value.}}
78+
}
79+
80+
void test_junit5_6(Optional<String> op){
81+
Assertions.assertTrue(op.isPresent(), () -> "Hello");
82+
op.get(); // Compliant
83+
}
84+
85+
void test_junit5_7(Optional<String> op){
86+
Assertions.assertFalse(op.isEmpty(), () -> "Hello");
87+
op.get(); // Compliant
88+
}
89+
90+
void test_junit5_8(Optional<String> op, int i){
91+
Assertions.assertFalse(i < 0, () -> "Hello");
92+
op.get(); // Noncompliant {{Call "op.isPresent()" or "!op.isEmpty()" before accessing the value.}}
93+
}
94+
95+
void test_junit5_9(Optional<String> op){
96+
Assertions.fail();
97+
op.get(); // Compliant
98+
}
99+
100+
void test_junit5_10(Optional<String> op){
101+
Assertions.fail("Hello");
102+
op.get(); // Compliant
103+
}
104+
105+
void test_junit5_11(Optional<String> op){
106+
Assertions.fail("Hello", new Exception());
107+
op.get(); // Compliant
108+
}
109+
110+
void test_junit5_12(Optional<String> op){
111+
Assertions.fail(new Exception());
112+
op.get(); // Compliant
113+
}
114+
115+
void test_junit5_13(Optional<String> op){
116+
Assertions.fail(() -> "Hello");
117+
op.get(); // Compliant
118+
}
119+
120+
void test_junit5_14(Optional<String> op){
121+
Assertions.assertTrue(op.isPresent());
122+
op.get(); // Compliant
123+
}
124+
125+
void test_junit5_15(Optional<String> op){
126+
Assertions.assertFalse(op.isPresent(), "Hello");
127+
op.get(); // Noncompliant
128+
}
129+
130+
void test_junit4_1(Optional<String> op){
131+
Assert.assertTrue("Hello", op.isPresent());
132+
op.get(); // Compliant
133+
}
134+
135+
void test_junit4_2(Optional<String> op){
136+
Assert.assertTrue("Hello", op.isEmpty());
137+
op.get(); // Noncompliant {{Call "op.isPresent()" or "!op.isEmpty()" before accessing the value.}}
138+
}
139+
140+
void test_junit4_3(Optional<String> op){
141+
Assert.assertFalse(op.isPresent());
142+
op.get(); // Noncompliant {{Call "op.isPresent()" or "!op.isEmpty()" before accessing the value.}}
143+
}
144+
145+
void test_junit4_4(Optional<String> op){
146+
Assert.assertFalse(op.isEmpty());
147+
op.get(); // Compliant
148+
}
149+
150+
void test_junit4_5(Optional<String> op, int i){
151+
Assert.assertFalse(i < 0);
152+
op.get(); // Noncompliant {{Call "op.isPresent()" or "!op.isEmpty()" before accessing the value.}}
153+
}
154+
155+
void test_junit4_6(Optional<String> op){
156+
Assert.fail();
157+
op.get(); // Compliant
158+
}
159+
160+
void test_junit4_7(Optional<String> op){
161+
Assert.fail("Hello");
162+
op.get(); // Compliant
163+
}
164+
165+
void test_junit4_8(Optional<String> op){
166+
Assert.assertTrue(op.isPresent());
167+
op.get(); // Compliant
168+
}
169+
170+
void test_junit4_9(Optional<String> op){
171+
Assert.assertFalse("", op.isEmpty());
172+
op.get(); // Compliant
173+
}
174+
52175
}

java-symbolic-execution/src/main/java/org/sonar/java/se/xproc/BehaviorCache.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,9 @@ static class HardcodedMethodBehaviors {
130130
"org.apache.commons.lang3.json",
131131
"org.apache.logging.log4j.core.util.json",
132132
"org.eclipse.core.runtime.json",
133-
"org.springframework.util.json"
133+
"org.springframework.util.json",
134+
"org.junit.jupiter.api.json",
135+
"org.junit.json"
134136
};
135137

136138
private static final Type LIST_OF_METHOD_BEHAVIORS_TYPE = new TypeToken<List<MethodBehavior>>() {}.getType();
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
[
2+
{
3+
"signature": "org.junit.Assert#assertTrue(Z)V",
4+
"varArgs": false,
5+
"declaredExceptions": [],
6+
"yields": [
7+
{
8+
"parametersConstraints": [
9+
["TRUE"]
10+
],
11+
"resultIndex": -1,
12+
"resultConstraint": null
13+
},
14+
{
15+
"parametersConstraints": [
16+
["FALSE"]
17+
],
18+
"exception": ["java.lang.AssertionError"]
19+
}
20+
]
21+
},
22+
{
23+
"signature": "org.junit.Assert#assertTrue(Ljava/lang/String;Z)V",
24+
"varArgs": false,
25+
"declaredExceptions": [],
26+
"yields": [
27+
{
28+
"parametersConstraints": [
29+
[],
30+
["TRUE"]
31+
],
32+
"resultIndex": -1,
33+
"resultConstraint": null
34+
},
35+
{
36+
"parametersConstraints": [
37+
[],
38+
["FALSE"]
39+
],
40+
"exception": ["java.lang.AssertionError"]
41+
}
42+
]
43+
},
44+
{
45+
"signature": "org.junit.Assert#assertFalse(Z)V",
46+
"varArgs": false,
47+
"declaredExceptions": [],
48+
"yields": [
49+
{
50+
"parametersConstraints": [
51+
["FALSE"]
52+
],
53+
"resultIndex": -1,
54+
"resultConstraint": null
55+
},
56+
{
57+
"parametersConstraints": [
58+
["TRUE"]
59+
],
60+
"exception": ["java.lang.AssertionError"]
61+
}
62+
]
63+
},
64+
{
65+
"signature": "org.junit.Assert#assertFalse(Ljava/lang/String;Z)V",
66+
"varArgs": false,
67+
"declaredExceptions": [],
68+
"yields": [
69+
{
70+
"parametersConstraints": [
71+
[],
72+
["FALSE"]
73+
],
74+
"resultIndex": -1,
75+
"resultConstraint": null
76+
},
77+
{
78+
"parametersConstraints": [
79+
[],
80+
["TRUE"]
81+
],
82+
"exception": ["java.lang.AssertionError"]
83+
}
84+
]
85+
},
86+
{
87+
"signature": "org.junit.Assert#fail()V",
88+
"varArgs": false,
89+
"declaredExceptions": [],
90+
"yields": [
91+
{
92+
"parametersConstraints": [
93+
[]
94+
],
95+
"exception": ["java.lang.AssertionError"]
96+
}
97+
]
98+
},
99+
{
100+
"signature": "org.junit.Assert#fail(Ljava/lang/String;)V",
101+
"varArgs": false,
102+
"declaredExceptions": [],
103+
"yields": [
104+
{
105+
"parametersConstraints": [
106+
[]
107+
],
108+
"exception": ["java.lang.AssertionError"]
109+
}
110+
]
111+
}
112+
]

0 commit comments

Comments
 (0)