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

1"""Comprehensive pytest tests for justcode-python bindings.""" 

2 

3import pytest 

4import justcode_python 

5 

6 

7class TestPyConfig: 

8 """Tests for PyConfig class.""" 

9 

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 

15 

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 

21 

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 

27 

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 

33 

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 

39 

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 

47 

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 

55 

56 

57class TestEncode: 

58 """Tests for encode function.""" 

59 

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 

65 

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 

71 

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 

77 

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 

83 

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 

89 

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 

95 

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 

101 

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 

107 

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 

113 

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 

119 

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 

126 

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 

133 

134 with pytest.raises(TypeError): 

135 justcode_python.encode(UnsupportedType()) 

136 

137 

138class TestDecode: 

139 """Tests for decode function.""" 

140 

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 

146 

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 

152 

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" 

158 

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 == "" 

164 

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 

170 

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 

176 

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 

182 

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 

189 

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 

195 

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" 

201 

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 

207 

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 

214 

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") 

219 

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") 

225 

226 

227class TestRoundTrip: 

228 """Tests for encode/decode round-trip operations.""" 

229 

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 

236 

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 

243 

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 

250 

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 

257 

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 

264 

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 

271 

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 

278 

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 

286 

287 

288class TestEdgeCases: 

289 """Tests for edge cases and error handling.""" 

290 

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 

296 

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 

302 

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 

308 

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") 

313 

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") 

319 

320 

321class TestVersion: 

322 """Tests for module version.""" 

323 

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" 

329 

330