| """相容性知识库数据文件加载 / 校验 / 降级测试(compatibility-engine-upgrade 任务 1.4)。 |
| |
| 覆盖需求 1.2(外置数据文件、加载失败优雅降级、结构可校验)。 |
| """ |
|
|
| from __future__ import annotations |
|
|
| import os |
|
|
| from skills.compatibility import rules |
| from skills.compatibility.knowledge_base import KnowledgeBase, get_default_kb |
|
|
|
|
| def test_default_kb_loads_data_files_without_degradation(): |
| """默认数据目录下三份 yaml 应正常加载,辅料 / 反应部分不降级。""" |
| kb = KnowledgeBase.load() |
| |
| assert "excipients" not in kb.degraded |
| assert "reactions" not in kb.degraded |
| assert len(kb.excipients()) >= 1 |
| assert len(kb.rules()) >= 1 |
|
|
|
|
| def test_kb_validate_reports_no_problems(): |
| """打包的数据文件应通过结构校验(必填字段、枚举合法、定量字段带 source)。""" |
| kb = KnowledgeBase.load() |
| problems = kb.validate() |
| assert problems == [], f"知识库校验应无问题,实际:{problems}" |
|
|
|
|
| def test_missing_data_dir_degrades_to_builtin_without_crash(): |
| """数据目录缺失 → 降级到内置最小集,不抛异常,仍可用。""" |
| kb = KnowledgeBase.load(data_dir=os.path.join(os.sep, "nonexistent_kb_dir_xyz")) |
| assert "excipients" in kb.degraded |
| assert "reactions" in kb.degraded |
| |
| profile = kb.resolve("乳糖") |
| assert profile.known is True |
| assert "reducing_sugar" in profile.tags |
| assert len(kb.rules()) == len(rules.RULES) |
|
|
|
|
| def test_resolve_equivalent_to_builtin_for_known_excipients(): |
| """数据文件解析结果与内置最小集对已知辅料等价(任务 1.1 只搬运、不改判定)。""" |
| kb = KnowledgeBase.load() |
| for name in ["乳糖", "硬脂酸镁", "微晶纤维素", "聚维酮", "magnesium stearate"]: |
| from_kb = kb.resolve(name) |
| builtin = rules._resolve_builtin(name) |
| assert from_kb.known == builtin.known, name |
| assert set(from_kb.tags) == set(builtin.tags), name |
|
|
|
|
| def test_unknown_excipient_marked_not_known(): |
| kb = KnowledgeBase.load() |
| profile = kb.resolve("某种不存在的辅料XYZ") |
| assert profile.known is False |
| assert profile.tags == frozenset() |
|
|
|
|
| def test_wildcard_group_ids_expanded_to_all_groups(): |
| """reactions.yaml 中 group_ids: '*'(吸附规则)应展开为全部已知官能团。""" |
| kb = KnowledgeBase.load() |
| adsorption_rules = [r for r in kb.rules() if r.reaction == "adsorption"] |
| assert adsorption_rules, "应存在吸附规则" |
| assert adsorption_rules[0].group_ids == frozenset(rules.FUNCTIONAL_GROUP_META.keys()) |
|
|
|
|
| def test_evaluate_uses_knowledge_base_path(): |
| """evaluate 经知识库路径产出与历史一致的经典判定(胺 + 乳糖 → 高风险美拉德)。""" |
| assessment = rules.evaluate([{"id": "primary_amine"}], ["乳糖"]) |
| assert assessment.overall_risk == rules.RISK_HIGH |
| er = assessment.excipient_results[0] |
| assert "maillard" in [r.reaction for r in er.reactions] |
|
|