85 lines
3.9 KiB
JavaScript
85 lines
3.9 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import { readFile } from 'node:fs/promises'
|
|
import test from 'node:test'
|
|
|
|
import {
|
|
PALLET_LOCATION_SCENARIOS,
|
|
inspectCrossScenarioIsolation,
|
|
inspectScenarioReport,
|
|
parseMatrixArguments,
|
|
} from './pallet-location-test-env-acceptance.mjs'
|
|
|
|
const source = await readFile(new URL('./pallet-location-test-env-acceptance.mjs', import.meta.url), 'utf8')
|
|
|
|
test('pallet location matrix declares deterministic one, two, and three-image scenarios', () => {
|
|
assert.equal(PALLET_LOCATION_SCENARIOS.length, 5)
|
|
assert.deepEqual(PALLET_LOCATION_SCENARIOS.map((item) => item.expectedPalletCount), [1, 1, 1, 2, 3])
|
|
assert.match(source, /--modules', 'orders,inbound-measurement'/)
|
|
assert.match(source, /--verify-pallet-location-guide', 'true'/)
|
|
assert.match(source, /--wait-split-package-count', '18'/)
|
|
assert.match(source, /--wait-split-package-count', '12'/)
|
|
assert.match(source, /--wait-split-package-count', '61'/)
|
|
assert.match(source, /第3张确认后扩容只追加且既有槽身份不漂移/)
|
|
})
|
|
|
|
test('matrix options select known scenarios without duplicate or unknown names', () => {
|
|
const parsed = parseMatrixArguments([
|
|
'--origin-warehouse-name', '测试仓',
|
|
'--scenarios', 'single-image-single-slot,two-image-incremental-growth',
|
|
'--output=reports/custom.json',
|
|
])
|
|
assert.equal(parsed.originWarehouseName, '测试仓')
|
|
assert.deepEqual(parsed.scenarioNames, ['single-image-single-slot', 'two-image-incremental-growth'])
|
|
assert.equal(parsed.output, 'reports/custom.json')
|
|
assert.throws(() => parseMatrixArguments(['--scenarios', 'unknown']), /未知场景/)
|
|
assert.throws(() => parseMatrixArguments(['--scenarios', 'measured-volume-growth,measured-volume-growth']), /重复场景/)
|
|
})
|
|
|
|
test('scenario inspection requires deletion release, refill reuse, WAIT_SPLIT, and guide identity', () => {
|
|
const scenario = PALLET_LOCATION_SCENARIOS[0]
|
|
const requiredNames = [
|
|
'删除只解绑图片且原 reservation/location 变为 RESERVED_EMPTY',
|
|
'替代图片按新 resultId 复用原空槽',
|
|
'固定客户第 1 单停在待分柜',
|
|
'报告敏感信息扫描',
|
|
]
|
|
const report = {
|
|
success: true,
|
|
marker: 'TEST',
|
|
summary: { total: 10, failed: 0 },
|
|
createdResources: {
|
|
inboundMeasurement: { inboundId: '11', measurementId: '12', palletCount: 1, processStatus: 'WAIT_SPLIT' },
|
|
inboundMeasurementLocationGuide: {
|
|
inboundId: '11', blockId: '13', reservationId: '14', locationId: '15',
|
|
deleteSucceeded: true, slotReused: true,
|
|
},
|
|
},
|
|
steps: [
|
|
...requiredNames.map((name) => ({ name, passed: true })),
|
|
{ name: '第1张确认后整票库位块计数与槽身份完整', passed: true,
|
|
evidence: 'blockId=13, reserved=1, actual=1, empty=0, slots=1' },
|
|
],
|
|
}
|
|
const inspected = inspectScenarioReport(scenario, report, 0)
|
|
assert.equal(inspected.passed, true)
|
|
report.steps.find((step) => step.name.startsWith('删除只解绑')).passed = false
|
|
assert.equal(inspectScenarioReport(scenario, report, 0).passed, false)
|
|
})
|
|
|
|
test('cross-scenario inspection permits shared A0 location but rejects shared reservation or block', () => {
|
|
const results = [
|
|
{ resources: { inboundId: '1', blockId: '11', reservationId: '21', locationId: 'A0' } },
|
|
{ resources: { inboundId: '2', blockId: '12', reservationId: '22', locationId: 'A0' } },
|
|
]
|
|
assert.equal(inspectCrossScenarioIsolation(results).passed, true)
|
|
results[1].resources.reservationId = '21'
|
|
assert.equal(inspectCrossScenarioIsolation(results).passed, false)
|
|
})
|
|
|
|
test('matrix does not disable locations, execute SQL, deploy, or use a shell child process', () => {
|
|
assert.doesNotMatch(source, /location-status|batch-disable|UPDATE\s+|DELETE\s+FROM|INSERT\s+INTO/i)
|
|
assert.doesNotMatch(source, /jenkins|docker\s+compose|kubectl/i)
|
|
assert.match(source, /shell: false/)
|
|
assert.match(source, /A0 仅在普通库位自然不足时观测/)
|
|
})
|