Skip to content

Commit 63a1807

Browse files
committed
fix: strip ANSI escape codes in CLI tests for CI compatibility
Rich inserts ANSI escape sequences that split option names (e.g. --api-key becomes \e[1;36m-\e[0m\e[1;36m-api\e[0m...) even with NO_COLOR=1. Strip all ANSI codes from output before asserting.
1 parent 2f4423a commit 63a1807

1 file changed

Lines changed: 63 additions & 86 deletions

File tree

tests/test_cli.py

Lines changed: 63 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,39 @@
11
"""Tests for CLI entry point."""
22

33
import os
4+
import re
45
import subprocess
56
import sys
67

7-
# Env that disables Rich ANSI codes so assertions can match plain text
8-
_PLAIN_ENV = {**os.environ, "NO_COLOR": "1"}
8+
# Env that disables Rich color codes (bold/dim may still appear)
9+
_PLAIN_ENV = {**os.environ, "NO_COLOR": "1", "TERM": "dumb"}
910

11+
_ANSI_RE = re.compile(r"\x1b\[[0-9;]*m")
1012

11-
def test_help_exits_zero():
12-
result = subprocess.run(
13-
[sys.executable, "-m", "zad_cli", "--help"],
13+
14+
def _strip_ansi(text: str) -> str:
15+
return _ANSI_RE.sub("", text)
16+
17+
18+
def _run_help(*args: str) -> subprocess.CompletedProcess:
19+
"""Run a CLI command with --help and return the result."""
20+
return subprocess.run(
21+
[sys.executable, "-m", "zad_cli", *args, "--help"],
1422
capture_output=True,
1523
text=True,
1624
env=_PLAIN_ENV,
1725
)
26+
27+
28+
def test_help_exits_zero():
29+
result = _run_help()
30+
out = _strip_ansi(result.stdout)
1831
assert result.returncode == 0
19-
assert "CLI for ZAD" in result.stdout
20-
assert "--api-key" in result.stdout
21-
assert "--project" in result.stdout
22-
assert "ZAD_PROJECT_ID" in result.stdout
23-
assert "--verbose" in result.stdout
32+
assert "CLI for ZAD" in out
33+
assert "--api-key" in out
34+
assert "--project" in out
35+
assert "ZAD_PROJECT_ID" in out
36+
assert "--verbose" in out
2437

2538

2639
def test_version():
@@ -35,34 +48,26 @@ def test_version():
3548

3649

3750
def test_project_help_without_api_key():
38-
result = subprocess.run(
39-
[sys.executable, "-m", "zad_cli", "project", "--help"],
40-
capture_output=True,
41-
text=True,
42-
env=_PLAIN_ENV,
43-
)
51+
result = _run_help("project")
52+
out = _strip_ansi(result.stdout)
4453
assert result.returncode == 0
45-
assert "list" in result.stdout
46-
assert "status" in result.stdout
47-
assert "delete" in result.stdout
48-
assert "refresh" in result.stdout
49-
assert "subdomains" in result.stdout
50-
assert "check-subdomain" in result.stdout
54+
assert "list" in out
55+
assert "status" in out
56+
assert "delete" in out
57+
assert "refresh" in out
58+
assert "subdomains" in out
59+
assert "check-subdomain" in out
5160

5261

5362
def test_deployment_help_shows_create():
54-
result = subprocess.run(
55-
[sys.executable, "-m", "zad_cli", "deployment", "--help"],
56-
capture_output=True,
57-
text=True,
58-
env=_PLAIN_ENV,
59-
)
63+
result = _run_help("deployment")
64+
out = _strip_ansi(result.stdout)
6065
assert result.returncode == 0
61-
assert "create" in result.stdout
62-
assert "delete" in result.stdout
63-
assert "update-image" in result.stdout
66+
assert "create" in out
67+
assert "delete" in out
68+
assert "update-image" in out
6469
# check-subdomain was moved to project
65-
assert "check-subdomain" not in result.stdout
70+
assert "check-subdomain" not in out
6671

6772

6873
def test_deploy_create_takes_positional_name():
@@ -71,84 +76,61 @@ def test_deploy_create_takes_positional_name():
7176
[sys.executable, "-m", "zad_cli", "deployment", "create", "test"],
7277
capture_output=True,
7378
text=True,
74-
env={"PATH": "/usr/bin:/bin", "NO_COLOR": "1"},
79+
env={"PATH": "/usr/bin:/bin", "NO_COLOR": "1", "TERM": "dumb"},
7580
)
81+
err = _strip_ansi(result.stderr)
7682
assert result.returncode != 0
7783
# Should fail on missing project/key or missing component args, not on argument parsing
78-
assert "ZAD_PROJECT_ID" in result.stderr or "ZAD_API_KEY" in result.stderr or "--component" in result.stderr
84+
assert "ZAD_PROJECT_ID" in err or "ZAD_API_KEY" in err or "--component" in err
7985

8086

8187
def test_component_help_shows_delete():
82-
result = subprocess.run(
83-
[sys.executable, "-m", "zad_cli", "component", "--help"],
84-
capture_output=True,
85-
text=True,
86-
env=_PLAIN_ENV,
87-
)
88+
result = _run_help("component")
89+
out = _strip_ansi(result.stdout)
8890
assert result.returncode == 0
89-
assert "delete" in result.stdout
90-
assert "add" in result.stdout
91-
assert "list" in result.stdout
91+
assert "delete" in out
92+
assert "add" in out
93+
assert "list" in out
9294

9395

9496
def test_service_help_shows_delete():
95-
result = subprocess.run(
96-
[sys.executable, "-m", "zad_cli", "service", "--help"],
97-
capture_output=True,
98-
text=True,
99-
env=_PLAIN_ENV,
100-
)
97+
result = _run_help("service")
98+
out = _strip_ansi(result.stdout)
10199
assert result.returncode == 0
102-
assert "delete" in result.stdout
103-
assert "add" in result.stdout
104-
assert "types" in result.stdout
100+
assert "delete" in out
101+
assert "add" in out
102+
assert "types" in out
105103

106104

107105
def test_task_list_uses_filter_project():
108106
"""task list should use --filter-project to clearly distinguish from global -p."""
109-
result = subprocess.run(
110-
[sys.executable, "-m", "zad_cli", "task", "list", "--help"],
111-
capture_output=True,
112-
text=True,
113-
env=_PLAIN_ENV,
114-
)
107+
result = _run_help("task", "list")
108+
out = _strip_ansi(result.stdout)
115109
assert result.returncode == 0
116-
assert "--filter-project" in result.stdout
110+
assert "--filter-project" in out
117111

118112

119113
def test_deployment_create_has_yes_flag():
120114
"""deployment create (upsert) should require confirmation via --yes."""
121-
result = subprocess.run(
122-
[sys.executable, "-m", "zad_cli", "deployment", "create", "--help"],
123-
capture_output=True,
124-
text=True,
125-
env=_PLAIN_ENV,
126-
)
115+
result = _run_help("deployment", "create")
116+
out = _strip_ansi(result.stdout)
127117
assert result.returncode == 0
128-
assert "--yes" in result.stdout
118+
assert "--yes" in out
129119

130120

131121
def test_logs_takes_positional_deployment():
132122
"""logs should accept deployment as a positional argument."""
133-
result = subprocess.run(
134-
[sys.executable, "-m", "zad_cli", "logs", "--help"],
135-
capture_output=True,
136-
text=True,
137-
env=_PLAIN_ENV,
138-
)
123+
result = _run_help("logs")
124+
out = _strip_ansi(result.stdout)
139125
assert result.returncode == 0
140-
assert "DEPLOYMENT" in result.stdout
126+
assert "DEPLOYMENT" in out
141127

142128

143129
def test_clone_help_shows_check():
144-
result = subprocess.run(
145-
[sys.executable, "-m", "zad_cli", "clone", "--help"],
146-
capture_output=True,
147-
text=True,
148-
env=_PLAIN_ENV,
149-
)
130+
result = _run_help("clone")
131+
out = _strip_ansi(result.stdout)
150132
assert result.returncode == 0
151-
assert "check" in result.stdout
133+
assert "check" in out
152134

153135

154136
def test_all_subcommands_have_help():
@@ -169,10 +151,5 @@ def test_all_subcommands_have_help():
169151
"open",
170152
]
171153
for cmd in subcommands:
172-
result = subprocess.run(
173-
[sys.executable, "-m", "zad_cli", cmd, "--help"],
174-
capture_output=True,
175-
text=True,
176-
env=_PLAIN_ENV,
177-
)
154+
result = _run_help(cmd)
178155
assert result.returncode == 0, f"{cmd} --help failed: {result.stderr}"

0 commit comments

Comments
 (0)