|
| 1 | +import json |
1 | 2 | import sys |
2 | 3 | from types import SimpleNamespace |
3 | 4 |
|
@@ -67,6 +68,22 @@ def test_cli_subcommands_registered(): |
67 | 68 | assert sub in result.output, f"subcommand `{sub}` missing from help" |
68 | 69 |
|
69 | 70 |
|
| 71 | +def test_cli_top_level_command_help_is_available(): |
| 72 | + from click.testing import CliRunner |
| 73 | + |
| 74 | + runner = CliRunner() |
| 75 | + commands = [ |
| 76 | + "a", "hk", "us", "global", "indices", "zt-pool", "flow", "stock", "fund", "news", |
| 77 | + "daily", "profile", "portfolio", "alert", "note", "diary", "diagnose", "guide", "example", |
| 78 | + "cache-clear", "update", "uninstall", |
| 79 | + ] |
| 80 | + |
| 81 | + for command in commands: |
| 82 | + result = runner.invoke(cli, [command, "--help"]) |
| 83 | + assert result.exit_code == 0, f"{command} --help failed: {result.output}" |
| 84 | + assert "Usage:" in result.output |
| 85 | + |
| 86 | + |
70 | 87 | def test_cli_stock_runs_single_stock_quote(monkeypatch): |
71 | 88 | from click.testing import CliRunner |
72 | 89 |
|
@@ -187,6 +204,22 @@ def fake_run(cmd, check): |
187 | 204 | )] |
188 | 205 |
|
189 | 206 |
|
| 207 | +def test_cli_update_failure_mentions_python_version(monkeypatch): |
| 208 | + from click.testing import CliRunner |
| 209 | + |
| 210 | + def fake_run(cmd, check): |
| 211 | + return SimpleNamespace(returncode=1) |
| 212 | + |
| 213 | + monkeypatch.setattr(cli_module.subprocess, "run", fake_run) |
| 214 | + |
| 215 | + runner = CliRunner() |
| 216 | + result = runner.invoke(cli, ["update"]) |
| 217 | + |
| 218 | + assert result.exit_code != 0 |
| 219 | + assert "Python 3.9+" in result.output |
| 220 | + assert "python3 -m pip install --upgrade young-stock-cli" in result.output |
| 221 | + |
| 222 | + |
190 | 223 | def test_cli_uninstall_runs_pip_uninstall(monkeypatch): |
191 | 224 | from click.testing import CliRunner |
192 | 225 |
|
@@ -403,3 +436,28 @@ def test_cli_diagnose_outputs_network_guidance(monkeypatch): |
403 | 436 | assert result.exit_code == 0 |
404 | 437 | assert "网络诊断" in result.output |
405 | 438 | assert "建议" in result.output |
| 439 | + |
| 440 | + |
| 441 | +def test_cli_diagnose_json_outputs_machine_readable_support_info(monkeypatch, tmp_path): |
| 442 | + from click.testing import CliRunner |
| 443 | + |
| 444 | + monkeypatch.setenv("YOUNG_STOCK_PROFILE", str(tmp_path / "profile.json")) |
| 445 | + monkeypatch.setenv("YOUNG_STOCK_HOME", str(tmp_path / "home")) |
| 446 | + monkeypatch.setattr( |
| 447 | + cli_module._core, |
| 448 | + "SOURCE_HEALTH", |
| 449 | + SimpleNamespace(snapshot=lambda name: SimpleNamespace(success_rate=1.0, average_latency_ms=0.0, should_skip=False)), |
| 450 | + ) |
| 451 | + |
| 452 | + result = CliRunner().invoke(cli, ["diagnose", "--json"]) |
| 453 | + |
| 454 | + assert result.exit_code == 0 |
| 455 | + payload = json.loads(result.output) |
| 456 | + assert payload["command"] == "young diagnose" |
| 457 | + assert payload["version"] == __version__ |
| 458 | + assert payload["python"]["executable"] == sys.executable |
| 459 | + assert payload["paths"]["profile"].endswith("profile.json") |
| 460 | + assert payload["paths"]["home"].endswith("home") |
| 461 | + assert payload["paths"]["cache"] |
| 462 | + assert payload["read_only"] is True |
| 463 | + assert {source["name"] for source in payload["sources"]} >= {"eastmoney", "sina", "tencent", "ths", "futu"} |
0 commit comments