"""State is the source of truth; the struct must survive a dump/validate round-trip and render into the .md views. (Parsing .md back is intentionally not implemented.)""" from __future__ import annotations from visualnovel import state from visualnovel.schemas import Character, GameState, Scene def _sample() -> GameState: return GameState( seed=7, vibe="cozy ยท Fantasy forest", style_guide="anime, soft cel shading", scene=Scene( id="threshold", place="The Threshold", description="edge of the wood", mood="cozy", present=["moth"], ), characters={ "moth": Character( id="moth", name="Mothlight", one_line="a nervous lantern-moth", appearance="amber wings", ), }, ) def test_state_struct_roundtrip(): s = _sample() again = GameState.model_validate(s.model_dump()) assert again == s assert again.characters["moth"].name == "Mothlight" def test_render_world_md_contains_scene(): s = _sample() md = state.render_world_md(s) assert "The Threshold" in md assert "Mothlight" in md # character index assert "{{" not in md # all placeholders filled def test_render_character_md(): s = _sample() md = state.render_character_md(s, s.characters["moth"]) assert "Mothlight" in md and "amber wings" in md assert "{{" not in md