muse-agent-example/.claude/skills/replay-eval/scripts/test_load_reference_work.py

132 lines
5.0 KiB
Python

#!/usr/bin/env python3
"""参考作品只读适配器的纯数据组装测试。"""
from __future__ import annotations
import json
import pathlib
import sys
import unittest
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parent))
from load_reference_work import ( # noqa: E402
AdapterError,
build_replay_config,
project_card,
)
WORK = {
"id": 8,
"title": "深空之影",
"revision": 12,
"chapter_count": 594,
"parse_status": "pending",
}
REFERENCE = {
"declared_chapter_count": 595,
"imported_chapter_count": 594,
"parse_scope": {"from": 1, "to": 594},
"parse_status": "parsing",
}
def card_row(card_id=11126, name="苏铭"):
return {
"id": card_id,
"status": "pending",
"source_type": "upgrade_book",
"source_id": 8,
"revision": 3,
"update_time": "2026-07-19T00:00:00+00:00",
"draft_payload": {
"type": "character",
"名称": name,
"别名": [f"{name}别名"],
"出场章": [1, 430, 489, 550],
"字段": {
"演变历程": [
{"章": 420, "台阶": "历史台阶"},
{"章": 489, "台阶": "未来台阶"},
],
"演变概括": "全书终态摘要,不应透传",
"境界与能力": "终局能力,不应透传",
"说话方式": "可选静态字段",
},
"一句话摘要": "终局摘要,不应透传",
},
}
class LoadReferenceWorkTest(unittest.TestCase):
def test_window_freeze_uses_absolute_bounds_and_excludes_target_window(self):
config = build_replay_config(
work=WORK,
reference=REFERENCE,
outline_rows=[
{"id": 1, "window_no": 20, "from_order": 401, "to_order": 429, "outline_text": "历史窗", "check_status": "revised"},
{"id": 2, "window_no": 19, "from_order": 430, "to_order": 438, "outline_text": "目标后窗", "check_status": "revised"},
],
scaffold_rows=[
{"id": 10, "chapter": 428, "title": "前章", "outline_text": "前情", "entities": None, "pattern_hints": []},
],
target_scaffold={"id": 11, "chapter": 430, "title": "目标", "outline_text": "目标章事实"},
card_rows=[card_row(), card_row(11127, "赵宁")],
card_selection={"correctCardIds": [11126], "placeboCardIds": [11127]},
as_of=429,
target=430,
evaluation_set_version="set-test",
strategy_version="strategy-test",
)
windows = config["snapshot"]["data"]["outlineWindows"]
self.assertEqual([item["from_order"] for item in windows], [401])
public = json.dumps(
{
"snapshot": config["snapshot"],
"commonContext": config["commonContext"],
"arms": config["arms"],
"sources": config["sources"],
},
ensure_ascii=False,
)
self.assertNotIn("目标章事实", public)
def test_card_is_eval_draft_and_history_is_frozen(self):
result = project_card(card_row(), as_of=488, source_version="db-work-8-v12")
encoded = json.dumps(result, ensure_ascii=False)
self.assertEqual(result["evaluationStatus"], "eval_draft")
self.assertFalse(result["productionRetrievalEligible"])
self.assertEqual([item["章"] for item in result["milestones"]], [420])
self.assertNotIn("终局摘要", encoded)
self.assertNotIn("终局能力", encoded)
self.assertEqual(result["source"]["sourceId"], "eval-draft:11126")
self.assertEqual(result["source"]["sourceVersion"], "db-work-8-v12")
def test_missing_history_fails_closed_instead_of_using_static_card_fields(self):
row = card_row()
row["draft_payload"]["字段"].pop("演变历程")
with self.assertRaises(AdapterError):
project_card(row, as_of=488, source_version="db-work-8-v12")
def test_sources_have_source_id_and_version(self):
config = build_replay_config(
work=WORK,
reference=REFERENCE,
outline_rows=[{"id": 1, "from_order": 1, "to_order": 10, "outline_text": "历史窗"}],
scaffold_rows=[],
target_scaffold={"id": 11, "chapter": 489, "title": "目标", "outline_text": "目标事实"},
card_rows=[card_row(), card_row(11127, "赵宁")],
card_selection={"correctCardIds": [11126], "placeboCardIds": [11127]},
as_of=488,
target=489,
evaluation_set_version="set-test",
strategy_version="strategy-test",
)
self.assertTrue(config["sources"])
self.assertTrue(all(item["sourceId"] and item["sourceVersion"] for item in config["sources"]))
self.assertEqual(config["referenceWork"]["version"], "db-work-8-rev-12-imported-594")
if __name__ == "__main__":
unittest.main()