Files
AirPlan-V2/test_p1_19_20.py
AirPlan 6130478c96 feat: AirPlan V2 — 全专家插件强制路由 + 事件系统规范化
P0-8 扩大: do_mode.py finish_worker 全专家插件强制路由
- GUI→XDB, network→NDB, C/C++→SDB, done→Rvr, blocked/failed→Dbg
- 证据去重: 已有 xdbSessions/ndbSessions/sdbReports/rvrReviewed 则跳过

P1-GAP17: 事件 emit 规范化
- 新增 7 个事件常量 (TASK_ENTERED, TASK_FINISHED, ENGINE_ENTERED 等)
- 全部 emit 调用替换字符串字面量为常量,零残留
- 30 个事件类型常量全部定义且唯一

P1-GAP18: 事件日志原子轮转
- emit 计数器每 128 次检查轮转,避免每次 emit 读文件
- 清除未使用的 _emit_with_completion/_pending_merge_complete
- 原子轮转: tempfile+os.replace 保证不损坏

eng 极端接管: 强制调用全部专家插件 (Dbg/XDB/NDB/SDB/Rvr)
commands/do.md: 更新为全专家插件路由文档

全量测试: 69 通过, 0 失败

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 15:56:44 +08:00

152 lines
5.0 KiB
Python
Executable File
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
"""P1-19 P1-20 功能测试"""
import sys
import os
import tempfile
from pathlib import Path
# 添加 lib 路径
sys.path.insert(0, str(Path(__file__).parent / "lib"))
def test_task_graph_test_required():
"""P1-19.1: 测试 TaskNode 的 test_required 字段"""
from air_runtime.task_graph import TaskNode
node = TaskNode(id="T-001", task="test", test_required=True)
assert node.test_required == True, "test_required should be True"
node2 = TaskNode(id="T-002", task="test2")
assert node2.test_required == False, "test_required should default to False"
# 测试序列化/反序列化
data = {"id": "T-003", "testRequired": True, "status": "TODO", "task": "test", "filesDirs": "", "doneWhen": "", "inDegree": 0, "outEdges": [], "writeSet": []}
node3 = TaskNode(
id=data["id"], status=data["status"], task=data["task"],
files_dirs=data["filesDirs"], done_when=data["doneWhen"],
test_required=data["testRequired"]
)
assert node3.test_required == True, "test_required should deserialize correctly"
print("✓ P1-19.1 test_required 字段测试通过")
return True
def test_arc_boundary_test_injection():
"""P1-19.1: 测试边界测试任务注入"""
from air_runtime.modes.arc_mode import _inject_boundary_tests, _build_graph_from_todo
from air_runtime.task_graph import TaskGraph, TaskNode
from air_runtime.todo_parser import TodoTask
# 创建模拟 tasks
tasks = [
TodoTask(task_id="T-001", task="实现模块A", files_dirs="src/moduleA/", status="TODO"),
TodoTask(task_id="T-002", task="实现模块B", files_dirs="src/moduleB/", status="TODO"),
]
graph = TaskGraph()
for t in tasks:
graph.add_node(TaskNode(id=t.task_id, task=t.task, files_dirs=t.files_dirs))
# 注入边界测试
_inject_boundary_tests(graph, tasks)
# 检查是否生成了测试任务
test_nodes = [n for n in graph.nodes.values() if n.test_required]
assert len(test_nodes) >= 2, f"应该生成至少2个测试任务实际: {len(test_nodes)}"
# 检查测试任务的 done_when
for node in test_nodes:
assert "测试通过" in node.done_when, f"测试任务的 done_when 应包含'测试通过': {node.done_when}"
print(f"✓ P1-19.1 边界测试注入测试通过,生成了 {len(test_nodes)} 个测试任务")
return True
def test_review_runtime_high_risk_audit():
"""P1-19.2: 测试高风险审计数据结构"""
from air_runtime.review_runtime import ReviewReport, HighRiskAudit, HighRiskFinding
# 创建带 highRiskAudit 的报告
finding = HighRiskFinding(file="src/test.cpp", line=100, severity="high", issue="空指针风险")
hra = HighRiskAudit(
lifecycle=[finding],
nullPointer=[finding],
overallRisk="high",
deliveryVerdict="needs-fix"
)
report = ReviewReport(
task_id="T-001",
verdict="pass",
high_risk_audit=hra
)
assert report.high_risk_audit.overallRisk == "high"
assert report.high_risk_audit.deliveryVerdict == "needs-fix"
assert len(report.high_risk_audit.lifecycle) == 1
# 测试序列化
from air_runtime.review_runtime import ReviewRuntime
d = ReviewRuntime._report_to_dict(report)
assert d["highRiskAudit"]["overallRisk"] == "high"
assert d["highRiskAudit"]["deliveryVerdict"] == "needs-fix"
# 测试反序列化
report2 = ReviewRuntime._dict_to_report(d)
assert report2.high_risk_audit.deliveryVerdict == "needs-fix"
print("✓ P1-19.2 highRiskAudit 测试通过")
return True
def test_do_ui_task_detection():
"""P1-20: 测试 UI 任务检测"""
from air_runtime.modes.do_mode import is_ui_task, route_ui_task
# UI 任务检测
assert is_ui_task("实现登录界面UI") == True, "应该检测为 UI 任务"
assert is_ui_task("实现按钮组件") == True, "应该检测为 UI 任务"
assert is_ui_task("React 前端开发") == True, "应该检测为 UI 任务"
assert is_ui_task("实现后端API") == False, "不应该检测为 UI 任务"
assert is_ui_task("数据库优化") == False, "不应该检测为 UI 任务"
print("✓ P1-20 is_ui_task 测试通过")
return True
def main():
print("=" * 50)
print("P1-19 P1-20 功能测试")
print("=" * 50)
tests = [
("P1-19.1 test_required 字段", test_task_graph_test_required),
("P1-19.1 边界测试注入", test_arc_boundary_test_injection),
("P1-19.2 highRiskAudit", test_review_runtime_high_risk_audit),
("P1-20 UI 任务检测", test_do_ui_task_detection),
]
passed = 0
failed = 0
for name, test_fn in tests:
try:
test_fn()
passed += 1
except Exception as e:
print(f"{name} 失败: {e}")
import traceback
traceback.print_exc()
failed += 1
print("=" * 50)
print(f"测试结果: {passed} 通过, {failed} 失败")
print("=" * 50)
return failed == 0
if __name__ == "__main__":
success = main()
sys.exit(0 if success else 1)