gitlink-cli/skills/gitlink-newcomer/tests/test_newcomer.py

129 lines
4.5 KiB
Python
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.

"""gitlink-newcomer 单元测试。
覆盖 good-first-issue 识别、友好度评分、ID 区分、引导生成与看板渲染。
使用合成数据,不触网,可离线运行:
python -m pytest tests/ -v
"""
from __future__ import annotations
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "scripts"))
import pytest
from newcomer import (
score_issue, build_guidance, render_board,
_issue_number, _issue_gid, _labels_of,
)
def issue(name="", body="", labels=None, comments=0, number=None, gid=None):
d = {"name": name, "description": body, "comment_journals_count": comments}
if labels is not None:
d["issue_tags"] = [{"name": x} for x in labels]
if number is not None:
d["number"] = number
if gid is not None:
d["id"] = gid
return d
class TestLabels:
def test_extract_dict_labels(self):
assert _labels_of(issue(labels=["Bug", "good first issue"])) == ["bug", "good first issue"]
def test_no_labels(self):
assert _labels_of(issue()) == []
class TestIdDistinction:
def test_web_number_preferred(self):
assert _issue_number(issue(number=12)) == 12
def test_no_web_number_returns_none(self):
# 列表接口只有全局 id不应被当作 web 序号
assert _issue_number(issue(gid=140801)) is None
def test_gid_extracted(self):
assert _issue_gid(issue(gid=140801)) == 140801
class TestScoreIssue:
def test_good_first_label_boosts(self):
s = score_issue(issue(name="fix typo", labels=["good first issue"]))
assert s["friendliness"] >= 75
assert s["is_good_first"] is True
assert "新手友好标签" in str(s["signals"])
def test_hard_keyword_lowers(self):
s = score_issue(issue(name="refactor concurrency architecture",
body="needs deep refactor of the core"))
assert s["friendliness"] < 55
assert s["is_good_first"] is False
def test_easy_keyword(self):
s = score_issue(issue(name="update docs and fix typo in readme"))
assert s["friendliness"] > 50
assert any("易上手" in sig for sig in s["signals"])
def test_hard_label(self):
s = score_issue(issue(name="something", labels=["hard"]))
assert "高难度标签" in str(s["signals"])
def test_difficulty_levels(self):
easy = score_issue(issue(name="docs typo", labels=["good first issue"]))
hard = score_issue(issue(name="refactor architecture performance concurrency"))
assert easy["difficulty"] in ("入门", "较易")
assert hard["difficulty"] in ("中等", "进阶")
def test_score_bounded(self):
s = score_issue(issue(name="good first " * 10, labels=["good first issue", "beginner"]))
assert 0 <= s["friendliness"] <= 100
def test_long_body_penalty(self):
short = score_issue(issue(name="task", body="x" * 100))
long = score_issue(issue(name="task", body="x" * 2000))
assert long["friendliness"] <= short["friendliness"]
class TestGuidance:
def test_uses_number_when_available(self):
g = build_guidance(score_issue(issue(name="fix", number=12)), "o", "r")
assert "#12" in g
def test_uses_title_when_no_number(self):
s = score_issue(issue(name="修复文档错别字", gid=999))
g = build_guidance(s, "o", "r")
# 无 web 序号时用标题引用,不出现 #999
assert "#999" not in g
assert "修复文档错别字" in g
def test_contains_fork_flow(self):
g = build_guidance(score_issue(issue(name="task", number=1)), "Gitlink", "gitlink-cli")
assert "repo +fork" in g
assert "Gitlink" in g
class TestBoard:
def test_empty_candidates(self):
result = {"owner": "o", "repo": "r", "total_issues": 3,
"candidate_count": 0, "candidates": [], "all_scored": []}
board = render_board(result, "o", "r")
assert "暂未发现" in board
def test_board_with_candidates(self):
cand = score_issue(issue(name="fix typo in docs", labels=["good first issue"], gid=100))
result = {"owner": "o", "repo": "r", "total_issues": 5,
"candidate_count": 1, "candidates": [cand], "all_scored": [cand]}
board = render_board(result, "o", "r")
assert "新手任务看板" in board
assert "id:100" in board # 无 web 序号时标注全局 id
if __name__ == "__main__":
sys.exit(pytest.main([__file__, "-v"]))