import assert from 'node:assert/strict' import { spawn } from 'node:child_process' import test from 'node:test' import { fileURLToPath } from 'node:url' const launcher = fileURLToPath(new URL('./backend-check.ps1', import.meta.url)) const quote = value => `'${String(value).replaceAll("'", "''")}'` // 运行真实 PowerShell 参数解析与入口,执行分支使用内存 Maven 替身,不启动 Java。 function run(args, mockExit) { if (mockExit !== undefined) assert.ok(process.env.CHONGCHONG_LOCAL_CHECK_OWNER, 'Run tests through local-check.ps1') const mock = mockExit === undefined ? '' : `function global:Mock-Maven { Write-Host ('MOCK_ARGS:' + (ConvertTo-Json -Compress -InputObject @($args))); $global:LASTEXITCODE = ${mockExit} }; ` const parameters = [] for (let i = 0; i < args.length; i++) { const key = args[i].slice(1) parameters.push(`${quote(key)}=${key === 'DryRun' ? '$true' : quote(args[++i])}`) } if (mockExit !== undefined) parameters.push("MavenCommand='Mock-Maven'") const command = `$ErrorActionPreference='Stop'; ${mock}$parameters=@{${parameters.join(';')}}; & ${quote(launcher)} @parameters; exit $LASTEXITCODE` return new Promise((resolve, reject) => { const child = spawn('pwsh', ['-NoProfile', '-NonInteractive', '-OutputFormat', 'Text', '-EncodedCommand', Buffer.from(command, 'utf16le').toString('base64')]) let output = '' child.stdout.on('data', chunk => { output += chunk }) child.stderr.on('data', chunk => { output += chunk }) child.on('error', reject) child.on('close', code => resolve({ code, output })) }) } test('module selection is mandatory and rejects inactive modules and injected Maven options', async () => { for (const args of [[], ['-Modules', 'gateway-overseas'], ['-Modules', 'order,'], ['-Modules', '-DskipTests']]) { const result = await run([...args, '-DryRun']) assert.equal(result.code, 2, result.output) assert.doesNotMatch(result.output, /DRY-RUN PASS/) } }) test('default selection runs only requested modules plus upstream dependencies', async () => { const result = await run(['-Modules', 'order,firstleg,order', '-DryRun']) assert.equal(result.code, 0, result.output) assert.match(result.output, /-pl order,firstleg -am test/) assert.doesNotMatch(result.output, /skipTests|maven.test.skip|backend-full-regression/) }) test('compile retains compilation of test sources without executing tests', async () => { const result = await run(['-Mode', 'Compile', '-Modules', 'order'], 0) assert.equal(result.code, 0, result.output) assert.match(result.output, /MOCK_ARGS:.*"-pl","order","-am","test-compile"/) assert.match(result.output, /Compile check PASS/) }) test('focused selection resolves exact classes and rejects missing or broad selectors', async () => { const good = await run(['-Mode', 'Focused', '-Modules', 'common-core', '-Tests', 'ApiResponseTest,BoundedRetryPolicyTest', '-DryRun']) assert.equal(good.code, 0, good.output) assert.match(good.output, /-Dtest=com.baiyue.common.core.ApiResponseTest,com.baiyue.common.core.BoundedRetryPolicyTest/) for (const name of ['MissingTest', '*Test', 'ApiResponseTest#method']) { const result = await run(['-Mode', 'Focused', '-Modules', 'common-core', '-Tests', name, '-DryRun']) assert.equal(result.code, 2, result.output) } }) test('test filter cannot silently apply to compile or module mode', async () => { for (const mode of ['Compile', 'Module']) { const result = await run(['-Mode', mode, '-Modules', 'common-core', '-Tests', 'ApiResponseTest', '-DryRun']) assert.equal(result.code, 2, result.output) } const missing = await run(['-Mode', 'Focused', '-Modules', 'common-core', '-DryRun']) assert.equal(missing.code, 2, missing.output) }) test('Maven failure is propagated without claiming success', async () => { const result = await run(['-Modules', 'common-core'], 7) assert.equal(result.code, 7, result.output) assert.doesNotMatch(result.output, /check PASS/) }) test('Maven success without freshly executed selected tests cannot pass', async () => { const result = await run(['-Mode', 'Focused', '-Modules', 'common-core', '-Tests', 'ApiResponseTest'], 0) assert.notEqual(result.code, 0, result.output) assert.match(result.output, /No executed tests in fresh reports/) assert.doesNotMatch(result.output, /check PASS/) })