numpydantic/tests/test_interface/test_zarr.py

130 lines
3.6 KiB
Python
Raw Permalink Normal View History

import json
import numpy as np
2024-04-30 02:49:38 +00:00
import pytest
2024-04-30 02:49:38 +00:00
from numpydantic.interface import ZarrInterface
from numpydantic.interface.zarr import ZarrArrayPath
from numpydantic.testing.cases import ZarrCase, ZarrDirCase, ZarrNestedCase, ZarrZipCase
from numpydantic.testing.helpers import InterfaceCase
2024-04-30 02:49:38 +00:00
2024-09-23 20:28:38 +00:00
pytestmark = pytest.mark.zarr
2024-04-30 02:49:38 +00:00
@pytest.fixture(
params=[ZarrCase, ZarrZipCase, ZarrDirCase, ZarrNestedCase],
)
def zarr_case(request) -> InterfaceCase:
return request.param
2024-05-09 05:06:41 +00:00
@pytest.fixture(
params=[
None, # use the default store
"dir_array",
"zip_array",
"nested_dir_array",
],
ids=["MutableMapping", "DirectoryStore", "ZipStore", "NestedDirectoryStore"],
2024-04-30 02:49:38 +00:00
)
2024-05-09 05:06:41 +00:00
def store(request):
if isinstance(request.param, str):
return request.getfixturevalue(request.param)
else:
return request.param
2024-04-30 02:49:38 +00:00
def test_zarr_enabled():
assert ZarrInterface.enabled()
def test_zarr_check(interface_cases, tmp_output_dir_func):
2024-04-30 02:49:38 +00:00
"""
We should only use the zarr interface for zarr-like things
"""
array = interface_cases.make_array(path=tmp_output_dir_func)
if interface_cases.interface is ZarrInterface:
assert ZarrInterface.check(array)
2024-04-30 02:49:38 +00:00
else:
assert not ZarrInterface.check(array)
2024-04-30 02:49:38 +00:00
2024-09-23 20:28:38 +00:00
@pytest.mark.shape
def test_zarr_shape(shape_cases, zarr_case):
shape_cases.interface = zarr_case
shape_cases.validate_case()
2024-05-09 05:06:41 +00:00
2024-09-23 20:28:38 +00:00
@pytest.mark.dtype
def test_zarr_dtype(dtype_cases, zarr_case):
dtype_cases.interface = zarr_case
if dtype_cases.skip():
pytest.skip()
dtype_cases.validate_case()
@pytest.mark.parametrize("array", ["zarr_nested_array", "zarr_array"])
def test_zarr_from_tuple(array, model_blank, request):
"""Should be able to do the same validation logic from tuples as an input"""
array = request.getfixturevalue(array)
if isinstance(array, ZarrArrayPath):
2024-10-04 02:57:54 +00:00
_ = model_blank(array=(array.file, array.path))
else:
2024-10-04 02:57:54 +00:00
_ = model_blank(array=(array,))
def test_zarr_from_path(zarr_array, model_blank):
"""Should be able to just pass a path"""
2024-10-04 02:57:54 +00:00
_ = model_blank(array=zarr_array)
def test_zarr_array_path_from_iterable(zarr_array):
"""Construct a zarr array path from some iterable!!!"""
# from a single path
apath = ZarrArrayPath.from_iterable((zarr_array,))
assert apath.file == zarr_array
assert apath.path is None
inner_path = "/test/array"
apath = ZarrArrayPath.from_iterable((zarr_array, inner_path))
assert apath.file == zarr_array
assert apath.path == inner_path
@pytest.mark.serialization
@pytest.mark.parametrize("dump_array", [True, False])
@pytest.mark.parametrize("roundtrip", [True, False])
def test_zarr_to_json(zarr_case, model_blank, roundtrip, dump_array, tmp_path):
expected_fields = (
"Type",
"Data type",
"Shape",
"Chunk shape",
"Compressor",
"Store type",
"hexdigest",
)
lol_array = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=int)
array = zarr_case.make_array(array=lol_array, dtype=int, path=tmp_path)
instance = model_blank(array=array)
2024-09-22 01:26:25 +00:00
context = {"dump_array": dump_array}
as_json = json.loads(
instance.model_dump_json(round_trip=roundtrip, context=context)
)["array"]
if roundtrip:
if dump_array:
assert np.array_equal(as_json["value"], lol_array)
else:
if as_json.get("file", False):
assert "array" not in as_json
for field in expected_fields:
assert field in as_json["info"]
assert len(as_json["info"]["hexdigest"]) == 40
else:
assert np.array_equal(as_json, lol_array)