Skip to content

Commit 1aeb5b5

Browse files
committed
test(P10): guard architecture size budgets
1 parent 83c9508 commit 1aeb5b5

1 file changed

Lines changed: 52 additions & 0 deletions

File tree

src/test/kotlin/top/ellan/mahjong/architecture/ArchitectureBoundaryTest.kt

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,47 @@ class ArchitectureBoundaryTest {
136136
)
137137
}
138138

139+
@Test
140+
fun `known large orchestration files stay under size budgets`() {
141+
val violations = lineBudgets.mapNotNull { budget ->
142+
val file = projectRoot.resolve(budget.path)
143+
val lineCount = Files.readAllLines(file).size
144+
if (lineCount <= budget.maxLines) {
145+
null
146+
} else {
147+
"${budget.path}: $lineCount lines exceeds budget ${budget.maxLines}"
148+
}
149+
}
150+
151+
assertTrue(
152+
violations.isEmpty(),
153+
"Large files should shrink or stay flat; raise a budget only with an accompanying split plan:\n${violations.joinToString("\n")}"
154+
)
155+
}
156+
157+
@Test
158+
fun `known broad public surfaces stay under method budgets`() {
159+
val violations = publicMethodBudgets.mapNotNull { budget ->
160+
val file = projectRoot.resolve(budget.path)
161+
val methodCount = Files.readString(file).lineSequence()
162+
.count { line -> publicMemberPattern.matches(line) }
163+
if (methodCount <= budget.maxPublicMembers) {
164+
null
165+
} else {
166+
"${budget.path}: $methodCount public members exceeds budget ${budget.maxPublicMembers}"
167+
}
168+
}
169+
170+
assertTrue(
171+
violations.isEmpty(),
172+
"Broad public surfaces should shrink or stay flat; prefer narrow interfaces before adding more public members:\n${violations.joinToString("\n")}"
173+
)
174+
}
175+
139176
private companion object {
177+
data class LineBudget(val path: String, val maxLines: Int)
178+
data class PublicMethodBudget(val path: String, val maxPublicMembers: Int)
179+
140180
val projectRoot: Path = Path.of("").toAbsolutePath()
141181
val forbiddenRuleImports = listOf(
142182
"import org.bukkit.",
@@ -173,6 +213,18 @@ class ArchitectureBoundaryTest {
173213
"src/main/kotlin/top/ellan/mahjong/riichi",
174214
"src/main/kotlin/top/ellan/mahjong/gb/jni"
175215
).map { projectRoot.resolve(it).normalize() }
216+
val lineBudgets = listOf(
217+
LineBudget("build.gradle.kts", 350),
218+
LineBudget("src/main/java/top/ellan/mahjong/table/core/MahjongTableSession.java", 1650),
219+
LineBudget("src/main/java/top/ellan/mahjong/table/core/MahjongTableManager.java", 1000),
220+
LineBudget("src/main/java/top/ellan/mahjong/render/scene/TableRenderer.java", 2150)
221+
)
222+
val publicMethodBudgets = listOf(
223+
PublicMethodBudget("src/main/java/top/ellan/mahjong/table/core/MahjongTableSession.java", 230),
224+
PublicMethodBudget("src/main/java/top/ellan/mahjong/table/core/MahjongTableManager.java", 50),
225+
PublicMethodBudget("src/main/java/top/ellan/mahjong/render/scene/TableRenderer.java", 40)
226+
)
227+
val publicMemberPattern = Regex("""^\s+public (?!class|interface|enum|record).*""")
176228

177229
fun sourceFiles(vararg roots: String): List<Path> = roots.flatMap { root ->
178230
val rootPath = projectRoot.resolve(root)

0 commit comments

Comments
 (0)