Skip to content

Commit 1ed6efa

Browse files
authored
Fix missing info in summaries #1588, #1734 (#1782)
Fix empty display names, missing info in summaries, summary tests and add extra summary tests
1 parent a2dcd6e commit 1ed6efa

File tree

8 files changed

+125
-15
lines changed

8 files changed

+125
-15
lines changed

utbot-framework-test/src/test/kotlin/org/utbot/examples/enums/ComplexEnumExamplesTest.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ class ComplexEnumExamplesTest : UtValueTestCaseChecker(
7575
}
7676

7777
@Test
78-
@Disabled("TODO: nested anonymous classes are not supported: https://github.com/UnitTestBot/UTBotJava/issues/617")
7978
fun testFindState() {
8079
check(
8180
ComplexEnumExamples::findState,

utbot-summary-tests/src/test/kotlin/examples/collections/SummaryListWrapperReturnsVoidTest.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,17 @@ class SummaryListWrapperReturnsVoidTest : SummaryTestCaseGeneratorTest(
1616
) {
1717
@Test
1818
fun testRunForEach() {
19-
val summary1 = "Test throws NullPointerException in: list.forEach(o -> {\n" +
19+
val summary1 = "Test invokes:\n" +
20+
" {@link java.util.List#forEach(java.util.function.Consumer)} once\n" +
21+
"throws NullPointerException in: list.forEach(o -> {\n" +
2022
" if (o == null)\n" +
2123
" i[0]++;\n" +
22-
"});"
24+
"});\n"
2325
val summary2 = "Test returns from: return i[0];"
2426
val summary3 = "Test returns from: return i[0];"
2527
val summary4 = "Test returns from: return i[0];"
2628

27-
val methodName1 = "testRunForEach_ThrowNullPointerException"
29+
val methodName1 = "testRunForEach_ListForEach"
2830
val methodName2 = "testRunForEach_Return0OfI"
2931
val methodName3 = "testRunForEach_Return0OfI_1"
3032
val methodName4 = "testRunForEach_Return0OfI_2"

utbot-summary-tests/src/test/kotlin/examples/enums/ComplexEnumExampleTest.kt renamed to utbot-summary-tests/src/test/kotlin/examples/enums/SummaryComplexEnumExampleTest.kt

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import org.utbot.framework.plugin.api.MockStrategyApi
99
import org.utbot.testing.DoNotCalculate
1010

1111
@ExtendWith(CustomJavaDocTagsEnabler::class)
12-
class ComplexEnumExampleTest : SummaryTestCaseGeneratorTest(
12+
class SummaryComplexEnumExampleTest : SummaryTestCaseGeneratorTest(
1313
ComplexEnumExamples::class
1414
) {
1515
@Test
@@ -85,4 +85,53 @@ class ComplexEnumExampleTest : SummaryTestCaseGeneratorTest(
8585

8686
summaryCheck(method, mockStrategy, coverage, summaryKeys, methodNames, displayNames)
8787
}
88+
89+
@Test
90+
fun testFindState() {
91+
val summary1 = "@utbot.classUnderTest {@link ComplexEnumExamples}\n" +
92+
"@utbot.methodUnderTest {@link org.utbot.examples.enums.ComplexEnumExamples#findState(int)}\n" +
93+
"@utbot.invokes {@link org.utbot.examples.enums.State#findStateByCode(int)}\n" +
94+
"@utbot.returnsFrom {@code return State.findStateByCode(code);}\n"
95+
val summary2 = "@utbot.classUnderTest {@link ComplexEnumExamples}\n" +
96+
"@utbot.methodUnderTest {@link org.utbot.examples.enums.ComplexEnumExamples#findState(int)}\n" +
97+
"@utbot.invokes {@link org.utbot.examples.enums.State#findStateByCode(int)}\n" +
98+
"@utbot.returnsFrom {@code return State.findStateByCode(code);}\n"
99+
val summary3 = "@utbot.classUnderTest {@link ComplexEnumExamples}\n" +
100+
"@utbot.methodUnderTest {@link org.utbot.examples.enums.ComplexEnumExamples#findState(int)}\n" +
101+
"@utbot.invokes {@link org.utbot.examples.enums.State#findStateByCode(int)}\n" +
102+
"@utbot.returnsFrom {@code return State.findStateByCode(code);}\n"
103+
104+
val methodName1 = "testFindState_ReturnStateFindStateByCode"
105+
val methodName2 = "testFindState_ReturnStateFindStateByCode_1"
106+
val methodName3 = "testFindState_ReturnStateFindStateByCode_2"
107+
108+
val displayName1 = "-> return State.findStateByCode(code)"
109+
val displayName2 = "-> return State.findStateByCode(code)"
110+
val displayName3 = "-> return State.findStateByCode(code)"
111+
112+
val summaryKeys = listOf(
113+
summary1,
114+
summary2,
115+
summary3
116+
)
117+
118+
val displayNames = listOf(
119+
displayName1,
120+
displayName2,
121+
displayName3
122+
)
123+
124+
val methodNames = listOf(
125+
methodName1,
126+
methodName2,
127+
methodName3
128+
)
129+
130+
131+
val method = ComplexEnumExamples::findState
132+
val mockStrategy = MockStrategyApi.NO_MOCKS
133+
val coverage = DoNotCalculate
134+
135+
summaryCheck(method, mockStrategy, coverage, summaryKeys, methodNames, displayNames)
136+
}
88137
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package examples.mock
2+
3+
import examples.SummaryTestCaseGeneratorTest
4+
import org.junit.jupiter.api.Test
5+
import org.utbot.examples.mock.CommonMocksExample
6+
import org.utbot.framework.plugin.api.MockStrategyApi
7+
import org.utbot.testing.DoNotCalculate
8+
9+
class SummaryCommonMocksExample : SummaryTestCaseGeneratorTest(
10+
CommonMocksExample::class,
11+
) {
12+
@Test
13+
fun testClinitMockExample() {
14+
val summary1 = "Test invokes:\n" +
15+
" {@link java.lang.Integer#intValue()} twice\n" +
16+
"returns from: return -ObjectWithFinalStatic.keyValue;\n"
17+
18+
val methodName1 = "testClinitMockExample_IntegerIntValue"
19+
20+
val displayName1 = "IntegerIntValue -> return -ObjectWithFinalStatic.keyValue"
21+
22+
23+
val summaryKeys = listOf(
24+
summary1
25+
)
26+
27+
val displayNames = listOf(
28+
displayName1
29+
)
30+
31+
val methodNames = listOf(
32+
methodName1
33+
)
34+
35+
val method = CommonMocksExample::clinitMockExample
36+
val mockStrategy = MockStrategyApi.OTHER_CLASSES
37+
val coverage = DoNotCalculate
38+
39+
summaryCheck(method, mockStrategy, coverage, summaryKeys, methodNames, displayNames)
40+
}
41+
}

utbot-summary-tests/src/test/kotlin/examples/recursion/SummaryRecursionTest.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ class SummaryRecursionTest : SummaryTestCaseGeneratorTest(
2626
val summary3 = "@utbot.classUnderTest {@link Recursion}\n" +
2727
"@utbot.methodUnderTest {@link org.utbot.examples.recursion.Recursion#fib(int)}\n" +
2828
"@utbot.executesCondition {@code (n == 1): False}\n" +
29+
"@utbot.invokes {@link org.utbot.examples.recursion.Recursion#fib(int)}\n" +
30+
"@utbot.invokes {@link org.utbot.examples.recursion.Recursion#fib(int)}\n" +
2931
"@utbot.triggersRecursion fib, where the test execute conditions:\n" +
3032
" {@code (n == 1): True}\n" +
3133
"return from: {@code return 1;}" +
@@ -84,6 +86,7 @@ class SummaryRecursionTest : SummaryTestCaseGeneratorTest(
8486
val summary2 = "@utbot.classUnderTest {@link Recursion}\n" +
8587
"@utbot.methodUnderTest {@link org.utbot.examples.recursion.Recursion#factorial(int)}\n" +
8688
"@utbot.executesCondition {@code (n == 0): False}\n" +
89+
"@utbot.invokes {@link org.utbot.examples.recursion.Recursion#factorial(int)}\n" +
8790
"@utbot.triggersRecursion factorial, where the test return from: {@code return 1;}" +
8891
"@utbot.returnsFrom {@code return n * factorial(n - 1);}"
8992
val summary3 = "@utbot.classUnderTest {@link Recursion}\n" +

utbot-summary-tests/src/test/kotlin/math/SummaryIntMathLogTest.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@ class SummaryIntMathLogTest : SummaryTestCaseGeneratorTest(
2626
"@utbot.invokes {@link java.math.RoundingMode#ordinal()}\n" +
2727
"@utbot.throwsException {@link java.lang.NullPointerException} in: mode"
2828

29-
val methodName1 = "testLog2"
30-
val methodName2 = "testLog2_1"
31-
val methodName3 = "testLog2_2"
29+
val methodName1 = "testLog2_IntegerNumberOfLeadingZeros"
30+
val methodName2 = "testLog2_IntegerNumberOfLeadingZeros_1"
31+
val methodName3 = "testLog2_IntMathLessThanBranchFree"
3232
val methodName4 = "testLog2_RoundingModeOrdinal"
3333

34-
val displayName1 = ""
35-
val displayName2 = ""
36-
val displayName3 = ""
34+
val displayName1 = "switch(mode) case: FLOOR -> return (Integer.SIZE - 1) - Integer.numberOfLeadingZeros(x)"
35+
val displayName2 = "switch(mode) case: CEILING -> return Integer.SIZE - Integer.numberOfLeadingZeros(x - 1)"
36+
val displayName3 = "switch(mode) case: HALF_EVEN -> return logFloor + lessThanBranchFree(cmp, x)"
3737
val displayName4 = "switch(mode) case: -> ThrowNullPointerException"
3838

3939
val summaryKeys = listOf(

utbot-summary-tests/src/test/kotlin/math/SummaryOfMathTest.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,9 @@ class SummaryOfMathTest : SummaryTestCaseGeneratorTest(
232232
" {@code (count == 0): True}\n" +
233233
" invoke:\n" +
234234
" {@link guava.examples.math.StatsAccumulator#isFinite(double)} twice\n" +
235-
"Tests next execute conditions:\n" +
235+
"Tests later invoke:\n" +
236+
" {@link guava.examples.math.StatsAccumulator#add(double)} once\n" +
237+
"execute conditions:\n" +
236238
" {@code (null): False}\n" +
237239
"call {@link guava.examples.math.StatsAccumulator#isFinite(double)},\n" +
238240
" there it invoke:\n" +

utbot-summary/src/main/kotlin/org/utbot/summary/tag/StatementTreeBuilder.kt

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class StatementTreeBuilder(private val splitSteps: SplitSteps, private val trace
4343
* @see ExecutionStructureAnalysis
4444
* as they require initial tree tag structure. Otherwise it would be unreadable code here.
4545
*/
46-
private fun buildStatementTree(startIndex: Int = 0, statementTag: StatementTag? = null, depth: Int = 0): Int {
46+
private fun buildStatementTree(startIndex: Int = 0, statementTag: StatementTag? = null, depth: Int = 0, isInvokedRecursively: Boolean = false): Int {
4747
var currentIndex = startIndex
4848
var previousStatementTag = statementTag
4949
while (currentIndex < traceSteps.size) {
@@ -54,14 +54,28 @@ class StatementTreeBuilder(private val splitSteps: SplitSteps, private val trace
5454
nextStatementTag?.let {
5555
when {
5656
it.step.depth < depth -> {
57-
return currentIndex--
57+
// When analyzing a steps' path, we can accidentally return before we process the whole path,
58+
// this leads to missing info in summaries.
59+
// In order to solve it, we track whether we called the method from [StatementTreeBuilder.build()]
60+
// or called it here recursively.
61+
// In the first case we do not return,
62+
// in the second case we return an index.
63+
currentIndex--
64+
if (isInvokedRecursively) return currentIndex
65+
else return@let
5866
}
5967
it.step.depth > depth -> {
6068
currentStatement.invoke = nextStatementTag
69+
70+
// We save the nextStatementTag in .next as well at the end of the step path
71+
// in order to recover info from it
72+
if (currentIndex == traceSteps.lastIndex) currentStatement.next = nextStatementTag
73+
6174
currentIndex = buildStatementTree(
6275
currentIndex + 1,
6376
nextStatementTag,
64-
nextStatementTag.step.depth
77+
nextStatementTag.step.depth,
78+
isInvokedRecursively = true
6579
)
6680
currentIndex--
6781
}

0 commit comments

Comments
 (0)