@@ -11,7 +11,19 @@ const val testCiTargetGroup = "verification"
11
11
private val testFileNameRegex =
12
12
Regex (" ^(?!(abstract|fake)).*?(Test)(s)?\\ d*" , RegexOption .IGNORE_CASE )
13
13
14
- private val classDeclarationRegex = Regex (""" class\s+([A-Za-z_][A-Za-z0-9_]*)""" )
14
+ private val classDeclarationRegex = Regex (""" (?<!private\s)class\s+([A-Za-z_][A-Za-z0-9_]*)""" )
15
+
16
+ // Essential annotations (most common subset)
17
+ private val essentialTestAnnotations =
18
+ setOf (
19
+ " @Test" ,
20
+ " @TestTemplate" ,
21
+ " @ParameterizedTest" ,
22
+ " @RepeatedTest" ,
23
+ " @TestFactory" ,
24
+ " @org.junit.Test" , // JUnit 4
25
+ " @org.testng.annotations.Test" // TestNG
26
+ )
15
27
16
28
fun addTestCiTargets (
17
29
testFiles : FileCollection ,
@@ -56,21 +68,40 @@ fun addTestCiTargets(
56
68
}
57
69
}
58
70
71
+ private fun containsEssentialTestAnnotations (content : String ): Boolean {
72
+ return essentialTestAnnotations.any { content.contains(it) }
73
+ }
74
+
59
75
private fun getTestClassNameIfAnnotated (file : File ): String? {
60
- return file
61
- .takeIf { it.exists() }
62
- ?.readText()
63
- ?.takeIf {
64
- it.contains(" @Test" ) || it.contains(" @TestTemplate" ) || it.contains(" @ParameterizedTest" )
65
- }
66
- ?.let { content ->
67
- val className = classDeclarationRegex.find(content)?.groupValues?.getOrNull(1 )
68
- return if (className != null && ! className.startsWith(" Fake" )) {
69
- className
70
- } else {
71
- null
72
- }
73
- }
76
+ val content = file.takeIf { it.exists() }?.readText() ? : return null
77
+
78
+ // Only process files that contain test annotations
79
+ if (! containsEssentialTestAnnotations(content)) {
80
+ return null
81
+ }
82
+
83
+ // Find all non-private class declarations
84
+ val classMatches = classDeclarationRegex.findAll(content).toList()
85
+
86
+ // First, try to find a class that ends with "Test" or "Tests"
87
+ for (match in classMatches) {
88
+ val className = match.groupValues.getOrNull(1 ) ? : continue
89
+ if ((className.endsWith(" Test" ) || className.endsWith(" Tests" )) &&
90
+ ! className.startsWith(" Fake" ) &&
91
+ ! className.startsWith(" Abstract" )) {
92
+ return className
93
+ }
94
+ }
95
+
96
+ // Fallback: find the first non-private class that's not Fake or Abstract
97
+ for (match in classMatches) {
98
+ val className = match.groupValues.getOrNull(1 ) ? : continue
99
+ if (! className.startsWith(" Fake" ) && ! className.startsWith(" Abstract" )) {
100
+ return className
101
+ }
102
+ }
103
+
104
+ return null
74
105
}
75
106
76
107
fun ensureTargetGroupExists (targetGroups : TargetGroups , group : String ) {
0 commit comments