Name the caboose, the train and the Running Track hazard
This commit is contained in:
@@ -338,6 +338,69 @@ describe('the page explains itself', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('never puts an internal tray id on a BUTTON either', () => {
|
||||
// The history check below missed this: `maneuver.redFlags` was labelled "Red Flags on tray3",
|
||||
// so the id leaked through the action list rather than the log. Every button, every turn.
|
||||
const game = newGame(2345);
|
||||
for (let i = 0; i < 400; i++) {
|
||||
if (currentActor(game) === null) break;
|
||||
const { options } = actionGroups(game);
|
||||
if (options.length === 0) break;
|
||||
for (const o of options) {
|
||||
const label = describeIntent(game.state, o);
|
||||
assert.doesNotMatch(label, /\btray\d+\b/, `internal tray id on a button: ${label}`);
|
||||
}
|
||||
if (!submit(game, options[0]!)) break;
|
||||
}
|
||||
});
|
||||
|
||||
it('never offers to load a caboose', () => {
|
||||
// A caboose carries the crew, not freight. "add loaded caboose" appeared because the button was
|
||||
// formatted by hand instead of using the labeller that already knew.
|
||||
const game = newGame(2345);
|
||||
for (let i = 0; i < 400; i++) {
|
||||
if (currentActor(game) === null) break;
|
||||
const { options } = actionGroups(game);
|
||||
if (options.length === 0) break;
|
||||
for (const o of options) {
|
||||
assert.doesNotMatch(
|
||||
describeIntent(game.state, o),
|
||||
/(loaded|empty) caboose/,
|
||||
'a caboose was described as loaded or empty',
|
||||
);
|
||||
}
|
||||
if (!submit(game, options[0]!)) break;
|
||||
}
|
||||
});
|
||||
|
||||
it('warns that an industry on the Running Track is in the way of arrivals', () => {
|
||||
// §11.2 — a Facility carries its own rails, so it does NOT block traffic. But §10 makes a car
|
||||
// left standing between the Limits and the Office a collision, and nothing said so.
|
||||
const game = newGame(9);
|
||||
const area = game.state.officeAreas.get(0)!;
|
||||
const industry = {
|
||||
geometry: { kind: 'facility' as const, facility: 'grocersWarehouse' as const, axis: 'ew' as const },
|
||||
baseOperationalRail: true, standing: [], modifiers: [], enhancements: [],
|
||||
facility: {
|
||||
kind: 'freight' as const, subtype: 'grocersWarehouse',
|
||||
allows: { outbound: false, inbound: true },
|
||||
outboundBox: [], inboundBox: [], capacity: { outbound: 0, inbound: 1 },
|
||||
menAtWork: [null, null, null], industryTrack: { length: 2, cars: [] },
|
||||
laborers: 1, porters: 0, usedThisStage: { laborers: 0, porters: 0 },
|
||||
},
|
||||
};
|
||||
area.grid.set(`${area.runningRow},2`, industry as never);
|
||||
area.grid.set(`${area.runningRow - 1},0`, JSON.parse(JSON.stringify(industry)) as never);
|
||||
|
||||
const cells = view(game).cells;
|
||||
const onRunning = cells.find((c) => c.row === area.runningRow && c.col === 2)!;
|
||||
const below = cells.find((c) => c.row === area.runningRow - 1 && c.col === 0)!;
|
||||
|
||||
assert.match(onRunning.what, /RUNNING TRACK/, 'no warning on a Running Track industry');
|
||||
assert.match(onRunning.what, /pass straight through/, 'does not say traffic still passes');
|
||||
assert.doesNotMatch(below.what, /RUNNING TRACK/, 'a Secondary Track industry must not warn');
|
||||
});
|
||||
|
||||
it('never puts an internal tray id in front of a player', () => {
|
||||
// The §8.1 clearance question read "may tray2 follow tray3 into the next Subdivision?" — the
|
||||
// sharpest decision in the game, phrased in internal identifiers.
|
||||
|
||||
Reference in New Issue
Block a user