feat(v1.2.0): retry API, dernier commit, tri, coloration, export JSON
- client.py: _get_with_retry (max 2 retries, backoff lineaire), get_latest_commit - collector.py: champ last_commit_date dans RepoData - display.py: colonne "Dernier commit", _sort_repos (name/issues/release/activity), _colorize_milestone_due (rouge/jaune/vert selon echeance) - cli.py: options --sort/-s et --format/-f (table/json) - exporter.py: nouveau module, repos_to_dicts + export_json - 88 tests (35 nouveaux), ruff clean fixes #8, fixes #7, fixes #10, fixes #9, fixes #6 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -26,7 +26,7 @@ class TestMainNominal:
|
||||
|
||||
mock_client_cls.assert_called_once_with("http://localhost:3000", "test-token-123")
|
||||
mock_collect.assert_called_once_with(mock_client, include=None, exclude=None)
|
||||
mock_render.assert_called_once_with(mock_collect.return_value)
|
||||
mock_render.assert_called_once_with(mock_collect.return_value, sort_key="name")
|
||||
|
||||
@patch("gitea_dashboard.cli.render_dashboard")
|
||||
@patch("gitea_dashboard.cli.collect_all")
|
||||
@@ -193,3 +193,88 @@ class TestMainWithFilters:
|
||||
main([])
|
||||
|
||||
mock_collect.assert_called_once_with(mock_client, include=None, exclude=None)
|
||||
|
||||
|
||||
class TestParseArgsSort:
|
||||
"""Test --sort argument parsing."""
|
||||
|
||||
def test_sort_default(self):
|
||||
"""Without --sort, default is 'name'."""
|
||||
from gitea_dashboard.cli import parse_args
|
||||
|
||||
args = parse_args([])
|
||||
assert args.sort == "name"
|
||||
|
||||
def test_sort_issues(self):
|
||||
"""--sort issues is accepted."""
|
||||
from gitea_dashboard.cli import parse_args
|
||||
|
||||
args = parse_args(["--sort", "issues"])
|
||||
assert args.sort == "issues"
|
||||
|
||||
def test_sort_short_flag(self):
|
||||
"""-s activity is accepted."""
|
||||
from gitea_dashboard.cli import parse_args
|
||||
|
||||
args = parse_args(["-s", "activity"])
|
||||
assert args.sort == "activity"
|
||||
|
||||
def test_sort_invalid(self):
|
||||
"""--sort invalid raises SystemExit (argparse error)."""
|
||||
from gitea_dashboard.cli import parse_args
|
||||
|
||||
with pytest.raises(SystemExit):
|
||||
parse_args(["--sort", "invalid"])
|
||||
|
||||
|
||||
class TestParseArgsFormat:
|
||||
"""Test --format argument parsing."""
|
||||
|
||||
def test_format_default(self):
|
||||
"""Without --format, default is 'table'."""
|
||||
from gitea_dashboard.cli import parse_args
|
||||
|
||||
args = parse_args([])
|
||||
assert args.format == "table"
|
||||
|
||||
def test_format_json(self):
|
||||
"""--format json is accepted."""
|
||||
from gitea_dashboard.cli import parse_args
|
||||
|
||||
args = parse_args(["--format", "json"])
|
||||
assert args.format == "json"
|
||||
|
||||
def test_format_short_flag(self):
|
||||
"""-f json is accepted."""
|
||||
from gitea_dashboard.cli import parse_args
|
||||
|
||||
args = parse_args(["-f", "json"])
|
||||
assert args.format == "json"
|
||||
|
||||
def test_format_invalid(self):
|
||||
"""--format invalid raises SystemExit."""
|
||||
from gitea_dashboard.cli import parse_args
|
||||
|
||||
with pytest.raises(SystemExit):
|
||||
parse_args(["--format", "invalid"])
|
||||
|
||||
|
||||
class TestMainFormatJson:
|
||||
"""Test main() with --format json."""
|
||||
|
||||
@patch("gitea_dashboard.cli.collect_all")
|
||||
@patch("gitea_dashboard.cli.GiteaClient")
|
||||
def test_json_output(self, mock_client_cls, mock_collect, capsys):
|
||||
"""--format json produces valid JSON on stdout."""
|
||||
import json
|
||||
|
||||
env = {"GITEA_TOKEN": "test-token"}
|
||||
mock_client_cls.return_value = MagicMock()
|
||||
mock_collect.return_value = []
|
||||
|
||||
with patch.dict("os.environ", env, clear=True):
|
||||
main(["--format", "json"])
|
||||
|
||||
captured = capsys.readouterr()
|
||||
parsed = json.loads(captured.out)
|
||||
assert isinstance(parsed, list)
|
||||
|
||||
Reference in New Issue
Block a user