#!/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)