Skip to content

Commit 2e8e8cb

Browse files
committed
chore: make tests compact
1 parent b74b78d commit 2e8e8cb

1 file changed

Lines changed: 62 additions & 71 deletions

File tree

tests/test_chunk_grids.py

Lines changed: 62 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
import numpy as np
55
import pytest
66

7-
from tests.test_codecs.conftest import ExpectErr
7+
from tests.test_codecs.conftest import Expect, ExpectErr
88
from zarr.core.chunk_grids import (
99
_guess_regular_chunks,
10+
normalize_chunks_1d,
1011
normalize_chunks_nd,
1112
resolve_outer_and_inner_chunks,
1213
)
@@ -128,103 +129,93 @@ def test_chunk_layout_nested() -> None:
128129
assert top.inner.inner.inner is None
129130

130131

131-
def test_normalize_chunks_1d_errors() -> None:
132-
from zarr.core.chunk_grids import normalize_chunks_1d
133-
134-
with pytest.raises(ValueError, match="Chunk size must be positive"):
135-
normalize_chunks_1d(0, 100)
136-
with pytest.raises(ValueError, match="Chunk size must be positive"):
137-
normalize_chunks_1d(-2, 100)
138-
with pytest.raises(ValueError, match="must not be empty"):
139-
normalize_chunks_1d([], 100)
140-
with pytest.raises(ValueError, match="must be positive"):
141-
normalize_chunks_1d([10, -1, 10], 100)
142-
with pytest.raises(ValueError, match="do not sum to span"):
143-
normalize_chunks_1d([10, 20], 100)
144-
145-
146132
@pytest.mark.parametrize(
147133
"case",
148134
[
149-
# The motivating case: nested/RLE form for a single dim.
135+
ExpectErr(input=(0, 100), msg="Chunk size must be positive", exception_cls=ValueError),
136+
ExpectErr(input=(-2, 100), msg="Chunk size must be positive", exception_cls=ValueError),
137+
ExpectErr(input=([], 100), msg="must not be empty", exception_cls=ValueError),
138+
ExpectErr(input=([10, -1, 10], 100), msg="must be positive", exception_cls=ValueError),
139+
ExpectErr(input=([10, 20], 100), msg="do not sum to span", exception_cls=ValueError),
140+
# Nested/RLE form for a single dim is rejected with offending indices.
150141
ExpectErr(
151142
input=([[3, 3], 1], 7),
152143
msg="non-integer element(s) ([3, 3],) at indices (0,)",
153144
exception_cls=TypeError,
154145
),
155-
# Multiple non-int elements report all offending indices.
146+
# Multiple non-int elements: all offending indices reported.
156147
ExpectErr(
157148
input=([1, [2, 2], 1, [3]], 9),
158149
msg="non-integer element(s) ([2, 2], [3]) at indices (1, 3)",
159150
exception_cls=TypeError,
160151
),
161-
# Strings are also non-integers and should be reported the same way.
152+
# Strings are non-integers and should be reported the same way.
162153
ExpectErr(
163154
input=([2, "3", 5], 10),
164155
msg="non-integer element(s) ('3',) at indices (1,)",
165156
exception_cls=TypeError,
166157
),
167158
],
168-
ids=["rle-single-dim", "multiple-non-ints", "string-element"],
159+
ids=[
160+
"zero-uniform",
161+
"negative-uniform",
162+
"empty-list",
163+
"negative-element",
164+
"wrong-sum",
165+
"rle-single-dim",
166+
"multiple-non-ints",
167+
"string-element",
168+
],
169169
)
170-
def test_normalize_chunks_1d_rejects_non_int_elements(
171-
case: ExpectErr[tuple[list[Any], int]],
172-
) -> None:
173-
"""Reject nested/RLE-style chunk specs with a precise error pointing at offending indices."""
174-
from zarr.core.chunk_grids import normalize_chunks_1d
175-
170+
def test_normalize_chunks_1d_errors(case: ExpectErr[tuple[Any, int]]) -> None:
171+
"""Invalid 1D chunk specifications are rejected with informative error messages."""
176172
chunks, span = case.input
177173
with pytest.raises(case.exception_cls, match=re.escape(case.msg)):
178174
normalize_chunks_1d(chunks, span=span)
179175

180176

