Add HelpTopic dataclass and TOML loader
This commit is contained in:
parent
5eb205e7bf
commit
b69c2e83d9
2 changed files with 119 additions and 0 deletions
|
|
@ -3,6 +3,7 @@
|
|||
import importlib
|
||||
import logging
|
||||
import tomllib
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import cast
|
||||
|
||||
|
|
@ -139,3 +140,42 @@ def load_commands(directory: Path) -> list[CommandDefinition]:
|
|||
log.warning("failed to load command from %s: %s", path, e)
|
||||
|
||||
return commands
|
||||
|
||||
|
||||
@dataclass
|
||||
class HelpTopic:
|
||||
"""A help topic loaded from a TOML file."""
|
||||
|
||||
name: str
|
||||
body: str
|
||||
title: str = ""
|
||||
admin: bool = False
|
||||
|
||||
def __post_init__(self):
|
||||
if not self.title:
|
||||
self.title = self.name
|
||||
|
||||
|
||||
def load_help_topic(path: Path) -> HelpTopic:
|
||||
"""Load a single help topic from a TOML file."""
|
||||
with open(path, "rb") as f:
|
||||
data = tomllib.load(f)
|
||||
|
||||
return HelpTopic(
|
||||
name=data["name"],
|
||||
body=data["body"].strip(),
|
||||
title=data.get("title", ""),
|
||||
admin=data.get("admin", False),
|
||||
)
|
||||
|
||||
|
||||
def load_help_topics(directory: Path) -> dict[str, HelpTopic]:
|
||||
"""Load all help topics from a directory of TOML files."""
|
||||
topics: dict[str, HelpTopic] = {}
|
||||
for path in directory.glob("*.toml"):
|
||||
try:
|
||||
topic = load_help_topic(path)
|
||||
topics[topic.name] = topic
|
||||
except Exception as e:
|
||||
log.warning("failed to load help topic from %s: %s", path, e)
|
||||
return topics
|
||||
|
|
|
|||
79
tests/test_help_topics.py
Normal file
79
tests/test_help_topics.py
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
"""Tests for TOML help topic loading."""
|
||||
|
||||
import textwrap
|
||||
|
||||
import pytest
|
||||
|
||||
from mudlib.content import load_help_topics
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def help_dir(tmp_path):
|
||||
"""Create a temp directory with sample help TOML files."""
|
||||
topic = tmp_path / "combat.toml"
|
||||
topic.write_text(
|
||||
textwrap.dedent("""\
|
||||
name = "combat"
|
||||
title = "combat primer"
|
||||
body = \"\"\"
|
||||
combat is initiated when you attack another entity.
|
||||
use skills to learn your available moves.
|
||||
\"\"\"
|
||||
""")
|
||||
)
|
||||
|
||||
admin_topic = tmp_path / "building.toml"
|
||||
admin_topic.write_text(
|
||||
textwrap.dedent("""\
|
||||
name = "building"
|
||||
title = "builder's guide"
|
||||
admin = true
|
||||
body = \"\"\"
|
||||
use @dig to create zones and @paint to edit terrain.
|
||||
\"\"\"
|
||||
""")
|
||||
)
|
||||
return tmp_path
|
||||
|
||||
|
||||
def test_load_help_topics(help_dir):
|
||||
topics = load_help_topics(help_dir)
|
||||
assert "combat" in topics
|
||||
assert "building" in topics
|
||||
|
||||
|
||||
def test_help_topic_fields(help_dir):
|
||||
topics = load_help_topics(help_dir)
|
||||
combat = topics["combat"]
|
||||
assert combat.name == "combat"
|
||||
assert combat.title == "combat primer"
|
||||
assert combat.admin is False
|
||||
assert "combat is initiated" in combat.body
|
||||
|
||||
|
||||
def test_help_topic_admin_flag(help_dir):
|
||||
topics = load_help_topics(help_dir)
|
||||
building = topics["building"]
|
||||
assert building.admin is True
|
||||
|
||||
|
||||
def test_help_topic_title_defaults_to_name(tmp_path):
|
||||
topic = tmp_path / "simple.toml"
|
||||
topic.write_text('name = "simple"\nbody = "just a test"\n')
|
||||
topics = load_help_topics(tmp_path)
|
||||
assert topics["simple"].title == "simple"
|
||||
|
||||
|
||||
def test_load_help_topics_empty_dir(tmp_path):
|
||||
topics = load_help_topics(tmp_path)
|
||||
assert topics == {}
|
||||
|
||||
|
||||
def test_load_help_topics_skips_bad_files(tmp_path):
|
||||
bad = tmp_path / "broken.toml"
|
||||
bad.write_text("not valid toml [[[")
|
||||
good = tmp_path / "good.toml"
|
||||
good.write_text('name = "good"\nbody = "works"\n')
|
||||
topics = load_help_topics(tmp_path)
|
||||
assert "good" in topics
|
||||
assert "broken" not in topics
|
||||
Loading…
Reference in a new issue