64 lines
2.5 KiB
JavaScript
64 lines
2.5 KiB
JavaScript
import { readFile } from 'node:fs/promises';
|
|
import { readCampaignFlowSegments } from './campaign-flow-segments.mjs';
|
|
|
|
const { routes, segments, manifestHash } = await readCampaignFlowSegments();
|
|
const flowSource = await readFile(new URL('./verify-flow.mjs', import.meta.url), 'utf8');
|
|
const packageJson = JSON.parse(await readFile(new URL('../package.json', import.meta.url), 'utf8'));
|
|
|
|
assert(segments.length === 12, `Expected 12 campaign flow segments, received ${segments.length}.`);
|
|
assert(routes.length === 66, `Expected 66 campaign battle routes, received ${routes.length}.`);
|
|
assert(/^[a-f0-9]{64}$/.test(manifestHash), `Expected a SHA-256 flow manifest hash, received ${manifestHash}.`);
|
|
|
|
const flattenedBattleIds = segments.flatMap(({ battleIds }) => battleIds);
|
|
assert(
|
|
JSON.stringify(flattenedBattleIds) === JSON.stringify(routes.map(({ battleId }) => battleId)),
|
|
'Campaign flow segments must preserve the canonical 66-battle route order.'
|
|
);
|
|
|
|
const specialCheckpointSteps = {
|
|
'hanzhong-shuhan': 'shu-han-foundation-camp',
|
|
'yiling-baidi': 'baidi-entrustment-camp',
|
|
nanzhong: 'northern-campaign-prep-camp',
|
|
northern: 'ending-complete'
|
|
};
|
|
|
|
for (const segment of segments) {
|
|
assert(segment.index === segments.indexOf(segment), `Flow segment ${segment.id} has an invalid index.`);
|
|
assert(
|
|
countOccurrences(flowSource, `shouldRunFlowSegment('${segment.id}')`) === 1,
|
|
`Flow segment ${segment.id} must have exactly one executable body boundary.`
|
|
);
|
|
assert(
|
|
countOccurrences(flowSource, `completeFlowSegment(page, '${segment.id}')`) === 1,
|
|
`Flow segment ${segment.id} must have exactly one completion checkpoint.`
|
|
);
|
|
const specialStep = specialCheckpointSteps[segment.id];
|
|
if (specialStep) {
|
|
assert(
|
|
segment.checkpointStep === specialStep,
|
|
`Flow segment ${segment.id} must end at ${specialStep}, received ${segment.checkpointStep}.`
|
|
);
|
|
}
|
|
}
|
|
|
|
assert(
|
|
packageJson.scripts?.['verify:flow'] === 'node scripts/verify-flow-segments.mjs',
|
|
'The default verify:flow command must use the segmented orchestrator.'
|
|
);
|
|
assert(
|
|
packageJson.scripts?.['verify:flow:monolith'] === 'node scripts/verify-flow.mjs',
|
|
'The legacy monolith flow command must remain available for comparison.'
|
|
);
|
|
|
|
console.log(`Verified ${segments.length} campaign flow segments across ${routes.length} ordered battles (${manifestHash.slice(0, 12)}).`);
|
|
|
|
function countOccurrences(source, needle) {
|
|
return source.split(needle).length - 1;
|
|
}
|
|
|
|
function assert(condition, message) {
|
|
if (!condition) {
|
|
throw new Error(message);
|
|
}
|
|
}
|