import pytest from content_build.errors import BuildError from content_build.model import Entry, KnowsLink from content_build.resolve import resolve def ladder(): return Entry(id="rule.disposition-ladder", type="rule", status="canon", secrecy=0, related=[], body="x", source="t:1", rungs=["hostile", "cold", "neutral", "warm", "trusted"]) def town(): return Entry(id="town.a", type="town", status="canon", secrecy=0, related=[], body="A town.", source="t:2") def rumor(): return Entry(id="rumor.x", type="rumor", status="canon", secrecy=1, related=["town.a"], body="A rumor.", source="t:3") def npc(**over): base = dict(id="npc.t", type="person", status="canon", secrecy=0, related=["town.a"], body="Persona.", source="t:4", start_disposition="cold", knows=[KnowsLink("rumor.x", "neutral")]) base.update(over) return Entry(**base) def test_valid_world_resolves(): world = resolve([ladder(), town(), rumor(), npc()]) assert world.by_id["npc.t"].id == "npc.t" def test_duplicate_id(): with pytest.raises(BuildError): resolve([ladder(), town(), town()]) def test_illegal_namespace(): bad = Entry(id="shrine.s", type="place", status="canon", secrecy=0, related=[], body="x", source="t:9") with pytest.raises(BuildError): resolve([ladder(), bad]) def test_id_type_mismatch(): bad = Entry(id="place.s", type="town", status="canon", secrecy=0, related=[], body="x", source="t:9") with pytest.raises(BuildError): resolve([ladder(), bad]) def test_npc_type_must_be_person(): with pytest.raises(BuildError): resolve([ladder(), town(), rumor(), npc(type="town")]) def test_dangling_related(): with pytest.raises(BuildError): resolve([ladder(), town(), rumor(), npc(related=["town.nowhere"])]) def test_person_record_with_knows_rejected(): rec = Entry(id="person.p", type="person", status="canon", secrecy=0, related=[], body="x", source="t:9", knows=[KnowsLink("rumor.x", "warm")]) with pytest.raises(BuildError): resolve([ladder(), town(), rumor(), rec]) def test_npc_missing_start_disposition(): with pytest.raises(BuildError): resolve([ladder(), town(), rumor(), npc(start_disposition=None)]) def test_knows_target_must_be_knowledge_entry(): # points at the town (a canon entity), not a knowledge entry with pytest.raises(BuildError): resolve([ladder(), town(), rumor(), npc(knows=[KnowsLink("town.a", "cold")])]) def test_illegal_gate(): with pytest.raises(BuildError): resolve([ladder(), town(), rumor(), npc(knows=[KnowsLink("rumor.x", "besties")])]) def test_never_is_a_legal_gate(): world = resolve([ladder(), town(), rumor(), npc(knows=[KnowsLink("rumor.x", "never")])]) assert world.by_id["npc.t"].knows[0].gate == "never" def test_missing_ladder(): with pytest.raises(BuildError): resolve([town()]) def test_illegal_start_disposition(): with pytest.raises(BuildError): resolve([ladder(), town(), rumor(), npc(start_disposition="besties")]) def test_illegal_status(): bad = Entry(id="town.a", type="town", status="draft", secrecy=0, related=[], body="x", source="t:9") with pytest.raises(BuildError): resolve([ladder(), bad]) def test_npc_empty_knows_rejected(): with pytest.raises(BuildError): resolve([ladder(), town(), rumor(), npc(knows=[])]) def test_non_npc_with_start_disposition_rejected(): rec = Entry(id="person.p", type="person", status="canon", secrecy=0, related=[], body="x", source="t:9", start_disposition="cold") with pytest.raises(BuildError): resolve([ladder(), town(), rumor(), rec]) def test_empty_rungs_rejected(): empty = Entry(id="rule.disposition-ladder", type="rule", status="canon", secrecy=0, related=[], body="x", source="t:1", rungs=[]) with pytest.raises(BuildError): resolve([empty]) def test_canon_entity_nonzero_secrecy_rejected(): bad = Entry(id="town.a", type="town", status="canon", secrecy=2, related=[], body="x", source="t:9") with pytest.raises(BuildError): resolve([ladder(), bad]) def test_non_int_secrecy_raises(): bad = Entry(id="town.a", type="town", status="canon", secrecy="high", related=[], body="x", source="t:9") with pytest.raises(BuildError): resolve([ladder(), bad]) def test_non_list_rungs_raises(): bad_ladder = Entry(id="rule.disposition-ladder", type="rule", status="canon", secrecy=0, related=[], body="x", source="t:1", rungs="trusted") with pytest.raises(BuildError): resolve([bad_ladder])