Coverage for /home/jenkins/workspace/NDS/Zserio/NDS_ZSERIO-linux-build/compiler/extensions/python/runtime/tests/test_json.py: 100%

815 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2023-12-13 15:12 +0000

1import enum 

2import io 

3import unittest 

4import math 

5 

6 

7from test_object.api import CreatorEnum, CreatorBitmask, CreatorObject 

8 

9from zserio.bitbuffer import BitBuffer 

10from zserio.json import (JsonWriter, JsonEncoder, JsonParser, JsonTokenizer, JsonToken, JsonParserException, 

11 JsonDecoder, JsonReader, JsonEnumerableFormat) 

12from zserio.typeinfo import TypeInfo, MemberInfo, ItemInfo, TypeAttribute, MemberAttribute 

13from zserio.limits import INT64_MIN, UINT64_MAX 

14from zserio.exception import PythonRuntimeException 

15 

16class JsonWriterTest(unittest.TestCase): 

17 

18 def test_empty(self): 

19 json_writer = JsonWriter() 

20 self.assertEqual("", json_writer.get_io().getvalue()) 

21 

22 def test_null_value(self): 

23 json_writer = JsonWriter() 

24 json_writer.visit_value(None, MemberInfo("text", TypeInfo("string", str))) 

25 # note that this is not valid JSON 

26 self.assertEqual("\"text\": null", json_writer.get_io().getvalue()) 

27 

28 def test_value(self): 

29 json_writer = JsonWriter() 

30 json_writer.visit_value("test", MemberInfo("text", TypeInfo("string", str))) 

31 # note that this is not valid JSON 

32 self.assertEqual("\"text\": \"test\"", json_writer.get_io().getvalue()) 

33 

34 def test_enum_value(self): 

35 class TestEnum(enum.Enum): 

36 ZERO = 0 

37 ONE = 1 

38 MINUS_ONE = -1 

39 NOT_IN_TYPE_INFO = 2 

40 

41 test_enum_type_info = TypeInfo("TestEnum", TestEnum, attributes={ 

42 TypeAttribute.ENUM_ITEMS : [ 

43 ItemInfo("ZERO", TestEnum.ZERO, False, False), 

44 ItemInfo("One", TestEnum.ONE, False, False), 

45 ItemInfo("MINUS_ONE", TestEnum.MINUS_ONE, False, False) 

46 ] 

47 }) 

48 

49 test_enum_member_info = MemberInfo("enumField", test_enum_type_info) 

50 

51 json_writer = JsonWriter() 

52 json_writer.visit_value(TestEnum.ZERO, test_enum_member_info) 

53 json_writer.visit_value(TestEnum.ONE, test_enum_member_info) 

54 json_writer.visit_value(TestEnum.NOT_IN_TYPE_INFO, test_enum_member_info) 

55 json_writer.visit_value(TestEnum.MINUS_ONE, test_enum_member_info) 

56 # note that this is not valid JSON 

57 self.assertEqual("\"enumField\": \"ZERO\", " 

58 "\"enumField\": \"One\", " 

59 "\"enumField\": \"2 /* no match */\", " 

60 "\"enumField\": \"MINUS_ONE\"", 

61 json_writer.get_io().getvalue()) 

62 

63 json_writer = JsonWriter(enumerable_format=JsonEnumerableFormat.NUMBER) 

64 json_writer.visit_value(TestEnum.ZERO, test_enum_member_info) 

65 json_writer.visit_value(TestEnum.NOT_IN_TYPE_INFO, test_enum_member_info) 

66 json_writer.visit_value(TestEnum.MINUS_ONE, test_enum_member_info) 

67 # note that this is not valid JSON 

68 self.assertEqual("\"enumField\": 0, \"enumField\": 2, \"enumField\": -1", 

69 json_writer.get_io().getvalue()) 

70 

71 def test_bitmask_value(self): 

72 class TestBitmask: 

73 def __init__(self, value): 

74 self._value = value 

75 

76 @property 

77 def value(self): 

78 return self._value 

79 

80 class Values: 

81 ZERO = None 

82 ONE = None 

83 TWO = None 

84 

85 TestBitmask.Values.ZERO = TestBitmask(0) 

86 TestBitmask.Values.ONE = TestBitmask(1) 

87 TestBitmask.Values.TWO = TestBitmask(2) 

88 

89 test_bitmask_type_info = TypeInfo("TestBitmask", TestBitmask, attributes={ 

90 TypeAttribute.BITMASK_VALUES : [ 

91 ItemInfo("ZERO", TestBitmask.Values.ZERO, False, False), 

92 ItemInfo("One", TestBitmask.Values.ONE, False, False), 

93 ItemInfo("TWO", TestBitmask.Values.TWO, False, False) 

94 ] 

95 }) 

96 

97 test_bitmask_member_info = MemberInfo("bitmaskField", test_bitmask_type_info) 

98 

99 json_writer = JsonWriter() 

100 json_writer.visit_value(TestBitmask(0), test_bitmask_member_info) 

101 json_writer.visit_value(TestBitmask(2), test_bitmask_member_info) 

102 json_writer.visit_value(TestBitmask(3), test_bitmask_member_info) 

103 json_writer.visit_value(TestBitmask(4), test_bitmask_member_info) 

104 json_writer.visit_value(TestBitmask(7), test_bitmask_member_info) 

105 # note that this is not valid JSON 

106 self.assertEqual("\"bitmaskField\": \"ZERO\", " 

107 "\"bitmaskField\": \"TWO\", " 

108 "\"bitmaskField\": \"One | TWO\", " 

109 "\"bitmaskField\": \"4 /* no match */\", " 

110 "\"bitmaskField\": \"7 /* partial match: One | TWO */\"", 

111 json_writer.get_io().getvalue()) 

112 

113 json_writer = JsonWriter(enumerable_format=JsonEnumerableFormat.NUMBER) 

114 json_writer.visit_value(TestBitmask(0), test_bitmask_member_info) 

115 json_writer.visit_value(TestBitmask(7), test_bitmask_member_info) 

116 # note that this is not valid JSON 

117 self.assertEqual("\"bitmaskField\": 0, \"bitmaskField\": 7", json_writer.get_io().getvalue()) 

118 

119 def test_compound(self): 

120 json_writer = JsonWriter() 

121 json_writer.begin_root(object()) 

122 json_writer.visit_value(13, MemberInfo("identifier", TypeInfo("uint32", int))) 

123 json_writer.visit_value("test", MemberInfo("text", TypeInfo("string", str))) 

124 json_writer.visit_value(BitBuffer(bytes([0xFF,0x1F]), 13), 

125 MemberInfo("externData", TypeInfo("extern", BitBuffer))) 

126 json_writer.visit_value(bytes([0xCA,0xFE]), 

127 MemberInfo("bytesData", TypeInfo("bytes", bytearray))) 

128 json_writer.end_root(object()) 

129 self.assertEqual( 

130 "{\"identifier\": 13, \"text\": \"test\", " 

131 "\"externData\": {\"buffer\": [255, 31], \"bitSize\": 13}, " 

132 "\"bytesData\": {\"buffer\": [202, 254]}}", 

133 json_writer.get_io().getvalue()) 

134 

135 def test_nested_compound(self): 

136 json_writer = JsonWriter() 

137 self._walk_nested(json_writer) 

138 self.assertEqual("{\"identifier\": 13, \"nested\": {\"text\": \"test\"}}", 

139 json_writer.get_io().getvalue()) 

140 

141 def test_array(self): 

142 json_writer = JsonWriter() 

143 self._walk_array(json_writer) 

144 self.assertEqual("{\"array\": [1, 2]}", json_writer.get_io().getvalue()) 

145 

146 def test_array_with_indent(self): 

147 json_writer = JsonWriter(indent=2) 

148 self._walk_array(json_writer) 

149 self.assertEqual("{\n \"array\": [\n 1,\n 2\n ]\n}", json_writer.get_io().getvalue()) 

150 

151 def test_empty_indent(self): 

152 json_writer = JsonWriter(indent="") 

153 self._walk_nested(json_writer) 

154 self.assertEqual("{\n\"identifier\": 13,\n\"nested\": {\n\"text\": \"test\"\n}\n}", 

155 json_writer.get_io().getvalue()) 

156 

157 def test_str_indent(self): 

158 json_writer = JsonWriter(indent=" ") 

159 self._walk_nested(json_writer) 

160 self.assertEqual("{\n \"identifier\": 13,\n \"nested\": {\n \"text\": \"test\"\n }\n}", 

161 json_writer.get_io().getvalue()) 

