from scripts.slicing import slice_for_agent def _manifest(): return { "mode": "local", "base_ref": "origin/main", "head_ref": "HEAD", "default_branch": "main", "language_breakdown": {"python": 1, "javascript": 0, "typescript": 0, "csharp": 0, "skipped_files": []}, "changed_files": [{"path": "foo.py", "language": "python", "added_lines": [[10, 50]]}], "findings": [ {"tool": "vulture", "rule_id": "vulture:90pct", "severity": "medium", "file": "foo.py", "line": 10, "end_line": 10, "message": "unused function"}, {"tool": "radon", "rule_id": "radon:cc=12", "severity": "medium", "file": "foo.py", "line": 20, "end_line": 40, "message": "high CCN"}, {"tool": "interrogate", "rule_id": "interrogate:missing-docstring", "severity": "low", "file": "foo.py", "line": 5, "end_line": 5, "message": "missing docstring"}, {"tool": "lizard", "rule_id": "lizard:ccn=22", "severity": "high", "file": "foo.py", "line": 30, "end_line": 60, "message": "high CCN"}, {"tool": "knip", "rule_id": "knip:dead-export", "severity": "medium", "file": "src/a.ts", "line": 12, "end_line": 12, "message": "unused export"}, {"tool": "jscpd", "rule_id": "jscpd:clone-40lines", "severity": "medium", "file": "foo.py", "line": 100, "end_line": 140, "message": "duplicate"}, {"tool": "bandit", "rule_id": "B608", "severity": "high", "file": "foo.py", "line": 5, "end_line": 5, "message": "SQL injection"}, {"tool": "ruff-idiom", "rule_id": "C901", "severity": "medium", "file": "foo.py", "line": 50, "end_line": 50, "message": "too complex"}, {"tool": "ruff-idiom", "rule_id": "PLR0915", "severity": "medium", "file": "foo.py", "line": 60, "end_line": 60, "message": "too many statements"}, {"tool": "ruff-idiom", "rule_id": "SIM117", "severity": "low", "file": "foo.py", "line": 70, "end_line": 70, "message": "combine with"}, {"tool": "ruff-idiom", "rule_id": "PLR0913", "severity": "medium", "file": "foo.py", "line": 80, "end_line": 80, "message": "too many args"}, ], "package_diffs": {"python": {"added": [], "removed": [], "upgraded": []}}, "tool_stats": {}, "tools_unavailable": {}, "errors": [], } def test_maintainability_slice_includes_dedicated_tools(): sliced = slice_for_agent(_manifest(), "maintainability") tools = {f["tool"] for f in sliced["findings"]} assert tools >= {"vulture", "radon", "interrogate", "lizard", "knip", "jscpd"} def test_maintainability_slice_includes_complexity_idioms(): sliced = slice_for_agent(_manifest(), "maintainability") rules = {f["rule_id"] for f in sliced["findings"]} assert "C901" in rules assert "PLR0915" in rules def test_maintainability_slice_excludes_security_and_dependency(): sliced = slice_for_agent(_manifest(), "maintainability") tools = {f["tool"] for f in sliced["findings"]} assert "bandit" not in tools def test_maintainability_slice_excludes_non_complexity_idioms(): sliced = slice_for_agent(_manifest(), "maintainability") rules = {f["rule_id"] for f in sliced["findings"]} assert "SIM117" not in rules assert "PLR0913" not in rules def test_consistency_slice_excludes_complexity_idioms(): sliced = slice_for_agent(_manifest(), "consistency") rules = {f["rule_id"] for f in sliced["findings"]} assert "C901" not in rules assert "PLR0915" not in rules assert "SIM117" in rules assert "PLR0913" in rules