Files
gmtool/tests/con/continuum-2026.test.js
slaguru666andClaude Opus 4.8 b4d797b52d feat: port all six Continuum 2026 slots + real schedule times
Rewrite continuum-2026.js from the authoritative con-desk.html SLOTS
array: six real slots with days/times/systems/players and startsAt set,
so the hub's live-now/up-next follows the real convention clock.

Add five scenario modules (day-one, vain-crown, silvery-moon, chopper,
princes-bride) transcribed from the existing gm-utility console
timelines, and register them so every slot is tappable. Day One (BRP)
borrows the coc-d100 pack; the others map to their own systems.

Corrections found while porting: the slate is six slots (Slot 5 Silvery
Moon was missing) and s6 is 'Get to the Chopper — Another Fine Mess'.

tests/con/continuum-2026.test.js guards slot resolvability, valid dice
packs, and schedule status. 125 tests pass; build clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 21:52:53 +01:00

36 lines
1.6 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, it, expect } from 'vitest';
import continuum from '../../src/con/continuum-2026.js';
import { getScenario } from '../../src/scenarios/index.js';
import { validateScenario } from '../../src/core/scenario.js';
import { getRulePack } from '../../src/dice/rulepacks/index.js';
import { analyzeSchedule } from '../../src/con/schedule.js';
describe('Continuum 2026 con', () => {
it('lists the six ported slots', () => {
expect(continuum.slots).toHaveLength(6);
expect(continuum.slots.every((s) => s.scenarioId)).toBe(true);
});
it('every slot deep-links to a valid scenario with a known dice pack', () => {
for (const slot of continuum.slots) {
const scenario = getScenario(slot.scenarioId);
expect(scenario, slot.scenarioId).not.toBe(null);
expect(validateScenario(scenario), slot.scenarioId).toEqual([]);
expect(getRulePack(scenario.meta.system), scenario.meta.system).not.toBe(null);
}
});
it('marks the right slot live / next during the convention', () => {
// Sat 25 July, 15:00 local — the Vain Crown slot (14:00–18:00) is running.
// Parsing now with the same local (no-Z) format as the slots keeps this
// assertion timezone-independent.
const r = analyzeSchedule(continuum.slots, Date.parse('2026-07-25T15:00:00'));
expect(r.liveNow?.scenarioId).toBe('vain-crown');
expect(r.upNext?.scenarioId).toBe('silvery-moon');
const byId = Object.fromEntries(r.slots.map((s) => [s.scenarioId, s.status]));
expect(byId['day-one']).toBe('done');
expect(byId.afterimage).toBe('done');
expect(byId.chopper).toBe('upcoming');
});
});