import test from 'node:test' import assert from 'node:assert/strict' import { mkdtempSync, rmSync, mkdirSync, writeFileSync, readFileSync, existsSync } from 'node:fs' import { tmpdir } from 'node:os' import { join, resolve } from 'node:path' import { ADMIN_SOURCE_DIRS, collectBoundaryViolations, FORBIDDEN_COUPLING_TOKENS, readWorkspacePackage, REQUIRED_MANIFEST_FILES, resolveWorkspaceRoot, STANDALONE_PACKAGE_NAME, walk, } from '../src/config/workspace.ts' function tempRoot(): string { return mkdtempSync(join(tmpdir(), 'admin-workspace-')) } test('test_task_001_project_baseline_normal_primary_path', () => { // 正常主路径:独立工程从自身根目录完成一次边界校验,输出无违规。 const root = resolveWorkspaceRoot() const violations = collectBoundaryViolations(root) assert.deepEqual(violations, [], `工作区边界违规: ${violations.join('; ')}`) const pkg = readWorkspacePackage(root) assert.equal(pkg.name, STANDALONE_PACKAGE_NAME) for (const dep of ['vue', 'vue-router', 'pinia', 'element-plus']) { assert.ok(pkg.dependencies[dep], `缺少依赖 ${dep}`) } }) test('test_task_001_project_baseline_normal_variant_input', () => { // 正常变体:构建、开发、测试三套命令形态都指向独立后台工程。 const { scripts } = readWorkspacePackage() assert.match(scripts.build, /vue-tsc --noEmit/) assert.match(scripts.build, /vite build/) assert.match(scripts.dev, /vite/) assert.match(scripts.dev, /5174/) assert.match(scripts.test, /node --test/) assert.match(scripts.test, /tests\/\*\.test\.ts/) }) test('test_task_001_project_baseline_normal_repeated_operation_is_idempotent', () => { // 正常重复:重复校验不改变结果、不产生不稳定状态。 const first = collectBoundaryViolations() const second = collectBoundaryViolations() assert.deepEqual(second, first, '重复校验结果应稳定一致') const pkgA = readWorkspacePackage() const pkgB = readWorkspacePackage() assert.equal(pkgA.name, pkgB.name) assert.deepEqual(pkgA.dependencies, pkgB.dependencies) }) test('test_task_001_project_baseline_boundary_empty_input', () => { // 边界空值:允许的源码目录集合完整存在;扫描可容忍空目录不崩溃。 const root = resolveWorkspaceRoot() for (const dir of ADMIN_SOURCE_DIRS) { assert.equal(existsSync(join(root, dir)), true, `缺少允许源码目录 ${dir}`) } const empty = tempRoot() try { mkdirSync(join(empty, 'src')) assert.deepEqual(walk(empty), [], '空目录扫描应返回空结果且不抛异常') } finally { rmSync(empty, { recursive: true, force: true }) } }) test('test_task_001_project_baseline_boundary_single_item', () => { // 边界单元素:单一 SPA 入口与单一挂载点。 const root = resolveWorkspaceRoot() const html = readFileSync(join(root, 'index.html'), 'utf8') assert.match(html, /id="app"/) assert.match(html, /\/src\/main\.ts/) const main = readFileSync(join(root, 'src/main.ts'), 'utf8') assert.match(main, /\.mount\('#app'\)/) }) test('test_task_001_project_baseline_boundary_limit_or_missing_field', () => { // 边界上限/缺字段:严格类型与 ESM 模块边界等关键字段必须存在。 const root = resolveWorkspaceRoot() const tsconfig = readFileSync(join(root, 'tsconfig.json'), 'utf8') assert.match(tsconfig, /"strict":\s*true/) assert.match(tsconfig, /"moduleResolution":\s*"Bundler"/) const pkg = readWorkspacePackage(root) assert.equal(pkg.private, true) assert.ok(pkg.scripts.test, '缺少 test 命令字段') assert.ok(REQUIRED_MANIFEST_FILES.length >= 5, '清单字段不能为空') }) test('test_task_001_project_baseline_invalid_input_rejected', () => { // 异常输入:任何文件引用客户端耦合 token 都应被边界校验拒绝。 const root = tempRoot() try { for (const token of FORBIDDEN_COUPLING_TOKENS) { mkdirSync(join(root, 'src'), { recursive: true }) writeFileSync(join(root, 'src', 'bad.ts'), `// 越界引用\nconst t = '${token}'\n`) const violations = collectBoundaryViolations(root) assert.ok( violations.some((v) => v.includes(`引用了客户端耦合 token "${token}"`)), `token ${token} 应被识别为越界: ${violations.join('; ')}`, ) rmSync(join(root, 'src', 'bad.ts')) } } finally { rmSync(root, { recursive: true, force: true }) } }) test('test_task_001_project_baseline_dependency_failure_returns_actionable_message', () => { // 依赖失败:根目录定位失败与清单缺失时返回可操作错误。 const root = tempRoot() try { const missing = join(root, 'no-package') mkdirSync(missing) assert.throws( () => resolveWorkspaceRoot(missing), (error: Error) => error.message.includes('package.json'), ) const emptyDir = join(root, 'flat') mkdirSync(emptyDir) writeFileSync(join(emptyDir, 'package.json'), '{}') const violations = collectBoundaryViolations(emptyDir) assert.ok( violations.some((v) => v.includes('缺少必需清单文件 src/main.ts')), `依赖缺失应返回可操作清单消息: ${violations.join('; ')}`, ) } finally { rmSync(root, { recursive: true, force: true }) } })