| // This test should not hang, and should call the reviver function the expected number of times. |
| |
| function shouldBe(actualExpr, expectedExpr) { |
| function toString(x) { |
| return "" + x; |
| } |
| |
| let actual = eval(actualExpr); |
| let expected = eval(expectedExpr); |
| if (typeof actual != typeof expected) |
| throw Error("expected type " + typeof expected + " actual type " + typeof actual); |
| if (toString(actual) != toString(expected)) |
| throw Error("expected: " + expected + " actual: " + actual); |
| } |
| |
| let result; |
| let visited; |
| |
| function test(parseString, clearLength) { |
| visited = []; |
| var result = JSON.parse(parseString, function (key, value) { |
| visited.push('{' + key + ':' + value + '}'); |
| if (clearLength) |
| this.length = 0; |
| return; // returning undefined deletes the value. |
| }); |
| return result; |
| } |
| |
| result = test('[10]', false); |
| shouldBe("result", "undefined"); |
| shouldBe("visited", "['{0:10}','{:}']"); |
| shouldBe("visited.length", "2"); |
| |
| result = test('[10]', true); |
| shouldBe("result", "undefined"); |
| shouldBe("visited", "['{0:10}','{:}']"); |
| shouldBe("visited.length", "2"); |
| |
| result = test('[ [ 10, 11 ], 12, [13, 14, 15], 16, 17]', false); |
| shouldBe("result", "undefined"); |
| shouldBe("visited", "['{0:10}','{1:11}','{0:,}','{1:12}','{0:13}','{1:14}','{2:15}','{2:,,}','{3:16}','{4:17}','{:,,,,}']"); |
| shouldBe("visited.length", "11"); |
| |
| result = test('[ [ 10, 11 ], 12, [13, 14, 15], 16, 17]', true); |
| shouldBe("result", "undefined"); |
| shouldBe("visited", "['{0:10}','{1:undefined}','{0:}','{1:undefined}','{2:undefined}','{3:undefined}','{4:undefined}','{:}']"); |
| shouldBe("visited.length", "8"); |
| |
| result = test('[ { "a": [ 10, 11 ], "b": 12 } , [ 13, { "c": 14 }, 15], 16, 17]', false); |
| shouldBe("result", "undefined"); |
| shouldBe("visited", "['{0:10}','{1:11}','{a:,}','{b:12}','{0:[object Object]}','{0:13}','{c:14}','{1:[object Object]}','{2:15}','{1:,,}','{2:16}','{3:17}','{:,,,}']"); |
| shouldBe("visited.length", "13"); |
| |
| result = test('[ { "a": [ 10, 11 ], "b": 12 } , [ 13, { "c": 14 }, 15], 16, 17]', true); |
| shouldBe("result", "undefined"); |
| shouldBe("visited", "['{0:10}','{1:undefined}','{a:}','{b:12}','{0:[object Object]}','{1:undefined}','{2:undefined}','{3:undefined}','{:}']"); |
| shouldBe("visited.length", "9"); |
| |
| |
| function test2(parseString, clearLength) { |
| visited = []; |
| var result = JSON.parse(parseString, function (key, value) { |
| visited.push('{' + key + ':' + value + '}'); |
| if (clearLength) |
| this.length = 0; |
| return (typeof value === "number") ? value * 2 : value; |
| }); |
| return result; |
| } |
| |
| result = test2('[10]', false); |
| shouldBe("result", "[20]"); |
| shouldBe("visited", "['{0:10}','{:20}']"); |
| shouldBe("visited.length", "2"); |
| |
| result = test2('[10]', true); |
| shouldBe("result", "[20]"); |
| shouldBe("visited", "['{0:10}','{:20}']"); |
| shouldBe("visited.length", "2"); |
| |
| result = test2('[ [ 10, 11 ], 12, [13, 14, 15], 16, 17]', false); |
| shouldBe("result", "[20,22,24,26,28,30,32,34]"); |
| shouldBe("visited", "['{0:10}','{1:11}','{0:20,22}','{1:12}','{0:13}','{1:14}','{2:15}','{2:26,28,30}','{3:16}','{4:17}','{:20,22,24,26,28,30,32,34}']"); |
| shouldBe("visited.length", "11"); |
| |
| result = test2('[ [ 10, 11 ], 12, [13, 14, 15], 16, 17]', true); |
| shouldBe("result", "[]"); |
| shouldBe("visited", "['{0:10}','{1:undefined}','{0:}','{1:undefined}','{2:undefined}','{3:undefined}','{4:undefined}','{:}']"); |
| shouldBe("visited.length", "8"); |
| |
| result = test2('[ { "a": [ 10, 11 ], "b": 12 } , [ 13, { "c": 14 }, 15], 16, 17]', false); |
| shouldBe("result", "['[object Object]',26,'[object Object]',30,32,34]"); |
| shouldBe("visited", "['{0:10}','{1:11}','{a:20,22}','{b:12}','{0:[object Object]}','{0:13}','{c:14}','{1:[object Object]}','{2:15}','{1:26,[object Object],30}','{2:16}','{3:17}','{:[object Object],26,[object Object],30,32,34}']"); |
| shouldBe("visited.length", "13"); |
| |
| result = test2('[ { "a": [ 10, 11 ], "b": 12 } , [ 13, { "c": 14 }, 15], 16, 17]', true); |
| shouldBe("result", "[]"); |
| shouldBe("visited", "['{0:10}','{1:undefined}','{a:}','{b:12}','{0:[object Object]}','{1:undefined}','{2:undefined}','{3:undefined}','{:}']"); |
| shouldBe("visited.length", "9"); |