Skip to content

Commit

Permalink
update tests
Browse files Browse the repository at this point in the history
  • Loading branch information
andersy005 committed Sep 20, 2023
1 parent 4708ca2 commit ff1b4de
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 81 deletions.
12 changes: 12 additions & 0 deletions xarray/namedarray/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,18 @@ def chunksizes(
else:
return {}

@property
def sizes(self: typing.Any) -> dict[Hashable, int]:
"""Ordered mapping from dimension names to lengths.
Immutable.
See Also
--------
Dataset.sizes
"""
return dict(zip(self.dims, self.shape))

def _replace(
self: T_NamedArray, dims=_default, data=_default, attrs=_default
) -> T_NamedArray:
Expand Down
183 changes: 102 additions & 81 deletions xarray/tests/test_namedarray.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from abc import ABC, abstractclassmethod

import numpy as np
import pytest

Expand All @@ -6,96 +8,115 @@


@pytest.mark.parametrize(
"dims, data, attrs", [("x", [1, 2, 3], {"key": "value"}), ("y", [4, 5], None)]
)
def test_named_array_initialization(dims: str, data: T_DuckArray, attrs: dict) -> None:
named_array = NamedArray(dims, data, attrs)
assert named_array.dims == (dims,)
assert np.array_equal(named_array.data, data)
assert named_array.attrs == (attrs or {})


@pytest.mark.parametrize(
"dims, data, expected_ndim, expected_size, expected_dtype, expected_shape, expected_len",
"input_data, expected_output",
[
("x", [1, 2, 3], 1, 3, np.dtype(int), (3,), 3),
(["x", "y"], [[1, 2], [3, 4]], 2, 4, np.dtype(int), (2, 2), 2),
([1, 2, 3], np.array([1, 2, 3])),
(np.array([4, 5, 6]), np.array([4, 5, 6])),
],
)
def test_named_array_properties(
dims: str,
data: T_DuckArray,
expected_ndim: int,
expected_size: int,
expected_dtype: np.dtype,
expected_shape: tuple,
expected_len: int,
def test_as_compatible_data(
input_data: T_DuckArray, expected_output: T_DuckArray
) -> None:
named_array = NamedArray(dims, data)
expected_nbytes = expected_size * np.array(data).dtype.itemsize
assert named_array.ndim == expected_ndim
assert named_array.size == expected_size
assert named_array.dtype == expected_dtype
assert named_array.shape == expected_shape
assert named_array.nbytes == expected_nbytes
assert len(named_array) == expected_len
output = as_compatible_data(input_data)
assert np.array_equal(output, expected_output)


@pytest.mark.parametrize(
"initial_dims, initial_data, new_dims",
[
("x", [1, 2, 3], "y"),
(["x", "y"], [[1, 2], [3, 4]], ["a", "b"]),
],
)
def test_named_array_dims_setter(
initial_dims: str, initial_data: T_DuckArray, new_dims: str
) -> None:
named_array = NamedArray(initial_dims, initial_data)
named_array.dims = new_dims
assert named_array.dims == tuple(new_dims)
class NamedArraySubclassObjects(ABC):
@abstractclassmethod
def cls(self, *args, **kwargs) -> NamedArray:
raise NotImplementedError

def test_properties(self):
data = 0.5 * np.arange(10).reshape(2, 5)
named_array = self.cls(["x", "y"], data, {"key": "value"})
assert named_array.dims == ("x", "y")
assert np.array_equal(named_array.data, data)
assert named_array.attrs == {"key": "value"}
assert named_array.ndim == 2
assert named_array.sizes == {"x": 2, "y": 5}
assert named_array.size == 10
assert named_array.nbytes == 80
assert len(named_array) == 2

@pytest.mark.parametrize(
"initial_dims, initial_data, new_attrs",
[
("x", [1, 2, 3], {"new_key": "new_value"}),
(["x", "y"], [[1, 2], [3, 4]], {"a": 1, "b": 2}),
("x", [1, 2, 3], {}),
],
)
def test_named_array_attrs_setter(
initial_dims: str, initial_data: T_DuckArray, new_attrs: dict
) -> None:
named_array = NamedArray(initial_dims, initial_data)
named_array.attrs = new_attrs
assert named_array.attrs == new_attrs
def test_attrs(self):
named_array = self.cls(["x", "y"], np.arange(10).reshape(2, 5))
assert named_array.attrs == {}
named_array.attrs["key"] = "value"
assert named_array.attrs == {"key": "value"}
named_array.attrs = {"key": "value2"}
assert named_array.attrs == {"key": "value2"}


@pytest.mark.parametrize(
"initial_dims, initial_data, new_data",
[
("x", [1, 2, 3], [4, 5, 6]),
(["x", "y"], [[1, 2], [3, 4]], [[4, 5], [6, 7]]),
],
)
def test_named_array_data_setter(
initial_dims: str, initial_data: T_DuckArray, new_data: T_DuckArray
) -> None:
named_array = NamedArray(initial_dims, initial_data)
named_array.data = new_data
assert np.array_equal(named_array.data, new_data)
class TestNamedArray(NamedArraySubclassObjects):
def cls(self, *args, **kwargs) -> NamedArray:
return NamedArray(*args, **kwargs)

@pytest.fixture(autouse=True)
def setup(self):
self.inputs = np.random.random((3, 4, 5)).astype(np.float32)

@pytest.mark.parametrize(
"input_data, expected_output",
[
([1, 2, 3], np.array([1, 2, 3])),
(np.array([4, 5, 6]), np.array([4, 5, 6])),
],
)
def test_as_compatible_data(
input_data: T_DuckArray, expected_output: T_DuckArray
) -> None:
output = as_compatible_data(input_data)
assert np.array_equal(output, expected_output)
def test_data(self):
named_array = NamedArray(["x", "y", "z"], self.inputs)
assert np.array_equal(named_array.data, self.inputs)
with pytest.raises(ValueError):
named_array.data = np.random.random((3, 4)).astype(np.float64)

@pytest.mark.parametrize(
"data, dtype",
[
("foo", np.dtype("U3")),
(np.bytes_("foo"), np.dtype("S3")),
],
)
def test_0d_string(self, data, dtype):
named_array = NamedArray([], data)
assert named_array.data == data
assert named_array.dims == ()
assert named_array.sizes == {}
assert named_array.attrs == {}
assert named_array.ndim == 0
assert named_array.size == 1
assert named_array.dtype == dtype

def test_0d_datetime(self):
named_array = NamedArray([], np.datetime64("2000-01-01"))
assert named_array.dtype == np.dtype("datetime64[D]")

@pytest.mark.parametrize(
"timedelta, expected_dtype",
[
(np.timedelta64(1, "D"), np.dtype("timedelta64[D]")),
(np.timedelta64(1, "s"), np.dtype("timedelta64[s]")),
(np.timedelta64(1, "m"), np.dtype("timedelta64[m]")),
(np.timedelta64(1, "h"), np.dtype("timedelta64[h]")),
(np.timedelta64(1, "us"), np.dtype("timedelta64[us]")),
(np.timedelta64(1, "ns"), np.dtype("timedelta64[ns]")),
(np.timedelta64(1, "ps"), np.dtype("timedelta64[ps]")),
(np.timedelta64(1, "fs"), np.dtype("timedelta64[fs]")),
(np.timedelta64(1, "as"), np.dtype("timedelta64[as]")),
],
)
def test_0d_timedelta(self, timedelta, expected_dtype):
named_array = NamedArray([], timedelta)
assert named_array.dtype == expected_dtype
assert named_array.data == timedelta

@pytest.mark.parametrize(
"dims, data_shape, new_dims, raises",
[
(["x", "y", "z"], (2, 3, 4), ["a", "b", "c"], False),
(["x", "y", "z"], (2, 3, 4), ["a", "b"], True),
(["x", "y", "z"], (2, 4, 5), ["a", "b", "c", "d"], True),
([], [], (), False),
([], [], ("x",), True),
],
)
def test_dims_setter(self, dims, data_shape, new_dims, raises):
named_array = NamedArray(dims, np.random.random(data_shape))
assert named_array.dims == tuple(dims)
if raises:
with pytest.raises(ValueError):
named_array.dims = new_dims
else:
named_array.dims = new_dims
assert named_array.dims == tuple(new_dims)

0 comments on commit ff1b4de

Please sign in to comment.