162 

163 def test_int_indent(self): 

164 json_writer = JsonWriter(indent=2) 

165 self._walk_nested(json_writer) 

166 self.assertEqual("{\n \"identifier\": 13,\n \"nested\": {\n \"text\": \"test\"\n }\n}", 

167 json_writer.get_io().getvalue()) 

168 

169 def test_compact_separators(self): 

170 json_writer = JsonWriter(key_separator=":", item_separator=",") 

171 self._walk_nested(json_writer) 

172 self.assertEqual("{\"identifier\":13,\"nested\":{\"text\":\"test\"}}", 

173 json_writer.get_io().getvalue()) 

174 

175 def test_multiple_objects(self): 

176 json_writer = JsonWriter() 

177 self._walk_nested(json_writer) 

178 self._walk_nested(json_writer) 

179 self.assertEqual( 

180 "{\"identifier\": 13, \"nested\": {\"text\": \"test\"}}" 

181 "{\"identifier\": 13, \"nested\": {\"text\": \"test\"}}", 

182 json_writer.get_io().getvalue() 

183 ) 

184 

185 @staticmethod 

186 def _walk_nested(json_writer): 

187 creator_type_info = TypeInfo("Creator", object) 

188 

189 json_writer.begin_root(object()) 

190 json_writer.visit_value(13, MemberInfo("identifier", TypeInfo("uint32", int))) 

191 json_writer.begin_compound(object(), MemberInfo("nested", creator_type_info)) 

192 json_writer.visit_value("test", MemberInfo("text", TypeInfo("string", str))) 

193 json_writer.end_compound(object(), MemberInfo("nested", creator_type_info)) 

194 json_writer.end_root(object()) 

195 

196 @staticmethod 

197 def _walk_array(json_writer): 

198 array_member_info = MemberInfo("array", TypeInfo("uint32", int), attributes={ 

199 MemberAttribute.ARRAY_LENGTH : None 

200 }) 

201 

202 json_writer.begin_root(object()) 

203 json_writer.begin_array([1, 2], array_member_info) 

204 json_writer.visit_value(1, array_member_info, 0) 

205 json_writer.visit_value(2, array_member_info, 1) 

206 json_writer.end_array([1, 2], array_member_info) 

207 json_writer.end_root(object()) 

208 

209class JsonEncoderTest(unittest.TestCase): 

210 

211 def test_encode_null(self): 

212 json_encoder = JsonEncoder() 

213 self.assertEqual("null", json_encoder.encode_value(None)) 

214 

215 def test_encode_bool(self): 

216 json_encoder = JsonEncoder() 

217 self.assertEqual("true", json_encoder.encode_value(True)) 

218 self.assertEqual("false", json_encoder.encode_value(False)) 

219 

220 def test_encode_integral(self): 

221 json_encoder = JsonEncoder() 

222 self.assertEqual("-9223372036854775808", json_encoder.encode_value(INT64_MIN)) 

223 self.assertEqual("-1000", json_encoder.encode_value(-1000)) 

224 self.assertEqual("0", json_encoder.encode_value(0)) 

225 self.assertEqual("1000", json_encoder.encode_value(1000)) 

226 self.assertEqual("18446744073709551615", json_encoder.encode_value(UINT64_MAX)) 

227 

228 def test_encode_floating_point(self): 

229 json_encoder = JsonEncoder() 

230 self.assertEqual("-1.0", json_encoder.encode_value(-1.0)) 

231 self.assertEqual("0.0", json_encoder.encode_value(0.0)) 

232 self.assertEqual("1.0", json_encoder.encode_value(1.0)) 

233 

234 self.assertEqual("3.5", json_encoder.encode_value(3.5)) 

235 self.assertEqual("9.875", json_encoder.encode_value(9.875)) 

236 self.assertEqual("0.6171875", json_encoder.encode_value(0.6171875)) 

237 

238 self.assertEqual("1e+20", json_encoder.encode_value(1e20)) 

239 

240 self.assertEqual("NaN", json_encoder.encode_value(float('nan'))) 

241 self.assertEqual("Infinity", json_encoder.encode_value(float('inf'))) 

242 self.assertEqual("-Infinity", json_encoder.encode_value(float('-inf'))) 

243 

244 def test_encode_string(self): 

245 json_encoder = JsonEncoder() 

246 self.assertEqual("\"\"", json_encoder.encode_value("")) 

247 self.assertEqual("\"test\"", json_encoder.encode_value("test")) 

248 self.assertEqual("\"München\"", json_encoder.encode_value("München")) 

249 self.assertEqual("\"€\"", json_encoder.encode_value("€")) 

250 

251 # escapes 

252 self.assertEqual("\"\\\\\"", json_encoder.encode_value("\\")) 

253 self.assertEqual("\"\\\"\"", json_encoder.encode_value("\"")) 

254 self.assertEqual("\"\\b\"", json_encoder.encode_value("\b")) 

255 self.assertEqual("\"\\f\"", json_encoder.encode_value("\f")) 

256 self.assertEqual("\"\\n\"", json_encoder.encode_value("\n")) 

257 self.assertEqual("\"\\r\"", json_encoder.encode_value("\r")) 

258 self.assertEqual("\"\\t\"", json_encoder.encode_value("\t")) 

259 

260 self.assertEqual("\"\\n\\t%^@(*aAzZ01234569$%^!?<>[]](){}-=+~:;/|\\\\\\\"'Hello World2\"", 

261 json_encoder.encode_value( 

262 "\n\t%^@(*aAzZ01234569$%^!?<>[]](){}-=+~:;/|\\\"'Hello World2")) 

263 

264 # <= 0x1F -> unicode escape 

265 self.assertEqual("\"\\u001f\"", json_encoder.encode_value("\x1f")) 

266 

267class JsonParserTest(unittest.TestCase): 

268 

269 class DummyObserver(JsonParser.Observer): 

270 def __init__(self): 

271 self._report = [] 

272 

273 @property 

274 def report(self): 

275 return self._report 

276 

277 def begin_object(self): 

278 self._report.append("begin_object") 

279 

280 def end_object(self): 

281 self._report.append("end_object") 

282 

283 def begin_array(self): 

284 self._report.append("begin_array") 

285 

286 def end_array(self): 

287 self._report.append("end_array") 

288 

289 def visit_key(self, key): 

290 self._report.append(f"visit_key: {key}") 

291 

292 def visit_value(self, value): 

293 self._report.append(f"visit_value: {value}") 

294 

295 def test_json_parser_observer(self): 

296 observer = JsonParser.Observer() 

297 with self.assertRaises(NotImplementedError): 

298 observer.begin_object() 

299 with self.assertRaises(NotImplementedError): 

300 observer.end_object() 

301 with self.assertRaises(NotImplementedError): 

302 observer.begin_array() 

303 with self.assertRaises(NotImplementedError): 

304 observer.end_array() 

305 with self.assertRaises(NotImplementedError): 

306 observer.visit_key("key") 

307 with self.assertRaises(NotImplementedError): 

308 observer.visit_value(13) 

309 

310 def test_json_parser_tokenizer(self): 

311 text_io = io.StringIO("{\"array\":\n[\n{\"key\":\n10}]}") 

312 tokenizer = JsonTokenizer(text_io) 

313 token = tokenizer.next() 

314 tokens = [] 

315 while token not in [JsonToken.END_OF_FILE]: 

316 tokens.append((token, tokenizer.get_value())) 

317 token = tokenizer.next() 

318 

319 self.assertEqual( 

320 [ 

321 (JsonToken.BEGIN_OBJECT, "{"), 

322 (JsonToken.VALUE, "array"), 

323 (JsonToken.KEY_SEPARATOR, ":"), 

324 (JsonToken.BEGIN_ARRAY, "["), 

325 (JsonToken.BEGIN_OBJECT, "{"), 

326 (JsonToken.VALUE, "key"), 

327 (JsonToken.KEY_SEPARATOR, ":"), 

328 (JsonToken.VALUE, 10), 

329 (JsonToken.END_OBJECT, "}"), 

330 (JsonToken.END_ARRAY, "]"), 

331 (JsonToken.END_OBJECT, "}") 

332 ], tokens 

333 ) 

334 

335 def test_empty(self): 

336 text_io = io.StringIO("") 

337 observer = JsonParserTest.DummyObserver() 

338 json_parser = JsonParser(text_io, observer) 

339 self.assertTrue(json_parser.parse()) 

340 self.assertEqual([], observer.report) 

341 

