Files
2026-10-21 13:22:35 +08:00

83 lines
4.3 KiB
JavaScript

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/)
})