blob: 95ff5b8d1ee80632f11bee4146f8507c33b1469f [file] [log] [blame]
Ezio Melotti66f2ea02013-08-08 15:03:45 +03001from test.test_json 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)
Serhiy Storchaka47efb4a2015-01-26 13:16:30 +020090 except self.JSONDecodeError:
Christian Heimes90540002008-05-08 14:29:10 +000091 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:
Serhiy Storchaka47efb4a2015-01-26 13:16:30 +0200127 with self.assertRaises(self.JSONDecodeError) as cm:
128 self.loads(data)
129 err = cm.exception
130 self.assertEqual(err.msg, msg)
131 self.assertEqual(err.pos, idx)
132 self.assertEqual(err.lineno, 1)
133 self.assertEqual(err.colno, idx + 1)
134 self.assertEqual(str(err),
135 '%s: line 1 column %d (char %d)' %
136 (msg, idx + 1, idx))
Ezio Melotti37623ab2013-01-03 08:44:15 +0200137
138 def test_unexpected_data(self):
139 test_cases = [
140 ('[,', 'Expecting value', 1),
141 ('{"spam":[}', 'Expecting value', 9),
142 ('[42:', "Expecting ',' delimiter", 3),
143 ('[42 "spam"', "Expecting ',' delimiter", 4),
144 ('[42,]', 'Expecting value', 4),
145 ('{"spam":[42}', "Expecting ',' delimiter", 11),
146 ('["]', 'Unterminated string starting at', 1),
147 ('["spam":', "Expecting ',' delimiter", 7),
148 ('["spam",]', 'Expecting value', 8),
149 ('{:', 'Expecting property name enclosed in double quotes', 1),
150 ('{,', 'Expecting property name enclosed in double quotes', 1),
151 ('{42', 'Expecting property name enclosed in double quotes', 1),
152 ('[{]', 'Expecting property name enclosed in double quotes', 2),
153 ('{"spam",', "Expecting ':' delimiter", 7),
154 ('{"spam"}', "Expecting ':' delimiter", 7),
155 ('[{"spam"]', "Expecting ':' delimiter", 8),
156 ('{"spam":}', 'Expecting value', 8),
157 ('[{"spam":]', 'Expecting value', 9),
158 ('{"spam":42 "ham"', "Expecting ',' delimiter", 11),
159 ('[{"spam":42]', "Expecting ',' delimiter", 11),
160 ('{"spam":42,}', 'Expecting property name enclosed in double quotes', 11),
161 ]
162 for data, msg, idx in test_cases:
Serhiy Storchaka47efb4a2015-01-26 13:16:30 +0200163 with self.assertRaises(self.JSONDecodeError) as cm:
164 self.loads(data)
165 err = cm.exception
166 self.assertEqual(err.msg, msg)
167 self.assertEqual(err.pos, idx)
168 self.assertEqual(err.lineno, 1)
169 self.assertEqual(err.colno, idx + 1)
170 self.assertEqual(str(err),
171 '%s: line 1 column %d (char %d)' %
172 (msg, idx + 1, idx))
Ezio Melotti37623ab2013-01-03 08:44:15 +0200173
174 def test_extra_data(self):
175 test_cases = [
176 ('[]]', 'Extra data', 2),
177 ('{}}', 'Extra data', 2),
178 ('[],[]', 'Extra data', 2),
179 ('{},{}', 'Extra data', 2),
180 ]
181 test_cases += [
182 ('42,"spam"', 'Extra data', 2),
183 ('"spam",42', 'Extra data', 6),
184 ]
185 for data, msg, idx in test_cases:
Serhiy Storchaka47efb4a2015-01-26 13:16:30 +0200186 with self.assertRaises(self.JSONDecodeError) as cm:
187 self.loads(data)
188 err = cm.exception
189 self.assertEqual(err.msg, msg)
190 self.assertEqual(err.pos, idx)
191 self.assertEqual(err.lineno, 1)
192 self.assertEqual(err.colno, idx + 1)
193 self.assertEqual(str(err),
194 '%s: line 1 column %d (char %d)' %
195 (msg, idx + 1, idx))
Ezio Melotti37623ab2013-01-03 08:44:15 +0200196
Serhiy Storchaka920007a2013-02-21 20:26:52 +0200197 def test_linecol(self):
198 test_cases = [
199 ('!', 1, 1, 0),
200 (' !', 1, 2, 1),
201 ('\n!', 2, 1, 1),
202 ('\n \n\n !', 4, 6, 10),
203 ]
204 for data, line, col, idx in test_cases:
Serhiy Storchaka47efb4a2015-01-26 13:16:30 +0200205 with self.assertRaises(self.JSONDecodeError) as cm:
206 self.loads(data)
207 err = cm.exception
208 self.assertEqual(err.msg, 'Expecting value')
209 self.assertEqual(err.pos, idx)
210 self.assertEqual(err.lineno, line)
211 self.assertEqual(err.colno, col)
212 self.assertEqual(str(err),
213 'Expecting value: line %s column %d (char %d)' %
214 (line, col, idx))
Ezio Melotti6b60fb92011-05-14 06:47:51 +0300215
216class TestPyFail(TestFail, PyTest): pass
217class TestCFail(TestFail, CTest): pass