90 lines
4.1 KiB
Python
90 lines
4.1 KiB
Python
#!/usr/bin/env python3
|
|
"""Focused BAT-002 accepted-authority assertions."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import json
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
from PIL import Image
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
PAGE = ROOT / "docs/design-authority/pages/BAT-002-live-battle"
|
|
APPROVED = PAGE / "approved/v001"
|
|
SOURCE_MASTER = ROOT / "docs/prototype/generation/phase6_ui_direction_01/outputs/05_battle_ui_japanese_scale.png"
|
|
SOURCE_SCALE = ROOT / "docs/prototype/generation/phase6_battle_scale_04/outputs/battle-scale-proof-01/battle-scale-opening.png"
|
|
|
|
|
|
def load(path: Path):
|
|
return json.loads(path.read_text(encoding="utf-8"))
|
|
|
|
|
|
def sha256(path: Path) -> str:
|
|
digest = hashlib.sha256()
|
|
with path.open("rb") as handle:
|
|
for chunk in iter(lambda: handle.read(1024 * 1024), b""):
|
|
digest.update(chunk)
|
|
return digest.hexdigest()
|
|
|
|
|
|
class Bat002AuthorityTests(unittest.TestCase):
|
|
def test_approved_images_are_exact_existing_sources(self) -> None:
|
|
manifest = load(APPROVED / "manifest.json")
|
|
for key, source in (("approved_master", SOURCE_MASTER), ("scale_proof", SOURCE_SCALE)):
|
|
target = APPROVED / manifest[key]["path"]
|
|
recorded_source = (APPROVED / manifest[key]["source"]).resolve()
|
|
self.assertEqual(recorded_source, source.resolve())
|
|
self.assertTrue(recorded_source.is_file())
|
|
self.assertEqual(sha256(source), manifest[key]["sha256"])
|
|
self.assertEqual(sha256(target), manifest[key]["sha256"])
|
|
self.assertEqual(source.read_bytes(), target.read_bytes())
|
|
with Image.open(target) as image:
|
|
self.assertEqual(image.size, (2048, 1152))
|
|
self.assertFalse(manifest["generation"]["new_generation_used"])
|
|
self.assertEqual(manifest["generation"]["new_cost_usd"], 0.0)
|
|
|
|
def test_index_and_contract_retain_approved_authority_through_runtime_states(self) -> None:
|
|
index = load(ROOT / "docs/design-authority/design-index.json")["pages"]["BAT-002"]
|
|
contract = load(PAGE / "page-contract.json")
|
|
allowed_states = {
|
|
"IMPLEMENTATION_IN_PROGRESS",
|
|
"IMPLEMENTED_AWAITING_OWNER_RUNTIME_REVIEW",
|
|
"VERIFIED_AWAITING_OWNER_ACCEPTANCE",
|
|
"COMPLETE",
|
|
}
|
|
self.assertIn(index["status"], allowed_states)
|
|
self.assertIn(contract["state"], allowed_states)
|
|
self.assertEqual(index["approved"], "pages/BAT-002-live-battle/approved/v001/master.png")
|
|
self.assertEqual(index["approved_manifest"], "pages/BAT-002-live-battle/approved/v001/manifest.json")
|
|
self.assertTrue((APPROVED / "owner-approval.md").is_file())
|
|
|
|
def test_live_state_map_has_normalized_non_overflowing_layers(self) -> None:
|
|
mapping = load(APPROVED / "live-state-map.json")
|
|
self.assertEqual(mapping["state"], "APPROVED_FOR_RECONSTRUCTION")
|
|
layers = mapping["layers"]
|
|
self.assertEqual([layer["z"] for layer in layers], sorted({layer["z"] for layer in layers}))
|
|
for layer in layers:
|
|
x, y, width, height = layer["bounds"]
|
|
self.assertGreater(width, 0, layer["id"])
|
|
self.assertGreater(height, 0, layer["id"])
|
|
self.assertLessEqual(x + width, 1.000001, layer["id"])
|
|
self.assertLessEqual(y + height, 1.000001, layer["id"])
|
|
|
|
def test_dynamic_content_stays_engine_owned(self) -> None:
|
|
mapping = load(APPROVED / "live-state-map.json")
|
|
owners = {layer["id"]: layer["owner"] for layer in mapping["layers"]}
|
|
self.assertEqual(owners["allied_line"], "runtime_snapshot_actors")
|
|
self.assertEqual(owners["enemy_line"], "runtime_snapshot_actors")
|
|
self.assertEqual(owners["urgent_event_marker"], "engine_event_projection")
|
|
self.assertEqual(owners["ordered_actor_state_rail"], "engine_actor_state_and_actions")
|
|
rejected = " ".join(mapping["explicit_rejections"]).lower()
|
|
for phrase in ("flattened approved master", "historical generic show_battle()", "card wall", "pixel art", "baked names"):
|
|
self.assertIn(phrase, rejected)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|