Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: test/mjsunit/json.js

Issue 12702009: Extend test coverage for JSON.stringify's slow path. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | test/mjsunit/json2.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 TestInvalid('null ""'); 218 TestInvalid('null ""');
219 TestInvalid('null ""'); 219 TestInvalid('null ""');
220 TestInvalid('[] ""'); 220 TestInvalid('[] ""');
221 TestInvalid('[true] ""'); 221 TestInvalid('[true] ""');
222 TestInvalid('{} ""'); 222 TestInvalid('{} ""');
223 TestInvalid('{"x":true} ""'); 223 TestInvalid('{"x":true} ""');
224 TestInvalid('"Garbage""After string"'); 224 TestInvalid('"Garbage""After string"');
225 225
226 // Stringify 226 // Stringify
227 227
228 assertEquals("true", JSON.stringify(true)); 228 function TestStringify(expected, input) {
229 assertEquals("false", JSON.stringify(false)); 229 assertEquals(expected, JSON.stringify(input));
230 assertEquals("null", JSON.stringify(null)); 230 assertEquals(expected, JSON.stringify(input, null, 0));
231 assertEquals("false", JSON.stringify({toJSON: function () { return false; }})); 231 }
232 assertEquals("4", JSON.stringify(4));
233 assertEquals('"foo"', JSON.stringify("foo"));
234 assertEquals("null", JSON.stringify(Infinity));
235 assertEquals("null", JSON.stringify(-Infinity));
236 assertEquals("null", JSON.stringify(NaN));
237 assertEquals("4", JSON.stringify(new Number(4)));
238 assertEquals('"bar"', JSON.stringify(new String("bar")));
239 232
240 assertEquals('"foo\\u0000bar"', JSON.stringify("foo\0bar")); 233 TestStringify("true", true);
241 assertEquals('"f\\"o\'o\\\\b\\ba\\fr\\nb\\ra\\tz"', 234 TestStringify("false", false);
242 JSON.stringify("f\"o\'o\\b\ba\fr\nb\ra\tz")); 235 TestStringify("null", null);
236 TestStringify("false", {toJSON: function () { return false; }});
237 TestStringify("4", 4);
238 TestStringify('"foo"', "foo");
239 TestStringify("null", Infinity);
240 TestStringify("null", -Infinity);
241 TestStringify("null", NaN);
242 TestStringify("4", new Number(4));
243 TestStringify('"bar"', new String("bar"));
243 244
244 assertEquals("[1,2,3]", JSON.stringify([1, 2, 3])); 245 TestStringify('"foo\\u0000bar"', "foo\0bar");
246 TestStringify('"f\\"o\'o\\\\b\\ba\\fr\\nb\\ra\\tz"',
247 "f\"o\'o\\b\ba\fr\nb\ra\tz");
248
249 TestStringify("[1,2,3]", [1, 2, 3]);
245 assertEquals("[\n 1,\n 2,\n 3\n]", JSON.stringify([1, 2, 3], null, 1)); 250 assertEquals("[\n 1,\n 2,\n 3\n]", JSON.stringify([1, 2, 3], null, 1));
246 assertEquals("[\n 1,\n 2,\n 3\n]", JSON.stringify([1, 2, 3], null, 2)); 251 assertEquals("[\n 1,\n 2,\n 3\n]", JSON.stringify([1, 2, 3], null, 2));
247 assertEquals("[\n 1,\n 2,\n 3\n]", 252 assertEquals("[\n 1,\n 2,\n 3\n]",
248 JSON.stringify([1, 2, 3], null, new Number(2))); 253 JSON.stringify([1, 2, 3], null, new Number(2)));
249 assertEquals("[\n^1,\n^2,\n^3\n]", JSON.stringify([1, 2, 3], null, "^")); 254 assertEquals("[\n^1,\n^2,\n^3\n]", JSON.stringify([1, 2, 3], null, "^"));
250 assertEquals("[\n^1,\n^2,\n^3\n]", 255 assertEquals("[\n^1,\n^2,\n^3\n]",
251 JSON.stringify([1, 2, 3], null, new String("^"))); 256 JSON.stringify([1, 2, 3], null, new String("^")));
252 assertEquals("[\n 1,\n 2,\n [\n 3,\n [\n 4\n ],\n 5\n ],\n 6,\n 7\n]", 257 assertEquals("[\n 1,\n 2,\n [\n 3,\n [\n 4\n ],\n 5\n ],\n 6,\n 7\n]",
253 JSON.stringify([1, 2, [3, [4], 5], 6, 7], null, 1)); 258 JSON.stringify([1, 2, [3, [4], 5], 6, 7], null, 1));
254 assertEquals("[]", JSON.stringify([], null, 1)); 259 assertEquals("[]", JSON.stringify([], null, 1));
255 assertEquals("[1,2,[3,[4],5],6,7]", 260 assertEquals("[1,2,[3,[4],5],6,7]",
256 JSON.stringify([1, 2, [3, [4], 5], 6, 7], null)); 261 JSON.stringify([1, 2, [3, [4], 5], 6, 7], null));
257 assertEquals("[2,4,[6,[8],10],12,14]", 262 assertEquals("[2,4,[6,[8],10],12,14]",
258 JSON.stringify([1, 2, [3, [4], 5], 6, 7], DoubleNumbers)); 263 JSON.stringify([1, 2, [3, [4], 5], 6, 7], DoubleNumbers));
259 assertEquals('["a","ab","abc"]', JSON.stringify(["a","ab","abc"])); 264 TestStringify('["a","ab","abc"]', ["a","ab","abc"]);
260 assertEquals('{"a":1,"c":true}', 265 TestStringify('{"a":1,"c":true}', { a : 1,
261 JSON.stringify({ a : 1, 266 b : function() { 1 },
262 b : function() { 1 }, 267 c : true,
263 c : true, 268 d : function() { 2 } });
264 d : function() { 2 } })); 269 TestStringify('[1,null,true,null]',
265 assertEquals('[1,null,true,null]', 270 [1, function() { 1 }, true, function() { 2 }]);
266 JSON.stringify([1, function() { 1 }, true, function() { 2 }])); 271 TestStringify('"toJSON 123"',
267 assertEquals('"toJSON 123"', 272 { toJSON : function() { return 'toJSON 123'; } });
268 JSON.stringify({ toJSON : function() { return 'toJSON 123'; } })); 273 TestStringify('{"a":321}',
269 assertEquals('{"a":321}', 274 { a : { toJSON : function() { return 321; } } });
270 JSON.stringify({ a : { toJSON : function() { return 321; } } }));
271 var counter = 0; 275 var counter = 0;
272 assertEquals('{"getter":123}', 276 assertEquals('{"getter":123}',
273 JSON.stringify({ get getter() { counter++; return 123; } })); 277 JSON.stringify({ get getter() { counter++; return 123; } }));
274 assertEquals(1, counter); 278 assertEquals(1, counter);
275 assertEquals('{"a":"abc","b":"\u1234bc"}', 279 assertEquals('{"getter":123}',
276 JSON.stringify({ a : "abc", b : "\u1234bc" })); 280 JSON.stringify({ get getter() { counter++; return 123; } },
281 null,
282 0));
283 assertEquals(2, counter);
284
285 TestStringify('{"a":"abc","b":"\u1234bc"}',
286 { a : "abc", b : "\u1234bc" });
277 287
278 288
279 var a = { a : 1, b : 2 }; 289 var a = { a : 1, b : 2 };
280 delete a.a; 290 delete a.a;
281 assertEquals('{"b":2}', JSON.stringify(a)); 291 TestStringify('{"b":2}', a);
282 292
283 var b = {}; 293 var b = {};
284 b.__proto__ = { toJSON : function() { return 321;} }; 294 b.__proto__ = { toJSON : function() { return 321;} };
285 assertEquals("321", JSON.stringify(b)); 295 TestStringify("321", b);
286 296
287 var array = [""]; 297 var array = [""];
288 var expected = '""'; 298 var expected = '""';
289 for (var i = 0; i < 10000; i++) { 299 for (var i = 0; i < 10000; i++) {
290 array.push(""); 300 array.push("");
291 expected = '"",' + expected; 301 expected = '"",' + expected;
292 } 302 }
293 expected = '[' + expected + ']'; 303 expected = '[' + expected + ']';
294 assertEquals(expected, JSON.stringify(array)); 304 TestStringify(expected, array);
295 305
296 306
297 var circular = [1, 2, 3]; 307 var circular = [1, 2, 3];
298 circular[2] = circular; 308 circular[2] = circular;
299 assertThrows(function () { JSON.stringify(circular); }, TypeError); 309 assertThrows(function () { JSON.stringify(circular); }, TypeError);
310 assertThrows(function () { JSON.stringify(circular, null, 0); }, TypeError);
300 311
301 var singleton = []; 312 var singleton = [];
302 var multiOccurrence = [singleton, singleton, singleton]; 313 var multiOccurrence = [singleton, singleton, singleton];
303 assertEquals("[[],[],[]]", JSON.stringify(multiOccurrence)); 314 TestStringify("[[],[],[]]", multiOccurrence);
304 315
305 assertEquals('{"x":5,"y":6}', JSON.stringify({x:5,y:6})); 316 TestStringify('{"x":5,"y":6}', {x:5,y:6});
306 assertEquals('{"x":5}', JSON.stringify({x:5,y:6}, ['x'])); 317 assertEquals('{"x":5}', JSON.stringify({x:5,y:6}, ['x']));
307 assertEquals('{\n "a": "b",\n "c": "d"\n}', 318 assertEquals('{\n "a": "b",\n "c": "d"\n}',
308 JSON.stringify({a:"b",c:"d"}, null, 1)); 319 JSON.stringify({a:"b",c:"d"}, null, 1));
309 assertEquals('{"y":6,"x":5}', JSON.stringify({x:5,y:6}, ['y', 'x'])); 320 assertEquals('{"y":6,"x":5}', JSON.stringify({x:5,y:6}, ['y', 'x']));
310 321
311 // toJSON get string keys. 322 // toJSON get string keys.
312 var checker = {}; 323 var checker = {};
313 var array = [checker]; 324 var array = [checker];
314 checker.toJSON = function(key) { return 1 + key; }; 325 checker.toJSON = function(key) { return 1 + key; };
315 assertEquals('["10"]', JSON.stringify(array)); 326 TestStringify('["10"]', array);
316 327
317 // The gap is capped at ten characters if specified as string. 328 // The gap is capped at ten characters if specified as string.
318 assertEquals('{\n "a": "b",\n "c": "d"\n}', 329 assertEquals('{\n "a": "b",\n "c": "d"\n}',
319 JSON.stringify({a:"b",c:"d"}, null, 330 JSON.stringify({a:"b",c:"d"}, null,
320 " /*characters after 10th*/")); 331 " /*characters after 10th*/"));
321 332
322 //The gap is capped at ten characters if specified as number. 333 //The gap is capped at ten characters if specified as number.
323 assertEquals('{\n "a": "b",\n "c": "d"\n}', 334 assertEquals('{\n "a": "b",\n "c": "d"\n}',
324 JSON.stringify({a:"b",c:"d"}, null, 15)); 335 JSON.stringify({a:"b",c:"d"}, null, 15));
325 336
326 // Replaced wrapped primitives are unwrapped. 337 // Replaced wrapped primitives are unwrapped.
327 function newx(k, v) { return (k == "x") ? new v(42) : v; } 338 function newx(k, v) { return (k == "x") ? new v(42) : v; }
328 assertEquals('{"x":"42"}', JSON.stringify({x: String}, newx)); 339 assertEquals('{"x":"42"}', JSON.stringify({x: String}, newx));
329 assertEquals('{"x":42}', JSON.stringify({x: Number}, newx)); 340 assertEquals('{"x":42}', JSON.stringify({x: Number}, newx));
330 assertEquals('{"x":true}', JSON.stringify({x: Boolean}, newx)); 341 assertEquals('{"x":true}', JSON.stringify({x: Boolean}, newx));
331 342
332 assertEquals(undefined, JSON.stringify(undefined)); 343 TestStringify(undefined, undefined);
333 assertEquals(undefined, JSON.stringify(function () { })); 344 TestStringify(undefined, function () { });
334 // Arrays with missing, undefined or function elements have those elements 345 // Arrays with missing, undefined or function elements have those elements
335 // replaced by null. 346 // replaced by null.
336 assertEquals("[null,null,null]", 347 TestStringify("[null,null,null]", [undefined,,function(){}]);
337 JSON.stringify([undefined,,function(){}]));
338 348
339 // Objects with undefined or function properties (including replaced properties) 349 // Objects with undefined or function properties (including replaced properties)
340 // have those properties ignored. 350 // have those properties ignored.
341 assertEquals('{}', 351 assertEquals('{}',
342 JSON.stringify({a: undefined, b: function(){}, c: 42, d: 42}, 352 JSON.stringify({a: undefined, b: function(){}, c: 42, d: 42},
343 function(k, v) { if (k == "c") return undefined; 353 function(k, v) { if (k == "c") return undefined;
344 if (k == "d") return function(){}; 354 if (k == "d") return function(){};
345 return v; })); 355 return v; }));
346 356
347 TestInvalid('1); throw "foo"; (1'); 357 TestInvalid('1); throw "foo"; (1');
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 var func = function() { /* Is callable */ }; 418 var func = function() { /* Is callable */ };
409 419
410 var funcJSON = function() { /* Is callable */ }; 420 var funcJSON = function() { /* Is callable */ };
411 funcJSON.toJSON = function() { return "has toJSON"; }; 421 funcJSON.toJSON = function() { return "has toJSON"; };
412 422
413 var re = /Is callable/; 423 var re = /Is callable/;
414 424
415 var reJSON = /Is callable/; 425 var reJSON = /Is callable/;
416 reJSON.toJSON = function() { return "has toJSON"; }; 426 reJSON.toJSON = function() { return "has toJSON"; };
417 427
418 assertEquals( 428 TestStringify('[37,null,1,"foo","37","true",null,"has toJSON",{},"has toJSON"]',
419 '[37,null,1,"foo","37","true",null,"has toJSON",{},"has toJSON"]', 429 [num37, numFoo, numTrue,
420 JSON.stringify([num37, numFoo, numTrue, 430 strFoo, str37, strTrue,
421 strFoo, str37, strTrue, 431 func, funcJSON, re, reJSON]);
422 func, funcJSON, re, reJSON]));
423 432
424 433
425 var oddball = Object(42); 434 var oddball = Object(42);
426 oddball.__proto__ = { __proto__: null, toString: function() { return true; } }; 435 oddball.__proto__ = { __proto__: null, toString: function() { return true; } };
427 assertEquals('1', JSON.stringify(oddball)); 436 TestStringify('1', oddball);
428 437
429 var getCount = 0; 438 var getCount = 0;
430 var callCount = 0; 439 var callCount = 0;
431 var counter = { get toJSON() { getCount++; 440 var counter = { get toJSON() { getCount++;
432 return function() { callCount++; 441 return function() { callCount++;
433 return 42; }; } }; 442 return 42; }; } };
434 443
435 // RegExps are not callable, so they are stringified as objects. 444 // RegExps are not callable, so they are stringified as objects.
436 assertEquals('{}', JSON.stringify(/regexp/)); 445 TestStringify('{}', /regexp/);
437 assertEquals('42', JSON.stringify(counter)); 446 TestStringify('42', counter);
438 assertEquals(1, getCount); 447 assertEquals(2, getCount);
439 assertEquals(1, callCount); 448 assertEquals(2, callCount);
440 449
441 var oddball2 = Object(42); 450 var oddball2 = Object(42);
442 var oddball3 = Object("foo"); 451 var oddball3 = Object("foo");
443 oddball3.__proto__ = { __proto__: null, 452 oddball3.__proto__ = { __proto__: null,
444 toString: "not callable", 453 toString: "not callable",
445 valueOf: function() { return true; } }; 454 valueOf: function() { return true; } };
446 oddball2.__proto__ = { __proto__: null, 455 oddball2.__proto__ = { __proto__: null,
447 toJSON: function () { return oddball3; } } 456 toJSON: function () { return oddball3; } }
448 assertEquals('"true"', JSON.stringify(oddball2)); 457 TestStringify('"true"', oddball2);
449 458
450 459
451 var falseNum = Object("37"); 460 var falseNum = Object("37");
452 falseNum.__proto__ = Number.prototype; 461 falseNum.__proto__ = Number.prototype;
453 falseNum.toString = function() { return 42; }; 462 falseNum.toString = function() { return 42; };
454 assertEquals('"42"', JSON.stringify(falseNum)); 463 TestStringify('"42"', falseNum);
455 464
456 // Parse an object value as __proto__. 465 // Parse an object value as __proto__.
457 var o1 = JSON.parse('{"__proto__":[]}'); 466 var o1 = JSON.parse('{"__proto__":[]}');
458 assertEquals([], o1.__proto__); 467 assertEquals([], o1.__proto__);
459 assertEquals(["__proto__"], Object.keys(o1)); 468 assertEquals(["__proto__"], Object.keys(o1));
460 assertEquals([], Object.getOwnPropertyDescriptor(o1, "__proto__").value); 469 assertEquals([], Object.getOwnPropertyDescriptor(o1, "__proto__").value);
461 assertEquals(["__proto__"], Object.getOwnPropertyNames(o1)); 470 assertEquals(["__proto__"], Object.getOwnPropertyNames(o1));
462 assertTrue(o1.hasOwnProperty("__proto__")); 471 assertTrue(o1.hasOwnProperty("__proto__"));
463 assertTrue(Object.prototype.isPrototypeOf(o1)); 472 assertTrue(Object.prototype.isPrototypeOf(o1));
464 473
465 // Parse a non-object value as __proto__. 474 // Parse a non-object value as __proto__.
466 var o2 = JSON.parse('{"__proto__":5}'); 475 var o2 = JSON.parse('{"__proto__":5}');
467 assertEquals(5, o2.__proto__); 476 assertEquals(5, o2.__proto__);
468 assertEquals(["__proto__"], Object.keys(o2)); 477 assertEquals(["__proto__"], Object.keys(o2));
469 assertEquals(5, Object.getOwnPropertyDescriptor(o2, "__proto__").value); 478 assertEquals(5, Object.getOwnPropertyDescriptor(o2, "__proto__").value);
470 assertEquals(["__proto__"], Object.getOwnPropertyNames(o2)); 479 assertEquals(["__proto__"], Object.getOwnPropertyNames(o2));
471 assertTrue(o2.hasOwnProperty("__proto__")); 480 assertTrue(o2.hasOwnProperty("__proto__"));
472 assertTrue(Object.prototype.isPrototypeOf(o2)); 481 assertTrue(Object.prototype.isPrototypeOf(o2));
473 482
474 var json = '{"stuff before slash\\\\stuff after slash":"whatever"}'; 483 var json = '{"stuff before slash\\\\stuff after slash":"whatever"}';
475 assertEquals(json, JSON.stringify(JSON.parse(json))); 484 TestStringify(json, JSON.parse(json));
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/json2.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698