feat: filter Wishlist from --my-tasks; document the mode (#71)
Tasks in the "Wishlist" bucket version are now excluded from the list and summary entirely (no due date, noise backlog); exact case match, tasks without a version are unaffected. Document --my-tasks in README and the user guide (sorting, summary metrics, OSC 8 links, stream separation); all examples use synthetic data. Declare ruff known-first-party in pyproject so the lint result is CWD-independent.
This commit is contained in:
@@ -4,9 +4,11 @@ from datetime import date
|
||||
from unittest import mock
|
||||
|
||||
from redmine_reporter.task_list import (
|
||||
EXCLUDED_VERSION_NAMES,
|
||||
PRIORITY_RANK,
|
||||
build_task_rows,
|
||||
calculate_task_summary,
|
||||
filter_excluded_versions,
|
||||
format_summary_line,
|
||||
priority_rank,
|
||||
)
|
||||
@@ -100,6 +102,72 @@ def test_rows_without_due_go_last_and_tiebreak_by_id():
|
||||
assert [r["issue_id"] for r in rows] == [30, 12, 25]
|
||||
|
||||
|
||||
# -- Фильтр версий-исключений (Wishlist) --
|
||||
|
||||
|
||||
def test_excluded_version_names_constant():
|
||||
"""Точный состав бакет-версий, исключаемых из --my-tasks."""
|
||||
assert EXCLUDED_VERSION_NAMES == frozenset({"Wishlist"})
|
||||
|
||||
|
||||
def test_filter_excludes_wishlist_issue():
|
||||
"""Задача в версии Wishlist удаляется из выборки."""
|
||||
items = [
|
||||
(make_issue(1, fixed_version="Wishlist"), None),
|
||||
(make_issue(2, fixed_version="v2.5.0"), date(2026, 11, 1)),
|
||||
]
|
||||
kept = filter_excluded_versions(items)
|
||||
assert [issue.id for issue, _ in kept] == [2]
|
||||
|
||||
|
||||
def test_filter_keeps_issue_without_version():
|
||||
"""Задача без версии фильтром не трогается."""
|
||||
items = [(make_issue(3), None)]
|
||||
kept = filter_excluded_versions(items)
|
||||
assert [issue.id for issue, _ in kept] == [3]
|
||||
|
||||
|
||||
def test_filter_keeps_regular_version_without_due():
|
||||
"""Обычная версия без срока -- не бакет, задача остаётся."""
|
||||
items = [(make_issue(4, fixed_version="v3.0.0"), None)]
|
||||
kept = filter_excluded_versions(items)
|
||||
assert [issue.id for issue, _ in kept] == [4]
|
||||
|
||||
|
||||
def test_filter_is_case_sensitive():
|
||||
"""Сравнение имени версии точное: wishlist строчными -- НЕ исключение."""
|
||||
items = [
|
||||
(make_issue(5, fixed_version="wishlist"), None),
|
||||
(make_issue(6, fixed_version="WISHLIST"), None),
|
||||
(make_issue(7, fixed_version="Wishlist"), None),
|
||||
]
|
||||
kept = filter_excluded_versions(items)
|
||||
assert [issue.id for issue, _ in kept] == [5, 6]
|
||||
|
||||
|
||||
def test_filter_returns_only_excluded_when_all_match():
|
||||
items = [(make_issue(8, fixed_version="Wishlist"), None)]
|
||||
assert filter_excluded_versions(items) == []
|
||||
|
||||
|
||||
def test_filter_preserves_due_pairing():
|
||||
"""Фильтр не теряет парную к задаче дату срока."""
|
||||
due = date(2026, 12, 1)
|
||||
items = [(make_issue(9, fixed_version="v1"), due)]
|
||||
((issue, kept_due),) = filter_excluded_versions(items)
|
||||
assert issue.id == 9
|
||||
assert kept_due is due
|
||||
|
||||
|
||||
def test_filter_tolerates_version_without_name_attribute():
|
||||
"""fixed_version без атрибута name -- задача остаётся (getattr-безопасность)."""
|
||||
issue = make_issue(10)
|
||||
issue.fixed_version = mock.MagicMock(spec=[])
|
||||
items = [(issue, None)]
|
||||
kept = filter_excluded_versions(items)
|
||||
assert [i.id for i, _ in kept] == [10]
|
||||
|
||||
|
||||
# -- Просроченность --
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user