1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
|
from argparse import Namespace
from pathlib import Path
import pytest
from pytest_mock import MockerFixture
from pytest_watcher.config import (
CLI_FIELDS,
CONFIG_SECTION_NAME,
find_config,
parse_config,
)
from pytest_watcher.constants import DEFAULT_DELAY
from pytest_watcher.watcher import Config
@pytest.fixture(autouse=True)
def _patch_cwd(mocker: MockerFixture, tmp_path: Path):
mock = mocker.patch("pytest_watcher.config.Path.cwd")
mock.return_value = tmp_path
@pytest.fixture
def empty_namespace(tmp_path: Path):
return Namespace(
path=tmp_path,
now=None,
clear=None,
delay=None,
runner=None,
patterns=None,
ignore_patterns=None,
)
@pytest.fixture
def config(empty_namespace: Namespace) -> Config:
return Config.create(empty_namespace)
@pytest.fixture
def pyproject_toml(pyproject_toml_path: Path) -> Path:
pyproject_toml_path.write_text(
f"[tool.{CONFIG_SECTION_NAME}]\n"
"now = true\n"
"delay = 999\n"
"runner = 'tox'\n"
"runner_args = ['--lf', '--nf']\n"
"patterns = ['*.py', '.env']\n"
"ignore_patterns = ['ignore.py']\n"
)
return pyproject_toml_path
@pytest.fixture
def namespace(tmp_path: Path) -> Namespace:
return Namespace(
path=tmp_path,
now=True,
clear=True,
delay=20,
runner="tox",
patterns=["*.py", ".env"],
ignore_patterns=["main.py"],
)
def test_default_values(config: Config):
assert config.now is False
assert config.delay == DEFAULT_DELAY
assert config.runner == "pytest"
assert config.runner_args == []
assert config.patterns == []
assert config.ignore_patterns == []
def test_cli_args(namespace: Namespace, tmp_path: Path):
runner_args = ["--lf", "--nf"]
config = Config.create(namespace=namespace, extra_args=runner_args)
for f in CLI_FIELDS:
assert getattr(config, f) == getattr(namespace, f)
assert config.runner_args == runner_args
def test_cli_args_none_values_are_skipped(tmp_path: Path):
namespace = Namespace(
path=tmp_path,
now=None,
clear=None,
delay=None,
runner=None,
patterns=None,
ignore_patterns=None,
)
config = Config.create(namespace=namespace, extra_args=None)
for f in CLI_FIELDS:
assert getattr(config, f) is not None
assert config.runner_args == []
def test_pyproject_toml(pyproject_toml: Path, config: Config):
assert config.now is True
assert config.delay == 999
assert config.runner == "tox"
assert config.runner_args == ["--lf", "--nf"]
assert config.patterns == ["*.py", ".env"]
assert config.ignore_patterns == ["ignore.py"]
def test_cli_args_preferred_over_pyproject_toml(
pyproject_toml: Path, namespace: Namespace
):
extra_args = ["--cli", "--args"]
config = Config.create(namespace, extra_args=extra_args)
for f in CLI_FIELDS:
assert getattr(config, f) == getattr(namespace, f)
assert config.runner_args == extra_args
@pytest.mark.parametrize(
("work_dir"),
[
Path(""),
Path("test/"),
Path("test/nested/dir/"),
],
)
def test_find_config(
tmp_path: Path, pyproject_toml_path: Path, work_dir: Path, mocker: MockerFixture
):
work_dir = tmp_path.joinpath(work_dir)
work_dir.mkdir(parents=True, exist_ok=True)
got = find_config(tmp_path)
assert got == pyproject_toml_path, "Config file not found"
def test_parse_config_no_section(pyproject_toml_path: Path):
pyproject_toml_path.write_text("[tool.another_section]\ndelay = 2\nrunner = 'tox'\n")
got = parse_config(pyproject_toml_path)
assert got == {}
def test_parse_config_parse_error(pyproject_toml_path: Path):
pyproject_toml_path.write_text(
f"[tool.{CONFIG_SECTION_NAME}]\ndelay = 2\nrunner = invalid\n"
)
with pytest.raises(SystemExit, match="Error parsing pyproject.toml"):
parse_config(pyproject_toml_path)
def test_parse_config_unrecognized_option(pyproject_toml_path: Path):
pyproject_toml_path.write_text(f"[tool.{CONFIG_SECTION_NAME}]\nfoo = 'bar'\n")
with pytest.raises(SystemExit, match="Unrecognized option"):
parse_config(pyproject_toml_path)
|