A 5e storytelling engine with an LLM DM
1"""Tests for CLI helpers — cold-start detection and onboarding artifacts."""
2
3import pytest
4
5from storied.character import create_character
6from storied.cli import _is_cold_start
7from storied.paths import world_path
8
9
10@pytest.fixture
11def _minimal_character() -> None:
12 """Create a minimal character so load_character finds one."""
13 create_character(
14 player_id="default",
15 name="Test",
16 race="Human",
17 char_class="Fighter",
18 level=1,
19 abilities={
20 "strength": 10,
21 "dexterity": 10,
22 "constitution": 10,
23 "intelligence": 10,
24 "wisdom": 10,
25 "charisma": 10,
26 },
27 hp_max=10,
28 ac=10,
29 )
30
31
32@pytest.fixture
33def _world_style() -> None:
34 """Write a non-empty style.md for the default world."""
35 world_dir = world_path("default")
36 world_dir.mkdir(parents=True, exist_ok=True)
37 (world_dir / "style.md").write_text("Grim. Slow-burn.\n")
38
39
40class TestColdStartDetection:
41 def test_cold_start_when_nothing_exists(self):
42 assert _is_cold_start("default", "default") is True
43
44 @pytest.mark.usefixtures("_minimal_character")
45 def test_cold_start_when_only_character_exists(self):
46 assert _is_cold_start("default", "default") is True
47
48 @pytest.mark.usefixtures("_world_style")
49 def test_cold_start_when_only_style_exists(self):
50 assert _is_cold_start("default", "default") is True
51
52 @pytest.mark.usefixtures("_minimal_character", "_world_style")
53 def test_not_cold_start_when_both_exist(self):
54 assert _is_cold_start("default", "default") is False
55
56 @pytest.mark.usefixtures("_minimal_character")
57 def test_not_cold_start_ignores_other_worlds(self):
58 # Style lives in a different world — doesn't count for this one.
59 world_dir = world_path("other")
60 world_dir.mkdir(parents=True, exist_ok=True)
61 (world_dir / "style.md").write_text("A vibe.\n")
62
63 assert _is_cold_start("default", "default") is True
64
65
66class TestOnboardingPromptExists:
67 def test_new_game_prompt_file_exists(self):
68 from storied.engine import load_prompt
69
70 content = load_prompt("new-game")
71 # Sanity check: the prompt mentions both onboarding deliverables.
72 assert "tune" in content
73 assert "create_character" in content
74 assert "end_session" in content