实现侧: - 上下文:任务范围拆分为 范围校验/范围授权;索引按可发现口径重建、索引新鲜度改对称差;依赖校验统一快照漂移说明。 - 知识方法:方法与材料读取口径统一;超限方法材料按可选省略,核对路径不再二次计费;删除无合同的读时重算。 - 任务运行:新增 context.usage/tool.denied 事件类型;连接池常驻并在装配生命周期内开关;调用结算与核对分列。 - 效果评测/审校修订/交付连载/作者经验/作品规划:凭据冻结、标定消费、导出补证、事实引文核对等收尾修复。 - 资源加载:能力正文不再夹带索引用的导航注记(该注记此前进入角色与技能的模型提示)。 - 元数据:受保护骨架与代码保护属性对齐;字段校验与内置结构口径同步。 - 基础设施:环境预检进入装配生命周期;数据库连接运行期字段不参与相等比较;索引指纹归一化 jsonb 浮点。 - 删除被替代实现:7 份旧提示词模板与空壳 资料来源 读取器。 用例侧: - 用例身份与导航元信息迁移;夹具补生命周期、同库暴露与模板封存; - 本轮定向修复:方法材料省略、事实引文、迁移回执、额度与暂停用例、慢用例超时预算等。
119 lines
4.5 KiB
Python
119 lines
4.5 KiB
Python
"""领域入口拒绝无效输入,不将内部错误伪装成空结果。"""
|
|
|
|
from types import SimpleNamespace
|
|
|
|
import pytest
|
|
|
|
from muse.作品规划.接口 import 节奏分布
|
|
from muse.作品规划.模型 import 作品错误
|
|
from muse.元数据.接口 import 元数据错误
|
|
from muse.故事世界 import 人物关系, 设定修订
|
|
from muse.故事世界.模型 import 事实错误
|
|
from muse.正式变更.接口 import 变更错误
|
|
from muse.正文写作.正式提交 import _核对必需检查
|
|
|
|
|
|
@pytest.mark.case_id("NC-O09-RHYTHM-EMPTY")
|
|
def test_节奏空输入拒绝非空保留比例():
|
|
with pytest.raises(作品错误) as 错误:
|
|
节奏分布((), frozenset({"日常"}))
|
|
assert 错误.value.错误码 == "RHYTHM_INVALID"
|
|
assert 节奏分布(
|
|
({"节奏": ("日常",)}, {"节奏": ("冲突", "日常")}), frozenset({"日常", "冲突"})
|
|
) == {"日常": 1.0, "冲突": 0.5}
|
|
|
|
|
|
@pytest.mark.case_id("NC-O09-REFERENCE-FAIL-CLOSED")
|
|
def test_无效关系引用结构不返回空端点(monkeypatch):
|
|
row = {
|
|
"schema_binding": {
|
|
"schema_id": "relation",
|
|
"base_version": 1,
|
|
"effective_schema_hash": "hash",
|
|
},
|
|
"instance_family": "relation",
|
|
"content": {},
|
|
}
|
|
monkeypatch.setattr(设定修订, "读取事实结构", lambda *a: (None, None, None))
|
|
monkeypatch.setattr(人物关系, "读取作品范围", lambda *a: None)
|
|
monkeypatch.setattr(人物关系, "故事存储", lambda *a: SimpleNamespace(列出对象=lambda *a: [row]))
|
|
|
|
def invalid(*a):
|
|
raise 元数据错误("FIELD_INVALID", "缺引用字段")
|
|
|
|
monkeypatch.setattr(人物关系, "校验值", invalid)
|
|
with pytest.raises(事实错误) as 错误:
|
|
人物关系.列出关系(None, "author", "work")
|
|
assert 错误.value.错误码 == "FACT_REFERENCE_INVALID"
|
|
assert isinstance(错误.value.__cause__, 元数据错误)
|
|
|
|
def broken(*a):
|
|
raise RuntimeError("unexpected")
|
|
|
|
monkeypatch.setattr(人物关系, "校验值", broken)
|
|
with pytest.raises(RuntimeError, match="unexpected"):
|
|
人物关系.列出关系(None, "author", "work")
|
|
|
|
|
|
@pytest.mark.case_id("NC-O09-CHECK-OWNER")
|
|
@pytest.mark.parametrize(
|
|
"结论,代码", [(None, "CHECK_MISSING"), ("failed", "CHECK_FAILED"), ("passed", None)]
|
|
)
|
|
def test_模型候选只经B06读取对应版本检查(monkeypatch, 结论, 代码):
|
|
import muse.审校修订.接口 as 审校
|
|
|
|
调用 = []
|
|
|
|
def read(conn, candidate_id, candidate_revision):
|
|
调用.append((conn, candidate_id, candidate_revision))
|
|
return 结论
|
|
|
|
monkeypatch.setattr(审校, "读取必需检查结论于", read, raising=False)
|
|
|
|
class 连:
|
|
def execute(self, sql, params):
|
|
assert "muse_writing_candidate" in sql and "muse_review_report" not in sql
|
|
return SimpleNamespace(fetchone=lambda: ("model",))
|
|
|
|
conn = 连()
|
|
if 代码:
|
|
with pytest.raises(变更错误) as 错误:
|
|
_核对必需检查(conn, {"candidate_id": "candidate", "revision": 3})
|
|
assert 错误.value.错误码 == 代码
|
|
else:
|
|
_核对必需检查(conn, {"candidate_id": "candidate", "revision": 3})
|
|
assert 调用 == [(conn, "candidate", 3)]
|
|
|
|
|
|
@pytest.mark.case_id("NC-O09-MANUAL-CHECK")
|
|
def test_人工候选不借用模型必需检查(monkeypatch):
|
|
import muse.审校修订.接口 as 审校
|
|
|
|
monkeypatch.setattr(
|
|
审校, "读取必需检查结论于", lambda *a: pytest.fail("不应读取模型检查"), raising=False
|
|
)
|
|
conn = SimpleNamespace(execute=lambda *a: SimpleNamespace(fetchone=lambda: ("manual",)))
|
|
_核对必需检查(conn, {"candidate_id": "manual", "revision": 1})
|
|
|
|
|
|
@pytest.mark.case_id("NC-O09-MISSING-WORK")
|
|
def test_探索交接缺失作品显式拒绝(monkeypatch):
|
|
import muse.作品规划.探索交接 as 交接
|
|
|
|
monkeypatch.setattr(交接, "读取作者目录", lambda *a: None)
|
|
monkeypatch.setattr(
|
|
交接,
|
|
"作品存储",
|
|
lambda *a: SimpleNamespace(读取探索选定=lambda *a: None, 读取=lambda *a: None),
|
|
)
|
|
monkeypatch.setattr(交接.探索选定入口, "_取得稿", lambda *a: {})
|
|
入口 = object.__new__(交接.探索选定入口)
|
|
请求 = SimpleNamespace(target_ref="exploration-selection:missing", work_id="missing")
|
|
with pytest.raises(作品错误) as 错误:
|
|
入口.查看(
|
|
None,
|
|
SimpleNamespace(作者="author"),
|
|
SimpleNamespace(业务请求=请求, 目标=请求.target_ref),
|
|
)
|
|
assert 错误.value.错误码 == "WORK_NOT_FOUND"
|