feat(mystery): narration() helper and encounter narration registry

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-09 09:23:37 -05:00
parent bf8a693949
commit d3a2f4e1d7
2 changed files with 71 additions and 2 deletions
+26 -2
View File
@@ -1,5 +1,5 @@
import { describe, it, expect } from 'vitest'
import { parseRoom, parseItem, parseEnding, parseEncounterNarration } from './loader'
import { describe, it, expect, beforeEach } from 'vitest'
import { parseRoom, parseItem, parseEnding, parseEncounterNarration, narration, registerEncounterNarrations, _resetEncounterNarrationRegistry } from './loader'
const FOYER_MD = `---
id: foyer
@@ -286,3 +286,27 @@ initialPhase: p
expect(() => parseEncounterNarration(md, 'encounters/x.md')).toThrow(/no narration sections/i)
})
})
describe('narration registry', () => {
beforeEach(() => {
_resetEncounterNarrationRegistry()
})
it('returns prose for a registered encounter and key', () => {
registerEncounterNarrations([
{ id: 'rat', startsIn: 'cellar-stair', initialPhase: 'lurking', narrations: { lurking: 'watches' } },
])
expect(narration('rat', 'lurking')).toBe('watches')
})
it('throws with available keys when key is missing', () => {
registerEncounterNarrations([
{ id: 'rat', startsIn: 'cellar-stair', initialPhase: 'lurking', narrations: { lurking: 'a', resolved: 'b' } },
])
expect(() => narration('rat', 'sleping')).toThrow(/no matching section.*Available: lurking, resolved/i)
})
it('throws when encounter is unknown', () => {
expect(() => narration('ghost', 'whatever')).toThrow(/unknown encounter id "ghost"/i)
})
})