import os from pathlib import Path from typing import Optional import pytest import sh import dotenv from dotenv.cli import cli as dotenv_cli from dotenv.version import __version__ @pytest.mark.parametrize( "output_format,content,expected", ( (None, "x='a b c'", """x=a b c\n"""), ("simple", "x='a b c'", """x=a b c\n"""), ("simple", """x='"a b c"'""", """x="a b c"\n"""), ("simple", '''x="'a b c'"''', """x='a b c'\n"""), ("json", "x='a b c'", """{\n "x": "a b c"\n}\n"""), ("shell", "x='a b c'", "x='a b c'\n"), ("shell", """x='"a b c"'""", """x='"a b c"'\n"""), ("shell", '''x="'a b c'"''', """x=''"'"'a b c'"'"''\n"""), ("shell", "x='a\nb\nc'", "x='a\nb\nc'\n"), ("export", "x='a b c'", """export x='a b c'\n"""), ), ) def test_list( cli, dotenv_path, output_format: Optional[str], content: str, expected: str ): dotenv_path.write_text(content + "\n") args = ["--file", dotenv_path, "list"] if format is not None: args.extend(["--format", output_format]) result = cli.invoke(dotenv_cli, args) assert (result.exit_code, result.output) == (0, expected) def test_list_non_existent_file(cli): result = cli.invoke(dotenv_cli, ["--file", "nx_file", "list"]) assert result.exit_code == 2, result.output assert "Error opening env file" in result.output def test_list_not_a_file(cli): result = cli.invoke(dotenv_cli, ["--file", ".", "list"]) assert result.exit_code == 2, result.output assert "Error opening env file" in result.output def test_list_no_file(cli): result = cli.invoke(dotenv.cli.list_values, []) assert (result.exit_code, result.output) == (1, "") def test_get_existing_value(cli, dotenv_path): dotenv_path.write_text("a=b") result = cli.invoke(dotenv_cli, ["--file", dotenv_path, "get", "a"]) assert (result.exit_code, result.output) == (0, "b\n") def test_get_non_existent_value(cli, dotenv_path): result = cli.invoke(dotenv_cli, ["--file", dotenv_path, "get", "a"]) assert (result.exit_code, result.output) == (1, "") def test_get_non_existent_file(cli): result = cli.invoke(dotenv_cli, ["--file", "nx_file", "get", "a"]) assert result.exit_code == 2 assert "Error opening env file" in result.output def test_get_not_a_file(cli): result = cli.invoke(dotenv_cli, ["--file", ".", "get", "a"]) assert result.exit_code == 2 assert "Error opening env file" in result.output def test_unset_existing_value(cli, dotenv_path): dotenv_path.write_text("a=b") result = cli.invoke(dotenv_cli, ["--file", dotenv_path, "unset", "a"]) assert (result.exit_code, result.output) == (0, "Successfully removed a\n") assert dotenv_path.read_text() == "" def test_unset_non_existent_value(cli, dotenv_path): result = cli.invoke(dotenv_cli, ["--file", dotenv_path, "unset", "a"]) assert (result.exit_code, result.output) == (1, "") assert dotenv_path.read_text() == "" @pytest.mark.parametrize( "quote_mode,variable,value,expected", ( ("always", "a", "x", "a='x'\n"), ("never", "a", "x", "a=x\n"), ("auto", "a", "x", "a=x\n"), ("auto", "a", "x y", "a='x y'\n"), ("auto", "a", "$", "a='$'\n"), ), ) def test_set_quote_options(cli, dotenv_path, quote_mode, variable, value, expected): result = cli.invoke( dotenv_cli, [ "--file", dotenv_path, "--export", "false", "--quote", quote_mode, "set", variable, value, ], ) assert (result.exit_code, result.output) == (0, "{}={}\n".format(variable, value)) assert dotenv_path.read_text() == expected @pytest.mark.parametrize( "dotenv_path,export_mode,variable,value,expected", ( (Path(".nx_file"), "true", "a", "x", "export a='x'\n"), (Path(".nx_file"), "false", "a", "x", "a='x'\n"), ), ) def test_set_export(cli, dotenv_path, export_mode, variable, value, expected): result = cli.invoke( dotenv_cli, [ "--file", dotenv_path, "--quote", "always", "--export", export_mode, "set", variable, value, ], ) assert (result.exit_code, result.output) == (0, "{}={}\n".format(variable, value)) assert dotenv_path.read_text() == expected def test_set_non_existent_file(cli): result = cli.invoke(dotenv.cli.set_value, ["a", "b"]) assert (result.exit_code, result.output) == (1, "") def test_set_no_file(cli): result = cli.invoke(dotenv_cli, ["--file", "nx_file", "set"]) assert result.exit_code == 2 assert "Missing argument" in result.output def test_get_default_path(tmp_path): with sh.pushd(tmp_path): (tmp_path / ".env").write_text("a=b") result = sh.dotenv("get", "a") assert result == "b\n" def test_run(tmp_path): with sh.pushd(tmp_path): (tmp_path / ".env").write_text("a=b") result = sh.dotenv("run", "printenv", "a") assert result == "b\n" def test_run_with_existing_variable(tmp_path): with sh.pushd(tmp_path): (tmp_path / ".env").write_text("a=b") env = dict(os.environ) env.update({"LANG": "en_US.UTF-8", "a": "c"}) result = sh.dotenv("run", "printenv", "a", _env=env) assert result == "b\n" def test_run_with_existing_variable_not_overridden(tmp_path): with sh.pushd(tmp_path): (tmp_path / ".env").write_text("a=b") env = dict(os.environ) env.update({"LANG": "en_US.UTF-8", "a": "c"}) result = sh.dotenv("run", "--no-override", "printenv", "a", _env=env) assert result == "c\n" def test_run_with_none_value(tmp_path): with sh.pushd(tmp_path): (tmp_path / ".env").write_text("a=b\nc") result = sh.dotenv("run", "printenv", "a") assert result == "b\n" def test_run_with_other_env(dotenv_path): dotenv_path.write_text("a=b") result = sh.dotenv("--file", dotenv_path, "run", "printenv", "a") assert result == "b\n" def test_run_without_cmd(cli): result = cli.invoke(dotenv_cli, ["run"]) assert result.exit_code == 2 assert "Invalid value for '-f'" in result.output def test_run_with_invalid_cmd(cli): result = cli.invoke(dotenv_cli, ["run", "i_do_not_exist"]) assert result.exit_code == 2 assert "Invalid value for '-f'" in result.output def test_run_with_version(cli): result = cli.invoke(dotenv_cli, ["--version"]) assert result.exit_code == 0 assert result.output.strip().endswith(__version__)