diff options
Diffstat (limited to 'test/conftest.py')
-rw-r--r-- | test/conftest.py | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/test/conftest.py b/test/conftest.py new file mode 100644 index 0000000..f31967d --- /dev/null +++ b/test/conftest.py @@ -0,0 +1,106 @@ +"""PyTest fixtures for testing the project.""" +from __future__ import annotations + +import os +import shutil +import subprocess +from contextlib import contextmanager +from pathlib import Path +from typing import TYPE_CHECKING, Iterator + +import pytest + +# pylint: disable=wildcard-import,unused-wildcard-import +from ansiblelint.testing.fixtures import * # noqa: F403 +from ansiblelint.yaml_utils import FormattedYAML + +if TYPE_CHECKING: + from typing import List # pylint: disable=ungrouped-imports + + from _pytest import nodes + from _pytest.config import Config + from _pytest.config.argparsing import Parser + + +@contextmanager +def cwd(path: str) -> Iterator[None]: + """Context manager for chdir.""" + old_pwd = os.getcwd() + os.chdir(path) + try: + yield + finally: + os.chdir(old_pwd) + + +def pytest_addoption(parser: Parser) -> None: + """Add --regenerate-formatting-fixtures option to pytest.""" + parser.addoption( + "--regenerate-formatting-fixtures", + action="store_true", + default=False, + help="Regenerate formatting fixtures with prettier and internal formatter", + ) + + +def pytest_collection_modifyitems(items: list[nodes.Item], config: Config) -> None: + """Skip tests based on --regenerate-formatting-fixtures option.""" + do_regenerate = config.getoption("--regenerate-formatting-fixtures") + skip_other = pytest.mark.skip( + reason="not a formatting_fixture test and " + "--regenerate-formatting-fixtures was specified" + ) + skip_formatting_fixture = pytest.mark.skip( + reason="specify --regenerate-formatting-fixtures to " + "only run formatting_fixtures test" + ) + for item in items: + if do_regenerate and "formatting_fixtures" not in item.keywords: + item.add_marker(skip_other) + elif not do_regenerate and "formatting_fixtures" in item.keywords: + item.add_marker(skip_formatting_fixture) + + +def pytest_configure(config: Config) -> None: + """Register custom markers.""" + if config.getoption("--regenerate-formatting-fixtures"): + regenerate_formatting_fixtures() + + +def regenerate_formatting_fixtures() -> None: + """Re-generate formatting fixtures with prettier and internal formatter. + + Pass ``--regenerate-formatting-fixtures`` to run this and skip all other tests. + This is a "test" because once fixtures are regenerated, + we run prettier again to make sure it does not change files formatted + with our internal formatting code. + """ + subprocess.check_call(["which", "prettier"]) + + yaml = FormattedYAML() + + fixtures_dir = Path("test/fixtures/") + fixtures_dir_before = fixtures_dir / "formatting-before" + fixtures_dir_prettier = fixtures_dir / "formatting-prettier" + fixtures_dir_after = fixtures_dir / "formatting-after" + + fixtures_dir_prettier.mkdir(exist_ok=True) + fixtures_dir_after.mkdir(exist_ok=True) + + # Copying before fixtures... + for fixture in fixtures_dir_before.glob("fmt-[0-9].yml"): + shutil.copy(str(fixture), str(fixtures_dir_prettier / fixture.name)) + shutil.copy(str(fixture), str(fixtures_dir_after / fixture.name)) + + # Writing fixtures with prettier... + subprocess.check_call(["prettier", "-w", str(fixtures_dir_prettier)]) + # NB: pre-commit end-of-file-fixer can also modify files. + + # Writing fixtures with ansiblelint.yaml_utils.FormattedYAML() + for fixture in fixtures_dir_after.glob("fmt-[0-9].yml"): + data = yaml.loads(fixture.read_text()) + output = yaml.dumps(data) + fixture.write_text(output) + + # Make sure prettier won't make changes in {fixtures_dir_after} + subprocess.check_call(["prettier", "-c", str(fixtures_dir_after)]) |