refactor: enforce 800 line source limits
This commit is contained in:
79
web/tests/code-size-limits.test.mjs
Normal file
79
web/tests/code-size-limits.test.mjs
Normal file
@@ -0,0 +1,79 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import { readdirSync, readFileSync } from 'node:fs'
|
||||
import { join, relative } from 'node:path'
|
||||
import test from 'node:test'
|
||||
|
||||
const MAX_SOURCE_UNIT_LINES = 800
|
||||
const REPO_ROOT = new URL('../..', import.meta.url).pathname
|
||||
|
||||
const FRONTEND_SOURCE_ROOTS = [
|
||||
'web/src/components',
|
||||
'web/src/composables',
|
||||
'web/src/utils',
|
||||
'web/src/views',
|
||||
]
|
||||
|
||||
const FRONTEND_EXTENSIONS = new Set(['.html', '.js', '.mjs', '.ts', '.tsx', '.vue'])
|
||||
|
||||
function extensionOf(path) {
|
||||
const index = path.lastIndexOf('.')
|
||||
return index === -1 ? '' : path.slice(index)
|
||||
}
|
||||
|
||||
function countLines(source) {
|
||||
return source.length === 0 ? 0 : source.split('\n').length
|
||||
}
|
||||
|
||||
function walkFiles(root, shouldInclude) {
|
||||
const result = []
|
||||
const stack = [root]
|
||||
|
||||
while (stack.length > 0) {
|
||||
const current = stack.pop()
|
||||
const entries = readdirSync(current, { withFileTypes: true })
|
||||
|
||||
for (const entry of entries) {
|
||||
const path = join(current, entry.name)
|
||||
if (entry.isDirectory()) {
|
||||
if (!['node_modules', 'dist', 'build', 'coverage'].includes(entry.name)) {
|
||||
stack.push(path)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if (shouldInclude(path)) {
|
||||
result.push(path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
function listOversizedFrontendUnits() {
|
||||
return FRONTEND_SOURCE_ROOTS.flatMap((root) => {
|
||||
const absoluteRoot = join(REPO_ROOT, root)
|
||||
return walkFiles(
|
||||
absoluteRoot,
|
||||
(path) => FRONTEND_EXTENSIONS.has(extensionOf(path))
|
||||
)
|
||||
})
|
||||
.map((path) => ({
|
||||
path: relative(REPO_ROOT, path),
|
||||
lines: countLines(readFileSync(path, 'utf8')),
|
||||
}))
|
||||
.filter((item) => item.lines > MAX_SOURCE_UNIT_LINES)
|
||||
.sort((left, right) => right.lines - left.lines)
|
||||
}
|
||||
|
||||
test('前端核心组件和模块不超过 800 行', () => {
|
||||
const oversized = listOversizedFrontendUnits()
|
||||
|
||||
assert.deepEqual(
|
||||
oversized,
|
||||
[],
|
||||
`以下前端核心源文件超过 ${MAX_SOURCE_UNIT_LINES} 行:\n${
|
||||
oversized.map((item) => `- ${item.path}: ${item.lines}`).join('\n')
|
||||
}`
|
||||
)
|
||||
})
|
||||
Reference in New Issue
Block a user