342 def test_one_string(self): 

343 text_io = io.StringIO("\"text\"") 

344 observer = JsonParserTest.DummyObserver() 

345 json_parser = JsonParser(text_io, observer) 

346 self.assertTrue(json_parser.parse()) 

347 self.assertEqual(["visit_value: text"], observer.report) 

348 

349 def test_two_strings(self): 

350 text_io = io.StringIO("\"text\"\"second\"") 

351 observer = JsonParserTest.DummyObserver() 

352 json_parser = JsonParser(text_io, observer) 

353 self.assertFalse(json_parser.parse()) 

354 self.assertEqual(["visit_value: text"], observer.report) 

355 self.assertTrue(json_parser.parse()) 

356 self.assertEqual(["visit_value: text", "visit_value: second"], observer.report) 

357 

358 def test_parse(self): 

359 text_io = io.StringIO("{\"array\":\n[\n{\"key1\":\n10, \"key2\":\n\"text\"}, {}]}") 

360 observer = JsonParserTest.DummyObserver() 

361 json_parser = JsonParser(text_io, observer) 

362 self.assertTrue(json_parser.parse()) 

363 

364 self.assertEqual([ 

365 "begin_object", 

366 "visit_key: array", 

367 "begin_array", 

368 "begin_object", 

369 "visit_key: key1", 

370 "visit_value: 10", 

371 "visit_key: key2", 

372 "visit_value: text", 

373 "end_object", 

374 "begin_object", 

375 "end_object", 

376 "end_array", 

377 "end_object" 

378 ], observer.report) 

379 

380 def test_unexpected_object(self): 

381 text_io = io.StringIO("{\n\n{\n\n") 

382 observer = JsonParserTest.DummyObserver() 

383 json_parser = JsonParser(text_io, observer) 

384 with self.assertRaises(JsonParserException) as error: 

385 json_parser.parse() 

386 

387 self.assertEqual("JsonParser:3:1: Unexpected token: JsonToken.BEGIN_OBJECT ('{'), " 

388 "expecting JsonToken.END_OBJECT!", str(error.exception)) 

389 

390 self.assertEqual(["begin_object"], observer.report) 

391 

392 def test_unexpected_object_after_item_separator(self): 

393 text_io = io.StringIO("{\n \"key\": 10,\n {\n") 

394 observer = JsonParserTest.DummyObserver() 

395 json_parser = JsonParser(text_io, observer) 

396 with self.assertRaises(JsonParserException) as error: 

397 json_parser.parse() 

398 

399 self.assertEqual("JsonParser:3:3: Unexpected token: JsonToken.BEGIN_OBJECT ('{'), " 

400 "expecting JsonToken.VALUE!", str(error.exception)) 

401 

402 self.assertEqual(["begin_object", "visit_key: key", "visit_value: 10"], observer.report) 

403 

404 def test_missing_object_item_separator(self): 

405 text_io = io.StringIO("{\n\"item1\":\"text\"\n\"item2\":\"text\"\n}") 

406 observer = JsonParserTest.DummyObserver() 

407 json_parser = JsonParser(text_io, observer) 

408 with self.assertRaises(JsonParserException) as error: 

409 json_parser.parse() 

410 

411 self.assertEqual("JsonParser:3:1: Unexpected token: JsonToken.VALUE ('item2'), " 

412 "expecting JsonToken.END_OBJECT!", str(error.exception)) 

413 

414 self.assertEqual([ 

415 "begin_object", 

416 "visit_key: item1", "visit_value: text" 

417 ], observer.report) 

418 

419 def test_wrong_key_type(self): 

420 text_io = io.StringIO("{\n10:\"text\"\n}") 

421 observer = JsonParserTest.DummyObserver() 

422 json_parser = JsonParser(text_io, observer) 

423 with self.assertRaises(JsonParserException) as error: 

424 json_parser.parse() 

425 

426 self.assertEqual("JsonParser:2:1: Key must be a string value!", str(error.exception)) 

427 

428 self.assertEqual(["begin_object"], observer.report) 

429 

430 def test_unexpected_element_token(self): 

431 text_io = io.StringIO("{\n\"item\":}") 

432 observer = JsonParserTest.DummyObserver() 

433 json_parser = JsonParser(text_io, observer) 

434 with self.assertRaises(JsonParserException) as error: 

435 json_parser.parse() 

436 

437 self.assertEqual("JsonParser:2:8: Unexpected token: JsonToken.END_OBJECT ('}'), " 

438 "expecting one of [JsonToken.BEGIN_OBJECT, JsonToken.BEGIN_ARRAY, JsonToken.VALUE]!", 

439 str(error.exception)) 

440 

441 self.assertEqual(["begin_object", "visit_key: item"], observer.report) 

442 

443 def test_missing_array_element_separator(self): 

444 text_io = io.StringIO("{\n\"array\":\n[10\n20\n]}") 

445 observer = JsonParserTest.DummyObserver() 

446 json_parser = JsonParser(text_io, observer) 

447 with self.assertRaises(JsonParserException) as error: 

448 json_parser.parse() 

449 

450 self.assertEqual("JsonParser:4:1: Unexpected token: JsonToken.VALUE ('20'), " 

451 "expecting JsonToken.END_ARRAY!", str(error.exception)) 

452 

453 self.assertEqual([ 

454 "begin_object", 

455 "visit_key: array", 

456 "begin_array", 

457 "visit_value: 10" 

458 ], observer.report) 

459 

460class JsonDecoderTest(unittest.TestCase): 

461 

462 def test_decode_null(self): 

463 self._check_decoder_success("null", 0, 4, None) 

464 self._check_decoder_success("{ } null", 4, 4, None) 

465 self._check_decoder_success("null { }", 0, 4, None) 

466 self._check_decoder_failure("invalid", 0, 1) 

467 self._check_decoder_failure("invalid", 1, 4) 

468 self._check_decoder_failure("nul", 0, 3) 

469 

470 def test_decode_true(self): 

471 self._check_decoder_success("true", 0, 4, True) 

472 self._check_decoder_success("{ } true", 4, 4, True) 

473 self._check_decoder_success("true { }", 0, 4, True) 

474 self._check_decoder_failure("invalid", 0, 1) 

475 self._check_decoder_failure("stainless", 1, 4) 

476 self._check_decoder_failure("tru", 0, 3) 

477 

478 def test_decode_false(self): 

479 self._check_decoder_success("false", 0, 5, False) 

480 self._check_decoder_success("{ } false", 4, 5, False) 

481 self._check_decoder_success("false { }", 0, 5, False) 

482 self._check_decoder_failure("invalid", 0, 1) 

483 self._check_decoder_failure("affected", 1, 5) 

484 self._check_decoder_failure("fal", 0, 3) 

485 

486 def test_decode_nan(self): 

487 self._check_decoder_success("NaN", 0, 3, float("nan")) 

488 self._check_decoder_success("{ } NaN", 4, 3, float("nan")) 

489 self._check_decoder_success("NaN { }", 0, 3, float("nan")) 

490 self._check_decoder_failure("invalid", 0, 1) 

491 self._check_decoder_failure("iNactive", 1, 3) 

492 self._check_decoder_failure("Na", 0, 2) 

493 

494 def test_decode_positive_infinity(self): 

495 self._check_decoder_success("Infinity", 0, 8, float("inf")) 

496 self._check_decoder_success("{ } Infinity", 4, 8, float("inf")) 

497 self._check_decoder_success("Infinity { }", 0, 8, float("inf")) 

498 self._check_decoder_failure("invalid", 0, 1) 

499 self._check_decoder_failure("iInfinvalid", 1, 8) 

500 self._check_decoder_failure("Infin", 0, 5) 

501 

502 def test_decode_negative_infinity(self): 

503 self._check_decoder_success("-Infinity", 0, 9, float("-inf")) 

504 self._check_decoder_success("{ } -Infinity", 4, 9, float("-inf")) 

505 self._check_decoder_success("-Infinity { }", 0, 9, float("-inf")) 

506 self._check_decoder_failure("invalid", 0, 1) 

507 self._check_decoder_failure("i-Infinvalid", 1, 9) 

508 self._check_decoder_failure("-Infin", 0, 6) 

509 self._check_decoder_failure("-Infix", 0, 6) 

510 

511 def test_decode_signed_integral(self): 

512 self._check_decoder_success("-0", 0, 2, 0) 

513 self._check_decoder_success("{ } -0", 4, 2, 0) 

514 self._check_decoder_success("-0 { }", 0, 2, 0) 

