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
« prev ^ index » next coverage.py v6.5.0, created at 2023-12-13 15:12 +0000
1import enum
2import io
3import unittest
4import math
7from test_object.api import CreatorEnum, CreatorBitmask, CreatorObject
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
16class JsonWriterTest(unittest.TestCase):
18 def test_empty(self):
19 json_writer = JsonWriter()
20 self.assertEqual("", json_writer.get_io().getvalue())
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())
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())
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
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 })
49 test_enum_member_info = MemberInfo("enumField", test_enum_type_info)
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())
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())
71 def test_bitmask_value(self):
72 class TestBitmask:
73 def __init__(self, value):
74 self._value = value
76 @property
77 def value(self):
78 return self._value
80 class Values:
81 ZERO = None
82 ONE = None
83 TWO = None
85 TestBitmask.Values.ZERO = TestBitmask(0)
86 TestBitmask.Values.ONE = TestBitmask(1)
87 TestBitmask.Values.TWO = TestBitmask(2)
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 })
97 test_bitmask_member_info = MemberInfo("bitmaskField", test_bitmask_type_info)
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())
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())
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())
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())
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())
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())
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())
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())
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())
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())
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 )
185 @staticmethod
186 def _walk_nested(json_writer):
187 creator_type_info = TypeInfo("Creator", object)
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())
196 @staticmethod
197 def _walk_array(json_writer):
198 array_member_info = MemberInfo("array", TypeInfo("uint32", int), attributes={
199 MemberAttribute.ARRAY_LENGTH : None
200 })
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())
209class JsonEncoderTest(unittest.TestCase):
211 def test_encode_null(self):
212 json_encoder = JsonEncoder()
213 self.assertEqual("null", json_encoder.encode_value(None))
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))
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))
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))
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))
238 self.assertEqual("1e+20", json_encoder.encode_value(1e20))
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')))
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("€"))
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"))
260 self.assertEqual("\"\\n\\t%^@(*aAzZ01234569$%^!?<>[]](){}-=+~:;/|\\\\\\\"'Hello World2\"",
261 json_encoder.encode_value(
262 "\n\t%^@(*aAzZ01234569$%^!?<>[]](){}-=+~:;/|\\\"'Hello World2"))
264 # <= 0x1F -> unicode escape
265 self.assertEqual("\"\\u001f\"", json_encoder.encode_value("\x1f"))
267class JsonParserTest(unittest.TestCase):
269 class DummyObserver(JsonParser.Observer):
270 def __init__(self):
271 self._report = []
273 @property
274 def report(self):
275 return self._report
277 def begin_object(self):
278 self._report.append("begin_object")
280 def end_object(self):
281 self._report.append("end_object")
283 def begin_array(self):
284 self._report.append("begin_array")
286 def end_array(self):
287 self._report.append("end_array")
289 def visit_key(self, key):
290 self._report.append(f"visit_key: {key}")
292 def visit_value(self, value):
293 self._report.append(f"visit_value: {value}")
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)
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()
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 )
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)
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)
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)
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())
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)
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()
387 self.assertEqual("JsonParser:3:1: Unexpected token: JsonToken.BEGIN_OBJECT ('{'), "
388 "expecting JsonToken.END_OBJECT!", str(error.exception))
390 self.assertEqual(["begin_object"], observer.report)
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()
399 self.assertEqual("JsonParser:3:3: Unexpected token: JsonToken.BEGIN_OBJECT ('{'), "
400 "expecting JsonToken.VALUE!", str(error.exception))
402 self.assertEqual(["begin_object", "visit_key: key", "visit_value: 10"], observer.report)
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()
411 self.assertEqual("JsonParser:3:1: Unexpected token: JsonToken.VALUE ('item2'), "
412 "expecting JsonToken.END_OBJECT!", str(error.exception))
414 self.assertEqual([
415 "begin_object",
416 "visit_key: item1", "visit_value: text"
417 ], observer.report)
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()
426 self.assertEqual("JsonParser:2:1: Key must be a string value!", str(error.exception))
428 self.assertEqual(["begin_object"], observer.report)
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()
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))
441 self.assertEqual(["begin_object", "visit_key: item"], observer.report)
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()
450 self.assertEqual("JsonParser:4:1: Unexpected token: JsonToken.VALUE ('20'), "
451 "expecting JsonToken.END_ARRAY!", str(error.exception))
453 self.assertEqual([
454 "begin_object",
455 "visit_key: array",
456 "begin_array",
457 "visit_value: 10"
458 ], observer.report)
460class JsonDecoderTest(unittest.TestCase):
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)
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)
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)
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)
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)
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)
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)
518 self._check_decoder_failure("--10", 0, 1)
519 self._check_decoder_failure("-", 0, 1)
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)
529 self._check_decoder_failure("+10", 0, 1)
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)
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)
550 self._check_decoder_failure("1EE20", 0, 2)
551 self._check_decoder_failure("1E++20", 0, 3)
553 self._check_decoder_failure("1e", 0, 2)
554 self._check_decoder_failure("1e+", 0, 3)
555 self._check_decoder_failure("1E-", 0, 3)
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, "")
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, "€")
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")
575 self._check_decoder_success("\"\\n\\t%^@(*aAzZ01234569$%^!?<>[]](){}-=+~:;/|\\\\\\\"'Hello World2\"",
576 0, 62, "\n\t%^@(*aAzZ01234569$%^!?<>[]](){}-=+~:;/|\\\"\'Hello World2")
578 # <= 0x1F -> unicode escape
579 self._check_decoder_success("\"\\u001f\"", 0, 8, "\u001f")
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)
587 def test_wrong_arguments(self):
588 self._check_decoder_failure("", 1, 0)
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)
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)
605class JsonTokenizerTest(unittest.TestCase):
607 def test_tokens(self):
608 text_io = io.StringIO("{\"array\":\n[\n{\"key\":\n10}]}")
609 tokenizer = JsonTokenizer(text_io)
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())
635 def test_line_column(self):
636 text_io = io.StringIO("\n{\r \"key\" \n :\n10}\r")
637 tokenizer = JsonTokenizer(text_io)
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())
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())
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())
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())
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())
664 self.assertEqual(JsonToken.END_OF_FILE, tokenizer.next())
665 self.assertEqual(5, tokenizer.get_line())
666 self.assertEqual(4, tokenizer.get_column())
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 += "}"
680 text_io = io.StringIO(json_string)
681 tokenizer = JsonTokenizer(text_io)
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())
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())
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())
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())
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())
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())
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())
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())
724 self.assertEqual(JsonToken.END_OBJECT, tokenizer.next())
725 self.assertEqual(1 + k + 2, tokenizer.get_line())
726 self.assertEqual(1, tokenizer.get_column())
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 += "}"
740 text_io = io.StringIO(json_string)
741 tokenizer = JsonTokenizer(text_io)
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())
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())
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())
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())
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())
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())
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())
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())
784 self.assertEqual(JsonToken.END_OBJECT, tokenizer.next())
785 self.assertEqual(1 + k + 2, tokenizer.get_line())
786 self.assertEqual(1, tokenizer.get_column())
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 += "}"
800 text_io = io.StringIO(json_string)
801 tokenizer = JsonTokenizer(text_io)
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())
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())
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())
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())
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())
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())
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())
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())
844 self.assertEqual(JsonToken.END_OBJECT, tokenizer.next())
845 self.assertEqual(1 + k + 2, tokenizer.get_line())
846 self.assertEqual(1, tokenizer.get_column())
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))
855class JsonReaderTest(unittest.TestCase):
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()
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 )
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))
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
966 def test_read_two_objects(self):
967 text_io = io.StringIO(
968 "{\"value\": 13}\n" +
969 "{\"value\": 42, \"text\": \"test\"}\n"
970 )
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))
977 self.assertEqual(13, creator_object1.value)
978 self.assertEqual("", creator_object1.text)
980 creator_object2 = json_reader.read(CreatorObject.type_info())
981 self.assertTrue(creator_object2 is not None)
982 self.assertTrue(isinstance(creator_object2, CreatorObject))
984 self.assertEqual(42, creator_object2.value)
985 self.assertEqual("test", creator_object2.text)
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 )
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))
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)
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)")
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)")
1072 def test_json_parser_exception(self):
1073 text_io = io.StringIO(
1074 "{\"value\"\n\"value\""
1075 )
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))
1083 def test_wrong_key_exception(self):
1084 text_io = io.StringIO(
1085 "{\"value\": 13,\n\"nonexisting\": 10}"
1086 )
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))
1094 def test_wrong_value_type_exception(self):
1095 text_io = io.StringIO(
1096 "{\n \"value\": \"13\"\n}"
1097 )
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))
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 )
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))
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 )
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))
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 )
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))
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 )
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))
1195 def test_json_array_exception(self):
1196 text_io = io.StringIO(
1197 "[1, 2]"
1198 )
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))
1206 def test_json_value_exception(self):
1207 text_io = io.StringIO(
1208 "\"text\""
1209 )
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))
1217 def test_bitbuffer_adapter_uninitialized_calls(self):
1218 bitbuffer_adapter = JsonReader._BitBufferAdapter()
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")
1236 def test_bytes_adapter_uninitialized_calls(self):
1237 bytes_adapter = JsonReader._BytesAdapter()
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")
1255 def test_creator_adapter_uninitialized_calls(self):
1256 creator_adapter = JsonReader._CreatorAdapter()
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)
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 )
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))
1287 self.assertEqual(expected_value, creator_object.nested.creator_enum)
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 )
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))
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 )
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))
1317 self.assertEqual(expected_value, creator_object.nested.creator_bitmask)
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 )
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))