blob: 5b652e864a7301b30f4148d34ff2dc335d7da5a8 [file] [log] [blame]
Ezio Melotti6b60fb92011-05-14 06:47:51 +03001from test.json_tests import PyTest, CTest
Ezio Melotti37623ab2013-01-03 08:44:15 +02002import re
Christian Heimes90540002008-05-08 14:29:10 +00003
Ezio Melotti8c523702012-11-26 19:24:20 +02004# 2007-10-05
Christian Heimes90540002008-05-08 14:29:10 +00005JSONDOCS = [
6 # http://json.org/JSON_checker/test/fail1.json
7 '"A JSON payload should be an object or array, not a string."',
8 # http://json.org/JSON_checker/test/fail2.json
9 '["Unclosed array"',
10 # http://json.org/JSON_checker/test/fail3.json
Ezio Melotti8c523702012-11-26 19:24:20 +020011 '{unquoted_key: "keys must be quoted"}',
Christian Heimes90540002008-05-08 14:29:10 +000012 # http://json.org/JSON_checker/test/fail4.json
13 '["extra comma",]',
14 # http://json.org/JSON_checker/test/fail5.json
15 '["double extra comma",,]',
16 # http://json.org/JSON_checker/test/fail6.json
17 '[ , "<-- missing value"]',
18 # http://json.org/JSON_checker/test/fail7.json
19 '["Comma after the close"],',
20 # http://json.org/JSON_checker/test/fail8.json
21 '["Extra close"]]',
22 # http://json.org/JSON_checker/test/fail9.json
23 '{"Extra comma": true,}',
24 # http://json.org/JSON_checker/test/fail10.json
25 '{"Extra value after close": true} "misplaced quoted value"',
26 # http://json.org/JSON_checker/test/fail11.json
27 '{"Illegal expression": 1 + 2}',
28 # http://json.org/JSON_checker/test/fail12.json
29 '{"Illegal invocation": alert()}',
30 # http://json.org/JSON_checker/test/fail13.json
31 '{"Numbers cannot have leading zeroes": 013}',
32 # http://json.org/JSON_checker/test/fail14.json
33 '{"Numbers cannot be hex": 0x14}',
34 # http://json.org/JSON_checker/test/fail15.json
35 '["Illegal backslash escape: \\x15"]',
36 # http://json.org/JSON_checker/test/fail16.json
Ezio Melotti8c523702012-11-26 19:24:20 +020037 '[\\naked]',
Christian Heimes90540002008-05-08 14:29:10 +000038 # http://json.org/JSON_checker/test/fail17.json
39 '["Illegal backslash escape: \\017"]',
40 # http://json.org/JSON_checker/test/fail18.json
41 '[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]',
42 # http://json.org/JSON_checker/test/fail19.json
43 '{"Missing colon" null}',
44 # http://json.org/JSON_checker/test/fail20.json
45 '{"Double colon":: null}',
46 # http://json.org/JSON_checker/test/fail21.json
47 '{"Comma instead of colon", null}',
48 # http://json.org/JSON_checker/test/fail22.json
49 '["Colon instead of comma": false]',
50 # http://json.org/JSON_checker/test/fail23.json
51 '["Bad value", truth]',
52 # http://json.org/JSON_checker/test/fail24.json
53 "['single quote']",
Ezio Melotti8c523702012-11-26 19:24:20 +020054 # http://json.org/JSON_checker/test/fail25.json
55 '["\ttab\tcharacter\tin\tstring\t"]',
56 # http://json.org/JSON_checker/test/fail26.json
57 '["tab\\ character\\ in\\ string\\ "]',
58 # http://json.org/JSON_checker/test/fail27.json
59 '["line\nbreak"]',
60 # http://json.org/JSON_checker/test/fail28.json
61 '["line\\\nbreak"]',
62 # http://json.org/JSON_checker/test/fail29.json
63 '[0e]',
64 # http://json.org/JSON_checker/test/fail30.json
65 '[0e+]',
66 # http://json.org/JSON_checker/test/fail31.json
67 '[0e+-1]',
68 # http://json.org/JSON_checker/test/fail32.json
69 '{"Comma instead if closing brace": true,',
70 # http://json.org/JSON_checker/test/fail33.json
71 '["mismatch"}',
Christian Heimes90540002008-05-08 14:29:10 +000072 # http://code.google.com/p/simplejson/issues/detail?id=3
73 '["A\u001FZ control characters in string"]',
74]
75
76SKIPS = {
77 1: "why not have a string payload?",
78 18: "spec doesn't specify any nesting limitations",
79}
80
Ezio Melotti6b60fb92011-05-14 06:47:51 +030081class TestFail:
Christian Heimes90540002008-05-08 14:29:10 +000082 def test_failures(self):
83 for idx, doc in enumerate(JSONDOCS):
84 idx = idx + 1
85 if idx in SKIPS:
Ezio Melotti6b60fb92011-05-14 06:47:51 +030086 self.loads(doc)
Christian Heimes90540002008-05-08 14:29:10 +000087 continue
88 try:
Ezio Melotti6b60fb92011-05-14 06:47:51 +030089 self.loads(doc)
Christian Heimes90540002008-05-08 14:29:10 +000090 except ValueError:
91 pass
92 else:
Benjamin Petersonc6b607d2009-05-02 12:36:44 +000093 self.fail("Expected failure for fail{0}.json: {1!r}".format(idx, doc))
Doug Hellmann1c524752010-07-21 12:29:04 +000094
95 def test_non_string_keys_dict(self):
96 data = {'a' : 1, (1, 2) : 2}
97
98 #This is for c encoder
Ezio Melotti6b60fb92011-05-14 06:47:51 +030099 self.assertRaises(TypeError, self.dumps, data)
Doug Hellmann1c524752010-07-21 12:29:04 +0000100
101 #This is for python encoder
Ezio Melotti6b60fb92011-05-14 06:47:51 +0300102 self.assertRaises(TypeError, self.dumps, data, indent=True)
103
Ezio Melotti37623ab2013-01-03 08:44:15 +0200104 def test_truncated_input(self):
105 test_cases = [
106 ('', 'Expecting value', 0),
107 ('[', 'Expecting value', 1),
108 ('[42', "Expecting ',' delimiter", 3),
109 ('[42,', 'Expecting value', 4),
110 ('["', 'Unterminated string starting at', 1),
111 ('["spam', 'Unterminated string starting at', 1),
112 ('["spam"', "Expecting ',' delimiter", 7),
113 ('["spam",', 'Expecting value', 8),
114 ('{', 'Expecting property name enclosed in double quotes', 1),
115 ('{"', 'Unterminated string starting at', 1),
116 ('{"spam', 'Unterminated string starting at', 1),
117 ('{"spam"', "Expecting ':' delimiter", 7),
118 ('{"spam":', 'Expecting value', 8),
119 ('{"spam":42', "Expecting ',' delimiter", 10),
120 ('{"spam":42,', 'Expecting property name enclosed in double quotes', 11),
121 ]
122 test_cases += [
123 ('"', 'Unterminated string starting at', 0),
124 ('"spam', 'Unterminated string starting at', 0),
125 ]
126 for data, msg, idx in test_cases:
127 self.assertRaisesRegex(ValueError,
Serhiy Storchaka920007a2013-02-21 20:26:52 +0200128 r'^{0}: line 1 column {1} \(char {2}\)'.format(
129 re.escape(msg), idx + 1, idx),
Ezio Melotti37623ab2013-01-03 08:44:15 +0200130 self.loads, data)
131
132 def test_unexpected_data(self):
133 test_cases = [
134 ('[,', 'Expecting value', 1),
135 ('{"spam":[}', 'Expecting value', 9),
136 ('[42:', "Expecting ',' delimiter", 3),
137 ('[42 "spam"', "Expecting ',' delimiter", 4),
138 ('[42,]', 'Expecting value', 4),
139 ('{"spam":[42}', "Expecting ',' delimiter", 11),
140 ('["]', 'Unterminated string starting at', 1),
141 ('["spam":', "Expecting ',' delimiter", 7),
142 ('["spam",]', 'Expecting value', 8),
143 ('{:', 'Expecting property name enclosed in double quotes', 1),
144 ('{,', 'Expecting property name enclosed in double quotes', 1),
145 ('{42', 'Expecting property name enclosed in double quotes', 1),
146 ('[{]', 'Expecting property name enclosed in double quotes', 2),
147 ('{"spam",', "Expecting ':' delimiter", 7),
148 ('{"spam"}', "Expecting ':' delimiter", 7),
149 ('[{"spam"]', "Expecting ':' delimiter", 8),
150 ('{"spam":}', 'Expecting value', 8),
151 ('[{"spam":]', 'Expecting value', 9),
152 ('{"spam":42 "ham"', "Expecting ',' delimiter", 11),
153 ('[{"spam":42]', "Expecting ',' delimiter", 11),
154 ('{"spam":42,}', 'Expecting property name enclosed in double quotes', 11),
155 ]
156 for data, msg, idx in test_cases:
157 self.assertRaisesRegex(ValueError,
Serhiy Storchaka920007a2013-02-21 20:26:52 +0200158 r'^{0}: line 1 column {1} \(char {2}\)'.format(
159 re.escape(msg), idx + 1, idx),
Ezio Melotti37623ab2013-01-03 08:44:15 +0200160 self.loads, data)
161
162 def test_extra_data(self):
163 test_cases = [
164 ('[]]', 'Extra data', 2),
165 ('{}}', 'Extra data', 2),
166 ('[],[]', 'Extra data', 2),
167 ('{},{}', 'Extra data', 2),
168 ]
169 test_cases += [
170 ('42,"spam"', 'Extra data', 2),
171 ('"spam",42', 'Extra data', 6),
172 ]
173 for data, msg, idx in test_cases:
174 self.assertRaisesRegex(ValueError,
175 r'^{0}: line 1 column {1} - line 1 column {2}'
Serhiy Storchaka920007a2013-02-21 20:26:52 +0200176 r' \(char {3} - {4}\)'.format(
177 re.escape(msg), idx + 1, len(data) + 1, idx, len(data)),
Ezio Melotti37623ab2013-01-03 08:44:15 +0200178 self.loads, data)
179
Serhiy Storchaka920007a2013-02-21 20:26:52 +0200180 def test_linecol(self):
181 test_cases = [
182 ('!', 1, 1, 0),
183 (' !', 1, 2, 1),
184 ('\n!', 2, 1, 1),
185 ('\n \n\n !', 4, 6, 10),
186 ]
187 for data, line, col, idx in test_cases:
188 self.assertRaisesRegex(ValueError,
189 r'^Expecting value: line {0} column {1}'
190 r' \(char {2}\)$'.format(line, col, idx),
191 self.loads, data)
Ezio Melotti6b60fb92011-05-14 06:47:51 +0300192
193class TestPyFail(TestFail, PyTest): pass
194class TestCFail(TestFail, CTest): pass