Coverage for tests / unit / no_torch / test_serializing_edge_cases.py: 100%
60 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-02-22 01:52 -0700
« prev ^ index » next coverage.py v7.13.4, created at 2026-02-22 01:52 -0700
1"""Edge case tests for zanj/serializing.py to improve coverage."""
3from __future__ import annotations
5import numpy as np
6import pytest
8from zanj import ZANJ
9from zanj.serializing import zanj_external_serialize
12class TestZanjExternalSerialize:
13 """Tests for zanj_external_serialize function edge cases."""
15 def test_duplicate_external_path(self):
16 """Lines 124-127: Duplicate external path should raise ValueError."""
17 z = ZANJ()
18 array1 = np.random.rand(10, 10)
19 array2 = np.random.rand(5, 5)
21 # First call with path ('data',) should succeed
22 zanj_external_serialize(
23 z, array1, path=("data",), item_type="npy", _format="numpy.ndarray:external"
24 )
26 # Second call with same path should raise ValueError
27 with pytest.raises(ValueError, match="already exists"):
28 zanj_external_serialize(
29 z,
30 array2,
31 path=("data",),
32 item_type="npy",
33 _format="numpy.ndarray:external",
34 )
36 def test_path_prefix_conflict_child_first(self):
37 """Lines 137-142: Path prefix conflict where new path is parent of existing."""
38 z = ZANJ()
39 array1 = np.random.rand(10, 10)
40 array2 = np.random.rand(5, 5)
42 # First: add child path 'layer/1/weight'
43 zanj_external_serialize(
44 z,
45 array1,
46 path=("layer", "1", "weight"),
47 item_type="npy",
48 _format="numpy.ndarray:external",
49 )
51 # Second: try to add parent path 'layer/1' - should conflict
52 with pytest.raises(ValueError, match="is a prefix of another path"):
53 zanj_external_serialize(
54 z,
55 array2,
56 path=("layer", "1"),
57 item_type="npy",
58 _format="numpy.ndarray:external",
59 )
61 def test_path_prefix_conflict_parent_first(self):
62 """Lines 134-136: Path prefix conflict where new path is child of existing."""
63 z = ZANJ()
64 array1 = np.random.rand(10, 10)
65 array2 = np.random.rand(5, 5)
67 # First: add parent path 'layer/1'
68 zanj_external_serialize(
69 z,
70 array1,
71 path=("layer", "1"),
72 item_type="npy",
73 _format="numpy.ndarray:external",
74 )
76 # Second: try to add child path 'layer/1/weight' - should conflict
77 with pytest.raises(ValueError, match="is a prefix of another path"):
78 zanj_external_serialize(
79 z,
80 array2,
81 path=("layer", "1", "weight"),
82 item_type="npy",
83 _format="numpy.ndarray:external",
84 )
86 def test_invalid_npy_data_type(self):
87 """Line 160: Invalid data type for NPY serialization should raise TypeError."""
88 z = ZANJ()
90 # Pass a string instead of array - should fail
91 with pytest.raises(TypeError, match="expected numpy.ndarray"):
92 zanj_external_serialize(
93 z,
94 data="not an array",
95 path=("test",),
96 item_type="npy",
97 _format="numpy.ndarray:external",
98 )
100 def test_invalid_jsonl_data_type(self):
101 """Line 184: Invalid data type for JSONL serialization should raise TypeError."""
102 z = ZANJ()
104 # Create a custom class that is not iterable/sequence/dataframe
105 class NotSerializableAsJsonl:
106 pass
108 obj = NotSerializableAsJsonl()
110 with pytest.raises(TypeError, match="expected list or pandas.DataFrame"):
111 zanj_external_serialize(
112 z,
113 data=obj,
114 path=("test",),
115 item_type="jsonl",
116 _format="list:external",
117 )
119 def test_valid_npy_serialization(self):
120 """Verify valid NPY serialization works correctly."""
121 z = ZANJ()
122 array = np.random.rand(10, 10)
124 result = zanj_external_serialize(
125 z,
126 array,
127 path=("valid_array",),
128 item_type="npy",
129 _format="numpy.ndarray:external",
130 )
132 assert "__muutils_format__" in result
133 assert result["__muutils_format__"] == "numpy.ndarray:external"
134 assert "valid_array.npy" in z._externals
136 def test_valid_jsonl_list_serialization(self):
137 """Verify valid JSONL list serialization works correctly."""
138 z = ZANJ()
139 data = [{"a": 1}, {"b": 2}, {"c": 3}]
141 result = zanj_external_serialize(
142 z,
143 data,
144 path=("valid_list",),
145 item_type="jsonl",
146 _format="list:external",
147 )
149 assert "__muutils_format__" in result
150 assert result["__muutils_format__"] == "list:external"
151 assert "valid_list.jsonl" in z._externals
153 def test_non_overlapping_paths_allowed(self):
154 """Verify that non-overlapping paths with similar prefixes are allowed."""
155 z = ZANJ()
156 array1 = np.random.rand(10, 10)
157 array2 = np.random.rand(5, 5)
159 # These should NOT conflict: 'layer.1' and 'layer.1.weight' as strings
160 # but 'layer/1' and 'layer/10' should be fine
161 zanj_external_serialize(
162 z,
163 array1,
164 path=("layer", "1"),
165 item_type="npy",
166 _format="numpy.ndarray:external",
167 )
169 # 'layer/10' is NOT a prefix of 'layer/1' or vice versa
170 zanj_external_serialize(
171 z,
172 array2,
173 path=("layer", "10"),
174 item_type="npy",
175 _format="numpy.ndarray:external",
176 )
178 assert "layer/1.npy" in z._externals
179 assert "layer/10.npy" in z._externals