from scripts.slicing import slice_for_agent def _manifest_dict(): 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": "src/api.py", "language": "python", "added_lines": [[10, 15]]}], "findings": [ {"tool": "bandit", "rule_id": "B608", "severity": "high", "file": "src/api.py", "line": 12, "end_line": 12, "message": "sqlinj"}, {"tool": "mypy", "rule_id": "arg-type", "severity": "medium", "file": "src/api.py", "line": 14, "end_line": 14, "message": "type"}, {"tool": "gitleaks", "rule_id": "aws-token", "severity": "critical", "file": "src/api.py", "line": 11, "end_line": 11, "message": "leak"}, {"tool": "pip-audit", "rule_id": "GHSA-x", "severity": "high", "file": "requirements.txt", "line": 1, "end_line": 1, "message": "vuln"}, {"tool": "opengrep", "rule_id": "py.dangerous","severity": "high", "file": "src/api.py", "line": 13, "end_line": 13, "message": "dangerous"}, {"tool": "ruff", "rule_id": "S102", "severity": "high", "file": "src/api.py", "line": 10, "end_line": 10, "message": "issue"}, {"tool": "ruff-idiom", "rule_id": "SIM102", "severity": "low", "file": "src/api.py", "line": 20, "end_line": 20, "message": "collapsible-if"}, ], "package_diffs": {"python": {"added": [], "removed": [], "upgraded": []}}, "tool_stats": {}, "tools_unavailable": {}, "errors": [], } def test_security_slice_only_security_tools(): sliced = slice_for_agent(_manifest_dict(), "security-triage") tools = {f["tool"] for f in sliced["findings"]} assert tools == {"bandit", "opengrep", "ruff"} def test_type_safety_slice_only_type_tools(): sliced = slice_for_agent(_manifest_dict(), "type-safety") tools = {f["tool"] for f in sliced["findings"]} assert tools == {"mypy"} def test_dependency_slice_includes_dep_tools_and_diffs(): sliced = slice_for_agent(_manifest_dict(), "dependency") tools = {f["tool"] for f in sliced["findings"]} assert tools == {"pip-audit"} assert "package_diffs" in sliced def test_secrets_slice_only_gitleaks(): sliced = slice_for_agent(_manifest_dict(), "secrets") tools = {f["tool"] for f in sliced["findings"]} assert tools == {"gitleaks"} def test_consistency_slice_excludes_non_idiom_tools(): sliced = slice_for_agent(_manifest_dict(), "consistency") tools = {f["tool"] for f in sliced["findings"]} non_idiom = {"bandit", "mypy", "gitleaks", "pip-audit", "opengrep", "ruff"} assert tools & non_idiom == set() assert "changed_files" in sliced def test_consistency_slice_includes_ruff_idiom(): sliced = slice_for_agent(_manifest_dict(), "consistency") tools = {f["tool"] for f in sliced["findings"]} assert tools == {"ruff-idiom"} rule_ids = {f["rule_id"] for f in sliced["findings"]} assert "SIM102" in rule_ids def test_security_slice_excludes_ruff_idiom(): sliced = slice_for_agent(_manifest_dict(), "security-triage") tools = {f["tool"] for f in sliced["findings"]} assert "ruff-idiom" not in tools assert tools == {"bandit", "opengrep", "ruff"} def _manifest_with_lua_gha(): """Manifest with selene, luac, actionlint, and zizmor findings.""" return { "mode": "local", "base_ref": "origin/main", "head_ref": "HEAD", "default_branch": "main", "language_breakdown": { "python": 0, "javascript": 0, "typescript": 0, "csharp": 0, "lua": 1, "github_actions": 1, "skipped_files": [], }, "changed_files": [ {"path": "src/game.lua", "language": "lua", "added_lines": [[5, 10]]}, {"path": ".github/workflows/ci.yml", "language": "github-actions", "added_lines": [[12, 12]]}, ], "findings": [ {"tool": "selene", "rule_id": "undefined_variable", "severity": "high", "file": "src/game.lua", "line": 5, "end_line": 5, "message": "undefined var"}, {"tool": "luac", "rule_id": "syntax-error", "severity": "critical","file": "src/game.lua", "line": 8, "end_line": 8, "message": "syntax error"}, {"tool": "actionlint", "rule_id": "expression", "severity": "high", "file": ".github/workflows/ci.yml", "line": 12, "end_line": 12, "message": "bad expr"}, {"tool": "zizmor", "rule_id": "unpinned-uses", "severity": "medium", "file": ".github/workflows/ci.yml", "line": 15, "end_line": 15, "message": "unpin"}, ], "package_diffs": {}, "tool_stats": {}, "tools_unavailable": {}, "errors": [], } def test_gha_reviewer_slice_only_gha_tools(): sliced = slice_for_agent(_manifest_with_lua_gha(), "gha-reviewer") tools = {f["tool"] for f in sliced["findings"]} assert tools == {"actionlint", "zizmor"} def test_gha_reviewer_slice_excludes_lua_tools(): sliced = slice_for_agent(_manifest_with_lua_gha(), "gha-reviewer") tools = {f["tool"] for f in sliced["findings"]} assert "selene" not in tools assert "luac" not in tools def test_selene_routes_to_maintainability(): sliced = slice_for_agent(_manifest_with_lua_gha(), "maintainability") tools = {f["tool"] for f in sliced["findings"]} assert "selene" in tools def test_luac_routes_to_security_triage(): sliced = slice_for_agent(_manifest_with_lua_gha(), "security-triage") tools = {f["tool"] for f in sliced["findings"]} assert "luac" in tools def test_luac_routes_to_maintainability(): sliced = slice_for_agent(_manifest_with_lua_gha(), "maintainability") tools = {f["tool"] for f in sliced["findings"]} assert "luac" in tools def test_security_triage_excludes_gha_tools(): sliced = slice_for_agent(_manifest_with_lua_gha(), "security-triage") tools = {f["tool"] for f in sliced["findings"]} assert "actionlint" not in tools assert "zizmor" not in tools def _manifest_with_powershell(): """Manifest with psscriptanalyzer (security + style rules) and injectionhunter.""" return { "mode": "local", "base_ref": "origin/main", "head_ref": "HEAD", "default_branch": "main", "language_breakdown": { "python": 0, "javascript": 0, "typescript": 0, "csharp": 0, "lua": 0, "powershell": 1, "github_actions": 0, "skipped_files": [], }, "changed_files": [ {"path": "scripts/Deploy.ps1", "language": "powershell", "added_lines": [[10, 40]]}, ], "findings": [ {"tool": "psscriptanalyzer", "rule_id": "PSAvoidUsingInvokeExpression", "severity": "medium", "file": "scripts/Deploy.ps1", "line": 12, "end_line": 12, "message": "iex"}, {"tool": "psscriptanalyzer", "rule_id": "PSAvoidUsingWriteHost", "severity": "medium", "file": "scripts/Deploy.ps1", "line": 5, "end_line": 5, "message": "write-host"}, {"tool": "injectionhunter", "rule_id": "InjectionRisk.InvokeExpression","severity": "high", "file": "scripts/Deploy.ps1", "line": 12, "end_line": 12, "message": "injection"}, ], "package_diffs": {}, "tool_stats": {}, "tools_unavailable": {}, "errors": [], } def test_injectionhunter_routes_to_security_triage(): sliced = slice_for_agent(_manifest_with_powershell(), "security-triage") tools = {f["tool"] for f in sliced["findings"]} assert "injectionhunter" in tools def test_psscriptanalyzer_security_rules_route_to_security_triage(): sliced = slice_for_agent(_manifest_with_powershell(), "security-triage") rules = {f["rule_id"] for f in sliced["findings"] if f["tool"] == "psscriptanalyzer"} assert rules == {"PSAvoidUsingInvokeExpression"} def test_psscriptanalyzer_style_rules_route_to_maintainability(): sliced = slice_for_agent(_manifest_with_powershell(), "maintainability") rules = {f["rule_id"] for f in sliced["findings"] if f["tool"] == "psscriptanalyzer"} assert rules == {"PSAvoidUsingWriteHost"} def test_maintainability_excludes_injectionhunter(): sliced = slice_for_agent(_manifest_with_powershell(), "maintainability") tools = {f["tool"] for f in sliced["findings"]} assert "injectionhunter" not in tools