515 self._check_decoder_success("-1", 0, 2, -1) 

516 self._check_decoder_success("-9223372036854775808", 0, 20, -9223372036854775808) 

517 

518 self._check_decoder_failure("--10", 0, 1) 

519 self._check_decoder_failure("-", 0, 1) 

520 

521 def test_decode_unsigned_integral(self): 

522 self._check_decoder_success("0", 0, 1, 0) 

523 self._check_decoder_success("{ } 0", 4, 1, 0) 

524 self._check_decoder_success("0 { }", 0, 1, 0) 

525 self._check_decoder_success("1", 0, 1, 1) 

526 self._check_decoder_success("9223372036854775807", 0, 19, 9223372036854775807) 

527 self._check_decoder_success("18446744073709551615", 0, 20, 18446744073709551615) 

528 

529 self._check_decoder_failure("+10", 0, 1) 

530 

531 def test_decode_double(self): 

532 self._check_decoder_success("0.0", 0, 3, 0.0) 

533 self._check_decoder_success("{ } 0.0", 4, 3, 0.0) 

534 self._check_decoder_success("0.0 { }", 0, 3, 0.0) 

535 self._check_decoder_success("-1.0", 0, 4, -1.0) 

536 self._check_decoder_success("1.0", 0, 3, 1.0) 

537 self._check_decoder_success("3.5", 0, 3, 3.5) 

538 self._check_decoder_success("9.875", 0, 5, 9.875) 

539 self._check_decoder_success("0.6171875", 0, 9, 0.6171875) 

540 

541 self._check_decoder_success("1e+20", 0, 5, 1e+20) 

542 self._check_decoder_success("1E+20", 0, 5, 1E+20) 

543 self._check_decoder_success("1e-20", 0, 5, 1e-20) 

544 self._check_decoder_success("1E-20", 0, 5, 1E-20) 

545 self._check_decoder_success("-1e+20", 0, 6, -1e+20) 

546 self._check_decoder_success("-1E+20", 0, 6, -1E+20) 

547 self._check_decoder_success("-1e-20", 0, 6, -1e-20) 

548 self._check_decoder_success("-1E-20", 0, 6, -1E-20) 

549 

550 self._check_decoder_failure("1EE20", 0, 2) 

551 self._check_decoder_failure("1E++20", 0, 3) 

552 

553 self._check_decoder_failure("1e", 0, 2) 

554 self._check_decoder_failure("1e+", 0, 3) 

555 self._check_decoder_failure("1E-", 0, 3) 

556 

557 def test_decode_string(self): 

558 self._check_decoder_success("\"\"", 0, 2, "") 

559 self._check_decoder_success("{ } \"\"", 4, 2, "") 

560 self._check_decoder_success("\"\" { }", 0, 2, "") 

561 

562 self._check_decoder_success("\"test\"", 0, 6, "test") 

563 self._check_decoder_success("\"München\"", 0, 9, "München") 

564 self._check_decoder_success("\"€\"", 0, 3, "€") 

565 

566 # escapes 

567 self._check_decoder_success("\"\\\\\"", 0, 4, "\\") 

568 self._check_decoder_success("\"\\\"\"", 0, 4, "\"") 

569 self._check_decoder_success("\"\\b\"", 0, 4, "\b") 

570 self._check_decoder_success("\"\\f\"", 0, 4, "\f") 

571 self._check_decoder_success("\"\\n\"", 0, 4, "\n") 

572 self._check_decoder_success("\"\\r\"", 0, 4, "\r") 

573 self._check_decoder_success("\"\\t\"", 0, 4, "\t") 

574 

575 self._check_decoder_success("\"\\n\\t%^@(*aAzZ01234569$%^!?<>[]](){}-=+~:;/|\\\\\\\"'Hello World2\"", 

576 0, 62, "\n\t%^@(*aAzZ01234569$%^!?<>[]](){}-=+~:;/|\\\"\'Hello World2") 

577 

578 # <= 0x1F -> unicode escape 

579 self._check_decoder_success("\"\\u001f\"", 0, 8, "\u001f") 

580 

581 self._check_decoder_failure("\"\\u001x\"", 0, 7) 

582 self._check_decoder_failure("\"unterminated", 0, 13) 

583 self._check_decoder_failure("\"wrong escape \\", 0, 15) 

584 self._check_decoder_failure("\"wrong unicode escape \\u0", 0, 25) 

585 self._check_decoder_failure("\"unknown escape \\x", 0, 18) 

586 

587 def test_wrong_arguments(self): 

588 self._check_decoder_failure("", 1, 0) 

589 

590 def _check_decoder_success(self, content, pos, expected_num_read, expected_value): 

591 result = JsonDecoder.decode_value(content, pos) 

592 self.assertEqual(True, result.success) 

593 if isinstance(expected_value, float) and math.isnan(expected_value): 

594 self.assertTrue(math.isnan(result.value)) 

595 else: 

596 self.assertEqual(expected_value, result.value) 

597 self.assertEqual(expected_num_read, result.num_read_chars) 

598 

599 def _check_decoder_failure(self, content, pos, expected_num_read): 

600 result = JsonDecoder.decode_value(content, pos) 

601 self.assertEqual(False, result.success) 

602 self.assertEqual(None, result.value) 

603 self.assertEqual(expected_num_read, result.num_read_chars) 

604 

605class JsonTokenizerTest(unittest.TestCase): 

606 

607 def test_tokens(self): 

608 text_io = io.StringIO("{\"array\":\n[\n{\"key\":\n10}]}") 

609 tokenizer = JsonTokenizer(text_io) 

610 

611 self.assertEqual(JsonToken.BEGIN_OBJECT, tokenizer.next()) 

612 self.assertEqual('{', tokenizer.get_value()) 

613 self.assertEqual(JsonToken.VALUE, tokenizer.next()) 

614 self.assertEqual("array", tokenizer.get_value()) 

615 self.assertEqual(JsonToken.KEY_SEPARATOR, tokenizer.next()) 

616 self.assertEqual(':', tokenizer.get_value()) 

617 self.assertEqual(JsonToken.BEGIN_ARRAY, tokenizer.next()) 

618 self.assertEqual('[', tokenizer.get_value()) 

619 self.assertEqual(JsonToken.BEGIN_OBJECT, tokenizer.next()) 

620 self.assertEqual('{', tokenizer.get_value()) 

621 self.assertEqual(JsonToken.VALUE, tokenizer.next()) 

622 self.assertEqual("key", tokenizer.get_value()) 

623 self.assertEqual(JsonToken.KEY_SEPARATOR, tokenizer.next()) 

624 self.assertEqual(':', tokenizer.get_value()) 

625 self.assertEqual(JsonToken.VALUE, tokenizer.next()) 

626 self.assertEqual(10, tokenizer.get_value()) 

627 self.assertEqual(JsonToken.END_OBJECT, tokenizer.next()) 

628 self.assertEqual('}', tokenizer.get_value()) 

629 self.assertEqual(JsonToken.END_ARRAY, tokenizer.next()) 

630 self.assertEqual(']', tokenizer.get_value()) 

631 self.assertEqual(JsonToken.END_OBJECT, tokenizer.next()) 

632 self.assertEqual('}', tokenizer.get_value()) 

633 self.assertEqual(JsonToken.END_OF_FILE, tokenizer.next()) 

634 

635 def test_line_column(self): 

636 text_io = io.StringIO("\n{\r \"key\" \n :\n10}\r") 

637 tokenizer = JsonTokenizer(text_io) 

638 

639 self.assertEqual(JsonToken.BEGIN_OBJECT, tokenizer.next()) 

640 self.assertEqual('{', tokenizer.get_value()) 

641 self.assertEqual(2, tokenizer.get_line()) 

642 self.assertEqual(1, tokenizer.get_column()) 

643 

644 self.assertEqual(JsonToken.VALUE, tokenizer.next()) 

645 self.assertEqual("key", tokenizer.get_value()) 

646 self.assertEqual(3, tokenizer.get_line()) 

647 self.assertEqual(4, tokenizer.get_column()) 

648 

649 self.assertEqual(JsonToken.KEY_SEPARATOR, tokenizer.next()) 

650 self.assertEqual(':', tokenizer.get_value()) 

651 self.assertEqual(4, tokenizer.get_line()) 

652 self.assertEqual(2, tokenizer.get_column()) 

653 

654 self.assertEqual(JsonToken.VALUE, tokenizer.next()) 

655 self.assertEqual(10, tokenizer.get_value()) 

656 self.assertEqual(5, tokenizer.get_line()) 

