Skip to content

Commit c67e5e5

Browse files
authored
Added support for summaries on the nested classes (#1452)
1 parent 72264ad commit c67e5e5

File tree

3 files changed

+87
-4
lines changed

3 files changed

+87
-4
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package org.utbot.examples.nested;
2+
3+
public class DeepNested {
4+
public class Nested1 {
5+
public class Nested2 {
6+
public int f(int i) {
7+
if (i > 0) {
8+
return 10;
9+
}
10+
return 0;
11+
}
12+
}
13+
}
14+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package examples.nested
2+
3+
import examples.CustomJavaDocTagsEnabler
4+
import examples.SummaryTestCaseGeneratorTest
5+
import org.junit.jupiter.api.Test
6+
import org.junit.jupiter.api.extension.ExtendWith
7+
import org.utbot.examples.nested.DeepNested
8+
import org.utbot.examples.recursion.Recursion
9+
import org.utbot.framework.plugin.api.MockStrategyApi
10+
import org.utbot.testing.DoNotCalculate
11+
12+
@ExtendWith(CustomJavaDocTagsEnabler::class)
13+
class SummaryNestedTest : SummaryTestCaseGeneratorTest(
14+
DeepNested.Nested1.Nested2::class
15+
) {
16+
@Test
17+
fun testNested() {
18+
val summary1 = "@utbot.classUnderTest {@link DeepNested.Nested1.Nested2}\n" +
19+
"@utbot.methodUnderTest {@link org.utbot.examples.nested.DeepNested.Nested1.Nested2#f(int)}\n" +
20+
"@utbot.executesCondition {@code (i > 0): False}\n" +
21+
"@utbot.returnsFrom {@code return 0;}\n"
22+
23+
val summary2 = "@utbot.classUnderTest {@link DeepNested.Nested1.Nested2}\n" +
24+
"@utbot.methodUnderTest {@link org.utbot.examples.nested.DeepNested.Nested1.Nested2#f(int)}\n" +
25+
"@utbot.executesCondition {@code (i > 0): True}\n" +
26+
"@utbot.returnsFrom {@code return 10;}"
27+
28+
val methodName1 = "testF_ILessOrEqualZero"
29+
val methodName2 = "testF_IGreaterThanZero"
30+
31+
val displayName1 = "i > 0 : False -> return 0"
32+
val displayName2 = "i > 0 : True -> return 10"
33+
34+
val summaryKeys = listOf(
35+
summary1,
36+
summary2
37+
)
38+
39+
val displayNames = listOf(
40+
displayName1,
41+
displayName2
42+
)
43+
44+
val methodNames = listOf(
45+
methodName1,
46+
methodName2
47+
)
48+
49+
val method = DeepNested.Nested1.Nested2::f
50+
val mockStrategy = MockStrategyApi.NO_MOCKS
51+
val coverage = DoNotCalculate
52+
53+
summaryCheck(method, mockStrategy, coverage, summaryKeys, methodNames, displayNames)
54+
}
55+
}

utbot-summary/src/main/kotlin/org/utbot/summary/ast/SourceCodeParser.kt

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class SourceCodeParser {
5555
val clazz = it.types.firstOrNull { clazz ->
5656
clazz.name.identifier == className
5757
} ?: traverseInnerClassDeclarations(
58-
it.types.flatMap { declaration -> declaration.childNodes },
58+
it.types.flatMap { declaration -> declaration.childNodes }.filterIsInstance<ClassOrInterfaceDeclaration>(),
5959
className
6060
)
6161

@@ -84,9 +84,23 @@ class SourceCodeParser {
8484
* Identifier is ClassOrInterfaceDeclaration
8585
*/
8686
private fun traverseInnerClassDeclarations(
87-
nodes: List<Node>, className: String
88-
): TypeDeclaration<*>? = nodes.filterIsInstance<ClassOrInterfaceDeclaration>()
89-
.firstOrNull { it.name.identifier == className }
87+
nodes: List<ClassOrInterfaceDeclaration>, className: String
88+
): TypeDeclaration<*>? {
89+
var result = nodes.firstOrNull { it.name.identifier == className }
90+
91+
if (result != null) return result
92+
93+
run childrenSearch@ {
94+
nodes.forEach {
95+
val childNodes = it.childNodes.filterIsInstance<ClassOrInterfaceDeclaration>()
96+
if (childNodes.isNotEmpty()) {
97+
result = traverseInnerClassDeclarations(childNodes, className) as ClassOrInterfaceDeclaration?
98+
if (result!= null) return@childrenSearch
99+
}
100+
}
101+
}
102+
return result
103+
}
90104
}
91105

92106
/**

0 commit comments

Comments
 (0)