muse-agent-example/tests/skills/establish-voice-baseline/test_establish_voice_baseline.py
zizi 091b66a9bb 重构: 收敛 Agent/Skill 运行时与创作质量闭环
将角色与 Skill 从 .claude 迁入 .agent,移除 Claude CLI 运行时并接入固定 Opus 角色 profile、完整 schema、预算 deadline、raw 与回执证据链。

同步拆分 Skill 职责、复利 lesson、Gate 回放、Dashboard 人审入口、数据库登记和机械门禁;候选设计正文不包含在本提交中。
2026-08-22 02:12:32 +08:00

103 lines
4.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""技能 1 定基线离线测试:结构合同、grounding 门、人工确认强制。"""
import pathlib
import sys
import tempfile
import unittest
from unittest.mock import patch
PROJECT_ROOT = pathlib.Path(__file__).resolve().parents[3]
SCRIPT_DIR = PROJECT_ROOT / ".agent" / "skills" / "establish-voice-baseline" / "scripts"
sys.path.insert(0, str(SCRIPT_DIR))
import establish_voice_baseline as base # noqa: E402
SOURCE_TEXT = "老周敲了敲桌角:「我说小子,茶要凉了。」青云城的雨说来就来。"
LEDGER = {
"schema_version": "voice-baseline-v1",
"work_ref": "synthetic:demo",
"narrator": {"sentence_habits": ["短句收束"], "punctuation_habits": []},
"characters": {"老周": {"verbal_tics": ["我说小子"], "sample_lines": ["我说小子,茶要凉了。"]}},
"untouchable_verbal_tics": {"老周": ["我说小子"]},
"protected_spans": ["青云城的雨说来就来"],
"blacklist": ["值得注意的是"],
}
class BaselineContractTest(unittest.TestCase):
def test_draft_output_can_feed_confirm(self):
with tempfile.TemporaryDirectory() as tmp:
root = pathlib.Path(tmp)
source = root / "source.txt"
source.write_text(SOURCE_TEXT, encoding="utf-8")
draft_output = root / "draft.json"
self.assertEqual(
0,
base.main([
"draft", "--work-ref", "synthetic:demo", "--text-file", str(source),
"--output", str(draft_output), "--offline",
]),
)
with patch.object(base, "collect_ledger", return_value={"version": 1}) as collect:
code = base.main([
"confirm", "--ledger-file", str(draft_output),
"--work-ref", "synthetic:demo", "--text-file", str(source),
"--reviewer", "qingse", "--output", str(root / "confirmed.json"),
])
self.assertEqual(code, 0)
collect.assert_called_once()
self.assertEqual(collect.call_args.args[0]["schema_version"], "voice-baseline-v1")
def test_valid_ledger_passes_grounding_and_persists(self):
with patch.object(base, "persist_baseline", return_value={"version": 1}) as persist:
result = base.collect_ledger(LEDGER, work_ref="synthetic:demo",
source_texts=[SOURCE_TEXT], reviewer="qingse")
self.assertEqual(result["version"], 1)
persist.assert_called_once()
def test_ungrounded_tic_is_rejected(self):
bad = dict(LEDGER, untouchable_verbal_tics={"老周": ["根本不存在的口癖"]})
with patch.object(base, "persist_baseline") as persist:
with self.assertRaisesRegex(base.BaselineContractError, "grounding"):
base.collect_ledger(bad, work_ref="synthetic:demo",
source_texts=[SOURCE_TEXT], reviewer="qingse")
persist.assert_not_called()
def test_ungrounded_protected_span_is_rejected(self):
bad = dict(LEDGER, protected_spans=["不在正文里的句子"])
with self.assertRaisesRegex(base.BaselineContractError, "grounding"):
base.collect_ledger(bad, work_ref="synthetic:demo",
source_texts=[SOURCE_TEXT], reviewer="qingse")
def test_reviewer_is_required(self):
# persist_baseline 的确认人门在连库之前,可直接测
with self.assertRaisesRegex(base.BaselineContractError, "人工确认"):
base.persist_baseline(LEDGER, source_text=SOURCE_TEXT, reviewer="")
def test_direct_persist_rechecks_grounding_before_db(self):
with self.assertRaisesRegex(base.BaselineContractError, "grounding"):
base.persist_baseline(
dict(LEDGER, protected_spans=["不在正文里的句子"]),
source_text=SOURCE_TEXT, reviewer="qingse",
)
def test_schema_version_is_enforced(self):
bad = dict(LEDGER, schema_version="nope")
with self.assertRaisesRegex(base.BaselineContractError, "schema_version"):
base.validate_ledger(bad, work_ref="synthetic:demo")
def test_work_ref_mismatch_is_enforced(self):
with self.assertRaisesRegex(base.BaselineContractError, "work_ref"):
base.validate_ledger(LEDGER, work_ref="synthetic:other")
def test_missing_narrator_is_enforced(self):
bad = dict(LEDGER)
del bad["narrator"]
with self.assertRaisesRegex(base.BaselineContractError, "narrator"):
base.validate_ledger(bad, work_ref="synthetic:demo")
if __name__ == "__main__":
unittest.main()