numpydantic/tests/test_interface/conftest.py
2024-10-18 20:19:22 -07:00

154 lines
3.9 KiB
Python

import pytest
from numpydantic.testing.cases import (
ALL_CASES,
ALL_CASES_PASSING,
DTYPE_AND_INTERFACE_CASES_PASSING,
)
from numpydantic.testing.helpers import InterfaceCase, ValidationCase, merge_cases
from numpydantic.testing.interfaces import (
DaskCase,
HDF5Case,
NumpyCase,
VideoCase,
ZarrCase,
ZarrDirCase,
ZarrNestedCase,
)
@pytest.fixture(
scope="function",
params=[
pytest.param(
NumpyCase,
marks=pytest.mark.numpy,
id="numpy",
),
pytest.param(
HDF5Case,
marks=pytest.mark.hdf5,
id="h5-array-path",
),
pytest.param(
DaskCase,
marks=pytest.mark.dask,
id="dask",
),
pytest.param(
ZarrCase,
marks=pytest.mark.zarr,
id="zarr-memory",
),
pytest.param(
ZarrNestedCase,
marks=pytest.mark.zarr,
id="zarr-nested",
),
pytest.param(
ZarrDirCase,
marks=pytest.mark.zarr,
id="zarr-dir",
),
pytest.param(VideoCase, marks=pytest.mark.video, id="video"),
],
)
def interface_cases(request) -> InterfaceCase:
"""
Fixture for combinatoric tests across all interface cases
"""
return request.param
@pytest.fixture(
params=(
pytest.param(p, id=p.id, marks=getattr(pytest.mark, p.interface.interface.name))
for p in ALL_CASES
)
)
def all_cases(interface_cases, request) -> ValidationCase:
"""
Combinatoric testing for all dtype, shape, and interface cases.
This is a very expensive fixture! Only use it for core functionality
that we want to be sure is *very true* in every circumstance,
INCLUDING invalid combinations of annotations and arrays.
Typically, that means only use this in `test_interfaces.py`
"""
case = merge_cases(request.param, ValidationCase(interface=interface_cases))
if case.skip():
pytest.skip()
return case
@pytest.fixture(
params=(
pytest.param(p, id=p.id, marks=getattr(pytest.mark, p.interface.interface.name))
for p in ALL_CASES_PASSING
)
)
def all_passing_cases(request) -> ValidationCase:
"""
Combinatoric testing for all dtype, shape, and interface cases,
but only the combinations that we expect to pass.
This is a very expensive fixture! Only use it for core functionality
that we want to be sure is *very true* in every circumstance.
Typically, that means only use this in `test_interfaces.py`
"""
if "subclass" in request.param.id.lower():
pytest.xfail()
return request.param
@pytest.fixture()
def all_cases_instance(all_cases, tmp_output_dir_func):
"""
all_cases but with an instantiated model
Args:
all_cases:
Returns:
"""
array = all_cases.array(path=tmp_output_dir_func)
instance = all_cases.model(array=array)
return instance
@pytest.fixture()
def all_passing_cases_instance(all_passing_cases, tmp_output_dir_func):
"""
all_cases but with an instantiated model
Args:
all_cases:
Returns:
"""
array = all_passing_cases.array(path=tmp_output_dir_func)
instance = all_passing_cases.model(array=array)
return instance
@pytest.fixture(
params=(
pytest.param(p, id=p.id, marks=getattr(pytest.mark, p.interface.interface.name))
for p in DTYPE_AND_INTERFACE_CASES_PASSING
)
)
def dtype_by_interface(request):
"""
Tests for all dtypes by all interfaces
"""
if "subclass" in request.param.id.lower():
pytest.xfail()
return request.param
@pytest.fixture()
def dtype_by_interface_instance(dtype_by_interface, tmp_output_dir_func):
array = dtype_by_interface.array(path=tmp_output_dir_func)
instance = dtype_by_interface.model(array=array)
return instance