181-
def test_normalize_chunks_nd_rejects_rle_inner_dim() -> None:
182-
"""End-to-end: a per-dim RLE form like [[3, 3], 1] surfaces the precise error."""
183-
with pytest.raises(
184-
TypeError, match=re.escape("non-integer element(s) ([3, 3],) at indices (0,)")
185-
):
186-
normalize_chunks_nd([[6, 4], [[3, 3], 1]], (10, 10))
187-
188-
189-
def test_normalize_chunks_errors() -> None:
190-
with pytest.raises(ValueError, match="does not accept None"):
191-
normalize_chunks_nd(None, (100,))
192-
with pytest.raises(ValueError):
193-
normalize_chunks_nd("foo", (100,))
194-
with pytest.raises(ValueError, match="dimensions"):
195-
normalize_chunks_nd((100, 10), (100,))
196-
with pytest.raises(ValueError, match="dimensions"):
197-
normalize_chunks_nd((10,), (100, 100))
198-
177+
@pytest.mark.parametrize(
178+
"case",
179+
[
180+
ExpectErr(input=(None, (100,)), msg="does not accept None", exception_cls=ValueError),
181+
ExpectErr(input=("foo", (100,)), msg="dimensions", exception_cls=ValueError),
182+
ExpectErr(input=((100, 10), (100,)), msg="dimensions", exception_cls=ValueError),
183+
ExpectErr(input=((10,), (100, 100)), msg="dimensions", exception_cls=ValueError),
184+
# End-to-end: per-dim RLE surfaces through normalize_chunks_nd.
185+
ExpectErr(
186+
input=([[6, 4], [[3, 3], 1]], (10, 10)),
187+
msg="non-integer element(s) ([3, 3],) at indices (0,)",
188+
exception_cls=TypeError,
189+
),
190+
],
191+
ids=["none", "string", "too-many-dims", "too-few-dims", "rle-inner-dim"],
192+
)
193+
def test_normalize_chunks_nd_errors(case: ExpectErr[tuple[Any, tuple[int, ...]]]) -> None:
194+
"""Invalid N-D chunk specifications are rejected with informative error messages."""
195+
chunks, shape = case.input
196+
with pytest.raises(case.exception_cls, match=re.escape(case.msg)):
197+
normalize_chunks_nd(chunks, shape)
199198

200-
def test_normalize_chunks_1d_uniform_returns_int64_array() -> None:
201-
"""The uniform-chunks branch must return a 1D int64 array — this is the
202-
representation that enables O(1) construction via np.full."""
203-
from zarr.core.chunk_grids import normalize_chunks_1d
204199

205-
result = normalize_chunks_1d(1000, 100_000)
200+
@pytest.mark.parametrize(
201+
"case",
202+
[
203+
# uniform-chunks branch: one int → broadcast across span via np.full.
204+
Expect(input=(1000, 100_000), expected=[1000] * 100),
205+
# explicit-per-chunk branch.
206+
Expect(input=([10, 20, 30, 40], 100), expected=[10, 20, 30, 40]),
207+
# -1 sentinel branch: one chunk covering the full span.
208+
Expect(input=(-1, 100), expected=[100]),
209+
],
210+
ids=["uniform", "explicit-list", "full-span-sentinel"],
211+
)
212+
def test_normalize_chunks_1d_returns_int64_array(
213+
case: Expect[tuple[Any, int], list[int]],
214+
) -> None:
215+
"""Every branch of normalize_chunks_1d must produce a 1D int64 array."""
216+
chunks, span = case.input
217+
result = normalize_chunks_1d(chunks, span)
206218
assert isinstance(result, np.ndarray)
207219
assert result.dtype == np.int64
208220
assert result.ndim == 1
209-
assert result.shape == (100,)
210-
assert (result == 1000).all()
211-
212-
213-
def test_normalize_chunks_1d_explicit_list_returns_int64_array() -> None:
214-
"""The explicit-per-chunk branch must also produce an int64 array."""
215-
from zarr.core.chunk_grids import normalize_chunks_1d
216-
217-
result = normalize_chunks_1d([10, 20, 30, 40], 100)
218-
assert isinstance(result, np.ndarray)
219-
assert result.dtype == np.int64
220-
assert result.tolist() == [10, 20, 30, 40]
221-
222-
223-
def test_normalize_chunks_1d_full_span_returns_int64_array() -> None:
224-
"""The -1 sentinel branch must also produce an int64 array."""
225-
from zarr.core.chunk_grids import normalize_chunks_1d
226-
227-
result = normalize_chunks_1d(-1, 100)
228-
assert isinstance(result, np.ndarray)
229-
assert result.dtype == np.int64
230-
assert result.tolist() == [100]
221+
assert result.tolist() == case.expected

0 commit comments

Comments
 (0)