17db96d56Sopenharmony_cifrom test.test_json import PyTest, CTest
27db96d56Sopenharmony_ci
37db96d56Sopenharmony_ci# 2007-10-05
47db96d56Sopenharmony_ciJSONDOCS = [
57db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail1.json
67db96d56Sopenharmony_ci    '"A JSON payload should be an object or array, not a string."',
77db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail2.json
87db96d56Sopenharmony_ci    '["Unclosed array"',
97db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail3.json
107db96d56Sopenharmony_ci    '{unquoted_key: "keys must be quoted"}',
117db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail4.json
127db96d56Sopenharmony_ci    '["extra comma",]',
137db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail5.json
147db96d56Sopenharmony_ci    '["double extra comma",,]',
157db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail6.json
167db96d56Sopenharmony_ci    '[   , "<-- missing value"]',
177db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail7.json
187db96d56Sopenharmony_ci    '["Comma after the close"],',
197db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail8.json
207db96d56Sopenharmony_ci    '["Extra close"]]',
217db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail9.json
227db96d56Sopenharmony_ci    '{"Extra comma": true,}',
237db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail10.json
247db96d56Sopenharmony_ci    '{"Extra value after close": true} "misplaced quoted value"',
257db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail11.json
267db96d56Sopenharmony_ci    '{"Illegal expression": 1 + 2}',
277db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail12.json
287db96d56Sopenharmony_ci    '{"Illegal invocation": alert()}',
297db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail13.json
307db96d56Sopenharmony_ci    '{"Numbers cannot have leading zeroes": 013}',
317db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail14.json
327db96d56Sopenharmony_ci    '{"Numbers cannot be hex": 0x14}',
337db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail15.json
347db96d56Sopenharmony_ci    '["Illegal backslash escape: \\x15"]',
357db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail16.json
367db96d56Sopenharmony_ci    '[\\naked]',
377db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail17.json
387db96d56Sopenharmony_ci    '["Illegal backslash escape: \\017"]',
397db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail18.json
407db96d56Sopenharmony_ci    '[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]',
417db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail19.json
427db96d56Sopenharmony_ci    '{"Missing colon" null}',
437db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail20.json
447db96d56Sopenharmony_ci    '{"Double colon":: null}',
457db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail21.json
467db96d56Sopenharmony_ci    '{"Comma instead of colon", null}',
477db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail22.json
487db96d56Sopenharmony_ci    '["Colon instead of comma": false]',
497db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail23.json
507db96d56Sopenharmony_ci    '["Bad value", truth]',
517db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail24.json
527db96d56Sopenharmony_ci    "['single quote']",
537db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail25.json
547db96d56Sopenharmony_ci    '["\ttab\tcharacter\tin\tstring\t"]',
557db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail26.json
567db96d56Sopenharmony_ci    '["tab\\   character\\   in\\  string\\  "]',
577db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail27.json
587db96d56Sopenharmony_ci    '["line\nbreak"]',
597db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail28.json
607db96d56Sopenharmony_ci    '["line\\\nbreak"]',
617db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail29.json
627db96d56Sopenharmony_ci    '[0e]',
637db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail30.json
647db96d56Sopenharmony_ci    '[0e+]',
657db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail31.json
667db96d56Sopenharmony_ci    '[0e+-1]',
677db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail32.json
687db96d56Sopenharmony_ci    '{"Comma instead if closing brace": true,',
697db96d56Sopenharmony_ci    # https://json.org/JSON_checker/test/fail33.json
707db96d56Sopenharmony_ci    '["mismatch"}',
717db96d56Sopenharmony_ci    # https://code.google.com/archive/p/simplejson/issues/3
727db96d56Sopenharmony_ci    '["A\u001FZ control characters in string"]',
737db96d56Sopenharmony_ci]
747db96d56Sopenharmony_ci
757db96d56Sopenharmony_ciSKIPS = {
767db96d56Sopenharmony_ci    1: "why not have a string payload?",
777db96d56Sopenharmony_ci    18: "spec doesn't specify any nesting limitations",
787db96d56Sopenharmony_ci}
797db96d56Sopenharmony_ci
807db96d56Sopenharmony_ciclass TestFail:
817db96d56Sopenharmony_ci    def test_failures(self):
827db96d56Sopenharmony_ci        for idx, doc in enumerate(JSONDOCS):
837db96d56Sopenharmony_ci            idx = idx + 1
847db96d56Sopenharmony_ci            if idx in SKIPS:
857db96d56Sopenharmony_ci                self.loads(doc)
867db96d56Sopenharmony_ci                continue
877db96d56Sopenharmony_ci            try:
887db96d56Sopenharmony_ci                self.loads(doc)
897db96d56Sopenharmony_ci            except self.JSONDecodeError:
907db96d56Sopenharmony_ci                pass
917db96d56Sopenharmony_ci            else:
927db96d56Sopenharmony_ci                self.fail("Expected failure for fail{0}.json: {1!r}".format(idx, doc))
937db96d56Sopenharmony_ci
947db96d56Sopenharmony_ci    def test_non_string_keys_dict(self):
957db96d56Sopenharmony_ci        data = {'a' : 1, (1, 2) : 2}
967db96d56Sopenharmony_ci        with self.assertRaisesRegex(TypeError,
977db96d56Sopenharmony_ci                'keys must be str, int, float, bool or None, not tuple'):
987db96d56Sopenharmony_ci            self.dumps(data)
997db96d56Sopenharmony_ci
1007db96d56Sopenharmony_ci    def test_not_serializable(self):
1017db96d56Sopenharmony_ci        import sys
1027db96d56Sopenharmony_ci        with self.assertRaisesRegex(TypeError,
1037db96d56Sopenharmony_ci                'Object of type module is not JSON serializable'):
1047db96d56Sopenharmony_ci            self.dumps(sys)
1057db96d56Sopenharmony_ci
1067db96d56Sopenharmony_ci    def test_truncated_input(self):
1077db96d56Sopenharmony_ci        test_cases = [
1087db96d56Sopenharmony_ci            ('', 'Expecting value', 0),
1097db96d56Sopenharmony_ci            ('[', 'Expecting value', 1),
1107db96d56Sopenharmony_ci            ('[42', "Expecting ',' delimiter", 3),
1117db96d56Sopenharmony_ci            ('[42,', 'Expecting value', 4),
1127db96d56Sopenharmony_ci            ('["', 'Unterminated string starting at', 1),
1137db96d56Sopenharmony_ci            ('["spam', 'Unterminated string starting at', 1),
1147db96d56Sopenharmony_ci            ('["spam"', "Expecting ',' delimiter", 7),
1157db96d56Sopenharmony_ci            ('["spam",', 'Expecting value', 8),
1167db96d56Sopenharmony_ci            ('{', 'Expecting property name enclosed in double quotes', 1),
1177db96d56Sopenharmony_ci            ('{"', 'Unterminated string starting at', 1),
1187db96d56Sopenharmony_ci            ('{"spam', 'Unterminated string starting at', 1),
1197db96d56Sopenharmony_ci            ('{"spam"', "Expecting ':' delimiter", 7),
1207db96d56Sopenharmony_ci            ('{"spam":', 'Expecting value', 8),
1217db96d56Sopenharmony_ci            ('{"spam":42', "Expecting ',' delimiter", 10),
1227db96d56Sopenharmony_ci            ('{"spam":42,', 'Expecting property name enclosed in double quotes', 11),
1237db96d56Sopenharmony_ci        ]
1247db96d56Sopenharmony_ci        test_cases += [
1257db96d56Sopenharmony_ci            ('"', 'Unterminated string starting at', 0),
1267db96d56Sopenharmony_ci            ('"spam', 'Unterminated string starting at', 0),
1277db96d56Sopenharmony_ci        ]
1287db96d56Sopenharmony_ci        for data, msg, idx in test_cases:
1297db96d56Sopenharmony_ci            with self.assertRaises(self.JSONDecodeError) as cm:
1307db96d56Sopenharmony_ci                self.loads(data)
1317db96d56Sopenharmony_ci            err = cm.exception
1327db96d56Sopenharmony_ci            self.assertEqual(err.msg, msg)
1337db96d56Sopenharmony_ci            self.assertEqual(err.pos, idx)
1347db96d56Sopenharmony_ci            self.assertEqual(err.lineno, 1)
1357db96d56Sopenharmony_ci            self.assertEqual(err.colno, idx + 1)
1367db96d56Sopenharmony_ci            self.assertEqual(str(err),
1377db96d56Sopenharmony_ci                             '%s: line 1 column %d (char %d)' %
1387db96d56Sopenharmony_ci                             (msg, idx + 1, idx))
1397db96d56Sopenharmony_ci
1407db96d56Sopenharmony_ci    def test_unexpected_data(self):
1417db96d56Sopenharmony_ci        test_cases = [
1427db96d56Sopenharmony_ci            ('[,', 'Expecting value', 1),
1437db96d56Sopenharmony_ci            ('{"spam":[}', 'Expecting value', 9),
1447db96d56Sopenharmony_ci            ('[42:', "Expecting ',' delimiter", 3),
1457db96d56Sopenharmony_ci            ('[42 "spam"', "Expecting ',' delimiter", 4),
1467db96d56Sopenharmony_ci            ('[42,]', 'Expecting value', 4),
1477db96d56Sopenharmony_ci            ('{"spam":[42}', "Expecting ',' delimiter", 11),
1487db96d56Sopenharmony_ci            ('["]', 'Unterminated string starting at', 1),
1497db96d56Sopenharmony_ci            ('["spam":', "Expecting ',' delimiter", 7),
1507db96d56Sopenharmony_ci            ('["spam",]', 'Expecting value', 8),
1517db96d56Sopenharmony_ci            ('{:', 'Expecting property name enclosed in double quotes', 1),
1527db96d56Sopenharmony_ci            ('{,', 'Expecting property name enclosed in double quotes', 1),
1537db96d56Sopenharmony_ci            ('{42', 'Expecting property name enclosed in double quotes', 1),
1547db96d56Sopenharmony_ci            ('[{]', 'Expecting property name enclosed in double quotes', 2),
1557db96d56Sopenharmony_ci            ('{"spam",', "Expecting ':' delimiter", 7),
1567db96d56Sopenharmony_ci            ('{"spam"}', "Expecting ':' delimiter", 7),
1577db96d56Sopenharmony_ci            ('[{"spam"]', "Expecting ':' delimiter", 8),
1587db96d56Sopenharmony_ci            ('{"spam":}', 'Expecting value', 8),
1597db96d56Sopenharmony_ci            ('[{"spam":]', 'Expecting value', 9),
1607db96d56Sopenharmony_ci            ('{"spam":42 "ham"', "Expecting ',' delimiter", 11),
1617db96d56Sopenharmony_ci            ('[{"spam":42]', "Expecting ',' delimiter", 11),
1627db96d56Sopenharmony_ci            ('{"spam":42,}', 'Expecting property name enclosed in double quotes', 11),
1637db96d56Sopenharmony_ci        ]
1647db96d56Sopenharmony_ci        for data, msg, idx in test_cases:
1657db96d56Sopenharmony_ci            with self.assertRaises(self.JSONDecodeError) as cm:
1667db96d56Sopenharmony_ci                self.loads(data)
1677db96d56Sopenharmony_ci            err = cm.exception
1687db96d56Sopenharmony_ci            self.assertEqual(err.msg, msg)
1697db96d56Sopenharmony_ci            self.assertEqual(err.pos, idx)
1707db96d56Sopenharmony_ci            self.assertEqual(err.lineno, 1)
1717db96d56Sopenharmony_ci            self.assertEqual(err.colno, idx + 1)
1727db96d56Sopenharmony_ci            self.assertEqual(str(err),
1737db96d56Sopenharmony_ci                             '%s: line 1 column %d (char %d)' %
1747db96d56Sopenharmony_ci                             (msg, idx + 1, idx))
1757db96d56Sopenharmony_ci
1767db96d56Sopenharmony_ci    def test_extra_data(self):
1777db96d56Sopenharmony_ci        test_cases = [
1787db96d56Sopenharmony_ci            ('[]]', 'Extra data', 2),
1797db96d56Sopenharmony_ci            ('{}}', 'Extra data', 2),
1807db96d56Sopenharmony_ci            ('[],[]', 'Extra data', 2),
1817db96d56Sopenharmony_ci            ('{},{}', 'Extra data', 2),
1827db96d56Sopenharmony_ci        ]
1837db96d56Sopenharmony_ci        test_cases += [
1847db96d56Sopenharmony_ci            ('42,"spam"', 'Extra data', 2),
1857db96d56Sopenharmony_ci            ('"spam",42', 'Extra data', 6),
1867db96d56Sopenharmony_ci        ]
1877db96d56Sopenharmony_ci        for data, msg, idx in test_cases:
1887db96d56Sopenharmony_ci            with self.assertRaises(self.JSONDecodeError) as cm:
1897db96d56Sopenharmony_ci                self.loads(data)
1907db96d56Sopenharmony_ci            err = cm.exception
1917db96d56Sopenharmony_ci            self.assertEqual(err.msg, msg)
1927db96d56Sopenharmony_ci            self.assertEqual(err.pos, idx)
1937db96d56Sopenharmony_ci            self.assertEqual(err.lineno, 1)
1947db96d56Sopenharmony_ci            self.assertEqual(err.colno, idx + 1)
1957db96d56Sopenharmony_ci            self.assertEqual(str(err),
1967db96d56Sopenharmony_ci                             '%s: line 1 column %d (char %d)' %
1977db96d56Sopenharmony_ci                             (msg, idx + 1, idx))
1987db96d56Sopenharmony_ci
1997db96d56Sopenharmony_ci    def test_linecol(self):
2007db96d56Sopenharmony_ci        test_cases = [
2017db96d56Sopenharmony_ci            ('!', 1, 1, 0),
2027db96d56Sopenharmony_ci            (' !', 1, 2, 1),
2037db96d56Sopenharmony_ci            ('\n!', 2, 1, 1),
2047db96d56Sopenharmony_ci            ('\n  \n\n     !', 4, 6, 10),
2057db96d56Sopenharmony_ci        ]
2067db96d56Sopenharmony_ci        for data, line, col, idx in test_cases:
2077db96d56Sopenharmony_ci            with self.assertRaises(self.JSONDecodeError) as cm:
2087db96d56Sopenharmony_ci                self.loads(data)
2097db96d56Sopenharmony_ci            err = cm.exception
2107db96d56Sopenharmony_ci            self.assertEqual(err.msg, 'Expecting value')
2117db96d56Sopenharmony_ci            self.assertEqual(err.pos, idx)
2127db96d56Sopenharmony_ci            self.assertEqual(err.lineno, line)
2137db96d56Sopenharmony_ci            self.assertEqual(err.colno, col)
2147db96d56Sopenharmony_ci            self.assertEqual(str(err),
2157db96d56Sopenharmony_ci                             'Expecting value: line %s column %d (char %d)' %
2167db96d56Sopenharmony_ci                             (line, col, idx))
2177db96d56Sopenharmony_ci
2187db96d56Sopenharmony_ciclass TestPyFail(TestFail, PyTest): pass
2197db96d56Sopenharmony_ciclass TestCFail(TestFail, CTest): pass
220