Skip to content

Commit

Permalink
SONARJAVA-4520 Rule S3655: False Positive with JUnit assertions (#4769)
Browse files Browse the repository at this point in the history
  • Loading branch information
ValentinAebi-sonar committed Apr 16, 2024
1 parent 92f27d6 commit 12b7ef1
Show file tree
Hide file tree
Showing 8 changed files with 442 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1706,7 +1706,7 @@
{
"ruleKey": "S3655",
"hasTruePositives": true,
"falseNegatives": 0,
"falseNegatives": 8,
"falsePositives": 0
},
{
Expand Down Expand Up @@ -2492,7 +2492,7 @@
{
"ruleKey": "S5960",
"hasTruePositives": false,
"falseNegatives": 3,
"falseNegatives": 4,
"falsePositives": 0
},
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"ruleKey": "S3655",
"hasTruePositives": true,
"falseNegatives": 0,
"falseNegatives": 8,
"falsePositives": 0
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"ruleKey": "S5960",
"hasTruePositives": false,
"falseNegatives": 3,
"falseNegatives": 4,
"falsePositives": 0
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package symbolicexecution.checks;

import java.util.Optional;
import org.junit.Assert;
import org.junit.jupiter.api.Assertions;

abstract class OptionalGetBeforeIsPresentCheck_jdk11 {

Expand Down Expand Up @@ -49,4 +51,125 @@ private void usingIsEmpty5() {
}
op.get(); // Noncompliant {{Call "op.isPresent()" or "!op.isEmpty()" before accessing the value.}}
}

void test_junit5_1(Optional<String> op){
Assertions.assertTrue(op.isPresent(), "Hello");
op.get(); // Compliant
}

void test_junit5_2(Optional<String> op){
Assertions.assertTrue(op.isEmpty(), "Hello");
op.get(); // Noncompliant {{Call "op.isPresent()" or "!op.isEmpty()" before accessing the value.}}
}

void test_junit5_3(Optional<String> op){
Assertions.assertFalse(op.isPresent());
op.get(); // Noncompliant {{Call "op.isPresent()" or "!op.isEmpty()" before accessing the value.}}
}

void test_junit5_4(Optional<String> op){
Assertions.assertFalse(op.isEmpty());
op.get(); // Compliant
}

void test_junit5_5(Optional<String> op, int i){
Assertions.assertFalse(i < 0);
op.get(); // Noncompliant {{Call "op.isPresent()" or "!op.isEmpty()" before accessing the value.}}
}

void test_junit5_6(Optional<String> op){
Assertions.assertTrue(op.isPresent(), () -> "Hello");
op.get(); // Compliant
}

void test_junit5_7(Optional<String> op){
Assertions.assertFalse(op.isEmpty(), () -> "Hello");
op.get(); // Compliant
}

void test_junit5_8(Optional<String> op, int i){
Assertions.assertFalse(i < 0, () -> "Hello");
op.get(); // Noncompliant {{Call "op.isPresent()" or "!op.isEmpty()" before accessing the value.}}
}

void test_junit5_9(Optional<String> op){
Assertions.fail();
op.get(); // Compliant
}

void test_junit5_10(Optional<String> op){
Assertions.fail("Hello");
op.get(); // Compliant
}

void test_junit5_11(Optional<String> op){
Assertions.fail("Hello", new Exception());
op.get(); // Compliant
}

void test_junit5_12(Optional<String> op){
Assertions.fail(new Exception());
op.get(); // Compliant
}

void test_junit5_13(Optional<String> op){
Assertions.fail(() -> "Hello");
op.get(); // Compliant
}

void test_junit5_14(Optional<String> op){
Assertions.assertTrue(op.isPresent());
op.get(); // Compliant
}

void test_junit5_15(Optional<String> op){
Assertions.assertFalse(op.isPresent(), "Hello");
op.get(); // Noncompliant
}

void test_junit4_1(Optional<String> op){
Assert.assertTrue("Hello", op.isPresent());
op.get(); // Compliant
}

void test_junit4_2(Optional<String> op){
Assert.assertTrue("Hello", op.isEmpty());
op.get(); // Noncompliant {{Call "op.isPresent()" or "!op.isEmpty()" before accessing the value.}}
}

void test_junit4_3(Optional<String> op){
Assert.assertFalse(op.isPresent());
op.get(); // Noncompliant {{Call "op.isPresent()" or "!op.isEmpty()" before accessing the value.}}
}

void test_junit4_4(Optional<String> op){
Assert.assertFalse(op.isEmpty());
op.get(); // Compliant
}

void test_junit4_5(Optional<String> op, int i){
Assert.assertFalse(i < 0);
op.get(); // Noncompliant {{Call "op.isPresent()" or "!op.isEmpty()" before accessing the value.}}
}

void test_junit4_6(Optional<String> op){
Assert.fail();
op.get(); // Compliant
}

void test_junit4_7(Optional<String> op){
Assert.fail("Hello");
op.get(); // Compliant
}

void test_junit4_8(Optional<String> op){
Assert.assertTrue(op.isPresent());
op.get(); // Compliant
}

void test_junit4_9(Optional<String> op){
Assert.assertFalse("", op.isEmpty());
op.get(); // Compliant
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,9 @@ static class HardcodedMethodBehaviors {
"org.apache.commons.lang3.json",
"org.apache.logging.log4j.core.util.json",
"org.eclipse.core.runtime.json",
"org.springframework.util.json"
"org.springframework.util.json",
"org.junit.jupiter.api.json",
"org.junit.json"
};

private static final Type LIST_OF_METHOD_BEHAVIORS_TYPE = new TypeToken<List<MethodBehavior>>() {}.getType();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
[
{
"signature": "org.junit.Assert#assertTrue(Z)V",
"varArgs": false,
"declaredExceptions": [],
"yields": [
{
"parametersConstraints": [
["TRUE"]
],
"resultIndex": -1,
"resultConstraint": null
},
{
"parametersConstraints": [
["FALSE"]
],
"exception": ["java.lang.AssertionError"]
}
]
},
{
"signature": "org.junit.Assert#assertTrue(Ljava/lang/String;Z)V",
"varArgs": false,
"declaredExceptions": [],
"yields": [
{
"parametersConstraints": [
[],
["TRUE"]
],
"resultIndex": -1,
"resultConstraint": null
},
{
"parametersConstraints": [
[],
["FALSE"]
],
"exception": ["java.lang.AssertionError"]
}
]
},
{
"signature": "org.junit.Assert#assertFalse(Z)V",
"varArgs": false,
"declaredExceptions": [],
"yields": [
{
"parametersConstraints": [
["FALSE"]
],
"resultIndex": -1,
"resultConstraint": null
},
{
"parametersConstraints": [
["TRUE"]
],
"exception": ["java.lang.AssertionError"]
}
]
},
{
"signature": "org.junit.Assert#assertFalse(Ljava/lang/String;Z)V",
"varArgs": false,
"declaredExceptions": [],
"yields": [
{
"parametersConstraints": [
[],
["FALSE"]
],
"resultIndex": -1,
"resultConstraint": null
},
{
"parametersConstraints": [
[],
["TRUE"]
],
"exception": ["java.lang.AssertionError"]
}
]
},
{
"signature": "org.junit.Assert#fail()V",
"varArgs": false,
"declaredExceptions": [],
"yields": [
{
"parametersConstraints": [
[]
],
"exception": ["java.lang.AssertionError"]
}
]
},
{
"signature": "org.junit.Assert#fail(Ljava/lang/String;)V",
"varArgs": false,
"declaredExceptions": [],
"yields": [
{
"parametersConstraints": [
[]
],
"exception": ["java.lang.AssertionError"]
}
]
}
]

0 comments on commit 12b7ef1

Please sign in to comment.