muse-agent-example/tests/skills/diagnose-ai-flavor/test_diagnose_ai_flavor.py

106 lines
5.1 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
"""技能 3 诊断离线测试:检测只查不改、产物头完整、检测完成即落库(--offline 除外)。"""
import json
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 / "muse" / "lifecycle" / "quality" / "humanization" / "skills" / "diagnose-ai-flavor" / "scripts"
sys.path.insert(0, str(SCRIPT_DIR))
import diagnose_ai_flavor as diag # noqa: E402
# 合成 AI 味文本:命中 l001/l002/l003(语料只用合成文本,版权边界见 humanization/README)
AI_FLAVOR_TEXT = (
"研究表明,能进这种地方的修士都不简单。"
"值得注意的是,门外已经下起了雨。"
"他嘴角微微上扬,没有说话。"
)
class DiagnosisContractTest(unittest.TestCase):
def test_run_diagnosis_produces_complete_artifact(self):
artifact = diag.run_diagnosis(AI_FLAVOR_TEXT, work_ref="synthetic:demo")
for key in ("text_hash", "rule_library_version", "mode", "findings"):
self.assertIn(key, artifact)
rule_ids = {f["rule_id"] for f in artifact["findings"]}
self.assertTrue({"l001", "l002", "l003"} <= rule_ids, rule_ids)
for f in artifact["findings"]:
self.assertIn(f["decision_proposal"], {"repair", "ask"})
self.assertTrue(f["spans"][0] in AI_FLAVOR_TEXT)
def test_work_ref_is_required(self):
with self.assertRaisesRegex(diag.DiagnoseContractError, "work_ref"):
diag.run_diagnosis(AI_FLAVOR_TEXT, work_ref="")
def test_empty_text_is_rejected(self):
with self.assertRaisesRegex(diag.DiagnoseContractError, "为空"):
diag.run_diagnosis("", work_ref="synthetic:demo")
def test_rule_library_version_is_stable_fingerprint(self):
rules1, v1 = diag.load_active_library()
_, v2 = diag.load_active_library()
self.assertEqual(v1, v2)
self.assertTrue(v1.startswith("v-"))
def test_cli_offline_writes_artifact_without_db(self):
with tempfile.TemporaryDirectory() as tmp:
text_path = pathlib.Path(tmp) / "text.txt"
text_path.write_text(AI_FLAVOR_TEXT, encoding="utf-8")
output = pathlib.Path(tmp) / "artifact.json"
with patch.object(diag, "persist_diagnosis") as persist:
code = diag.main(["run", "--text-file", str(text_path), "--work-ref", "synthetic:demo",
"--output", str(output), "--offline"])
self.assertEqual(code, 0)
persist.assert_not_called()
artifact = json.loads(output.read_text(encoding="utf-8"))
self.assertIn("findings", artifact)
def test_persist_rejects_text_hash_mismatch_before_db(self):
artifact = diag.run_diagnosis(AI_FLAVOR_TEXT, work_ref="synthetic:demo")
artifact["text_hash"] = "sha256:deadbeef"
with self.assertRaises(diag.DiagnoseContractError):
diag.persist_diagnosis(artifact, text=AI_FLAVOR_TEXT)
def test_cli_default_persists_detection(self):
# 默认(非 --offline)模式生产读数据库规则库;离线测试补丁文件库接缝,不触真实连接。
from deai import load
def _file_library(from_db=False):
samples = load.load_samples()
rules = load.load_rules(samples=samples)
return rules, diag.rule_library_version(rules)
with tempfile.TemporaryDirectory() as tmp:
text_path = pathlib.Path(tmp) / "text.txt"
text_path.write_text(AI_FLAVOR_TEXT, encoding="utf-8")
output = pathlib.Path(tmp) / "artifact.json"
with patch.object(diag, "persist_diagnosis", return_value={"run_id": "diag-x"}) as persist, \
patch.object(diag, "load_active_library", side_effect=_file_library):
code = diag.main(["run", "--text-file", str(text_path), "--work-ref", "synthetic:demo",
"--output", str(output)])
self.assertEqual(code, 0)
persist.assert_called_once()
def test_cli_external_findings_hash_mismatch_rejected(self):
with tempfile.TemporaryDirectory() as tmp:
text_path = pathlib.Path(tmp) / "text.txt"
text_path.write_text(AI_FLAVOR_TEXT, encoding="utf-8")
findings_path = pathlib.Path(tmp) / "external.json"
findings_path.write_text(json.dumps([{
"id": "x1", "text_hash": "sha256:deadbeef", "rule_id": "sem001", "rule_version": 1,
"spans": ["他"], "context_window": "他", "layer": "semantic", "evidence": "外部判定证据",
"possible_function": "none", "confidence": "medium", "decision_proposal": "pending",
}]), encoding="utf-8")
code = diag.main(["run", "--text-file", str(text_path), "--work-ref", "synthetic:demo",
"--external-findings", str(findings_path),
"--output", str(pathlib.Path(tmp) / "a.json"), "--offline"])
self.assertEqual(code, 2)
if __name__ == "__main__":
unittest.main()