657 self.assertEqual(1, tokenizer.get_column()) 

658 

659 self.assertEqual(JsonToken.END_OBJECT, tokenizer.next()) 

660 self.assertEqual('}', tokenizer.get_value()) 

661 self.assertEqual(5, tokenizer.get_line()) 

662 self.assertEqual(3, tokenizer.get_column()) 

663 

664 self.assertEqual(JsonToken.END_OF_FILE, tokenizer.next()) 

665 self.assertEqual(5, tokenizer.get_line()) 

666 self.assertEqual(4, tokenizer.get_column()) 

667 

668 def test_long_input_split_in_number(self): 

669 json_string = "" 

670 json_string += "{\n" # 2 chars 

671 k = 4000 

672 for i in range(k): # 20 x 4000 > 65534 to check reading by chunks 

673 # BUFFER_SIZE is 65536, thus 65534 % 20 gives position within the string below 

674 # where the buffer will be split => 14, which is somewhere in the middle of the number 

675 # |-> <-| 

676 json_string += " \"key\": 100000000,\n" # 20 chars 

677 json_string += " \"key\": 100000000\n" 

678 json_string += "}" 

679 

680 text_io = io.StringIO(json_string) 

681 tokenizer = JsonTokenizer(text_io) 

682 

683 self.assertEqual(JsonToken.BEGIN_OBJECT, tokenizer.next()) 

684 self.assertEqual('{', tokenizer.get_value()) 

685 self.assertEqual(1, tokenizer.get_line()) 

686 self.assertEqual(1, tokenizer.get_column()) 

687 

688 for i in range(k): 

689 self.assertEqual(JsonToken.VALUE, tokenizer.next()) 

690 self.assertEqual("key", tokenizer.get_value()) 

691 self.assertEqual(1 + i + 1, tokenizer.get_line()) 

692 self.assertEqual(3, tokenizer.get_column()) 

693 

694 self.assertEqual(JsonToken.KEY_SEPARATOR, tokenizer.next()) 

695 self.assertEqual(':', tokenizer.get_value()) 

696 self.assertEqual(1 + i + 1, tokenizer.get_line()) 

697 self.assertEqual(8, tokenizer.get_column()) 

698 

699 self.assertEqual(JsonToken.VALUE, tokenizer.next()) 

700 self.assertEqual(100000000, tokenizer.get_value()) 

701 self.assertEqual(1 + i + 1, tokenizer.get_line()) 

702 self.assertEqual(10, tokenizer.get_column()) 

703 

704 self.assertEqual(JsonToken.ITEM_SEPARATOR, tokenizer.next()) 

705 self.assertEqual(',', tokenizer.get_value()) 

706 self.assertEqual(1 + i + 1, tokenizer.get_line()) 

707 self.assertEqual(19, tokenizer.get_column()) 

708 

709 self.assertEqual(JsonToken.VALUE, tokenizer.next()) 

710 self.assertEqual("key", tokenizer.get_value()) 

711 self.assertEqual(1 + k + 1, tokenizer.get_line()) 

712 self.assertEqual(3, tokenizer.get_column()) 

713 

714 self.assertEqual(JsonToken.KEY_SEPARATOR, tokenizer.next()) 

715 self.assertEqual(':', tokenizer.get_value()) 

716 self.assertEqual(1 + k + 1, tokenizer.get_line()) 

717 self.assertEqual(8, tokenizer.get_column()) 

718 

719 self.assertEqual(JsonToken.VALUE, tokenizer.next()) 

720 self.assertEqual(100000000, tokenizer.get_value()) 

721 self.assertEqual(1 + k + 1, tokenizer.get_line()) 

722 self.assertEqual(10, tokenizer.get_column()) 

723 

724 self.assertEqual(JsonToken.END_OBJECT, tokenizer.next()) 

725 self.assertEqual(1 + k + 2, tokenizer.get_line()) 

726 self.assertEqual(1, tokenizer.get_column()) 

727 

728 def test_long_input_split_in_string(self): 

729 json_string = "" 

730 json_string += "{\n" # 2 chars 

731 k = 4000 

732 for i in range(k): # 20 x 4000 > 65534 to check reading by chunks 

733 # BUFFER_SIZE is 65536, thus 65534 % 20 gives position within the string below 

734 # where the buffer will be split => 14, which is somewhere in the middle of the number 

735 # |-> <-| 

736 json_string += " \"key\": \"1000000\",\n" # 20 chars 

737 json_string += " \"key\": \"1000000\"\n" 

738 json_string += "}" 

739 

740 text_io = io.StringIO(json_string) 

741 tokenizer = JsonTokenizer(text_io) 

742 

743 self.assertEqual(JsonToken.BEGIN_OBJECT, tokenizer.next()) 

744 self.assertEqual('{', tokenizer.get_value()) 

745 self.assertEqual(1, tokenizer.get_line()) 

746 self.assertEqual(1, tokenizer.get_column()) 

747 

748 for i in range(k): 

749 self.assertEqual(JsonToken.VALUE, tokenizer.next()) 

750 self.assertEqual("key", tokenizer.get_value()) 

751 self.assertEqual(1 + i + 1, tokenizer.get_line()) 

752 self.assertEqual(3, tokenizer.get_column()) 

753 

754 self.assertEqual(JsonToken.KEY_SEPARATOR, tokenizer.next()) 

755 self.assertEqual(':', tokenizer.get_value()) 

756 self.assertEqual(1 + i + 1, tokenizer.get_line()) 

757 self.assertEqual(8, tokenizer.get_column()) 

758 

759 self.assertEqual(JsonToken.VALUE, tokenizer.next()) 

760 self.assertEqual("1000000", tokenizer.get_value()) 

761 self.assertEqual(1 + i + 1, tokenizer.get_line()) 

762 self.assertEqual(10, tokenizer.get_column()) 

763 

764 self.assertEqual(JsonToken.ITEM_SEPARATOR, tokenizer.next()) 

765 self.assertEqual(',', tokenizer.get_value()) 

766 self.assertEqual(1 + i + 1, tokenizer.get_line()) 

767 self.assertEqual(19, tokenizer.get_column()) 

768 

769 self.assertEqual(JsonToken.VALUE, tokenizer.next()) 

770 self.assertEqual("key", tokenizer.get_value()) 

771 self.assertEqual(1 + k + 1, tokenizer.get_line()) 

772 self.assertEqual(3, tokenizer.get_column()) 

773 

774 self.assertEqual(JsonToken.KEY_SEPARATOR, tokenizer.next()) 

775 self.assertEqual(':', tokenizer.get_value()) 

776 self.assertEqual(1 + k + 1, tokenizer.get_line()) 

777 self.assertEqual(8, tokenizer.get_column()) 

778 

779 self.assertEqual(JsonToken.VALUE, tokenizer.next()) 

780 self.assertEqual("1000000", tokenizer.get_value()) 

781 self.assertEqual(1 + k + 1, tokenizer.get_line()) 

782 self.assertEqual(10, tokenizer.get_column()) 

783 

784 self.assertEqual(JsonToken.END_OBJECT, tokenizer.next()) 

785 self.assertEqual(1 + k + 2, tokenizer.get_line()) 

786 self.assertEqual(1, tokenizer.get_column()) 

787 

788 def test_long_input_split_in_double_after_e(self): 

789 json_string = "" 

790 json_string += "{\n" # 2 chars 

791 k = 4000 

792 for i in range(k): # 20 x 4000 > 65534 to check reading by chunks 

793 # BUFFER_SIZE is 65536, thus 65534 % 20 gives position within the string below 

794 # where the buffer will be split => 14, which is somewhere in the middle of the number 

795 # |-> <-| 

796 json_string += " \"key\": 1e5 ,\n" # 20 chars 

797 json_string += " \"key\": 1e5 \n" 

798 json_string += "}" 

799 

800 text_io = io.StringIO(json_string) 

801 tokenizer = JsonTokenizer(text_io) 

802 

803 self.assertEqual(JsonToken.BEGIN_OBJECT, tokenizer.next()) 

804 self.assertEqual('{', tokenizer.get_value()) 

805 self.assertEqual(1, tokenizer.get_line()) 

806 self.assertEqual(1, tokenizer.get_column()) 

807 

808 for i in range(k): 

809 self.assertEqual(JsonToken.VALUE, tokenizer.next()) 

810 self.assertEqual("key", tokenizer.get_value()) 

811 self.assertEqual(1 + i + 1, tokenizer.get_line()) 

812 self.assertEqual(3, tokenizer.get_column()) 

