Files
timmy-config/tests/test_pr_triage.py
Alexander Whitestone fe864962ec
Some checks failed
Architecture Lint / Linter Tests (pull_request) Successful in 33s
Smoke Test / smoke (pull_request) Failing after 39s
Validate Config / YAML Lint (pull_request) Failing after 27s
Validate Config / JSON Validate (pull_request) Successful in 22s
Validate Config / Python Syntax & Import Check (pull_request) Failing after 21s
Validate Config / Python Test Suite (pull_request) Has been skipped
Validate Config / Shell Script Lint (pull_request) Failing after 24s
Validate Config / Cron Syntax Check (pull_request) Successful in 5s
Validate Config / Deploy Script Dry Run (pull_request) Successful in 6s
Validate Config / Playbook Schema Validation (pull_request) Successful in 10s
PR Checklist / pr-checklist (pull_request) Failing after 11m27s
Architecture Lint / Lint Repository (pull_request) Failing after 11s
test: Enhance PR triage tests (#659)
2026-04-21 11:17:00 +00:00

186 lines
6.0 KiB
Python

#!/usr/bin/env python3
"""Tests for pr_triage.py — issue #659."""
import json
import sys
from pathlib import Path
import pytest
sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "scripts"))
from pr_triage import categorize, refs, find_dupes, find_stale, to_markdown, to_json
class TestCategorize:
def test_training_data_pairs(self):
assert categorize("feat: 500 emotional weather pairs (#603)") == "training_data"
def test_training_data_scene(self):
assert categorize("feat: 100 jazz scene descriptions (#612)") == "training_data"
def test_training_data_corpus(self):
assert categorize("Add crisis manipulation corpus (#598)") == "training_data"
def test_bug_fix(self):
assert categorize("fix: broken import in cli.py") == "bug_fix"
def test_bug_resolve(self):
assert categorize("resolve: memory leak in session store") == "bug_fix"
def test_feature(self):
assert categorize("feat: add token budget tracker") == "feature"
def test_feature_new(self):
assert categorize("new: nightly pipeline scheduler") == "feature"
def test_docs(self):
assert categorize("docs: update README config format") == "docs"
def test_ops(self):
assert categorize("ops: deploy config to Ezra VPS") == "ops"
def test_ops_ci(self):
assert categorize("ci: add smoke test workflow") == "ops"
def test_security(self):
assert categorize("security: fix XSS in gallery panel") == "security"
def test_other(self):
assert categorize("chore: cleanup whitespace") == "other"
def test_empty(self):
assert categorize("") == "other"
def test_none(self):
assert categorize(None) == "other"
def test_case_insensitive(self):
assert categorize("FIX: Resolve import error") == "bug_fix"
class TestRefs:
def test_single(self):
assert refs({"title": "Fix #123", "body": ""}) == [123]
def test_multiple(self):
assert refs({"title": "#10", "body": "Related to #20 and #30"}) == [10, 20, 30]
def test_dedup(self):
assert refs({"title": "#100", "body": "Closes #100"}) == [100]
def test_none(self):
assert refs({"title": "No refs", "body": ""}) == []
def test_body_only(self):
assert refs({"title": "Fix", "body": "Closes #42"}) == [42]
def test_null_body(self):
assert refs({"title": "#7", "body": None}) == [7]
class TestFindDupes:
def test_no_dupes(self):
prs = [{"number": 1, "title": "#10", "body": ""},
{"number": 2, "title": "#11", "body": ""}]
assert find_dupes(prs) == {}
def test_duplicate(self):
prs = [{"number": 1, "title": "#10", "body": ""},
{"number": 2, "title": "#10", "body": ""}]
d = find_dupes(prs)
assert d[10] == [1, 2]
def test_triple(self):
prs = [{"number": i, "title": "#42", "body": ""} for i in range(1, 4)]
d = find_dupes(prs)
assert len(d[42]) == 3
def test_partial_overlap(self):
prs = [{"number": 1, "title": "#10 #20", "body": ""},
{"number": 2, "title": "#10", "body": ""}]
d = find_dupes(prs)
assert 10 in d
assert 20 not in d
class TestFindStale:
def test_clean(self):
prs = [{"number": 1, "title": "#10", "body": ""}]
assert find_stale(prs, set()) == []
def test_stale(self):
prs = [{"number": 1, "title": "#10", "body": ""}]
s = find_stale(prs, {10})
assert len(s) == 1
assert s[0]["stale_refs"] == [10]
def test_mixed(self):
prs = [{"number": 1, "title": "#10 #20", "body": ""}]
s = find_stale(prs, {10})
assert s[0]["stale_refs"] == [10]
def test_multiple_prs(self):
prs = [
{"number": 1, "title": "#10", "body": ""},
{"number": 2, "title": "#20", "body": ""},
]
s = find_stale(prs, {10, 20})
assert len(s) == 2
class TestToMarkdown:
def test_basic_structure(self):
a = {
"repo": "test/repo", "total_open": 3,
"total_files_changed": 10, "total_additions": 100, "total_deletions": 20,
"categories": {"feature": 2, "bug_fix": 1},
"category_details": {
"feature": [{"number": 1, "title": "feat: x", "refs": [], "head": "f1", "files": 2, "created": "2026-04-01"}],
"bug_fix": [],
},
"duplicates": {}, "stale_prs": [],
"closed_issues_checked": 50,
"safe_merge_candidates": 0,
"timestamp": "2026-04-14T12:00:00Z",
}
md = to_markdown(a)
assert "test/repo" in md
assert "3" in md
assert "feature" in md
assert "## PR Triage Report" in md
def test_duplicates_section(self):
a = {"repo": "x", "total_open": 2, "total_files_changed": 0,
"total_additions": 0, "total_deletions": 0,
"categories": {}, "category_details": {},
"duplicates": {42: [1, 2]}, "stale_prs": [],
"closed_issues_checked": 0, "safe_merge_candidates": 0,
"timestamp": "2026-01-01"}
md = to_markdown(a)
assert "Duplicate" in md
assert "#42" in md
def test_stale_section(self):
a = {"repo": "x", "total_open": 1, "total_files_changed": 0,
"total_additions": 0, "total_deletions": 0,
"categories": {}, "category_details": {},
"duplicates": {},
"stale_prs": [{"pr": 5, "title": "old fix", "stale_refs": [10]}],
"closed_issues_checked": 50, "safe_merge_candidates": 0,
"timestamp": "2026-01-01"}
md = to_markdown(a)
assert "#5" in md
assert "Stale" in md
class TestToJson:
def test_roundtrip(self):
a = {"repo": "test", "total_open": 0}
out = to_json(a)
assert json.loads(out)["repo"] == "test"
def test_complex(self):
a = {"repo": "x", "duplicates": {1: [2, 3]}, "stale_prs": []}
out = to_json(a)
d = json.loads(out)
assert d["duplicates"]["1"] == [2, 3]