|
1 | 1 | import os |
2 | | -import subprocess |
3 | | -import sys |
4 | 2 | from pathlib import Path |
5 | | -from typing import Optional, Sequence |
| 3 | +from typing import Optional |
6 | 4 |
|
7 | 5 | import pytest |
8 | 6 |
|
9 | 7 | import dotenv |
10 | 8 | from dotenv.cli import cli as dotenv_cli |
11 | 9 | from dotenv.version import __version__ |
12 | | - |
13 | | -if sys.platform != "win32": |
14 | | - import sh |
15 | | - |
16 | | - |
17 | | -def invoke_sub(args: Sequence[str]) -> subprocess.CompletedProcess: |
18 | | - """ |
19 | | - Invoke the `dotenv` CLI in a subprocess. |
20 | | -
|
21 | | - This is necessary to test subcommands like `dotenv run` that replace the |
22 | | - current process. |
23 | | - """ |
24 | | - |
25 | | - return subprocess.run( |
26 | | - ["dotenv", *args], |
27 | | - capture_output=True, |
28 | | - text=True, |
29 | | - ) |
| 10 | +from tests.test_lib import check_process, run_dotenv |
30 | 11 |
|
31 | 12 |
|
32 | 13 | @pytest.mark.parametrize( |
@@ -192,122 +173,123 @@ def test_set_no_file(cli): |
192 | 173 | assert "Missing argument" in result.output |
193 | 174 |
|
194 | 175 |
|
195 | | -@pytest.mark.skipif(sys.platform == "win32", reason="sh module doesn't support Windows") |
196 | 176 | def test_get_default_path(tmp_path): |
197 | | - with sh.pushd(tmp_path): |
198 | | - (tmp_path / ".env").write_text("a=b") |
| 177 | + (tmp_path / ".env").write_text("A=x") |
199 | 178 |
|
200 | | - result = sh.dotenv("get", "a") |
| 179 | + result = run_dotenv(["get", "A"], cwd=tmp_path) |
201 | 180 |
|
202 | | - assert result == "b\n" |
| 181 | + check_process(result, exit_code=0, stdout="x\n") |
203 | 182 |
|
204 | 183 |
|
205 | | -@pytest.mark.skipif(sys.platform == "win32", reason="sh module doesn't support Windows") |
206 | 184 | def test_run(tmp_path): |
207 | | - with sh.pushd(tmp_path): |
208 | | - (tmp_path / ".env").write_text("a=b") |
| 185 | + (tmp_path / ".env").write_text("A=x") |
209 | 186 |
|
210 | | - result = sh.dotenv("run", "printenv", "a") |
| 187 | + result = run_dotenv(["run", "printenv", "A"], cwd=tmp_path) |
211 | 188 |
|
212 | | - assert result == "b\n" |
| 189 | + check_process(result, exit_code=0, stdout="x\n") |
213 | 190 |
|
214 | 191 |
|
215 | | -@pytest.mark.skipif(sys.platform == "win32", reason="sh module doesn't support Windows") |
216 | 192 | def test_run_with_existing_variable(tmp_path): |
217 | | - with sh.pushd(tmp_path): |
218 | | - (tmp_path / ".env").write_text("a=b") |
219 | | - env = dict(os.environ) |
220 | | - env.update({"LANG": "en_US.UTF-8", "a": "c"}) |
| 193 | + (tmp_path / ".env").write_text("A=x") |
| 194 | + env = dict(os.environ) |
| 195 | + env.update({"LANG": "en_US.UTF-8", "A": "y"}) |
221 | 196 |
|
222 | | - result = sh.dotenv("run", "printenv", "a", _env=env) |
| 197 | + result = run_dotenv(["run", "printenv", "A"], cwd=tmp_path, env=env) |
223 | 198 |
|
224 | | - assert result == "b\n" |
| 199 | + check_process(result, exit_code=0, stdout="x\n") |
225 | 200 |
|
226 | 201 |
|
227 | | -@pytest.mark.skipif(sys.platform == "win32", reason="sh module doesn't support Windows") |
228 | 202 | def test_run_with_existing_variable_not_overridden(tmp_path): |
229 | | - with sh.pushd(tmp_path): |
230 | | - (tmp_path / ".env").write_text("a=b") |
231 | | - env = dict(os.environ) |
232 | | - env.update({"LANG": "en_US.UTF-8", "a": "c"}) |
| 203 | + (tmp_path / ".env").write_text("A=x") |
| 204 | + env = dict(os.environ) |
| 205 | + env.update({"LANG": "en_US.UTF-8", "A": "C"}) |
233 | 206 |
|
234 | | - result = sh.dotenv("run", "--no-override", "printenv", "a", _env=env) |
| 207 | + result = run_dotenv( |
| 208 | + ["run", "--no-override", "printenv", "A"], cwd=tmp_path, env=env |
| 209 | + ) |
235 | 210 |
|
236 | | - assert result == "c\n" |
| 211 | + check_process(result, exit_code=0, stdout="C\n") |
237 | 212 |
|
238 | 213 |
|
239 | | -@pytest.mark.skipif(sys.platform == "win32", reason="sh module doesn't support Windows") |
240 | 214 | def test_run_with_none_value(tmp_path): |
241 | | - with sh.pushd(tmp_path): |
242 | | - (tmp_path / ".env").write_text("a=b\nc") |
| 215 | + (tmp_path / ".env").write_text("A=x\nc") |
243 | 216 |
|
244 | | - result = sh.dotenv("run", "printenv", "a") |
| 217 | + result = run_dotenv(["run", "printenv", "A"], cwd=tmp_path) |
245 | 218 |
|
246 | | - assert result == "b\n" |
| 219 | + check_process(result, exit_code=0, stdout="x\n") |
247 | 220 |
|
248 | 221 |
|
249 | | -@pytest.mark.skipif(sys.platform == "win32", reason="sh module doesn't support Windows") |
250 | | -def test_run_with_other_env(dotenv_path): |
251 | | - dotenv_path.write_text("a=b") |
| 222 | +def test_run_with_other_env(dotenv_path, tmp_path): |
| 223 | + dotenv_path.write_text("A=x") |
252 | 224 |
|
253 | | - result = sh.dotenv("--file", dotenv_path, "run", "printenv", "a") |
| 225 | + result = run_dotenv( |
| 226 | + ["--file", str(dotenv_path), "run", "printenv", "A"], |
| 227 | + cwd=tmp_path, |
| 228 | + ) |
254 | 229 |
|
255 | | - assert result == "b\n" |
| 230 | + check_process(result, exit_code=0, stdout="x\n") |
256 | 231 |
|
257 | 232 |
|
258 | | -def test_run_without_cmd(cli): |
259 | | - result = cli.invoke(dotenv_cli, ["run"]) |
| 233 | +def test_run_without_cmd(tmp_path): |
| 234 | + result = run_dotenv(["run"], cwd=tmp_path) |
260 | 235 |
|
261 | | - assert result.exit_code == 2 |
262 | | - assert "Invalid value for '-f'" in result.output |
| 236 | + check_process(result, exit_code=2) |
| 237 | + assert "Invalid value for '-f'" in result.stderr |
263 | 238 |
|
264 | 239 |
|
265 | | -def test_run_with_invalid_cmd(cli, dotenv_path): |
266 | | - result = cli.invoke(dotenv_cli, ["--file", dotenv_path, "run", "i_do_not_exist"]) |
| 240 | +def test_run_with_invalid_cmd(dotenv_path, tmp_path): |
| 241 | + result = run_dotenv( |
| 242 | + ["--file", str(dotenv_path), "run", "i_do_not_exist"], |
| 243 | + cwd=tmp_path, |
| 244 | + ) |
267 | 245 |
|
268 | | - assert result.exit_code == 1 |
269 | | - assert "Command not found: i_do_not_exist" in result.output |
| 246 | + check_process(result, exit_code=1) |
| 247 | + assert "Command not found: i_do_not_exist" in result.stderr |
270 | 248 |
|
271 | 249 |
|
272 | | -def test_run_with_env_missing_and_invalid_cmd(cli): |
| 250 | +def test_run_with_env_missing_and_invalid_cmd(tmp_path): |
273 | 251 | """ |
274 | 252 | Check that an .env file missing takes precedence over a command not found error. |
275 | 253 | """ |
276 | 254 |
|
277 | | - result = cli.invoke(dotenv_cli, ["run", "i_do_not_exist"]) |
| 255 | + result = run_dotenv(["run", "i_do_not_exist"], cwd=tmp_path) |
278 | 256 |
|
279 | | - assert result.exit_code == 2 |
280 | | - assert "Invalid value for '-f'" in result.output |
| 257 | + check_process(result, exit_code=2) |
| 258 | + assert "Invalid value for '-f'" in result.stderr |
281 | 259 |
|
282 | 260 |
|
283 | | -def test_run_with_version(cli): |
284 | | - result = cli.invoke(dotenv_cli, ["--version"]) |
| 261 | +def test_run_with_version(tmp_path): |
| 262 | + result = run_dotenv(["--version"], cwd=tmp_path) |
285 | 263 |
|
286 | | - assert result.exit_code == 0 |
287 | | - assert result.output.strip().endswith(__version__) |
| 264 | + check_process(result, exit_code=0) |
| 265 | + assert result.stdout.strip().endswith(__version__) |
288 | 266 |
|
289 | 267 |
|
290 | | -def test_run_with_command_flags(dotenv_path): |
| 268 | +def test_run_with_command_flags(dotenv_path, tmp_path): |
291 | 269 | """ |
292 | 270 | Check that command flags passed after `dotenv run` are not interpreted. |
293 | 271 |
|
294 | 272 | Here, we want to run `printenv --version`, not `dotenv --version`. |
295 | 273 | """ |
296 | 274 |
|
297 | | - result = invoke_sub(["--file", dotenv_path, "run", "printenv", "--version"]) |
| 275 | + result = run_dotenv( |
| 276 | + ["--file", str(dotenv_path), "run", "printenv", "--version"], |
| 277 | + cwd=tmp_path, |
| 278 | + ) |
298 | 279 |
|
299 | | - assert result.returncode == 0 |
| 280 | + check_process(result, exit_code=0) |
300 | 281 | assert result.stdout.strip().startswith("printenv ") |
301 | 282 |
|
302 | 283 |
|
303 | | -def test_run_with_dotenv_and_command_flags(cli, dotenv_path): |
| 284 | +def test_run_with_dotenv_and_command_flags(dotenv_path, tmp_path): |
304 | 285 | """ |
305 | 286 | Check that dotenv flags supersede command flags. |
306 | 287 | """ |
307 | 288 |
|
308 | | - result = invoke_sub( |
309 | | - ["--version", "--file", dotenv_path, "run", "printenv", "--version"] |
| 289 | + result = run_dotenv( |
| 290 | + ["--version", "--file", str(dotenv_path), "run", "printenv", "--version"], |
| 291 | + cwd=tmp_path, |
310 | 292 | ) |
311 | 293 |
|
312 | | - assert result.returncode == 0 |
| 294 | + check_process(result, exit_code=0) |
313 | 295 | assert result.stdout.strip().startswith("dotenv, version") |
0 commit comments