Source code for project_config.tests.pytest_plugin.helpers

"""Pytest plugin helpers."""

from __future__ import annotations

import os
import pathlib
import types
import typing as t

import pytest

from project_config.compat import TypeAlias
from project_config.tree import Tree


FileType: TypeAlias = t.Optional[t.Union[str, bool]]
FilesType: TypeAlias = t.Union[
    t.List[t.Tuple[str, FileType]],
    t.Dict[str, FileType],
]
RootdirType: TypeAlias = t.Union[str, pathlib.Path]


[docs]def create_files( # noqa: D103 files: FilesType, rootdir: RootdirType, ) -> None: if isinstance(rootdir, pathlib.Path): rootdir = str(rootdir) _files = files.items() if isinstance(files, dict) else files for fpath, content in _files: if content is False: continue full_path = os.path.join(rootdir, fpath) if content is None: os.mkdir(full_path) else: # same name as an existent directory, means that `files` has been # passed as a list of tuples content = t.cast(str, content) # ensure parent path directory exists parent_fpath, ext = os.path.splitext(full_path) if not ext: parent_fpath = os.path.abspath(os.path.dirname(parent_fpath)) if parent_fpath: os.makedirs(parent_fpath, exist_ok=True) if os.path.isdir(full_path): continue try: with open(full_path, "w", encoding="utf-8") as f: f.write(content) except OSError: # globs raising here in Windows continue
[docs]def create_tree( # noqa: D103 files: FilesType, rootdir: RootdirType, cache_files: bool = False, ) -> Tree: create_files(files, rootdir) tree = Tree(str(rootdir)) if cache_files: _files = ( list(files) if isinstance(files, dict) else [f[0] for f in files] ) tree.cache_files(_files) return tree
[docs]def assert_expected_files( # noqa: D103 expected_files: FilesType, rootdir: RootdirType, ) -> None: if isinstance(rootdir, pathlib.Path): rootdir = str(rootdir) _expected_files = ( expected_files.items() if isinstance(expected_files, dict) else expected_files ) for fpath, content in _expected_files: full_path = os.path.join(rootdir, fpath) if content is False: assert not os.path.exists(full_path) else: assert os.path.exists(full_path) if content is not None: try: with open(full_path, encoding="utf-8") as f: assert f.read() == content except IsADirectoryError: continue except PermissionError: pytest.skip() continue except OSError: continue
[docs]def get_reporter_class_from_module( # noqa: D103 reporter_module: types.ModuleType, color: bool, ) -> type: for object_name in dir(reporter_module): if object_name.startswith(("_", "Base")): continue if (color and "ColorReporter" in object_name) or ( not color and "Reporter" in object_name and "ColorReporter" not in object_name ): return getattr(reporter_module, object_name) # type: ignore raise ValueError( f"No{' color' if color else ''} reporter class found in" f" module '{reporter_module.__name__}'", )
__all__ = ( "assert_expected_files", "create_files", "create_tree", "get_reporter_class_from_module", )