Skip to content

Commit 8a27e38

Browse files
committed
fix(gradle): exclude private class for atomized test
1 parent 873f2d8 commit 8a27e38

File tree

2 files changed

+47
-16
lines changed

2 files changed

+47
-16
lines changed

packages/gradle/project-graph/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ plugins {
1010

1111
group = "dev.nx.gradle"
1212

13-
version = "0.1.0"
13+
version = "0.1.1"
1414

1515
repositories { mavenCentral() }
1616

packages/gradle/project-graph/src/main/kotlin/dev/nx/gradle/utils/CiTargetsUtils.kt

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,19 @@ const val testCiTargetGroup = "verification"
1111
private val testFileNameRegex =
1212
Regex("^(?!(abstract|fake)).*?(Test)(s)?\\d*", RegexOption.IGNORE_CASE)
1313

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+
)
1527

1628
fun addTestCiTargets(
1729
testFiles: FileCollection,
@@ -56,21 +68,40 @@ fun addTestCiTargets(
5668
}
5769
}
5870

71+
private fun containsEssentialTestAnnotations(content: String): Boolean {
72+
return essentialTestAnnotations.any { content.contains(it) }
73+
}
74+
5975
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
74105
}
75106

76107
fun ensureTargetGroupExists(targetGroups: TargetGroups, group: String) {

0 commit comments

Comments
 (0)