813 

814 self.assertEqual(JsonToken.KEY_SEPARATOR, tokenizer.next()) 

815 self.assertEqual(':', tokenizer.get_value()) 

816 self.assertEqual(1 + i + 1, tokenizer.get_line()) 

817 self.assertEqual(8, tokenizer.get_column()) 

818 

819 self.assertEqual(JsonToken.VALUE, tokenizer.next()) 

820 self.assertEqual(1e5, tokenizer.get_value()) 

821 self.assertEqual(1 + i + 1, tokenizer.get_line()) 

822 self.assertEqual(13, tokenizer.get_column()) 

823 

824 self.assertEqual(JsonToken.ITEM_SEPARATOR, tokenizer.next()) 

825 self.assertEqual(',', tokenizer.get_value()) 

826 self.assertEqual(1 + i + 1, tokenizer.get_line()) 

827 self.assertEqual(19, tokenizer.get_column()) 

828 

829 self.assertEqual(JsonToken.VALUE, tokenizer.next()) 

830 self.assertEqual("key", tokenizer.get_value()) 

831 self.assertEqual(1 + k + 1, tokenizer.get_line()) 

832 self.assertEqual(3, tokenizer.get_column()) 

833 

834 self.assertEqual(JsonToken.KEY_SEPARATOR, tokenizer.next()) 

835 self.assertEqual(':', tokenizer.get_value()) 

836 self.assertEqual(1 + k + 1, tokenizer.get_line()) 

837 self.assertEqual(8, tokenizer.get_column()) 

838 

839 self.assertEqual(JsonToken.VALUE, tokenizer.next()) 

840 self.assertEqual(1e5, tokenizer.get_value()) 

841 self.assertEqual(1 + k + 1, tokenizer.get_line()) 

842 self.assertEqual(13, tokenizer.get_column()) 

843 

844 self.assertEqual(JsonToken.END_OBJECT, tokenizer.next()) 

845 self.assertEqual(1 + k + 2, tokenizer.get_line()) 

846 self.assertEqual(1, tokenizer.get_column()) 

847 

848 def test_unknown_token(self): 

849 text_io = io.StringIO("\\\n") 

850 tokenizer = JsonTokenizer(text_io) 

851 with self.assertRaises(JsonParserException) as error: 

852 tokenizer.next() 

853 self.assertEqual("JsonTokenizer:1:1: Unknown token!", str(error.exception)) 

854 

855class JsonReaderTest(unittest.TestCase): 

856 

857 def test_json_reader_object_value_adapter(self): 

858 object_value_adapter = JsonReader._ObjectValueAdapter() 

859 with self.assertRaises(NotImplementedError): 

860 object_value_adapter.get() 

861 

862 def test_read_object(self): 

863 text_io = io.StringIO( 

864 "{\n" + 

865 " \"value\": 13,\n" + 

866 " \"nested\": {\n" + 

867 " \"value\": 10,\n" + 

868 " \"text\": \"nested\",\n" + 

869 " \"externData\": {\n" + 

870 " \"buffer\": [\n" + 

871 " 203,\n" + 

872 " 240\n" + 

873 " ],\n" + 

874 " \"bitSize\": 12\n" + 

875 " },\n" + 

876 " \"bytesData\": {\n" + 

877 " \"buffer\": [\n" + 

878 " 202,\n" + 

879 " 254\n" + 

880 " ]\n" + 

881 " },\n" + 

882 " \"creatorEnum\": 0,\n" + 

883 " \"creatorBitmask\": 1\n" + 

884 " },\n" + 

885 " \"text\": \"test\",\n" + 

886 " \"nestedArray\": [\n" + 

887 " {\n" + 

888 " \"value\": 5,\n" + 

889 " \"text\": \"nestedArray\",\n" + 

890 " \"externData\": {\n" + 

891 " \"buffer\": [\n" + 

892 " 202,\n" + 

893 " 254\n" + 

894 " ]," + 

895 " \"bitSize\": 15\n" + 

896 " },\n" + 

897 " \"bytesData\": {\n" 

898 " \"buffer\": [\n" 

899 " 203,\n" 

900 " 240\n" 

901 " ]\n" 

902 " },\n" 

903 " \"creatorEnum\": 1,\n" + 

904 " \"creatorBitmask\": 2\n" + 

905 " }\n" + 

906 " ],\n" + 

907 " \"textArray\": [\n" + 

908 " \"this\",\n" + 

909 " \"is\",\n" + 

910 " \"text\",\n" + 

911 " \"array\"\n" + 

912 " ],\n" + 

913 " \"externArray\": [\n" + 

914 " {\n" + 

915 " \"buffer\": [\n" + 

916 " 222,\n" + 

917 " 209\n" + 

918 " ]," + 

919 " \"bitSize\": 13\n" + 

920 " }\n" + 

921 " ],\n" + 

922 " \"bytesArray\": [\n" + 

923 " {\n" + 

924 " \"buffer\": [\n" + 

925 " 0\n" + 

926 " ]\n" + 

927 " }\n" + 

928 " ],\n" + 

929 " \"optionalBool\": null\n" + 

930 "}" 

931 ) 

932 

933 json_reader = JsonReader(text_io) 

934 creator_object = json_reader.read(CreatorObject.type_info()) 

935 self.assertTrue(creator_object is not None) 

936 self.assertTrue(isinstance(creator_object, CreatorObject)) 

937 

938 self.assertEqual(13, creator_object.value) 

939 self.assertEqual(13, creator_object.nested.param) 

940 self.assertEqual(10, creator_object.nested.value) 

941 self.assertEqual("nested", creator_object.nested.text) 

942 self.assertEqual(BitBuffer(bytes([0xCB, 0xF0]), 12), creator_object.nested.extern_data) 

943 self.assertEqual(bytes([0xCA, 0xFE]), creator_object.nested.bytes_data) 

944 self.assertEqual(CreatorEnum.ONE, creator_object.nested.creator_enum) 

945 self.assertEqual(CreatorBitmask.Values.READ, creator_object.nested.creator_bitmask) 

946 self.assertEqual("test", creator_object.text) 

947 self.assertEqual(1, len(creator_object.nested_array)) 

948 self.assertEqual(5, creator_object.nested_array[0].value) 

949 self.assertEqual("nestedArray", creator_object.nested_array[0].text) 

950 self.assertEqual(BitBuffer(bytes([0xCA, 0xFE]), 15), creator_object.nested_array[0].extern_data) 

951 self.assertEqual(bytes([0xCB, 0xF0]), creator_object.nested_array[0].bytes_data) 

952 self.assertEqual(CreatorEnum.TWO, creator_object.nested_array[0].creator_enum) 

953 self.assertEqual(CreatorBitmask.Values.WRITE, creator_object.nested_array[0].creator_bitmask) 

954 self.assertEqual(4, len(creator_object.text_array)) 

955 self.assertEqual("this", creator_object.text_array[0]) 

956 self.assertEqual("is", creator_object.text_array[1]) 

957 self.assertEqual("text", creator_object.text_array[2]) 

958 self.assertEqual("array", creator_object.text_array[3]) 

959 self.assertEqual(1, len(creator_object.extern_array)) 

960 self.assertEqual(BitBuffer(bytes([0xDE, 0xD1]), 13), creator_object.extern_array[0]) 

961 self.assertEqual(1, len(creator_object.bytes_array)) 

962 self.assertEqual(bytes([0]), creator_object.bytes_array[0]) 

963 self.assertEqual(None, creator_object.optional_bool) 

964 self.assertEqual(None, creator_object.optional_nested) # not present in json 

965 

966 def test_read_two_objects(self): 

967 text_io = io.StringIO( 

968 "{\"value\": 13}\n" + 

969 "{\"value\": 42, \"text\": \"test\"}\n" 

970 ) 

971 

972 json_reader = JsonReader(text_io) 

973 creator_object1 = json_reader.read(CreatorObject.type_info()) 

974 self.assertTrue(creator_object1 is not None) 

975 self.assertTrue(isinstance(creator_object1, CreatorObject)) 

976 

977 self.assertEqual(13, creator_object1.value) 

978 self.assertEqual("", creator_object1.text) 

979 

980 creator_object2 = json_reader.read(CreatorObject.type_info()) 

981 self.assertTrue(creator_object2 is not None) 

982 self.assertTrue(isinstance(creator_object2, CreatorObject)) 

983 

984 self.assertEqual(42, creator_object2.value) 

985 self.assertEqual("test", creator_object2.text) 

986 

