"""统一 CLI 测试。 验证子命令路由 + argparse 解析正确。 """ from __future__ import annotations import sys from unittest.mock import patch from a_share_cli.main import main def _run(args: str) -> int: with patch.object(sys, "argv", ["a-share", *args.split()]): try: return main() except SystemExit as e: return e.code if isinstance(e.code, int) else 1 def test_no_args_shows_help() -> None: rc = _run("") assert rc == 0 def test_crawl_default() -> None: with patch("a_share_cli.main.cmd_crawl", return_value=0) as mock: _run("crawl") mock.assert_called_once() def test_crawl_with_source() -> None: with patch("a_share_cli.main.cmd_crawl", return_value=0) as mock: _run("crawl --source cls") args = mock.call_args[0][0] assert args.source == "cls" def test_extract_with_date() -> None: with patch("a_share_cli.main.cmd_extract", return_value=0) as mock: _run("extract --date 20260616 --source sina") args = mock.call_args[0][0] assert args.date == "20260616" assert args.source == "sina" def test_events_with_provider() -> None: with patch("a_share_cli.main.cmd_events", return_value=0) as mock: _run("events --provider qwen --limit 5") args = mock.call_args[0][0] assert args.provider == "qwen" assert args.limit == 5 def test_search_default() -> None: with patch("a_share_cli.main.cmd_search", return_value=0) as mock: _run("search 宁德时代") args = mock.call_args[0][0] assert args.query == "宁德时代" assert args.top == 10 def test_search_with_filters() -> None: with patch("a_share_cli.main.cmd_search", return_value=0) as mock: _run("search 芯片 --source cls --sentiment positive --min-importance 3 --top 5") args = mock.call_args[0][0] assert args.query == "芯片" assert args.source == "cls" assert args.sentiment == "positive" assert args.min_importance == 3 assert args.top == 5 def test_search_with_stock() -> None: with patch("a_share_cli.main.cmd_search", return_value=0) as mock: _run("search 重大合同 --stock 300750.sz") args = mock.call_args[0][0] assert args.stock == "300750.sz" def test_pipeline_once() -> None: with patch("a_share_cli.main.cmd_pipeline", return_value=0) as mock: _run("pipeline --once --steps crawler,extractor") args = mock.call_args[0][0] assert args.once is True assert args.steps == "crawler,extractor" def test_status() -> None: with patch("a_share_cli.main.cmd_status", return_value=0) as mock: _run("status") mock.assert_called_once()