Skip to content

atomlib.testing

CallableT module-attribute

CallableT = TypeVar('CallableT', bound=Callable)

OUTPUT_PATH module-attribute

OUTPUT_PATH = parents[2] / 'tests/baseline_files'

INPUT_PATH module-attribute

INPUT_PATH = parents[2] / 'tests/input_files'

assert_files_equal

assert_files_equal(
    expected_path: Union[str, Path],
    actual_path: Union[str, Path],
)
Source code in atomlib/testing/__init__.py
def assert_files_equal(expected_path: t.Union[str, Path], actual_path: t.Union[str, Path]):
    with open(OUTPUT_PATH / expected_path, 'r') as f:
        expected = re.sub('\r\n', '\n', f.read())
    with open(actual_path, 'r') as f:
        actual = re.sub('\r\n', '\n', f.read())

    assert expected == actual

check_equals_file

check_equals_file(
    name: Union[str, Path], *, skip_lines: int = 0
) -> Callable[[Callable[..., Any]], Callable[..., None]]
Source code in atomlib/testing/__init__.py
def check_equals_file(name: t.Union[str, Path], *, skip_lines: int = 0) -> t.Callable[[t.Callable[..., t.Any]], t.Callable[..., None]]:
    def decorator(f: t.Callable[..., str]):
        @pytest.mark.expected_filename(name)
        def wrapper(expected_contents_text: str, *args, **kwargs):  # type: ignore
            buf = StringIO()
            f(buf, *args, **kwargs)
            if skip_lines > 0:
                lhs = "".join(buf.getvalue().splitlines(True)[skip_lines:])
                rhs = "".join(expected_contents_text.splitlines(True)[skip_lines:])
                assert lhs == rhs
            else:
                assert buf.getvalue() == expected_contents_text

        return _wrap_pytest(wrapper, f, lambda params: [inspect.Parameter('expected_contents_text', inspect.Parameter.POSITIONAL_OR_KEYWORD), *params[1:]])

    return decorator

check_equals_binary_file

check_equals_binary_file(
    name: Union[str, Path]
) -> Callable[[Callable[..., Any]], Callable[..., None]]
Source code in atomlib/testing/__init__.py
def check_equals_binary_file(name: t.Union[str, Path]) -> t.Callable[[t.Callable[..., t.Any]], t.Callable[..., None]]:
    def decorator(f: t.Callable[..., str]):
        @pytest.mark.expected_filename(name)
        def wrapper(expected_contents_binary: bytes, *args, **kwargs):  # type: ignore
            buf = BytesIO()
            f(buf, *args, **kwargs)
            assert buf.getvalue() == expected_contents_binary

        return _wrap_pytest(wrapper, f, lambda params: [inspect.Parameter('expected_contents_binary', inspect.Parameter.POSITIONAL_OR_KEYWORD), *params[1:]])

    return decorator

assert_structure_equal

assert_structure_equal(
    expected_path: Union[str, Path],
    actual: Union[str, Path, AtomsIOMixin],
)
Source code in atomlib/testing/__init__.py
def assert_structure_equal(expected_path: t.Union[str, Path], actual: t.Union[str, Path, AtomsIOMixin]):
    from atomlib.io import read

    expected = read(OUTPUT_PATH / expected_path)

    try:
        if isinstance(actual, (str, Path)):
            actual = t.cast('AtomsIOMixin', read(actual))
    except Exception:
        print("Failed to load structure under test.")
        raise

    try:
        if hasattr(actual, 'assert_equal'):
            actual.assert_equal(expected)  # type: ignore
        else:
            assert actual == expected
    except AssertionError:
        try:
            actual_path = Path(expected_path).with_stem(Path(expected_path).stem + '_actual').name
            print(f"Saving result structure to '{actual_path}'")
            actual.write(OUTPUT_PATH / actual_path)
        except Exception:
            print("Failed to save result structure.")
        raise

check_equals_structure

check_equals_structure(
    name: Union[str, Path]
) -> Callable[
    [Callable[..., AtomsIOMixin]], Callable[..., None]
]

Test that the wrapped function returns the same structure as contained in name.

Source code in atomlib/testing/__init__.py
def check_equals_structure(name: t.Union[str, Path]) -> t.Callable[[t.Callable[..., AtomsIOMixin]], t.Callable[..., None]]:
    """Test that the wrapped function returns the same structure as contained in `name`."""
    def decorator(f: t.Callable[..., 'AtomsIOMixin']):
        @pytest.mark.expected_filename(name)
        def wrapper(expected_structure: 'HasAtoms', *args, **kwargs):  # type: ignore
            result = f(*args, **kwargs)
            try:
                if hasattr(result, 'assert_equal'):
                    result.assert_equal(expected_structure)  # type: ignore
                else:
                    assert result == expected_structure
            except AssertionError:
                try:
                    actual_path = Path(name).with_stem(Path(name).stem + '_actual').name
                    print(f"Saving result structure to '{actual_path}'")
                    result.write(OUTPUT_PATH / actual_path)
                except Exception:
                    print("Failed to save result structure.")
                raise

        return _wrap_pytest(wrapper, f, lambda params: [inspect.Parameter('expected_structure', inspect.Parameter.POSITIONAL_OR_KEYWORD), *params])

    return decorator

check_parse_structure

check_parse_structure(
    name: Union[str, Path]
) -> Callable[
    [Callable[..., HasAtoms]], Callable[..., None]
]

Test that name parses to the same structure as given in the function body.

Source code in atomlib/testing/__init__.py
def check_parse_structure(name: t.Union[str, Path]) -> t.Callable[[t.Callable[..., HasAtoms]], t.Callable[..., None]]:
    """Test that `name` parses to the same structure as given in the function body."""
    def decorator(f: t.Callable[..., 'HasAtoms']):
        def wrapper(*args, **kwargs):  # type: ignore
            expected = f(*args, **kwargs)

            from atomlib.io import read
            result = read(INPUT_PATH / name)

            if hasattr(result, 'assert_equal'):
                result.assert_equal(expected)  # type: ignore
            else:
                assert result == expected

        return _wrap_pytest(wrapper, f)
    return decorator

check_figure_draw

check_figure_draw(
    name: Union[str, Path, Sequence[Union[str, Path]]],
    savefig_kwarg: Optional[Dict[str, Any]] = None,
) -> Callable[[Callable[..., None]], Callable[..., None]]

Test that the wrapped function draws an identical figure to name in baseline_images.

Source code in atomlib/testing/__init__.py
def check_figure_draw(name: t.Union[str, Path, t.Sequence[t.Union[str, Path]]],
                      savefig_kwarg: t.Optional[t.Dict[str, t.Any]] = None) -> t.Callable[[t.Callable[..., None]], t.Callable[..., None]]:
    """Test that the wrapped function draws an identical figure to `name` in `baseline_images`."""

    if isinstance(name, (str, Path)):
        names = (str(name),)
    else:
        names = tuple(map(str, name))

    def decorator(f: t.Callable[..., None]):
        from matplotlib.testing.decorators import image_comparison
        return image_comparison(list(names), savefig_kwarg=savefig_kwarg)(f)

    return decorator