Coverage for tests/test_justcode_python.py: 100%
209 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-11-06 21:05 +0100
« prev ^ index » next coverage.py v7.10.6, created at 2025-11-06 21:05 +0100
1"""Comprehensive pytest tests for justcode-python bindings."""
3import pytest
4import justcode_python
7class TestPyConfig:
8 """Tests for PyConfig class."""
10 def test_standard_config(self):
11 """Test creating a standard configuration."""
12 config = justcode_python.PyConfig.standard()
13 assert config.uses_variable_int_encoding() is True
14 assert config.get_limit() is None
16 def test_config_new_default(self):
17 """Test creating config with default values."""
18 config = justcode_python.PyConfig()
19 assert config.uses_variable_int_encoding() is True
20 assert config.get_limit() is None
22 def test_config_new_with_limit(self):
23 """Test creating config with size limit."""
24 config = justcode_python.PyConfig(size_limit=1024)
25 assert config.get_limit() == 1024
26 assert config.uses_variable_int_encoding() is True
28 def test_config_new_with_varint(self):
29 """Test creating config with variable int encoding."""
30 config = justcode_python.PyConfig(variable_int_encoding=False)
31 assert config.uses_variable_int_encoding() is False
32 assert config.get_limit() is None
34 def test_config_new_with_all_options(self):
35 """Test creating config with all options."""
36 config = justcode_python.PyConfig(size_limit=2048, variable_int_encoding=False)
37 assert config.get_limit() == 2048
38 assert config.uses_variable_int_encoding() is False
40 def test_config_with_limit(self):
41 """Test with_limit method."""
42 config = justcode_python.PyConfig.standard()
43 new_config = config.with_limit(4096)
44 assert new_config.get_limit() == 4096
45 # Original config should be unchanged
46 assert config.get_limit() is None
48 def test_config_with_variable_int_encoding(self):
49 """Test with_variable_int_encoding method."""
50 config = justcode_python.PyConfig.standard()
51 new_config = config.with_variable_int_encoding(False)
52 assert new_config.uses_variable_int_encoding() is False
53 # Original config should be unchanged
54 assert config.uses_variable_int_encoding() is True
57class TestEncode:
58 """Tests for encode function."""
60 def test_encode_int(self):
61 """Test encoding integers."""
62 encoded = justcode_python.encode(42)
63 assert isinstance(encoded, bytes)
64 assert len(encoded) > 0
66 def test_encode_negative_int(self):
67 """Test encoding negative integers."""
68 encoded = justcode_python.encode(-42)
69 assert isinstance(encoded, bytes)
70 assert len(encoded) > 0
72 def test_encode_large_int(self):
73 """Test encoding large integers."""
74 encoded = justcode_python.encode(2**63 - 1)
75 assert isinstance(encoded, bytes)
76 assert len(encoded) > 0
78 def test_encode_string(self):
79 """Test encoding strings."""
80 encoded = justcode_python.encode("hello")
81 assert isinstance(encoded, bytes)
82 assert len(encoded) > 0
84 def test_encode_empty_string(self):
85 """Test encoding empty string."""
86 encoded = justcode_python.encode("")
87 assert isinstance(encoded, bytes)
88 assert len(encoded) > 0
90 def test_encode_unicode_string(self):
91 """Test encoding Unicode strings."""
92 encoded = justcode_python.encode("hello 世界")
93 assert isinstance(encoded, bytes)
94 assert len(encoded) > 0
96 def test_encode_bool_true(self):
97 """Test encoding boolean True."""
98 encoded = justcode_python.encode(True)
99 assert isinstance(encoded, bytes)
100 assert len(encoded) > 0
102 def test_encode_bool_false(self):
103 """Test encoding boolean False."""
104 encoded = justcode_python.encode(False)
105 assert isinstance(encoded, bytes)
106 assert len(encoded) > 0
108 def test_encode_float(self):
109 """Test encoding floats."""
110 encoded = justcode_python.encode(3.14159)
111 assert isinstance(encoded, bytes)
112 assert len(encoded) > 0
114 def test_encode_bytes(self):
115 """Test encoding bytes."""
116 encoded = justcode_python.encode(b"hello")
117 assert isinstance(encoded, bytes)
118 assert len(encoded) > 0
120 def test_encode_with_config(self):
121 """Test encoding with custom config."""
122 config = justcode_python.PyConfig(size_limit=1024)
123 encoded = justcode_python.encode(42, config=config)
124 assert isinstance(encoded, bytes)
125 assert len(encoded) > 0
127 def test_encode_unsupported_type(self):
128 """Test encoding unsupported type raises error."""
129 # Lists with integers are supported, so test with an actually unsupported type
130 # Use a custom object that can't be encoded
131 class UnsupportedType:
132 pass
134 with pytest.raises(TypeError):
135 justcode_python.encode(UnsupportedType())
138class TestDecode:
139 """Tests for decode function."""
141 def test_decode_int(self):
142 """Test decoding integers."""
143 encoded = justcode_python.encode(12345)
144 decoded = justcode_python.decode(encoded, target_type="int")
145 assert decoded == 12345
147 def test_decode_negative_int(self):
148 """Test decoding negative integers."""
149 encoded = justcode_python.encode(-12345)
150 decoded = justcode_python.decode(encoded, target_type="int")
151 assert decoded == -12345
153 def test_decode_string(self):
154 """Test decoding strings."""
155 encoded = justcode_python.encode("test string")
156 decoded = justcode_python.decode(encoded, target_type="str")
157 assert decoded == "test string"
159 def test_decode_empty_string(self):
160 """Test decoding empty string."""
161 encoded = justcode_python.encode("")
162 decoded = justcode_python.decode(encoded, target_type="str")
163 assert decoded == ""
165 def test_decode_bool_true(self):
166 """Test decoding boolean True."""
167 encoded = justcode_python.encode(True)
168 decoded = justcode_python.decode(encoded, target_type="bool")
169 assert decoded is True
171 def test_decode_bool_false(self):
172 """Test decoding boolean False."""
173 encoded = justcode_python.encode(False)
174 decoded = justcode_python.decode(encoded, target_type="bool")
175 assert decoded is False
177 def test_decode_float(self):
178 """Test decoding floats."""
179 encoded = justcode_python.encode(3.14159)
180 decoded = justcode_python.decode(encoded, target_type="float")
181 assert abs(decoded - 3.14159) < 1e-6
183 def test_decode_bytes(self):
184 """Test decoding bytes."""
185 original = b"hello world"
186 encoded = justcode_python.encode(original)
187 decoded = justcode_python.decode(encoded, target_type="bytes")
188 assert decoded == original
190 def test_decode_auto_detect_int(self):
191 """Test auto-detection of integer type."""
192 encoded = justcode_python.encode(42)
193 decoded = justcode_python.decode(encoded)
194 assert decoded == 42
196 def test_decode_auto_detect_string(self):
197 """Test auto-detection of string type."""
198 encoded = justcode_python.encode("hello")
199 decoded = justcode_python.decode(encoded)
200 assert decoded == "hello"
202 def test_decode_auto_detect_bool(self):
203 """Test auto-detection of boolean type."""
204 encoded = justcode_python.encode(True)
205 decoded = justcode_python.decode(encoded)
206 assert decoded is True
208 def test_decode_with_config(self):
209 """Test decoding with custom config."""
210 config = justcode_python.PyConfig(size_limit=1024)
211 encoded = justcode_python.encode(42)
212 decoded = justcode_python.decode(encoded, config=config, target_type="int")
213 assert decoded == 42
215 def test_decode_invalid_bytes(self):
216 """Test decoding invalid bytes raises error."""
217 with pytest.raises(ValueError):
218 justcode_python.decode(b"invalid", target_type="int")
220 def test_decode_invalid_target_type(self):
221 """Test decoding with invalid target type raises error."""
222 encoded = justcode_python.encode(42)
223 with pytest.raises(ValueError):
224 justcode_python.decode(encoded, target_type="invalid_type")
227class TestRoundTrip:
228 """Tests for encode/decode round-trip operations."""
230 def test_roundtrip_int(self):
231 """Test round-trip encoding/decoding of integers."""
232 original = 12345
233 encoded = justcode_python.encode(original)
234 decoded = justcode_python.decode(encoded, target_type="int")
235 assert decoded == original
237 def test_roundtrip_negative_int(self):
238 """Test round-trip encoding/decoding of negative integers."""
239 original = -12345
240 encoded = justcode_python.encode(original)
241 decoded = justcode_python.decode(encoded, target_type="int")
242 assert decoded == original
244 def test_roundtrip_string(self):
245 """Test round-trip encoding/decoding of strings."""
246 original = "test string"
247 encoded = justcode_python.encode(original)
248 decoded = justcode_python.decode(encoded, target_type="str")
249 assert decoded == original
251 def test_roundtrip_unicode_string(self):
252 """Test round-trip encoding/decoding of Unicode strings."""
253 original = "hello 世界 🌍"
254 encoded = justcode_python.encode(original)
255 decoded = justcode_python.decode(encoded, target_type="str")
256 assert decoded == original
258 def test_roundtrip_bool(self):
259 """Test round-trip encoding/decoding of booleans."""
260 for original in [True, False]:
261 encoded = justcode_python.encode(original)
262 decoded = justcode_python.decode(encoded, target_type="bool")
263 assert decoded == original
265 def test_roundtrip_float(self):
266 """Test round-trip encoding/decoding of floats."""
267 original = 3.14159
268 encoded = justcode_python.encode(original)
269 decoded = justcode_python.decode(encoded, target_type="float")
270 assert abs(decoded - original) < 1e-6
272 def test_roundtrip_bytes(self):
273 """Test round-trip encoding/decoding of bytes."""
274 original = b"hello world"
275 encoded = justcode_python.encode(original)
276 decoded = justcode_python.decode(encoded, target_type="bytes")
277 assert decoded == original
279 def test_roundtrip_with_config(self):
280 """Test round-trip with custom configuration."""
281 config = justcode_python.PyConfig(size_limit=1024, variable_int_encoding=False)
282 original = 42
283 encoded = justcode_python.encode(original, config=config)
284 decoded = justcode_python.decode(encoded, config=config, target_type="int")
285 assert decoded == original
288class TestEdgeCases:
289 """Tests for edge cases and error handling."""
291 def test_encode_zero(self):
292 """Test encoding zero."""
293 encoded = justcode_python.encode(0)
294 decoded = justcode_python.decode(encoded, target_type="int")
295 assert decoded == 0
297 def test_encode_one(self):
298 """Test encoding one."""
299 encoded = justcode_python.encode(1)
300 decoded = justcode_python.decode(encoded, target_type="int")
301 assert decoded == 1
303 def test_encode_minus_one(self):
304 """Test encoding minus one."""
305 encoded = justcode_python.encode(-1)
306 decoded = justcode_python.decode(encoded, target_type="int")
307 assert decoded == -1
309 def test_decode_empty_bytes(self):
310 """Test decoding empty bytes raises error."""
311 with pytest.raises(ValueError):
312 justcode_python.decode(b"", target_type="int")
314 def test_decode_wrong_type(self):
315 """Test decoding with wrong target type raises error."""
316 encoded = justcode_python.encode(42)
317 with pytest.raises(ValueError):
318 justcode_python.decode(encoded, target_type="str")
321class TestVersion:
322 """Tests for module version."""
324 def test_version_exists(self):
325 """Test that __version__ exists."""
326 assert hasattr(justcode_python, "__version__")
327 assert isinstance(justcode_python.__version__, str)
328 assert justcode_python.__version__ == "0.2.0"