initial commit
This commit is contained in:
71
test/unit/server-imports.spec.js
Normal file
71
test/unit/server-imports.spec.js
Normal file
@@ -0,0 +1,71 @@
|
||||
import { readFileSync, readdirSync } from 'node:fs'
|
||||
import { resolve, dirname, relative } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { describe, it, expect } from 'vitest'
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url))
|
||||
const projectRoot = resolve(__dirname, '../..')
|
||||
const serverDir = resolve(projectRoot, 'server')
|
||||
|
||||
/** Collects all .js file paths under dir (recursive). */
|
||||
function listJsFiles(dir, base = dir) {
|
||||
const entries = readdirSync(dir, { withFileTypes: true })
|
||||
const files = []
|
||||
for (const e of entries) {
|
||||
const full = resolve(dir, e.name)
|
||||
if (e.isDirectory()) {
|
||||
files.push(...listJsFiles(full, base))
|
||||
}
|
||||
else if (e.isFile() && e.name.endsWith('.js')) {
|
||||
files.push(relative(base, full))
|
||||
}
|
||||
}
|
||||
return files
|
||||
}
|
||||
|
||||
/** Extracts relative import/require paths from file content (no node_modules). */
|
||||
function getRelativeImports(content) {
|
||||
const paths = []
|
||||
const fromRegex = /from\s+['"]([^'"]+)['"]/g
|
||||
const requireRegex = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g
|
||||
for (const re of [fromRegex, requireRegex]) {
|
||||
let m
|
||||
while ((m = re.exec(content)) !== null) {
|
||||
const p = m[1]
|
||||
if (p.startsWith('.')) paths.push(p)
|
||||
}
|
||||
}
|
||||
return paths
|
||||
}
|
||||
|
||||
describe('server imports', () => {
|
||||
it('only import from within server/ (no shared/ or other outside paths)', () => {
|
||||
const violations = []
|
||||
const files = listJsFiles(serverDir).map(f => resolve(serverDir, f))
|
||||
|
||||
for (const filePath of files) {
|
||||
const content = readFileSync(filePath, 'utf-8')
|
||||
const fileDir = dirname(filePath)
|
||||
for (const importPath of getRelativeImports(content)) {
|
||||
const resolved = resolve(fileDir, importPath)
|
||||
const relToServer = relative(serverDir, resolved)
|
||||
if (relToServer.startsWith('..') || relToServer.startsWith('/')) {
|
||||
violations.push({
|
||||
file: relative(projectRoot, filePath),
|
||||
import: importPath,
|
||||
resolved: relative(projectRoot, resolved),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expect(
|
||||
violations,
|
||||
violations.length
|
||||
? `Server files must not import from outside server/. Violations:\n${violations
|
||||
.map(v => ` ${v.file} → ${v.import} (resolves to ${v.resolved})`)
|
||||
.join('\n')}`
|
||||
: undefined,
|
||||
).toHaveLength(0)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user