Files
aetherbound-guild/tools/test_bat002_spec.py
T

102 lines
4.7 KiB
Python

#!/usr/bin/env python3
"""Focused BAT-002 live-battle specification assertions."""
from __future__ import annotations
import json
import unittest
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
PAGE = ROOT / "docs/design-authority/pages/BAT-002-live-battle"
def load(path: Path):
return json.loads(path.read_text(encoding="utf-8"))
class Bat002SpecificationTests(unittest.TestCase):
def setUp(self) -> None:
self.contract = load(PAGE / "page-contract.json")
self.matrix = load(PAGE / "state-matrix.json")
def test_index_preserves_spec_package_through_runtime_states(self) -> None:
index = load(ROOT / "docs/design-authority/design-index.json")
page = index["pages"]["BAT-002"]
self.assertIn(page["status"], {
"IMPLEMENTATION_IN_PROGRESS",
"IMPLEMENTED_AWAITING_OWNER_RUNTIME_REVIEW",
"VERIFIED_AWAITING_OWNER_ACCEPTANCE",
"COMPLETE",
})
self.assertEqual(page["contract"], "pages/BAT-002-live-battle/page-contract.json")
self.assertEqual(page["state_matrix"], "pages/BAT-002-live-battle/state-matrix.json")
def test_contract_and_matrix_cover_the_same_states(self) -> None:
self.assertEqual(self.contract["page_id"], "BAT-002")
self.assertIn(self.contract["state"], {
"IMPLEMENTATION_IN_PROGRESS",
"IMPLEMENTED_AWAITING_OWNER_RUNTIME_REVIEW",
"VERIFIED_AWAITING_OWNER_ACCEPTANCE",
"COMPLETE",
})
self.assertEqual(set(self.contract["states"]), set(self.matrix["states"]))
self.assertEqual(set(self.contract["states"]), set(self.contract["transition_graph"]))
declared_states = set(self.contract["states"])
for destinations in self.contract["transition_graph"].values():
self.assertTrue(set(destinations).issubset(declared_states))
self.assertEqual(self.contract["responsive_policy"]["text_scales"], [100, 130])
self.assertEqual(self.matrix["required_text_scales"], [100, 130])
self.assertEqual(set(self.matrix["required_locales"]), {"zh_CN", "en"})
self.assertEqual(
set(self.matrix["required_viewports"]),
{"760x360", "844x390", "1280x720"},
)
def test_waiting_error_and_interruption_states_are_explicit(self) -> None:
waiting = self.matrix["states"]["waiting_for_next_event"]
self.assertEqual(waiting["exact_english_copy"], "Waiting for next event")
invalid = self.matrix["states"]["invalid_event_data"]
self.assertEqual(invalid["timeline"], "paused")
self.assertEqual(invalid["primary_action"], "retry_snapshot")
self.assertIn("safe_exit", invalid["secondary_actions"])
interrupted = self.matrix["states"]["interrupted_background"]
self.assertEqual(interrupted["primary_action"], "open_bat006")
self.assertEqual(interrupted["timeline"], "frozen")
def test_live_battle_is_automatic_and_diagnostic_only(self) -> None:
corpus = " ".join(self.contract["constraints"] + self.matrix["required_boundaries"])
for forbidden in ("attack", "skill", "target-selection", "reorder", "equip", "Reserve-entry"):
self.assertIn(forbidden, corpus)
self.assertEqual(
set(self.contract["required_event_families"]),
set(self.matrix["required_event_families"]),
)
for required in ("melee_contact", "healing_source_and_recipient_change", "knockout_and_line_collapse"):
self.assertIn(required, self.contract["required_event_families"])
def test_page_ownership_and_stopping_boundary_are_truthful(self) -> None:
ownership = self.contract["control_ownership"]
for page_id in ("BAT-003", "BAT-004", "BAT-005", "BAT-006", "OUT-001"):
self.assertIn(page_id, " ".join(ownership.values()))
outcome = self.matrix["states"]["outcome_locked"]
self.assertEqual(outcome["primary_action"], "open_out001")
self.assertIn("no reward", outcome["guard"])
gate = self.contract["implementation_gate"]
self.assertIn("No image generation", gate)
self.assertIn("must not apply reward", gate)
def test_visual_authority_is_existing_hand_drawn_battle_direction(self) -> None:
provenance = " ".join(self.contract["provenance"])
constraints = " ".join(self.contract["constraints"])
self.assertIn("05_battle_ui_japanese_scale.png", provenance)
self.assertIn("phase6_battle_scale_04", provenance)
self.assertIn("functional provenance only", provenance)
self.assertIn("Pixel art", constraints)
self.assertIn("card-wall replacement", constraints)
if __name__ == "__main__":
unittest.main()