987 def test_read_unordered_bit_buffer(self): 

988 text_io = io.StringIO( 

989 "{\n" + 

990 " \"value\": 13,\n" + 

991 " \"nested\": {\n" + 

992 " \"value\": 10,\n" + 

993 " \"text\": \"nested\",\n" + 

994 " \"externData\": {\n" + 

995 " \"bitSize\": 12,\n" + 

996 " \"buffer\": [\n" + 

997 " 203,\n" + 

998 " 240\n" + 

999 " ]\n" + 

1000 " },\n" + 

1001 " \"bytesData\": {\n" + 

1002 " \"buffer\": [\n" + 

1003 " 202,\n" + 

1004 " 254\n" + 

1005 " ]\n" + 

1006 " },\n" + 

1007 " \"creatorEnum\": 0,\n" + 

1008 " \"creatorBitmask\": 1\n" + 

1009 " }\n" + 

1010 "}" 

1011 ) 

1012 

1013 json_reader = JsonReader(text_io) 

1014 creator_object = json_reader.read(CreatorObject.type_info()) 

1015 self.assertTrue(creator_object is not None) 

1016 self.assertTrue(isinstance(creator_object, CreatorObject)) 

1017 

1018 self.assertEqual(13, creator_object.value) 

1019 self.assertEqual(13, creator_object.nested.param) 

1020 self.assertEqual(10, creator_object.nested.value) 

1021 self.assertEqual("nested", creator_object.nested.text) 

1022 self.assertEqual(BitBuffer(bytes([0xCB, 0xF0]), 12), creator_object.nested.extern_data) 

1023 self.assertEqual(bytes([0xCA, 0xFE]), creator_object.nested.bytes_data) 

1024 self.assertEqual(CreatorEnum.ONE, creator_object.nested.creator_enum) 

1025 self.assertEqual(CreatorBitmask.Values.READ, creator_object.nested.creator_bitmask) 

1026 

1027 def test_read_stringified_enum(self): 

1028 self._check_read_stringified_enum("ONE", CreatorEnum.ONE) 

1029 self._check_read_stringified_enum("MinusOne", CreatorEnum.MINUS_ONE) 

1030 self._check_read_stringified_enum_raises("NONEXISTING", 

1031 "JsonReader: Cannot create enum 'test_object.CreatorEnum' " 

1032 "from string value 'NONEXISTING'! (JsonParser:3:24)") 

1033 self._check_read_stringified_enum_raises("***", 

1034 "JsonReader: Cannot create enum 'test_object.CreatorEnum' " 

1035 "from string value '***'! (JsonParser:3:24)") 

1036 self._check_read_stringified_enum_raises("10 /* no match */", 

1037 "JsonReader: Cannot create enum 'test_object.CreatorEnum' " 

1038 "from string value '10 /* no match */'! (JsonParser:3:24)") 

1039 self._check_read_stringified_enum_raises("-10 /* no match */", 

1040 "JsonReader: Cannot create enum 'test_object.CreatorEnum' " 

1041 "from string value '-10 /* no match */'! (JsonParser:3:24)") 

1042 self._check_read_stringified_enum_raises("", 

1043 "JsonReader: Cannot create enum 'test_object.CreatorEnum' " 

1044 "from string value ''! (JsonParser:3:24)") 

1045 

1046 def test_read_stringified_bitmask(self): 

1047 self._check_read_stringified_bitmask("READ", CreatorBitmask.Values.READ) 

1048 self._check_read_stringified_bitmask("READ | WRITE", 

1049 CreatorBitmask.Values.READ | CreatorBitmask.Values.WRITE) 

1050 self._check_read_stringified_bitmask_raises("NONEXISTING", 

1051 "JsonReader: Cannot create bitmask 'test_object.CreatorBitmask' " + 

1052 "from string value 'NONEXISTING'! (JsonParser:3:27)") 

1053 self._check_read_stringified_bitmask_raises("READ | NONEXISTING", 

1054 "JsonReader: Cannot create bitmask 'test_object.CreatorBitmask' " + 

1055 "from string value 'READ | NONEXISTING'! (JsonParser:3:27)") 

1056 self._check_read_stringified_bitmask_raises("READ * NONEXISTING", 

1057 "JsonReader: Cannot create bitmask 'test_object.CreatorBitmask' " + 

1058 "from string value 'READ * NONEXISTING'! (JsonParser:3:27)") 

1059 self._check_read_stringified_bitmask("7 /* READ | WRITE */", CreatorBitmask.from_value(7)) 

1060 self._check_read_stringified_bitmask("15 /* READ | WRITE */", CreatorBitmask.from_value(15)) 

1061 self._check_read_stringified_bitmask("4 /* no match */", CreatorBitmask.from_value(4)) 

1062 self._check_read_stringified_bitmask_raises("", 

1063 "JsonReader: Cannot create bitmask 'test_object.CreatorBitmask' " + 

1064 "from string value ''! (JsonParser:3:27)") 

1065 self._check_read_stringified_bitmask_raises(" ", 

1066 "JsonReader: Cannot create bitmask 'test_object.CreatorBitmask' " + 

1067 "from string value ' '! (JsonParser:3:27)") 

1068 self._check_read_stringified_bitmask_raises(" | ", 

1069 "JsonReader: Cannot create bitmask 'test_object.CreatorBitmask' " + 

1070 "from string value ' | '! (JsonParser:3:27)") 

1071 

1072 def test_json_parser_exception(self): 

1073 text_io = io.StringIO( 

1074 "{\"value\"\n\"value\"" 

1075 ) 

1076 

1077 json_reader = JsonReader(text_io) 

1078 with self.assertRaises(JsonParserException) as error: 

1079 json_reader.read(CreatorObject.type_info()) 

1080 self.assertEqual("JsonParser:2:1: Unexpected token: JsonToken.VALUE ('value'), " + 

1081 "expecting JsonToken.KEY_SEPARATOR!", str(error.exception)) 

1082 

1083 def test_wrong_key_exception(self): 

1084 text_io = io.StringIO( 

1085 "{\"value\": 13,\n\"nonexisting\": 10}" 

1086 ) 

1087 

1088 json_reader = JsonReader(text_io) 

1089 with self.assertRaises(PythonRuntimeException) as error: 

1090 json_reader.read(CreatorObject.type_info()) 

1091 self.assertEqual("ZserioTreeCreator: Field 'nonexisting' not found in " + 

1092 "'test_object.CreatorObject'! (JsonParser:2:16)", str(error.exception)) 

1093 

1094 def test_wrong_value_type_exception(self): 

1095 text_io = io.StringIO( 

1096 "{\n \"value\": \"13\"\n}" 

1097 ) 

1098 

1099 json_reader = JsonReader(text_io) 

1100 with self.assertRaises(PythonRuntimeException) as error: 

1101 json_reader.read(CreatorObject.type_info()) 

1102 self.assertEqual("ZserioTreeCreator: Unexpected value type '<class 'str'>', " + 

1103 "expecting '<class 'int'>'! (JsonParser:2:12)", str(error.exception)) 

1104 

1105 def test_wrong_bit_buffer_exception(self): 

1106 text_io = io.StringIO( 

1107 "{\n" + 

1108 " \"value\": 13,\n" + 

1109 " \"nested\": {\n" + 

1110 " \"value\": 10,\n" + 

1111 " \"text\": \"nested\",\n" + 

1112 " \"externData\": {\n" + 

1113 " \"buffer\": [\n" + 

1114 " 203,\n" + 

1115 " 240\n" + 

1116 " ],\n" + 

1117 " \"bitSize\": {\n" + 

1118 " }\n" + 

1119 " }\n" + 

1120 " }\n" + 

1121 "}" 

1122 ) 

1123 

1124 json_reader = JsonReader(text_io) 

1125 with self.assertRaises(PythonRuntimeException) as error: 

1126 json_reader.read(CreatorObject.type_info()) 

1127 self.assertEqual("JsonReader: Unexpected begin object in Bit Buffer! (JsonParser:11:25)", 

1128 str(error.exception)) 

1129 

1130 def test_partial_bit_buffer_exception(self): 

1131 text_io = io.StringIO( 

1132 "{\n" + 

1133 " \"value\": 13,\n" + 

1134 " \"nested\": {\n" + 

1135 " \"value\": 10,\n" + 

1136 " \"text\": \"nested\",\n" + 

1137 " \"externData\": {\n" + 

1138 " \"buffer\": [\n" + 

1139 " 203,\n" + 

1140 " 240\n" + 

1141 " ]\n" + 

1142 " }\n" + 

1143 " }\n" + 

1144 "}" 

1145 ) 

