JSON-stringify.js 22.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
// Copyright 2014 the V8 project authors. All rights reserved.
// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1.  Redistributions of source code must retain the above copyright
//     notice, this list of conditions and the following disclaimer.
// 2.  Redistributions in binary form must reproduce the above copyright
//     notice, this list of conditions and the following disclaimer in the
//     documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


function createTests() {
    var simpleArray = ['a', 'b', 'c'];
    var simpleObject = {a:"1", b:"2", c:"3"};
    var complexArray = ['a', 'b', 'c',,,simpleObject, simpleArray, [simpleObject,simpleArray]];
    var complexObject = {a:"1", b:"2", c:"3", d:undefined, e:null, "":12, get f(){ return simpleArray; }, array: complexArray};
    var simpleArrayWithProto = ['d', 'e', 'f'];
    simpleArrayWithProto.__proto__ = simpleObject;
    var simpleObjectWithProto = {d:"4", e:"5", f:"6", __proto__:simpleObject};
    var complexArrayWithProto = ['d', 'e', 'f',,,simpleObjectWithProto, simpleArrayWithProto, [simpleObjectWithProto,simpleArrayWithProto]];
    complexArrayWithProto.__proto__ = simpleObjectWithProto;
    var complexObjectWithProto = {d:"4", e:"5", f:"6", g:undefined, h:null, "":12, get i(){ return simpleArrayWithProto; }, array2: complexArrayWithProto, __proto__:complexObject};
    var objectWithSideEffectGetter = {get b() {this.foo=1;}};
    var objectWithSideEffectGetterAndProto = {__proto__:{foo:"bar"}, get b() {this.foo=1;}};
    var arrayWithSideEffectGetter = [];
    arrayWithSideEffectGetter.__defineGetter__("b", function(){this.foo=1;});
    var arrayWithSideEffectGetterAndProto = [];
    arrayWithSideEffectGetterAndProto.__defineGetter__("b", function(){this.foo=1;});
    arrayWithSideEffectGetterAndProto.__proto__ = {foo:"bar"};
    var result = [];
44
    result.push(function (jsonObject){
45 46
        return jsonObject.stringify(1);
    });
47
    result.push(function (jsonObject){
48 49
        return jsonObject.stringify(1.5);
    });
50
    result.push(function (jsonObject){
51 52
        return jsonObject.stringify(-1);
    });
53
    result.push(function (jsonObject){
54 55
        return jsonObject.stringify(-1.5);
    });
56
    result.push(function (jsonObject){
57 58
        return jsonObject.stringify(null);
    });
59
    result.push(function (jsonObject){
60 61
        return jsonObject.stringify("string");
    });
62
    result.push(function (jsonObject){
63 64
        return jsonObject.stringify(new Number(0));
    });
65
    result.push(function (jsonObject){
66 67
        return jsonObject.stringify(new Number(1));
    });
68
    result.push(function (jsonObject){
69 70
        return jsonObject.stringify(new Number(1.5));
    });
71
    result.push(function (jsonObject){
72 73
        return jsonObject.stringify(new Number(-1));
    });
74
    result.push(function (jsonObject){
75 76
        return jsonObject.stringify(new Number(-1.5));
    });
77
    result.push(function (jsonObject){
78 79
        return jsonObject.stringify(new String("a string object"));
    });
80
    result.push(function (jsonObject){
81 82
        return jsonObject.stringify(new Boolean(true));
    });
83
    result.push(function (jsonObject){
84 85 86 87 88
        var value = new Number(1);
        value.valueOf = function() { return 2; }
        return jsonObject.stringify(value);
    });
    result[result.length - 1].expected = '2';
89
    result.push(function (jsonObject){
90 91 92 93 94
        var value = new Boolean(true);
        value.valueOf = function() { return 2; }
        return jsonObject.stringify(value);
    });
    result[result.length - 1].expected = '2';
95
    result.push(function (jsonObject){
96 97 98 99 100
        var value = new String("fail");
        value.toString = function() { return "converted string"; }
        return jsonObject.stringify(value);
    });
    result[result.length - 1].expected = '"converted string"';
101
    result.push(function (jsonObject){
102 103
        return jsonObject.stringify(true);
    });
104
    result.push(function (jsonObject){
105 106
        return jsonObject.stringify(false);
    });
107
    result.push(function (jsonObject){
108 109
        return jsonObject.stringify(new Date(0));
    });
110
    result.push(function (jsonObject){
111 112 113
        return jsonObject.stringify({toJSON: Date.prototype.toJSON});
    });
    result[result.length - 1].throws = true;
114
    result.push(function (jsonObject){
115 116
        return jsonObject.stringify({toJSON: Date.prototype.toJSON, toISOString: function(){ return "custom toISOString"; }});
    });
117
    result.push(function (jsonObject){
118 119 120
        return jsonObject.stringify({toJSON: Date.prototype.toJSON, toISOString: function(){ return {}; }});
    });
    result[result.length - 1].throws = true;
121
    result.push(function (jsonObject){
122 123 124
        return jsonObject.stringify({toJSON: Date.prototype.toJSON, toISOString: function(){ throw "An exception"; }});
    });
    result[result.length - 1].throws = true;
125
    result.push(function (jsonObject){
126 127 128 129 130
        var d = new Date(0);
        d.toISOString = null;
        return jsonObject.stringify(d);
    });
    result[result.length - 1].throws = true;
131
    result.push(function (jsonObject){
132 133 134 135
        var d = new Date(0);
        d.toJSON = undefined;
        return jsonObject.stringify(d);
    });
136
    result.push(function (jsonObject){
137 138
        return jsonObject.stringify({get Foo() { return "bar"; }});
    });
139
    result.push(function (jsonObject){
140 141
        return jsonObject.stringify({get Foo() { this.foo="wibble"; return "bar"; }});
    });
142
    result.push(function (jsonObject){
143 144 145 146
        var count = 0;
        jsonObject.stringify({get Foo() { count++; return "bar"; }});
        return count;
    });
147
    result.push(function (jsonObject){
148 149 150
        var count = 0;
        return jsonObject.stringify({get Foo() { count++; delete this.bar; return "bar"; }, bar: "wibble"});
    });
151
    result.push(function (jsonObject){
152 153 154
        var count = 0;
        return jsonObject.stringify({a:"1", b:"2", c:"3", 5:4, 4:5, 2:6, 1:7});
    });
155
    result.push(function (jsonObject){
156 157 158 159
        var allString = true;
        jsonObject.stringify({a:"1", b:"2", c:"3", 5:4, 4:5, 2:6, 1:7}, function(k,v){allString = allString && (typeof k == "string"); return v});
        return allString;
    });
160
    result.push(function (jsonObject){
161 162 163 164
        var allString = true;
        jsonObject.stringify([1,2,3,4,5], function(k,v){allString = allString && (typeof k == "string"); return v});
        return allString;
    });
165
    result.push(function (jsonObject){
166 167 168 169
        var allString = true;
        var array = [];
        return jsonObject.stringify({a:"1", b:"2", c:"3", 5:4, 4:5, 2:6, 1:7}, array);
    });
170
    result.push(function (jsonObject){
171 172 173 174
        var allString = true;
        var array = ["a"];
        return jsonObject.stringify({get a(){return 1;array[1]="b";array[2]="c"}, b:"2", c:"3"}, array);
    });
175
    result.push(function (jsonObject){
176 177 178 179
        var allString = true;
        var array = [{toString:function(){array[0]='a'; array[1]='c'; array[2]='b'; return 'a'}}];
        return jsonObject.stringify(simpleObject, array);
    });
180
    result.push(function (jsonObject){
181 182 183 184
        var allString = true;
        var array = [{toString:function(){array[0]='a'; array[1]='c'; array[2]='b'; return 'a'}}];
        return jsonObject.stringify(simpleObjectWithProto, array);
    });
185
    result.push(function (jsonObject){
186 187 188 189 190
        var allString = true;
        var array = [1, new Number(2), NaN, Infinity, -Infinity, new String("str")];
        return jsonObject.stringify({"1":"1","2":"2","NaN":"NaN","Infinity":"Infinity","-Infinity":"-Infinity","str":"str"}, array);
    });
    result[result.length - 1].expected = '{"1":"1","2":"2","NaN":"NaN","Infinity":"Infinity","-Infinity":"-Infinity","str":"str"}';
191
    result.push(function (jsonObject){
192 193 194 195
        var allString = true;
        var array = ["1","2","3"];
        return jsonObject.stringify({1:'a', 2:'b', 3:'c'}, array);
    });
196
    result.push(function (jsonObject){
197 198 199 200
        var allString = true;
        var array = ["1","2","3"];
        return jsonObject.stringify(simpleArray, array);
    });
201
    result.push(function (jsonObject){
202 203
        return jsonObject.stringify(simpleArray, null, "  ");
    });
204
    result.push(function (jsonObject){
205 206
        return jsonObject.stringify(simpleArray, null, 4);
    });
207
    result.push(function (jsonObject){
208 209
        return jsonObject.stringify(simpleArray, null, "ab");
    });
210
    result.push(function (jsonObject){
211 212
        return jsonObject.stringify(simpleArray, null, 4);
    });
213
    result.push(function (jsonObject){
214 215
        return jsonObject.stringify(simpleObject, null, "  ");
    });
216
    result.push(function (jsonObject){
217 218
        return jsonObject.stringify(simpleObject, null, 4);
    });
219
    result.push(function (jsonObject){
220 221
        return jsonObject.stringify(simpleObject, null, "ab");
    });
222
    result.push(function (jsonObject){
223 224
        return jsonObject.stringify(simpleObject, null, 4);
    });
225
    result.push(function (jsonObject){
226 227
        return jsonObject.stringify(simpleObject, null, 10);
    });
228
    result.push(function (jsonObject){
229 230 231
        return jsonObject.stringify(simpleObject, null, 11);
    });
    result[result.length - 1].expected = JSON.stringify(simpleObject, null, 10);
232
    result.push(function (jsonObject){
233 234 235
        return jsonObject.stringify(simpleObject, null, "          ");
    });
    result[result.length - 1].expected = JSON.stringify(simpleObject, null, 10);
236
    result.push(function (jsonObject){
237 238 239
        return jsonObject.stringify(simpleObject, null, "           ");
    });
    result[result.length - 1].expected = JSON.stringify(simpleObject, null, 10);
240
    result.push(function (jsonObject){
241 242
        return jsonObject.stringify(complexArray, null, "  ");
    });
243
    result.push(function (jsonObject){
244 245
        return jsonObject.stringify(complexArray, null, 4);
    });
246
    result.push(function (jsonObject){
247 248
        return jsonObject.stringify(complexArray, null, "ab");
    });
249
    result.push(function (jsonObject){
250 251
        return jsonObject.stringify(complexArray, null, 4);
    });
252
    result.push(function (jsonObject){
253 254
        return jsonObject.stringify(complexObject, null, "  ");
    });
255
    result.push(function (jsonObject){
256 257
        return jsonObject.stringify(complexObject, null, 4);
    });
258
    result.push(function (jsonObject){
259 260
        return jsonObject.stringify(complexObject, null, "ab");
    });
261
    result.push(function (jsonObject){
262 263
        return jsonObject.stringify(complexObject, null, 4);
    });
264
    result.push(function (jsonObject){
265 266 267 268
        var allString = true;
        var array = ["1","2","3"];
        return jsonObject.stringify(simpleArrayWithProto, array);
    });
269
    result.push(function (jsonObject){
270 271
        return jsonObject.stringify(simpleArrayWithProto, null, "  ");
    });
272
    result.push(function (jsonObject){
273 274
        return jsonObject.stringify(simpleArrayWithProto, null, 4);
    });
275
    result.push(function (jsonObject){
276 277
        return jsonObject.stringify(simpleArrayWithProto, null, "ab");
    });
278
    result.push(function (jsonObject){
279 280
        return jsonObject.stringify(simpleArrayWithProto, null, 4);
    });
281
    result.push(function (jsonObject){
282 283
        return jsonObject.stringify(simpleObjectWithProto, null, "  ");
    });
284
    result.push(function (jsonObject){
285 286
        return jsonObject.stringify(simpleObjectWithProto, null, 4);
    });
287
    result.push(function (jsonObject){
288 289
        return jsonObject.stringify(simpleObjectWithProto, null, "ab");
    });
290
    result.push(function (jsonObject){
291 292
        return jsonObject.stringify(simpleObjectWithProto, null, 4);
    });
293
    result.push(function (jsonObject){
294 295
        return jsonObject.stringify(simpleObjectWithProto, null, 10);
    });
296
    result.push(function (jsonObject){
297 298 299
        return jsonObject.stringify(simpleObjectWithProto, null, 11);
    });
    result[result.length - 1].expected = JSON.stringify(simpleObjectWithProto, null, 10);
300
    result.push(function (jsonObject){
301 302 303
        return jsonObject.stringify(simpleObjectWithProto, null, "          ");
    });
    result[result.length - 1].expected = JSON.stringify(simpleObjectWithProto, null, 10);
304
    result.push(function (jsonObject){
305 306 307
        return jsonObject.stringify(simpleObjectWithProto, null, "           ");
    });
    result[result.length - 1].expected = JSON.stringify(simpleObjectWithProto, null, 10);
308
    result.push(function (jsonObject){
309 310
        return jsonObject.stringify(complexArrayWithProto, null, "  ");
    });
311
    result.push(function (jsonObject){
312 313
        return jsonObject.stringify(complexArrayWithProto, null, 4);
    });
314
    result.push(function (jsonObject){
315 316
        return jsonObject.stringify(complexArrayWithProto, null, "ab");
    });
317
    result.push(function (jsonObject){
318 319
        return jsonObject.stringify(complexArrayWithProto, null, 4);
    });
320
    result.push(function (jsonObject){
321 322
        return jsonObject.stringify(complexObjectWithProto, null, "  ");
    });
323
    result.push(function (jsonObject){
324 325
        return jsonObject.stringify(complexObjectWithProto, null, 4);
    });
326
    result.push(function (jsonObject){
327 328
        return jsonObject.stringify(complexObjectWithProto, null, "ab");
    });
329
    result.push(function (jsonObject){
330 331
        return jsonObject.stringify(complexObjectWithProto, null, 4);
    });
332
    result.push(function (jsonObject){
333 334
        return jsonObject.stringify(objectWithSideEffectGetter);
    });
335
    result.push(function (jsonObject){
336 337
        return jsonObject.stringify(objectWithSideEffectGetterAndProto);
    });
338
    result.push(function (jsonObject){
339 340
        return jsonObject.stringify(arrayWithSideEffectGetter);
    });
341
    result.push(function (jsonObject){
342 343 344 345 346 347 348
        return jsonObject.stringify(arrayWithSideEffectGetterAndProto);
    });
    var replaceTracker;
    function replaceFunc(key, value) {
        replaceTracker += key + "("+(typeof key)+")" + JSON.stringify(value) + ";";
        return value;
    }
349
    result.push(function (jsonObject){
350 351 352 353 354
        replaceTracker = "";
        jsonObject.stringify([1,2,3,,,,4,5,6], replaceFunc);
        return replaceTracker;
    });
    result[result.length - 1].expected = '(string)[1,2,3,null,null,null,4,5,6];0(number)1;1(number)2;2(number)3;3(number)undefined;4(number)undefined;5(number)undefined;6(number)4;7(number)5;8(number)6;'
355
    result.push(function (jsonObject){
356 357 358 359 360
        replaceTracker = "";
        jsonObject.stringify({a:"a", b:"b", c:"c", 3: "d", 2: "e", 1: "f"}, replaceFunc);
        return replaceTracker;
    });
    result[result.length - 1].expected = '(string){"1":"f","2":"e","3":"d","a":"a","b":"b","c":"c"};1(string)"f";2(string)"e";3(string)"d";a(string)"a";b(string)"b";c(string)"c";';
361
    result.push(function (jsonObject){
362 363 364 365 366
        var count = 0;
        var array = [{toString:function(){count++; array[0]='a'; array[1]='c'; array[2]='b'; return 'a'}}];
        jsonObject.stringify(simpleObject, array);
        return count;
    });
367
    result.push(function (jsonObject){
368 369 370 371
        var allString = true;
        var array = [{toString:function(){array[0]='a'; array[1]='c'; array[2]='b'; return 'a'}}, 'b', 'c'];
        return jsonObject.stringify(simpleObject, array);
    });
372
    result.push(function (jsonObject){
373 374 375 376 377
        var count = 0;
        var array = [{toString:function(){count++; array[0]='a'; array[1]='c'; array[2]='b'; return 'a'}}, 'b', 'c'];
        jsonObject.stringify(simpleObject, array);
        return count;
    });
378
    result.push(function (jsonObject){
379 380
        return jsonObject.stringify({a:"1", get b() { this.a="foo"; return "getter"; }, c:"3"});
    });
381
    result.push(function (jsonObject){
382 383
        return jsonObject.stringify({a:"1", get b() { this.c="foo"; return "getter"; }, c:"3"});
    });
384
    result.push(function (jsonObject){
385 386 387 388
        var setterCalled = false;
        jsonObject.stringify({a:"1", set b(s) { setterCalled = true; return "setter"; }, c:"3"});
        return setterCalled;
    });
389
    result.push(function (jsonObject){
390 391
        return jsonObject.stringify({a:"1", get b(){ return "getter"; }, set b(s) { return "setter"; }, c:"3"});
    });
392
    result.push(function (jsonObject){
393 394
        return jsonObject.stringify(new Array(10));
    });
395
    result.push(function (jsonObject){
396 397
        return jsonObject.stringify([undefined,,null,0,false]);
    });
398
    result.push(function (jsonObject){
399 400 401 402 403 404 405 406 407 408 409
        return jsonObject.stringify({p1:undefined,p2:null,p3:0,p4:false});
    });
    var cycleTracker = "";
    var cyclicObject = { get preSelf1() { cycleTracker+="preSelf1,"; return "preSelf1"; },
                             preSelf2: {toJSON:function(){cycleTracker+="preSelf2,"; return "preSelf2"}},
                             self: [],
                         get postSelf1() { cycleTracker+="postSelf1,"; return "postSelf1" },
                             postSelf2: {toJSON:function(){cycleTracker+="postSelf2,"; return "postSelf2"}},
                             toJSON : function(key) { cycleTracker += key + "("+(typeof key)+"):" + this; return this; }
                       };
    cyclicObject.self = cyclicObject;
410
    result.push(function (jsonObject){
411 412 413 414
        cycleTracker = "";
        return jsonObject.stringify(cyclicObject);
    });
    result[result.length - 1].throws = true;
415
    result.push(function (jsonObject){
416 417 418 419 420 421 422 423 424
        cycleTracker = "";
        try { jsonObject.stringify(cyclicObject); } catch(e) { cycleTracker += " -> exception" }
        return cycleTracker;
    });
    result[result.length - 1].expected = "(string):[object Object]preSelf1,preSelf2,self(string):[object Object] -> exception"
    var cyclicArray = [{toJSON : function(key,value) { cycleTracker += key + "("+(typeof key)+"):" + this; cycleTracker += "first,"; return this; }},
                       cyclicArray,
                       {toJSON : function(key,value) { cycleTracker += key + "("+(typeof key)+"):" + this; cycleTracker += "second,"; return this; }}];
    cyclicArray[1] = cyclicArray;
425
    result.push(function (jsonObject){
426 427 428 429
        cycleTracker = "";
        return jsonObject.stringify(cyclicArray);
    });
    result[result.length - 1].throws = true;
430
    result.push(function (jsonObject){
431 432 433 434 435 436 437 438 439 440 441
        cycleTracker = "";
        try { jsonObject.stringify(cyclicArray); } catch(e) { cycleTracker += " -> exception" }
        return cycleTracker;
    });
    result[result.length - 1].expected = "0(number):[object Object]first, -> exception";
    function createArray(len, o) { var r = []; for (var i = 0; i < len; i++) r[i] = o; return r; }
    var getterCalls;
    var magicObject = createArray(10, {abcdefg: [1,2,5,"ab", null, undefined, true, false,,],
                                       get calls() {return ++getterCalls; },
                                       "123":createArray(15, "foo"),
                                       "":{a:"b"}});
442
    result.push(function (jsonObject){
443 444 445
        getterCalls = 0;
        return jsonObject.stringify(magicObject) + " :: getter calls = " + getterCalls;
    });
446
    result.push(function (jsonObject){
447 448
        return jsonObject.stringify(undefined);
    });
449
    result.push(function (jsonObject){
450 451
        return jsonObject.stringify(null);
    });
452
    result.push(function (jsonObject){
453 454
        return jsonObject.stringify({toJSON:function(){ return undefined; }});
    });
455
    result.push(function (jsonObject){
456 457
        return jsonObject.stringify({toJSON:function(){ return null; }});
    });
458
    result.push(function (jsonObject){
459 460
        return jsonObject.stringify([{toJSON:function(){ return undefined; }}]);
    });
461
    result.push(function (jsonObject){
462 463
        return jsonObject.stringify([{toJSON:function(){ return null; }}]);
    });
464
    result.push(function (jsonObject){
465 466
        return jsonObject.stringify({a:{toJSON:function(){ return undefined; }}});
    });
467
    result.push(function (jsonObject){
468 469
        return jsonObject.stringify({a:{toJSON:function(){ return null; }}});
    });
470
    result.push(function (jsonObject){
471 472
        return jsonObject.stringify({a:{toJSON:function(){ return function(){}; }}});
    });
473
    result.push(function (jsonObject){
474 475
        return jsonObject.stringify({a:function(){}});
    });
476
    result.push(function (jsonObject){
477 478 479 480 481
        var deepObject = {};
        for (var i = 0; i < 1024; i++)
            deepObject = {next:deepObject};
        return jsonObject.stringify(deepObject);
    });
482
    result.push(function (jsonObject){
483 484 485 486 487
        var deepArray = [];
        for (var i = 0; i < 1024; i++)
            deepArray = [deepArray];
        return jsonObject.stringify(deepArray);
    });
488
    result.push(function (jsonObject){
489 490 491 492 493 494 495 496 497 498
        var depth = 0;
        function toDeepVirtualJSONObject() {
            if (++depth >= 1024)
                return {};
            var r = {};
            r.toJSON = toDeepVirtualJSONObject;
            return {recurse: r};
        }
        return jsonObject.stringify(toDeepVirtualJSONObject());
    });
499
    result.push(function (jsonObject){
500 501 502 503 504 505 506 507 508 509 510 511 512
        var depth = 0;
        function toDeepVirtualJSONArray() {
            if (++depth >= 1024)
                return [];
            var r = [];
            r.toJSON = toDeepJSONArray;
            return [r];
        }
        return jsonObject.stringify(toDeepVirtualJSONArray());
    });
    var fullCharsetString = "";
    for (var i = 0; i < 65536; i++)
        fullCharsetString += String.fromCharCode(i);
513
    result.push(function (jsonObject){
514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529
        return jsonObject.stringify(fullCharsetString);
    });
    return result;
}
var tests = createTests();
for (var i = 0; i < tests.length; i++) {
    try {
        debug(tests[i]);
        if (tests[i].throws)
            shouldThrow('tests[i](nativeJSON)');
        else if (tests[i].expected)
            shouldBe('tests[i](nativeJSON)',  "tests[i].expected");
        else
            shouldBe('tests[i](nativeJSON)',  "tests[i](JSON)");
    }catch(e){}
}