拆分代码;约束cli命令
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from typer.testing import CliRunner
|
||||
@@ -64,61 +65,60 @@ def test_build_runtime_context_uses_default_server(monkeypatch):
|
||||
assert runtime.server == core.DEFAULT_SERVER
|
||||
|
||||
|
||||
def test_help_json_lists_commands():
|
||||
def test_help_outputs_json_lists_commands():
|
||||
result = runner.invoke(app, ["help"])
|
||||
payload = json.loads(result.stdout)
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert payload["schema_version"] == "tjwater-cli/v1"
|
||||
assert any(command["command"] == "project" for command in payload["commands"])
|
||||
assert any(command["command"] == "analysis" for command in payload["commands"])
|
||||
assert payload["menu_level"] == 1
|
||||
assert all(command["command"] != "project list" for command in payload["commands"])
|
||||
|
||||
|
||||
def test_help_option_json_is_removed():
|
||||
result = runner.invoke(app, ["help", "--json"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert '"schema_version": "tjwater-cli/v1"' in result.stdout
|
||||
assert '"command": "project"' in result.stdout
|
||||
assert '"command": "analysis"' in result.stdout
|
||||
assert '"menu_level": 1' in result.stdout
|
||||
assert '"command": "project list"' not in result.stdout
|
||||
|
||||
|
||||
def test_help_defaults_to_text():
|
||||
result = runner.invoke(app, ["help"])
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "Commands:" in result.stdout
|
||||
assert "project: 项目与项目级元数据相关命令。" in result.stdout
|
||||
assert "analysis: 分析计算与诊断相关命令。" in result.stdout
|
||||
assert "Use `tjwater <menu> help` to see subcommands." in result.stdout
|
||||
assert "usage: tjwater project help" not in result.stdout
|
||||
assert "example: tjwater project help" not in result.stdout
|
||||
assert "project list: 列出当前用户可访问项目" not in result.stdout
|
||||
assert '"schema_version": "tjwater-cli/v1"' not in result.stdout
|
||||
assert result.exit_code == 2
|
||||
assert "No such option: --json" in result.output
|
||||
|
||||
|
||||
def test_simulation_help_lists_subcommands():
|
||||
result = runner.invoke(app, ["simulation", "help"])
|
||||
payload = json.loads(result.stdout)
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "模拟运行与调度相关命令。" in result.stdout
|
||||
assert "simulation run: 触发指定绝对时间的模拟运行" in result.stdout
|
||||
assert "usage: tjwater simulation run --start-time <START_TIME> --duration <DURATION>" in result.stdout
|
||||
assert "example: tjwater --auth-context auth.json simulation run --start-time 2025-01-02T03:04:05+08:00 --duration 30" in result.stdout
|
||||
assert payload["summary"] == "模拟运行与调度相关命令。"
|
||||
commands = {command["command"]: command for command in payload["commands"]}
|
||||
assert commands["simulation run"]["summary"] == "触发指定绝对时间的模拟运行"
|
||||
assert commands["simulation run"]["usage"] == "tjwater-cli simulation run --start-time <START_TIME> --duration <DURATION>"
|
||||
assert commands["simulation run"]["example"] == "tjwater-cli --auth-context auth.json simulation run --start-time 2025-01-02T03:04:05+08:00 --duration 30"
|
||||
|
||||
|
||||
def test_nested_group_help_lists_examples():
|
||||
result = runner.invoke(app, ["analysis", "leakage", "help"])
|
||||
payload = json.loads(result.stdout)
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "漏损分析相关命令。" in result.stdout
|
||||
assert "analysis leakage identify: 执行漏损识别" in result.stdout
|
||||
assert "example: tjwater --auth-context auth.json analysis leakage identify" in result.stdout
|
||||
assert payload["summary"] == "漏损分析相关命令。"
|
||||
commands = {command["command"]: command for command in payload["commands"]}
|
||||
assert commands["analysis leakage identify"]["summary"] == "执行漏损识别"
|
||||
assert commands["analysis leakage identify"]["example"] == "tjwater-cli --auth-context auth.json analysis leakage identify --start-time 2025-01-02T03:04:05+08:00 --end-time 2025-01-02T04:04:05+08:00"
|
||||
|
||||
|
||||
def test_analysis_help_uses_group_summaries_for_nested_groups():
|
||||
result = runner.invoke(app, ["analysis", "help"])
|
||||
payload = json.loads(result.stdout)
|
||||
commands = {command["command"]: command for command in payload["commands"]}
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "analysis leakage: 漏损分析相关命令。" in result.stdout
|
||||
assert "analysis burst-detection: 爆管检测相关命令。" in result.stdout
|
||||
assert "analysis burst-location" not in result.stdout
|
||||
assert "analysis risk" not in result.stdout
|
||||
assert "analysis leakage: 执行漏损识别" not in result.stdout
|
||||
assert "example: tjwater --auth-context auth.json analysis burst --start-time 2025-01-02T03:04:05+08:00 --duration 30 --burst-file ./burst.json --scheme burst_case_01" in result.stdout
|
||||
assert "example: tjwater --auth-context auth.json analysis valve --mode close --start-time 2025-01-02T03:04:05+08:00 --valve V1 --duration 900" in result.stdout
|
||||
assert commands["analysis leakage"]["summary"] == "漏损分析相关命令。"
|
||||
assert commands["analysis burst-detection"]["summary"] == "爆管检测相关命令。"
|
||||
assert "analysis burst-location" not in commands
|
||||
assert "analysis risk" not in commands
|
||||
assert commands["analysis burst"]["example"] == "tjwater-cli --auth-context auth.json analysis burst --start-time 2025-01-02T03:04:05+08:00 --duration 30 --burst-file ./burst.json --scheme burst_case_01"
|
||||
assert commands["analysis valve"]["example"] == "tjwater-cli --auth-context auth.json analysis valve --mode close --start-time 2025-01-02T03:04:05+08:00 --valve V1 --duration 900"
|
||||
|
||||
|
||||
def test_bare_analysis_uses_typer_help_with_descriptions():
|
||||
@@ -133,23 +133,48 @@ def test_bare_analysis_uses_typer_help_with_descriptions():
|
||||
assert "risk" not in result.stdout
|
||||
|
||||
|
||||
def test_leaf_help_shows_usage_and_example():
|
||||
def test_leaf_help_outputs_json():
|
||||
result = runner.invoke(app, ["help", "simulation", "run"])
|
||||
payload = json.loads(result.stdout)
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "Command: simulation run" in result.stdout
|
||||
assert "结果需后续通过 data timeseries 在对应时间段查询" in result.stdout
|
||||
assert "Usage: tjwater simulation run --start-time <START_TIME> --duration <DURATION>" in result.stdout
|
||||
assert "Examples:" in result.stdout
|
||||
assert "tjwater --auth-context auth.json simulation run --start-time 2025-01-02T03:04:05+08:00 --duration 30" in result.stdout
|
||||
assert payload["command"] == "simulation run"
|
||||
assert payload["output"] == "模拟触发结果;实时数据需通过 data timeseries 命令按时间段查询"
|
||||
assert payload["usage"] == "tjwater-cli simulation run --start-time <START_TIME> --duration <DURATION>"
|
||||
assert payload["examples"] == ["tjwater-cli --auth-context auth.json simulation run --start-time 2025-01-02T03:04:05+08:00 --duration 30"]
|
||||
|
||||
|
||||
def test_project_help_uses_legal_kind_example():
|
||||
result = runner.invoke(app, ["project", "help"])
|
||||
payload = json.loads(result.stdout)
|
||||
commands = {command["command"]: command for command in payload["commands"]}
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "example: tjwater --auth-context auth.json project data --kind scada-info" in result.stdout
|
||||
assert "--kind time" not in result.stdout
|
||||
assert commands["project data"]["example"] == "tjwater-cli --auth-context auth.json project data --kind scada-info"
|
||||
assert "--kind time" not in commands["project data"]["example"]
|
||||
|
||||
|
||||
def test_root_help_flag_uses_typer_style_with_examples():
|
||||
result = runner.invoke(app, ["--help"], prog_name="tjwater-cli")
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "Usage: tjwater-cli" in result.stdout
|
||||
assert "Examples:" in result.stdout
|
||||
assert "tjwater-cli help simulation run" in result.stdout
|
||||
|
||||
|
||||
def test_leaf_help_flag_includes_usage_and_example():
|
||||
result = runner.invoke(app, ["simulation", "run", "--help"], prog_name="tjwater-cli")
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert "Usage: tjwater-cli simulation run [OPTIONS]" in result.stdout
|
||||
assert "Usage example:" in result.stdout
|
||||
assert "--start-time <START_TIME>" in result.stdout
|
||||
assert "--duration" in result.stdout
|
||||
assert "Examples:" in result.stdout
|
||||
assert "tjwater-cli simulation run" in result.stdout
|
||||
assert "START_TIME" in result.stdout
|
||||
assert "DURATION" in result.stdout
|
||||
|
||||
|
||||
def test_analysis_burst_returns_next_step_to_fetch_scheme(monkeypatch, tmp_path: Path):
|
||||
@@ -186,8 +211,8 @@ def test_analysis_burst_returns_next_step_to_fetch_scheme(monkeypatch, tmp_path:
|
||||
|
||||
assert result.exit_code == 0
|
||||
assert '"summary": "爆管分析执行成功"' in result.stdout
|
||||
assert '"tjwater --auth-context auth.json data scheme get --name burst_case_01"' in result.stdout
|
||||
assert '"tjwater --auth-context auth.json data scheme list"' in result.stdout
|
||||
assert '"tjwater-cli --auth-context auth.json data scheme get --name burst_case_01"' in result.stdout
|
||||
assert '"tjwater-cli --auth-context auth.json data scheme list"' in result.stdout
|
||||
|
||||
|
||||
def test_main_missing_option_error_includes_usage_and_next_step(capsys):
|
||||
@@ -197,8 +222,8 @@ def test_main_missing_option_error_includes_usage_and_next_step(capsys):
|
||||
assert exit_code == 2
|
||||
assert '"summary": "缺少参数"' in stdout
|
||||
assert '"code": "MISSING_PARAMETER"' in stdout
|
||||
assert '"usage": "tjwater simulation run --start-time <START_TIME> --duration <DURATION>"' in stdout
|
||||
assert '"tjwater help simulation run"' in stdout
|
||||
assert '"usage": "tjwater-cli simulation run --start-time <START_TIME> --duration <DURATION>"' in stdout
|
||||
assert '"tjwater-cli help simulation run"' in stdout
|
||||
|
||||
|
||||
def test_main_bare_analysis_returns_typer_help_without_json_error(capsys):
|
||||
@@ -206,7 +231,7 @@ def test_main_bare_analysis_returns_typer_help_without_json_error(capsys):
|
||||
stdout = capsys.readouterr().out
|
||||
|
||||
assert exit_code == 0
|
||||
assert "Usage: tjwater analysis" in stdout
|
||||
assert "Usage: tjwater-cli analysis" in stdout
|
||||
assert "分析计算与诊断相关命令。" in stdout
|
||||
assert '"ok": false' not in stdout
|
||||
|
||||
@@ -268,8 +293,8 @@ def test_simulation_run_translates_rfc3339(monkeypatch, tmp_path: Path):
|
||||
"start_time": "03:04:05+08:00",
|
||||
"duration": 30,
|
||||
}
|
||||
assert '"tjwater --auth-context auth.json data timeseries realtime links --start-time 2025-01-02T03:04:05+08:00 --end-time 2025-01-02T03:34:05+08:00"' in result.stdout
|
||||
assert '"tjwater --auth-context auth.json data timeseries realtime nodes --start-time 2025-01-02T03:04:05+08:00 --end-time 2025-01-02T03:34:05+08:00"' in result.stdout
|
||||
assert '"tjwater-cli --auth-context auth.json data timeseries realtime links --start-time 2025-01-02T03:04:05+08:00 --end-time 2025-01-02T03:34:05+08:00"' in result.stdout
|
||||
assert '"tjwater-cli --auth-context auth.json data timeseries realtime nodes --start-time 2025-01-02T03:04:05+08:00 --end-time 2025-01-02T03:34:05+08:00"' in result.stdout
|
||||
|
||||
|
||||
def test_project_export_inp_downloads_file(monkeypatch, tmp_path: Path):
|
||||
|
||||
Reference in New Issue
Block a user