1146 

1147 json_reader = JsonReader(text_io) 

1148 with self.assertRaises(PythonRuntimeException) as error: 

1149 json_reader.read(CreatorObject.type_info()) 

1150 self.assertEqual("JsonReader: Unexpected end in Bit Buffer! (JsonParser:12:5)", str(error.exception)) 

1151 

1152 def test_wrong_bytes_exception(self): 

1153 text_io = io.StringIO( 

1154 "{\n" + 

1155 " \"value\": 13,\n" + 

1156 " \"nested\": {\n" + 

1157 " \"value\": 10,\n" + 

1158 " \"text\": \"nested\",\n" + 

1159 " \"externData\": {\n" + 

1160 " \"buffer\": [\n" + 

1161 " 203,\n" + 

1162 " 240\n" + 

1163 " ],\n" + 

1164 " \"bitSize\": 12\n" + 

1165 " },\n" + 

1166 " \"bytesData\": {\n" + 

1167 " \"buffer\": {}\n" + 

1168 " }\n" + 

1169 " }\n" + 

1170 "}" 

1171 ) 

1172 

1173 json_reader = JsonReader(text_io) 

1174 with self.assertRaises(PythonRuntimeException) as error: 

1175 json_reader.read(CreatorObject.type_info()) 

1176 self.assertEqual("JsonReader: Unexpected begin object in bytes! (JsonParser:14:23)", 

1177 str(error.exception)) 

1178 

1179 def test_partial_bytes_exception(self): 

1180 text_io = io.StringIO( 

1181 "{\n" + 

1182 " \"value\": 13,\n" + 

1183 " \"nested\": {\n" + 

1184 " \"bytesData\": {\n" + 

1185 " }\n" + 

1186 "}" 

1187 ) 

1188 

1189 json_reader = JsonReader(text_io) 

1190 with self.assertRaises(PythonRuntimeException) as error: 

1191 json_reader.read(CreatorObject.type_info()) 

1192 self.assertEqual("JsonReader: Unexpected end in bytes! (JsonParser:6:1)", 

1193 str(error.exception)) 

1194 

1195 def test_json_array_exception(self): 

1196 text_io = io.StringIO( 

1197 "[1, 2]" 

1198 ) 

1199 

1200 json_reader = JsonReader(text_io) 

1201 with self.assertRaises(PythonRuntimeException) as error: 

1202 json_reader.read(CreatorObject.type_info()) 

1203 self.assertEqual("JsonReader: ZserioTreeCreator expects json object! (JsonParser:1:1)", 

1204 str(error.exception)) 

1205 

1206 def test_json_value_exception(self): 

1207 text_io = io.StringIO( 

1208 "\"text\"" 

1209 ) 

1210 

1211 json_reader = JsonReader(text_io) 

1212 with self.assertRaises(PythonRuntimeException) as error: 

1213 json_reader.read(CreatorObject.type_info()) 

1214 self.assertEqual("JsonReader: ZserioTreeCreator expects json object! (JsonParser:1:1)", 

1215 str(error.exception)) 

1216 

1217 def test_bitbuffer_adapter_uninitialized_calls(self): 

1218 bitbuffer_adapter = JsonReader._BitBufferAdapter() 

1219 

1220 with self.assertRaises(PythonRuntimeException): 

1221 bitbuffer_adapter.begin_object() 

1222 with self.assertRaises(PythonRuntimeException): 

1223 bitbuffer_adapter.end_object() 

1224 with self.assertRaises(PythonRuntimeException): 

1225 bitbuffer_adapter.begin_array() 

1226 with self.assertRaises(PythonRuntimeException): 

1227 bitbuffer_adapter.end_array() 

1228 with self.assertRaises(PythonRuntimeException): 

1229 bitbuffer_adapter.visit_key("nonexisting") 

1230 bitbuffer_adapter.visit_key("buffer") 

1231 with self.assertRaises(PythonRuntimeException): 

1232 bitbuffer_adapter.visit_key("nonexisting") 

1233 with self.assertRaises(PythonRuntimeException): 

1234 bitbuffer_adapter.visit_value("BadValue") 

1235 

1236 def test_bytes_adapter_uninitialized_calls(self): 

1237 bytes_adapter = JsonReader._BytesAdapter() 

1238 

1239 with self.assertRaises(PythonRuntimeException): 

1240 bytes_adapter.begin_object() 

1241 with self.assertRaises(PythonRuntimeException): 

1242 bytes_adapter.end_object() 

1243 with self.assertRaises(PythonRuntimeException): 

1244 bytes_adapter.begin_array() 

1245 with self.assertRaises(PythonRuntimeException): 

1246 bytes_adapter.end_array() 

1247 with self.assertRaises(PythonRuntimeException): 

1248 bytes_adapter.visit_key("nonexisting") 

1249 bytes_adapter.visit_key("buffer") 

1250 with self.assertRaises(PythonRuntimeException): 

1251 bytes_adapter.visit_key("nonexisting") 

1252 with self.assertRaises(PythonRuntimeException): 

1253 bytes_adapter.visit_value("BadValue") 

1254 

1255 def test_creator_adapter_uninitialized_calls(self): 

1256 creator_adapter = JsonReader._CreatorAdapter() 

1257 

1258 with self.assertRaises(PythonRuntimeException): 

1259 creator_adapter.get() 

1260 with self.assertRaises(PythonRuntimeException): 

1261 creator_adapter.begin_object() 

1262 with self.assertRaises(PythonRuntimeException): 

1263 creator_adapter.end_object() 

1264 with self.assertRaises(PythonRuntimeException): 

1265 creator_adapter.begin_array() 

1266 with self.assertRaises(PythonRuntimeException): 

1267 creator_adapter.end_array() 

1268 with self.assertRaises(PythonRuntimeException): 

1269 creator_adapter.visit_key("key") 

1270 with self.assertRaises(PythonRuntimeException): 

1271 creator_adapter.visit_value(None) 

1272 

1273 def _check_read_stringified_enum(self, string_value, expected_value): 

1274 text_io = io.StringIO( 

1275 "{\n" 

1276 " \"nested\": {\n" 

1277 " \"creatorEnum\": \"" + string_value + "\"\n" 

1278 " }\n" 

1279 "}" 

1280 ) 

1281 

1282 json_reader = JsonReader(text_io) 

1283 creator_object = json_reader.read(CreatorObject.type_info()) 

1284 self.assertTrue(creator_object is not None) 

1285 self.assertTrue(isinstance(creator_object, CreatorObject)) 

1286 

1287 self.assertEqual(expected_value, creator_object.nested.creator_enum) 

1288 

1289 def _check_read_stringified_enum_raises(self, string_value, expected_message): 

1290 text_io = io.StringIO( 

1291 "{\n" 

1292 " \"nested\": {\n" 

1293 " \"creatorEnum\": \"" + string_value + "\"\n" 

1294 " }\n" 

1295 "}" 

1296 ) 

1297 

1298 json_reader = JsonReader(text_io) 

1299 with self.assertRaises(PythonRuntimeException) as error: 

1300 json_reader.read(CreatorObject.type_info()) 

1301 self.assertEqual(expected_message, str(error.exception)) 

1302 

1303 def _check_read_stringified_bitmask(self, string_value, expected_value): 

1304 text_io = io.StringIO( 

1305 "{\n" 

1306 " \"nested\": {\n" 

1307 " \"creatorBitmask\": \"" + string_value + "\"\n" 

1308 " }\n" 

1309 "}" 

1310 ) 

1311 

1312 json_reader = JsonReader(text_io) 

1313 creator_object = json_reader.read(CreatorObject.type_info()) 

1314 self.assertTrue(creator_object is not None) 

1315 self.assertTrue(isinstance(creator_object, CreatorObject)) 

1316 

1317 self.assertEqual(expected_value, creator_object.nested.creator_bitmask) 

1318 

1319 def _check_read_stringified_bitmask_raises(self, string_value, expected_message): 

1320 text_io = io.StringIO( 

1321 "{\n" 

1322 " \"nested\": {\n" 

1323 " \"creatorBitmask\": \"" + string_value + "\"\n" 

1324 " }\n" 

1325 "}" 

1326 ) 

1327 

1328 json_reader = JsonReader(text_io) 

1329 with self.assertRaises(PythonRuntimeException) as error: 

1330 json_reader.read(CreatorObject.type_info()) 

1331 self.assertEqual(expected_message, str(error.exception))