1
2function createTests() {
3    var result = [];
4    result.push(function(jsonObject){
5        return jsonObject.parse();
6    });
7    result[result.length - 1].throws = true;
8    result.push(function(jsonObject){
9        return jsonObject.parse('');
10    });
11    result[result.length - 1].throws = true;
12    result.push(function(jsonObject){
13        return jsonObject.parse('1');
14    });
15    result.push(function(jsonObject){
16        return jsonObject.parse('-1');
17    });
18    result.push(function(jsonObject){
19        return jsonObject.parse('Infinity');
20    });
21    result[result.length - 1].throws = true;
22    result.push(function(jsonObject){
23        return jsonObject.parse('NaN');
24    });
25    result[result.length - 1].throws = true;
26    result.push(function(jsonObject){
27        return jsonObject.parse('null');
28    });
29    result.push(function(jsonObject){
30        return jsonObject.parse('undefined');
31    });
32    result[result.length - 1].throws = true;
33    result.push(function(jsonObject){
34        return jsonObject.parse('{}');
35    });
36    result.push(function(jsonObject){
37        return jsonObject.parse('({})');
38    });
39    result[result.length - 1].throws = true;
40    result.push(function(jsonObject){
41        return jsonObject.parse('{a}');
42    });
43    result[result.length - 1].throws = true;
44    result.push(function(jsonObject){
45        return jsonObject.parse('{a:}');
46    });
47    result[result.length - 1].throws = true;
48    result.push(function(jsonObject){
49        return jsonObject.parse('{a:5}');
50    });
51    result[result.length - 1].throws = true;
52    result.push(function(jsonObject){
53        return jsonObject.parse('{a:5,}');
54    });
55    result[result.length - 1].throws = true;
56    result.push(function(jsonObject){
57        return jsonObject.parse('{"a"}');
58    });
59    result[result.length - 1].throws = true;
60    result.push(function(jsonObject){
61        return jsonObject.parse('{"a":}');
62    });
63    result[result.length - 1].throws = true;
64    result.push(function(jsonObject){
65        return jsonObject.parse('{"a":5}');
66    });
67    result.push(function(jsonObject){
68        return jsonObject.parse('{"__proto__":5}');
69    });
70    result.push(function(jsonObject){
71        return jsonObject.parse('{"a":5,}');
72    });
73    result[result.length - 1].throws = true;
74    result.push(function(jsonObject){
75        return jsonObject.parse('{"a":5,,}');
76    });
77    result[result.length - 1].throws = true;
78    result.push(function(jsonObject){
79        return jsonObject.parse('{"a":5,"a",}');
80    });
81    result[result.length - 1].throws = true;
82    result.push(function(jsonObject){
83        return jsonObject.parse('{"a":(5,"a"),}');
84    });
85    result[result.length - 1].throws = true;
86    result.push(function(jsonObject){
87        return jsonObject.parse('[]');
88    });
89    result.push(function(jsonObject){
90        return jsonObject.parse('[1]');
91    });
92    result.push(function(jsonObject){
93        return jsonObject.parse('[1,]');
94    });
95    result[result.length - 1].throws = true;
96    result.push(function(jsonObject){
97        return jsonObject.parse('[1,2]');
98    });
99    result.push(function(jsonObject){
100        return jsonObject.parse('[1,2,,]');
101    });
102    result[result.length - 1].throws = true;
103    result.push(function(jsonObject){
104        return jsonObject.parse('[1,2,,4]');
105    });
106    result[result.length - 1].throws = true;
107    result.push(function(jsonObject){
108        return jsonObject.parse('""');
109    });
110    result.push(function(jsonObject){
111        return jsonObject.parse('"\'"');
112    });
113    result.push(function(jsonObject){
114        return jsonObject.parse('"a\"');
115    });
116    result.push(function(jsonObject){
117        return jsonObject.parse('"a\\"');
118    });
119    result[result.length - 1].throws = true;
120    result.push(function(jsonObject){
121        return jsonObject.parse('"a\\z"');
122    });
123    result[result.length - 1].throws = true;
124    result.push(function(jsonObject){
125        return jsonObject.parse('"a\\\z"');
126    });
127    result[result.length - 1].throws = true;
128    result.push(function(jsonObject){
129        return jsonObject.parse('"a\\\\z"');
130    });
131    result.push(function(jsonObject){
132        return jsonObject.parse('"a\tz"');
133    });
134    result.push(function(jsonObject){
135        return jsonObject.parse('"a\\tz"');
136    });
137    result.push(function(jsonObject){
138        return jsonObject.parse('"a\nz"');
139    });
140    result[result.length - 1].throws = true;
141    result.push(function(jsonObject){
142        return jsonObject.parse('"a\\nz"');
143    });
144    result.push(function(jsonObject){
145        return jsonObject.parse('"a\rz"');
146    });
147    result[result.length - 1].throws = true;
148    result.push(function(jsonObject){
149        return jsonObject.parse('"a\\rz"');
150    });
151    result.push(function(jsonObject){
152        return jsonObject.parse('"a\/z"');
153    });
154    result.push(function(jsonObject){
155        return jsonObject.parse('"a\\/z"');
156    });
157    result.push(function(jsonObject){
158        return jsonObject.parse('"a\bz"');
159    });
160    result[result.length - 1].throws = true;
161    result.push(function(jsonObject){
162        return jsonObject.parse('"a\\bz"');
163    });
164    result.push(function(jsonObject){
165        return jsonObject.parse('"a\rz"');
166    });
167    result[result.length - 1].throws = true;
168    result.push(function(jsonObject){
169        return jsonObject.parse('"a\\rz"');
170    });
171    result.push(function(jsonObject){
172        return jsonObject.parse('"a\\uz"     ');
173    });
174    result[result.length - 1].throws = true;
175    result.push(function(jsonObject){
176        return jsonObject.parse('"a\\u0z"    ');
177    });
178    result[result.length - 1].throws = true;
179    result.push(function(jsonObject){
180        return jsonObject.parse('"a\\u00z"   ');
181    });
182    result[result.length - 1].throws = true;
183    result.push(function(jsonObject){
184        return jsonObject.parse('"a\\u000z"  ');
185    });
186    result[result.length - 1].throws = true;
187    result.push(function(jsonObject){
188        return jsonObject.parse('"a\\u0000z" ');
189    });
190    result.push(function(jsonObject){
191        return jsonObject.parse('"a\\u000Az" ');
192    });
193    result.push(function(jsonObject){
194        return jsonObject.parse('"a\\u000az" ');
195    });
196    result.push(function(jsonObject){
197        return jsonObject.parse('"a\\u000Gz" ');
198    });
199    result[result.length - 1].throws = true;
200    result.push(function(jsonObject){
201        return jsonObject.parse('"a\\u000gz" ');
202    });
203    result[result.length - 1].throws = true;
204    result.push(function(jsonObject){
205        return jsonObject.parse('"a\\u00A0z" ');
206    });
207    result.push(function(jsonObject){
208        return jsonObject.parse('"a\\u00a0z" ');
209    });
210    result.push(function(jsonObject){
211        return jsonObject.parse('"a\\u00G0z" ');
212    });
213    result[result.length - 1].throws = true;
214    result.push(function(jsonObject){
215        return jsonObject.parse('"a\\u00g0z" ');
216    });
217    result[result.length - 1].throws = true;
218    result.push(function(jsonObject){
219        return jsonObject.parse('"a\\u0A00z" ');
220    });
221    result.push(function(jsonObject){
222        return jsonObject.parse('"a\\u0a00z" ');
223    });
224    result.push(function(jsonObject){
225        return jsonObject.parse('"a\\u0G00z" ');
226    });
227    result[result.length - 1].throws = true;
228    result.push(function(jsonObject){
229        return jsonObject.parse('"a\\u0g00z" ');
230    });
231    result[result.length - 1].throws = true;
232    result.push(function(jsonObject){
233        return jsonObject.parse('"a\\uA000z" ');
234    });
235    result.push(function(jsonObject){
236        return jsonObject.parse('"a\\ua000z" ');
237    });
238    result.push(function(jsonObject){
239        return jsonObject.parse('"a\\uG000z" ');
240    });
241    result[result.length - 1].throws = true;
242    result.push(function(jsonObject){
243        return jsonObject.parse('"a\\ug000z" ');
244    });
245    result[result.length - 1].throws = true;
246    result.push(function(jsonObject){
247        return jsonObject.parse('00');
248    });
249    result[result.length - 1].throws = true;
250    result.push(function(jsonObject){
251        return jsonObject.parse('01');
252    });
253    result[result.length - 1].throws = true;
254    result.push(function(jsonObject){
255        return jsonObject.parse('0.a');
256    });
257    result[result.length - 1].throws = true;
258    result.push(function(jsonObject){
259        return jsonObject.parse('0x0');
260    });
261    result[result.length - 1].throws = true;
262    result.push(function(jsonObject){
263        return jsonObject.parse('2e1.3');
264    });
265    result[result.length - 1].throws = true;
266    result.push(function(jsonObject){
267        return jsonObject.parse('2e-+10');
268    });
269    result[result.length - 1].throws = true;
270    result.push(function(jsonObject){
271        return jsonObject.parse('2e+-10');
272    });
273    result[result.length - 1].throws = true;
274    result.push(function(jsonObject){
275        return jsonObject.parse('2e3e4');
276    });
277    result[result.length - 1].throws = true;
278    result.push(function(jsonObject){
279        return jsonObject.parse('-01.0');
280    });
281    result[result.length - 1].throws = true;
282    result.push(function(jsonObject){
283        return jsonObject.parse('-01');
284    });
285    result[result.length - 1].throws = true;
286    result.push(function(jsonObject){
287        return jsonObject.parse('-01.a');
288    });
289    result[result.length - 1].throws = true;
290    result.push(function(jsonObject){
291        return jsonObject.parse('1.e1');
292    });
293    result[result.length - 1].throws = true;
294    result.push(function(jsonObject){
295        return jsonObject.parse('{/* block comments are not allowed */}');
296    });
297    result[result.length - 1].throws = true;
298    result.push(function(jsonObject){
299        return jsonObject.parse('{// line comments are not allowed \n}');
300    });
301    result[result.length - 1].throws = true;
302    result.push(function(jsonObject){
303        return jsonObject.parse('true');
304    });
305    result.push(function(jsonObject){
306        return jsonObject.parse('false');
307    });
308    var simpleArray = ['a', 'b', 'c'];
309    var simpleObject = {a:"1", b:"2", c:"3"};
310    var complexArray = ['a', 'b', 'c',,,simpleObject, simpleArray, [simpleObject,simpleArray]];
311    var complexObject = {a:"1", b:"2", c:"3", d:4.5e10, g: 0.45e-5, h: 0.0, i: 0, j:.5, k:0., l:-0, m:-0.0, n:-0., o:-.5, p:-0.45e-10, q:-4.5e10, e:null, "":12, f: simpleArray, array: complexArray};
312    result.push(function(jsonObject){
313        return jsonObject.parse(JSON.stringify(simpleObject));
314    });
315    result[result.length - 1].expected = JSON.stringify(simpleObject);
316    result.push(function(jsonObject){
317        return jsonObject.parse(JSON.stringify(complexObject));
318    });
319    result.push(function(jsonObject){
320        return jsonObject.parse(JSON.stringify(complexObject));
321    });
322    result[result.length - 1].expected = JSON.stringify(complexObject);
323    result.push(function(jsonObject){
324        return jsonObject.parse(JSON.stringify(simpleObject,null,100));
325    });
326    result[result.length - 1].expected = JSON.stringify(simpleObject);
327    result.push(function(jsonObject){
328        return jsonObject.parse(JSON.stringify(complexObject,null,100));
329    });
330    result.push(function(jsonObject){
331        return jsonObject.parse(JSON.stringify(complexObject,null,100));
332    });
333    result[result.length - 1].expected = JSON.stringify(complexObject);
334    result.push(function(jsonObject){
335        return jsonObject.parse(JSON.stringify(simpleObject,null," "));
336    });
337    result[result.length - 1].expected = JSON.stringify(simpleObject);
338    result.push(function(jsonObject){
339        return jsonObject.parse(JSON.stringify(complexObject,null," "));
340    });
341    result.push(function(jsonObject){
342        return jsonObject.parse(JSON.stringify(complexObject,null," "));
343    });
344    result[result.length - 1].expected = JSON.stringify(complexObject);
345
346    result.push(function(jsonObject){
347        return jsonObject.parse(JSON.stringify(simpleObject,null,"\t"));
348    });
349    result[result.length - 1].expected = JSON.stringify(simpleObject);
350    result.push(function(jsonObject){
351        return jsonObject.parse(JSON.stringify(complexObject,null,"\t"));
352    });
353    result.push(function(jsonObject){
354        return jsonObject.parse(JSON.stringify(complexObject,null,"\t"));
355    });
356    result[result.length - 1].expected = JSON.stringify(complexObject);
357
358    result.push(function(jsonObject){
359        return jsonObject.parse(JSON.stringify(simpleObject,null,"\n"));
360    });
361    result[result.length - 1].expected = JSON.stringify(simpleObject);
362    result.push(function(jsonObject){
363        return jsonObject.parse(JSON.stringify(complexObject,null,"\n"));
364    });
365    result[result.length - 1].expected = JSON.stringify(complexObject);
366    function log(key, value) {
367        var o = {};
368        o[key] = value;
369        o.keyType = typeof key;
370        return o;
371    }
372    result.push(function(jsonObject){
373        return jsonObject.parse("true", log);
374    });
375    result.push(function(jsonObject){
376        return jsonObject.parse("false", log);
377    });
378    result.push(function(jsonObject){
379        return jsonObject.parse("null", log);
380    });
381    result.push(function(jsonObject){
382        return jsonObject.parse("1", log);
383    });
384    result.push(function(jsonObject){
385        return jsonObject.parse("1.5", log);
386    });
387    result.push(function(jsonObject){
388        return jsonObject.parse('"a string"', log);
389    });
390    result.push(function(jsonObject){
391        return jsonObject.parse(JSON.stringify(simpleArray), log);
392    });
393    result.push(function(jsonObject){
394        return jsonObject.parse(JSON.stringify(complexArray), log);
395    });
396    result.push(function(jsonObject){
397        return jsonObject.parse(JSON.stringify(simpleObject), log);
398    });
399    result.push(function(jsonObject){
400        return jsonObject.parse(JSON.stringify(complexObject), log);
401    });
402    result.push(function(jsonObject){
403        return jsonObject.parse('{"__proto__":{"a":5}}', log);
404    });
405    var logOrderString;
406    function logOrder(key, value) {
407        logOrderString += key +":"+JSON.stringify(value);
408        return null;
409    }
410    result.push(function(jsonObject){
411        logOrderString = "";
412        return jsonObject.parse("true", logOrder);
413    });
414    result.push(function(jsonObject){
415        logOrderString = "";
416        return jsonObject.parse("false", logOrder);
417    });
418    result.push(function(jsonObject){
419        logOrderString = "";
420        return jsonObject.parse("null", logOrder);
421    });
422    result.push(function(jsonObject){
423        logOrderString = "";
424        return jsonObject.parse("1", logOrder);
425    });
426    result.push(function(jsonObject){
427        logOrderString = "";
428        return jsonObject.parse("1.5", logOrder);
429    });
430    result.push(function(jsonObject){
431        logOrderString = "";
432        return jsonObject.parse('"a string"', logOrder);
433    });
434    result.push(function(jsonObject){
435        logOrderString = "";
436        return jsonObject.parse(JSON.stringify(simpleArray), logOrder);
437    });
438    result.push(function(jsonObject){
439        logOrderString = "";
440        return jsonObject.parse(JSON.stringify(complexArray), logOrder);
441    });
442    result.push(function(jsonObject){
443        logOrderString = "";
444        return jsonObject.parse(JSON.stringify(simpleObject), logOrder);
445    });
446    result.push(function(jsonObject){
447        logOrderString = "";
448        return jsonObject.parse(JSON.stringify(complexObject), logOrder);
449    });
450    result.push(function(jsonObject){
451        logOrderString = "";
452        jsonObject.parse("true", logOrder);
453        return logOrderString;
454    });
455    result.push(function(jsonObject){
456        logOrderString = "";
457        jsonObject.parse("false", logOrder);
458        return logOrderString;
459    });
460    result.push(function(jsonObject){
461        logOrderString = "";
462        jsonObject.parse("null", logOrder);
463        return logOrderString;
464    });
465    result.push(function(jsonObject){
466        logOrderString = "";
467        jsonObject.parse("1", logOrder);
468        return logOrderString;
469    });
470    result.push(function(jsonObject){
471        logOrderString = "";
472        jsonObject.parse("1.5", logOrder);
473        return logOrderString;
474    });
475    result.push(function(jsonObject){
476        logOrderString = "";
477        jsonObject.parse('"a string"', logOrder);
478        return logOrderString;
479    });
480    result.push(function(jsonObject){
481        logOrderString = "";
482        jsonObject.parse(JSON.stringify(simpleArray), logOrder);
483        return logOrderString;
484    });
485    result.push(function(jsonObject){
486        logOrderString = "";
487        jsonObject.parse(JSON.stringify(complexArray), logOrder);
488        return logOrderString;
489    });
490    result.push(function(jsonObject){
491        logOrderString = "";
492        jsonObject.parse(JSON.stringify(simpleObject), logOrder);
493        return logOrderString;
494    });
495    result.push(function(jsonObject){
496        logOrderString = "";
497        jsonObject.parse(JSON.stringify(complexObject), logOrder);
498        return logOrderString;
499    });
500    var callCount = 0;
501    function throwAfterFifthCall(key, value) {
502        logOrder(key, value);
503        if (++callCount > 5)
504            throw "from reviver";
505        return null;
506    }
507    result.push(function(jsonObject){
508        callCount = 0;
509        logOrderString = "";
510        return jsonObject.parse(JSON.stringify(complexArray), throwAfterFifthCall);
511    });
512    result[result.length - 1].throws = true;
513    result.push(function(jsonObject){
514        callCount = 0;
515        logOrderString = "";
516        return jsonObject.parse(JSON.stringify(simpleObject), throwAfterFifthCall);
517    });
518    result.push(function(jsonObject){
519        callCount = 0;
520        logOrderString = "";
521        return jsonObject.parse(JSON.stringify(complexObject), throwAfterFifthCall);
522    });
523    result[result.length - 1].throws = true;
524    result.push(function(jsonObject){
525        callCount = 0;
526        logOrderString = "";
527        try { jsonObject.parse(JSON.stringify(complexArray), throwAfterFifthCall); } catch (e) {}
528        return logOrderString;
529    });
530    result.push(function(jsonObject){
531        callCount = 0;
532        logOrderString = "";
533        try { jsonObject.parse(JSON.stringify(simpleObject), throwAfterFifthCall); } catch (e) {}
534        return logOrderString;
535    });
536    result.push(function(jsonObject){
537        callCount = 0;
538        logOrderString = "";
539        try { jsonObject.parse(JSON.stringify(complexObject), throwAfterFifthCall); } catch (e) {}
540        return logOrderString;
541    });
542    var unicode = "";
543    for (var i = 0; i < 1<<16; i++)
544        unicode += String.fromCharCode(i);
545    result.push(function(jsonObject){
546        return jsonObject.parse(JSON.stringify(unicode));
547    });
548    result[result.length - 1].unstringifiedExpected = unicode;
549    return result;
550}
551var tests = createTests();
552for (var i = 0; i < tests.length; i++) {
553    try {
554        debug(tests[i]);
555        if (tests[i].throws) {
556            shouldThrow('tests[i](nativeJSON)');
557            try {
558                var threw = false;
559                tests[i](JSON);
560            } catch(e) {
561                var threw = true;
562            }
563            if (!threw)
564                debug("json2.js did not throw for a test we expect to throw.");
565        } else if (tests[i].expected)
566            try { shouldBe('JSON.stringify(tests[i](nativeJSON))',  "tests[i].expected") } catch(e) { debug("threw - " + e)}
567        else if (tests[i].unstringifiedExpected)
568            try { shouldBe('tests[i](nativeJSON)',  "tests[i].unstringifiedExpected") } catch(e) { debug("threw - " + e)}
569        else
570            try { shouldBe('JSON.stringify(tests[i](nativeJSON))',  'JSON.stringify(tests[i](JSON))') } catch(e) { debug("threw - " + e) };
571    }catch(e){
572        debug(e);
573    }
574}
575successfullyParsed = true;
576
577