Skip to content

Commit 53cc1ae

Browse files
committed
test: add tests for cmd.run and cmd.run_interactive
1 parent 62c5d69 commit 53cc1ae

1 file changed

Lines changed: 125 additions & 35 deletions

File tree

tests/test_cmd.py

Lines changed: 125 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -57,39 +57,129 @@ def decode(self, encoding="utf-8", errors="strict"):
5757
cmd._try_decode(_bytes())
5858

5959

60-
def test_run_returns_command_with_shell_false():
61-
"""Test that cmd.run executes a list-based command without shell."""
62-
c = cmd.run(["python", "-c", "print('hello')"])
63-
assert c.return_code == 0
64-
assert "hello" in c.out
65-
66-
67-
def test_run_shell_returns_command_with_shell_true():
68-
"""Test that cmd.run_shell executes a string command via the shell."""
69-
c = cmd.run_shell("python -c \"print('hello')\"")
70-
assert c.return_code == 0
71-
assert "hello" in c.out
72-
73-
74-
def test_run_with_env():
75-
"""Test that cmd.run passes extra environment variables."""
76-
c = cmd.run(
77-
["python", "-c", "import os; print(os.environ['CZ_TEST_VAR'])"],
78-
env={"CZ_TEST_VAR": "test_value"},
79-
)
80-
assert c.return_code == 0
81-
assert "test_value" in c.out
82-
83-
84-
def test_run_with_string_emits_deprecation_warning():
85-
"""Test that passing a string to cmd.run() emits a DeprecationWarning."""
86-
import warnings
87-
88-
with warnings.catch_warnings(record=True) as w:
89-
warnings.simplefilter("always")
90-
c = cmd.run("python -c \"print('deprecated')\"")
60+
class TestRun:
61+
def test_returns_command_with_shell_false(self):
62+
"""Test that cmd.run executes a list-based command without shell."""
63+
c = cmd.run(["python", "-c", "print('hello')"])
64+
assert c.return_code == 0
65+
assert "hello" in c.out
66+
67+
def test_with_env(self):
68+
"""Test that cmd.run passes extra environment variables."""
69+
c = cmd.run(
70+
["python", "-c", "import os; print(os.environ['CZ_TEST_VAR'])"],
71+
env={"CZ_TEST_VAR": "test_value"},
72+
)
73+
assert c.return_code == 0
74+
assert "test_value" in c.out
75+
76+
def test_with_string_emits_deprecation_warning(self):
77+
"""Test that passing a string to cmd.run() emits a DeprecationWarning."""
78+
import warnings
79+
80+
with warnings.catch_warnings(record=True) as w:
81+
warnings.simplefilter("always")
82+
c = cmd.run("python -c \"print('deprecated')\"")
83+
assert c.return_code == 0
84+
assert "deprecated" in c.out
85+
assert len(w) == 1
86+
assert issubclass(w[0].category, DeprecationWarning)
87+
assert "cmd.run()" in str(w[0].message)
88+
89+
def test_stdout_captured(self):
90+
result = cmd.run(["python", "-c", "print('hello')"])
91+
assert "hello" in result.out
92+
assert isinstance(result.stdout, bytes)
93+
assert b"hello" in result.stdout
94+
95+
def test_stderr_captured(self):
96+
result = cmd.run(
97+
["python", "-c", "import sys; print('err msg', file=sys.stderr)"]
98+
)
99+
assert "err msg" in result.err
100+
assert isinstance(result.stderr, bytes)
101+
assert b"err msg" in result.stderr
102+
103+
def test_zero_return_code_on_success(self):
104+
result = cmd.run(["python", "-c", "import sys; sys.exit(0)"])
105+
assert result.return_code == 0
106+
107+
def test_nonzero_return_code_on_failure(self):
108+
result = cmd.run(["python", "-c", "import sys; sys.exit(42)"])
109+
assert result.return_code == 42
110+
111+
def test_env_passed_to_subprocess(self):
112+
result = cmd.run(
113+
["python", "-c", "import os; print(os.environ['CZ_TEST_VAR'])"],
114+
env={"CZ_TEST_VAR": "sentinelvalue"},
115+
)
116+
assert "sentinelvalue" in result.out
117+
assert result.return_code == 0
118+
119+
def test_env_merged_with_os_environ(self, monkeypatch):
120+
monkeypatch.setenv("CZ_EXISTING_VAR", "fromenv")
121+
result = cmd.run(
122+
["python", "-c", "import os; print(os.environ['CZ_EXISTING_VAR'])"],
123+
env={"CZ_EXTRA_VAR": "extra"},
124+
)
125+
assert "fromenv" in result.out
126+
127+
def test_empty_stdout_and_stderr(self):
128+
result = cmd.run(["python", "-c", '"pass"'])
129+
assert result.out == ""
130+
assert result.err == ""
131+
assert result.stdout == b""
132+
assert result.stderr == b""
133+
134+
def test_no_env_uses_os_environ(self, monkeypatch):
135+
monkeypatch.setenv("CZ_NO_ENV_TEST", "inherited")
136+
result = cmd.run(
137+
["python", "-c", "import os; print(os.environ['CZ_NO_ENV_TEST'])"]
138+
)
139+
assert "inherited" in result.out
140+
141+
142+
class TestRunShell:
143+
def test_returns_command_with_shell_true(self):
144+
"""Test that cmd.run_shell executes a string command via the shell."""
145+
c = cmd.run_shell("python -c \"print('hello')\"")
91146
assert c.return_code == 0
92-
assert "deprecated" in c.out
93-
assert len(w) == 1
94-
assert issubclass(w[0].category, DeprecationWarning)
95-
assert "cmd.run()" in str(w[0].message)
147+
assert "hello" in c.out
148+
149+
150+
class TestRunInteractive:
151+
def test_zero_return_code_on_success(self):
152+
return_code = cmd.run_interactive(["python", "-c", "import sys; sys.exit(0)"])
153+
assert return_code == 0
154+
155+
def test_nonzero_return_code_on_failure(self):
156+
return_code = cmd.run_interactive(["python", "-c", "import sys; sys.exit(3)"])
157+
assert return_code == 3
158+
159+
def test_env_passed_to_subprocess(self):
160+
return_code = cmd.run_interactive(
161+
[
162+
"python",
163+
"-c",
164+
"import os, sys; sys.exit(0 if os.environ['CZ_ITEST_VAR'] == 'val' else 1)",
165+
],
166+
env={"CZ_ITEST_VAR": "val"},
167+
)
168+
assert return_code == 0
169+
170+
def test_env_merged_with_os_environ(self, monkeypatch):
171+
monkeypatch.setenv("CZ_ITEST_EXISTING", "yes")
172+
return_code = cmd.run_interactive(
173+
[
174+
"python",
175+
"-c",
176+
"import os, sys; sys.exit(0 if os.environ['CZ_ITEST_EXISTING'] == 'yes' else 1)",
177+
],
178+
env={"CZ_ITEST_EXTRA": "extra"},
179+
)
180+
assert return_code == 0
181+
182+
def test_runs_with_string(self):
183+
"""Test that cmd.run_shell executes a string command via the shell."""
184+
return_code = cmd.run_interactive("python -c \"print('hello')\"")
185+
assert return_code == 0

0 commit comments

Comments
 (0)