Skip to content

Commit 7fe4cb5

Browse files
wip
1 parent c40ea21 commit 7fe4cb5

3 files changed

Lines changed: 122 additions & 61 deletions

File tree

src/plaid/utils/json_codec.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,4 +176,3 @@ def _decode_array(value: dict[str, Any]) -> np.ndarray:
176176

177177
raw = base64.b64decode(value["data"])
178178
return np.frombuffer(raw, dtype=dtype).reshape(shape).copy()
179-
</content>

tests/utils/test_cgns_json.py

Lines changed: 0 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,8 @@
77

88
from plaid.utils.cgns_helper import compare_cgns_trees
99
from plaid.utils.cgns_json import (
10-
_decode_array,
1110
_decode_node,
12-
_decode_value,
1311
_encode_node,
14-
_encode_value,
1512
cgns_tree_from_json,
1613
cgns_tree_from_json_payload,
1714
cgns_tree_to_json,
@@ -190,60 +187,3 @@ def test_decode_node_rejects_malformed_encoded_nodes(encoded, message):
190187
_decode_node(encoded)
191188

192189

193-
@pytest.mark.parametrize(
194-
"value, expected",
195-
[
196-
(np.int32(7), 7),
197-
(np.float64(1.25), 1.25),
198-
((np.int64(1), np.int64(2)), [1, 2]),
199-
],
200-
)
201-
def test_encode_value_normalizes_numpy_scalars_and_tuples(value, expected):
202-
"""NumPy scalar values and tuples are converted to JSON-compatible data."""
203-
assert _encode_value(value) == expected
204-
205-
206-
def test_encode_decode_value_roundtrips_bytes():
207-
"""Bytes values are encoded as base64 objects and decoded back to bytes."""
208-
value = b"CGNS bytes"
209-
210-
encoded = _encode_value(value)
211-
212-
assert encoded["kind"] == "bytes"
213-
assert _decode_value(encoded) == value
214-
215-
216-
def test_decode_value_decodes_nested_lists():
217-
"""List payloads are decoded recursively."""
218-
encoded_bytes = _encode_value(b"nested bytes")
219-
220-
assert _decode_value([encoded_bytes, [1, encoded_bytes]]) == [
221-
b"nested bytes",
222-
[1, b"nested bytes"],
223-
]
224-
225-
226-
def test_encode_value_rejects_unsupported_values():
227-
"""Unsupported value types raise a TypeError with a clear message."""
228-
with pytest.raises(TypeError, match="Unsupported CGNS value type"):
229-
_encode_value({"not": "a supported CGNS value"})
230-
231-
232-
def test_decode_value_leaves_unknown_dict_kind_unchanged():
233-
"""Unknown dictionary payloads are passed through unchanged."""
234-
value = {"kind": "custom", "data": [1, 2, 3]}
235-
236-
assert _decode_value(value) is value
237-
238-
239-
def test_decode_array_rejects_unknown_encoding():
240-
"""Only JSON and base64 ndarray encodings are supported."""
241-
with pytest.raises(ValueError, match="Unsupported ndarray encoding"):
242-
_decode_array(
243-
{
244-
"encoding": "unsupported",
245-
"dtype": "<f8",
246-
"shape": [0],
247-
"data": "",
248-
}
249-
)

tests/utils/test_json_codec.py

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
"""Tests for the generic JSON value codec helpers."""
2+
3+
import numpy as np
4+
import pytest
5+
6+
from plaid.utils.json_codec import (
7+
_decode_array,
8+
decode_json_value,
9+
decode_leaf_value,
10+
encode_json_value,
11+
encode_leaf_value,
12+
)
13+
14+
15+
@pytest.mark.parametrize(
16+
"value, expected",
17+
[
18+
(np.int32(7), 7),
19+
(np.float64(1.25), 1.25),
20+
((np.int64(1), np.int64(2)), [1, 2]),
21+
],
22+
)
23+
def test_encode_leaf_value_normalizes_numpy_scalars_and_tuples(value, expected):
24+
"""NumPy scalar values and tuples are converted to JSON-compatible data."""
25+
assert encode_leaf_value(value) == expected
26+
27+
28+
def test_encode_decode_leaf_value_roundtrips_bytes():
29+
"""Bytes values are encoded as base64 objects and decoded back to bytes."""
30+
value = b"CGNS bytes"
31+
32+
encoded = encode_leaf_value(value)
33+
34+
assert encoded["kind"] == "bytes"
35+
assert decode_leaf_value(encoded) == value
36+
37+
38+
def test_decode_leaf_value_decodes_nested_lists():
39+
"""List payloads are decoded recursively."""
40+
encoded_bytes = encode_leaf_value(b"nested bytes")
41+
42+
assert decode_leaf_value([encoded_bytes, [1, encoded_bytes]]) == [
43+
b"nested bytes",
44+
[1, b"nested bytes"],
45+
]
46+
47+
48+
def test_encode_leaf_value_rejects_unsupported_values():
49+
"""Unsupported value types raise a TypeError with a clear message."""
50+
with pytest.raises(TypeError, match="Unsupported value type for JSON serialization"):
51+
encode_leaf_value({"not": "a supported value"})
52+
53+
54+
def test_decode_leaf_value_leaves_unknown_dict_kind_unchanged():
55+
"""Unknown dictionary payloads are passed through unchanged."""
56+
value = {"kind": "custom", "data": [1, 2, 3]}
57+
58+
assert decode_leaf_value(value) is value
59+
60+
61+
def test_decode_array_rejects_unknown_encoding():
62+
"""Only JSON and base64 ndarray encodings are supported."""
63+
with pytest.raises(ValueError, match="Unsupported ndarray encoding"):
64+
_decode_array(
65+
{
66+
"encoding": "unsupported",
67+
"dtype": "<f8",
68+
"shape": [0],
69+
"data": "",
70+
}
71+
)
72+
73+
74+
def test_encode_decode_array_roundtrips_numeric_dtypes():
75+
"""Numeric NumPy arrays survive the base64 encode/decode roundtrip."""
76+
array = np.array([[1.0, 2.0], [3.0, 4.0]], dtype=np.float64)
77+
78+
encoded = encode_leaf_value(array)
79+
decoded = decode_leaf_value(encoded)
80+
81+
assert encoded["kind"] == "ndarray"
82+
assert np.array_equal(decoded, array)
83+
assert decoded.dtype == array.dtype
84+
85+
86+
def test_encode_decode_array_roundtrips_unicode_dtype():
87+
"""Unicode arrays are encoded with the JSON encoding and restored."""
88+
array = np.array(["alpha", "beta"], dtype="<U5")
89+
90+
encoded = encode_leaf_value(array)
91+
decoded = decode_leaf_value(encoded)
92+
93+
assert encoded["encoding"] == "json"
94+
assert np.array_equal(decoded, array)
95+
assert decoded.dtype == array.dtype
96+
97+
98+
def test_encode_array_rejects_object_dtype():
99+
"""Object dtype arrays are intentionally not part of the portable schema."""
100+
array = np.array([{"not": "portable"}], dtype=object)
101+
102+
with pytest.raises(TypeError, match="Object dtype arrays"):
103+
encode_leaf_value(array)
104+
105+
106+
def test_encode_json_value_roundtrips_nested_structures():
107+
"""Nested dicts and lists with arrays survive the JSON value roundtrip."""
108+
value = {
109+
"scalar": 3,
110+
"text": "hello",
111+
"array": np.array([1, 2, 3], dtype=np.int64),
112+
"nested": [np.float64(1.5), {"bytes": b"data"}],
113+
}
114+
115+
encoded = encode_json_value(value)
116+
decoded = decode_json_value(encoded)
117+
118+
assert decoded["scalar"] == 3
119+
assert decoded["text"] == "hello"
120+
assert np.array_equal(decoded["array"], value["array"])
121+
assert decoded["nested"][0] == 1.5
122+
assert decoded["nested"][1]["bytes"] == b"data"

0 commit comments

Comments
 (0)