diff --git a/test/built-ins/JSON/stringify/15.12.3-0-1.js b/test/built-ins/JSON/stringify/15.12.3-0-1.js deleted file mode 100644 index 7fa21c051c..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-0-1.js +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -info: | - This test should be run without any built-ins being added/augmented. - The initial value of [[Configurable]] on JSON is true. This means we - should be able to delete (8.6.2.5) the stringify and parse properties. -es5id: 15.12.3-0-1 -description: JSON.stringify must be deletable (configurable) ----*/ - -var o = JSON; -var desc = Object.getOwnPropertyDescriptor(o, "stringify"); - -assert.sameValue(desc.configurable, true, 'desc.configurable'); diff --git a/test/built-ins/JSON/stringify/15.12.3-0-2.js b/test/built-ins/JSON/stringify/15.12.3-0-2.js deleted file mode 100644 index 4c33fa73b8..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-0-2.js +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -info: | - This test should be run without any built-ins being added/augmented. - The name JSON must be bound to an object. - Section 15 says that every built-in Function object described in this - section � whether as a constructor, an ordinary function, or both � has - a length property whose value is an integer. Unless otherwise specified, - this value is equal to the largest number of named arguments shown in - the section headings for the function description, including optional - parameters. - This default applies to JSON.stringify, and it must exist as a function - taking 3 parameters. -es5id: 15.12.3-0-2 -description: JSON.stringify must exist as a function taking 3 parameters ----*/ - -var f = JSON.stringify; - -assert.sameValue(typeof(f), "function", 'typeof(f)'); -assert.sameValue(f.length, 3, 'f.length'); diff --git a/test/built-ins/JSON/stringify/15.12.3-11-1.js b/test/built-ins/JSON/stringify/15.12.3-11-1.js deleted file mode 100644 index 13654fbc1b..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-11-1.js +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-11-1 -description: JSON.stringify(undefined) returns undefined ----*/ - -assert.sameValue(JSON.stringify(undefined), undefined, 'JSON.stringify(undefined)'); diff --git a/test/built-ins/JSON/stringify/15.12.3-11-10.js b/test/built-ins/JSON/stringify/15.12.3-11-10.js deleted file mode 100644 index c59045ebb0..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-11-10.js +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-11-10 -description: > - A JSON.stringify replacer function applied to a top level scalar - value can return undefined. ----*/ - -assert.sameValue(JSON.stringify(42, function(k, v) { - return undefined -}), undefined, 'JSON.stringify(42, function(k, v) { return undefined })'); diff --git a/test/built-ins/JSON/stringify/15.12.3-11-11.js b/test/built-ins/JSON/stringify/15.12.3-11-11.js deleted file mode 100644 index f4da04f92c..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-11-11.js +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-11-11 -description: > - A JSON.stringify replacer function applied to a top level Object - can return undefined. ----*/ - -assert.sameValue(JSON.stringify({ - prop: 1 -}, function(k, v) { - return undefined -}), undefined, 'JSON.stringify({prop:1}, function(k, v) { return undefined })'); diff --git a/test/built-ins/JSON/stringify/15.12.3-11-12.js b/test/built-ins/JSON/stringify/15.12.3-11-12.js deleted file mode 100644 index 1238189a0f..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-11-12.js +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-11-12 -description: > - A JSON.stringify replacer function applied to a top level scalar - can return an Array. ----*/ - -assert.sameValue(JSON.stringify(42, function(k, v) { - return v == 42 ? [4, 2] : v -}), '[4,2]', 'JSON.stringify(42, function(k, v) { return v==42 ?[4,2]:v })'); diff --git a/test/built-ins/JSON/stringify/15.12.3-11-13.js b/test/built-ins/JSON/stringify/15.12.3-11-13.js deleted file mode 100644 index 22b244c0b6..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-11-13.js +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-11-13 -description: > - A JSON.stringify replacer function applied to a top level scalar - can return an Object. ----*/ - -assert.sameValue(JSON.stringify(42, function(k, v) { - return v == 42 ? { - forty: 2 - } : v -}), '{"forty":2}', 'JSON.stringify(42, function(k, v) { return v==42 ? {forty:2}: v})'); diff --git a/test/built-ins/JSON/stringify/15.12.3-11-14.js b/test/built-ins/JSON/stringify/15.12.3-11-14.js deleted file mode 100644 index 43a27b090d..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-11-14.js +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-11-14 -description: Applying JSON.stringify to a function returns undefined. ----*/ - -assert.sameValue(JSON.stringify(function() {}), undefined, 'JSON.stringify(function() {})'); diff --git a/test/built-ins/JSON/stringify/15.12.3-11-15.js b/test/built-ins/JSON/stringify/15.12.3-11-15.js deleted file mode 100644 index 5a4b35c96e..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-11-15.js +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-11-15 -description: > - Applying JSON.stringify with a replacer function to a function - returns the replacer value. ----*/ - -assert.sameValue(JSON.stringify(function() {}, function(k, v) { - return 99 -}), '99', 'JSON.stringify(function() {}, function(k,v) {return 99})'); diff --git a/test/built-ins/JSON/stringify/15.12.3-11-2.js b/test/built-ins/JSON/stringify/15.12.3-11-2.js deleted file mode 100644 index 721a2fb8ec..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-11-2.js +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-11-2 -description: > - A JSON.stringify replacer function is applied to a top level - undefined value. ----*/ - -assert.sameValue(JSON.stringify(undefined, function(k, v) { - return "replacement" -}), '"replacement"', 'JSON.stringify(undefined, function(k, v) { return "replacement" })'); diff --git a/test/built-ins/JSON/stringify/15.12.3-11-3.js b/test/built-ins/JSON/stringify/15.12.3-11-3.js deleted file mode 100644 index 5d265a1469..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-11-3.js +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-11-3 -description: A JSON.stringify correctly works on top level string values. ----*/ - -assert.sameValue(JSON.stringify("a string"), '"a string"', 'JSON.stringify("a string")'); diff --git a/test/built-ins/JSON/stringify/15.12.3-11-4.js b/test/built-ins/JSON/stringify/15.12.3-11-4.js deleted file mode 100644 index 14286a1fe0..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-11-4.js +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-11-4 -description: JSON.stringify correctly works on top level Number values. ----*/ - -assert.sameValue(JSON.stringify(123), '123', 'JSON.stringify(123)'); diff --git a/test/built-ins/JSON/stringify/15.12.3-11-5.js b/test/built-ins/JSON/stringify/15.12.3-11-5.js deleted file mode 100644 index 95e28dc58e..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-11-5.js +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-11-5 -description: JSON.stringify correctly works on top level Boolean values. ----*/ - -assert.sameValue(JSON.stringify(true), 'true', 'JSON.stringify(true)'); diff --git a/test/built-ins/JSON/stringify/15.12.3-11-6.js b/test/built-ins/JSON/stringify/15.12.3-11-6.js deleted file mode 100644 index b4426e9644..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-11-6.js +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-11-6 -description: JSON.stringify correctly works on top level null values. ----*/ - -assert.sameValue(JSON.stringify(null), 'null', 'JSON.stringify(null)'); diff --git a/test/built-ins/JSON/stringify/15.12.3-11-7.js b/test/built-ins/JSON/stringify/15.12.3-11-7.js deleted file mode 100644 index cd922bcdd7..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-11-7.js +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-11-7 -description: JSON.stringify correctly works on top level Number objects. ----*/ - -assert.sameValue(JSON.stringify(new Number(42)), '42', 'JSON.stringify(new Number(42))'); diff --git a/test/built-ins/JSON/stringify/15.12.3-11-8.js b/test/built-ins/JSON/stringify/15.12.3-11-8.js deleted file mode 100644 index 27bfa5c080..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-11-8.js +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-11-8 -description: JSON.stringify correctly works on top level String objects. ----*/ - -assert.sameValue(JSON.stringify(new String('wrappered')), '"wrappered"', 'JSON.stringify(new String(\'wrappered\'))'); diff --git a/test/built-ins/JSON/stringify/15.12.3-11-9.js b/test/built-ins/JSON/stringify/15.12.3-11-9.js deleted file mode 100644 index ef5a84af96..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-11-9.js +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-11-9 -description: JSON.stringify correctly works on top level Boolean objects. ----*/ - -assert.sameValue(JSON.stringify(new Boolean(false)), 'false', 'JSON.stringify(new Boolean(false))'); diff --git a/test/built-ins/JSON/stringify/15.12.3-4-1.js b/test/built-ins/JSON/stringify/15.12.3-4-1.js deleted file mode 100644 index d681486988..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-4-1.js +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-4-1 -description: > - JSON.stringify ignores replacer aruguments that are not functions - or arrays.. ----*/ - -assert.sameValue(JSON.stringify([42], {}), '[42]', 'JSON.stringify([42],{})'); diff --git a/test/built-ins/JSON/stringify/15.12.3-5-a-i-1.js b/test/built-ins/JSON/stringify/15.12.3-5-a-i-1.js deleted file mode 100644 index 0304b03c2f..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-5-a-i-1.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-5-a-i-1 -description: > - JSON.stringify converts Number wrapper object space aruguments to - Number values ----*/ - -var obj = { - a1: { - b1: [1, 2, 3, 4], - b2: { - c1: 1, - c2: 2 - } - }, - a2: 'a2' -}; - -assert.sameValue(JSON.stringify(obj, null, new Number(5)), JSON.stringify(obj, null, 5), 'JSON.stringify(obj,null, new Number(5))'); diff --git a/test/built-ins/JSON/stringify/15.12.3-5-b-i-1.js b/test/built-ins/JSON/stringify/15.12.3-5-b-i-1.js deleted file mode 100644 index baf3d06f5d..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-5-b-i-1.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-5-b-i-1 -description: > - JSON.stringify converts String wrapper object space aruguments to - String values ----*/ - -var obj = { - a1: { - b1: [1, 2, 3, 4], - b2: { - c1: 1, - c2: 2 - } - }, - a2: 'a2' -}; - -assert.sameValue(JSON.stringify(obj, null, new String('xxx')), JSON.stringify(obj, null, 'xxx'), 'JSON.stringify(obj,null, new String("xxx"))'); diff --git a/test/built-ins/JSON/stringify/15.12.3-6-a-1.js b/test/built-ins/JSON/stringify/15.12.3-6-a-1.js deleted file mode 100644 index 2d7e6386f0..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-6-a-1.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-6-a-1 -description: > - JSON.stringify treats numeric space arguments greater than 10 the - same as a space argument of 10. ----*/ - -var obj = { - a1: { - b1: [1, 2, 3, 4], - b2: { - c1: 1, - c2: 2 - } - }, - a2: 'a2' -}; - -assert.sameValue(JSON.stringify(obj, null, 10), JSON.stringify(obj, null, 100), 'JSON.stringify(obj,null, 10)'); diff --git a/test/built-ins/JSON/stringify/15.12.3-6-a-2.js b/test/built-ins/JSON/stringify/15.12.3-6-a-2.js deleted file mode 100644 index 16349f1f3d..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-6-a-2.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-6-a-2 -description: > - JSON.stringify truccates non-integer numeric space arguments to - their integer part. ----*/ - -var obj = { - a1: { - b1: [1, 2, 3, 4], - b2: { - c1: 1, - c2: 2 - } - }, - a2: 'a2' -}; - -assert.sameValue(JSON.stringify(obj, null, 5.99999), JSON.stringify(obj, null, 5), 'JSON.stringify(obj,null, 5.99999)'); diff --git a/test/built-ins/JSON/stringify/15.12.3-6-b-1.js b/test/built-ins/JSON/stringify/15.12.3-6-b-1.js deleted file mode 100644 index d178f1eef3..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-6-b-1.js +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-6-b-1 -description: > - JSON.stringify treats numeric space arguments less than 1 - (0.999999)the same as empty string space argument. ----*/ - -var obj = { - a1: { - b1: [1, 2, 3, 4], - b2: { - c1: 1, - c2: 2 - } - }, - a2: 'a2' -}; - -/* empty string should be same as no space arg */ -assert.sameValue(JSON.stringify(obj, null, 0.999999), JSON.stringify(obj)); diff --git a/test/built-ins/JSON/stringify/15.12.3-6-b-2.js b/test/built-ins/JSON/stringify/15.12.3-6-b-2.js deleted file mode 100644 index 504e939e67..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-6-b-2.js +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-6-b-2 -description: > - JSON.stringify treats numeric space arguments less than 1 (0)the - same as empty string space argument. ----*/ - -var obj = { - a1: { - b1: [1, 2, 3, 4], - b2: { - c1: 1, - c2: 2 - } - }, - a2: 'a2' -}; - -/* empty string should be same as no space arg */ -assert.sameValue(JSON.stringify(obj, null, 0), JSON.stringify(obj)); diff --git a/test/built-ins/JSON/stringify/15.12.3-6-b-3.js b/test/built-ins/JSON/stringify/15.12.3-6-b-3.js deleted file mode 100644 index 92db3c8254..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-6-b-3.js +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-6-b-3 -description: > - JSON.stringify treats numeric space arguments less than 1 (-5) the - same as empty string space argument. ----*/ - -var obj = { - a1: { - b1: [1, 2, 3, 4], - b2: { - c1: 1, - c2: 2 - } - }, - a2: 'a2' -}; - -/* empty string should be same as no space arg */ -assert.sameValue(JSON.stringify(obj, null, -5), JSON.stringify(obj)); diff --git a/test/built-ins/JSON/stringify/15.12.3-6-b-4.js b/test/built-ins/JSON/stringify/15.12.3-6-b-4.js deleted file mode 100644 index e492e43a3c..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-6-b-4.js +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-6-b-4 -description: > - JSON.stringify treats numeric space arguments (in the range 1..10) - is equivalent to a string of spaces of that length. ----*/ - -var obj = { - a1: { - b1: [1, 2, 3, 4], - b2: { - c1: 1, - c2: 2 - } - }, - a2: 'a2' -}; -var fiveSpaces = ' '; -// '12345' - -assert.sameValue(JSON.stringify(obj, null, 5), JSON.stringify(obj, null, fiveSpaces), 'JSON.stringify(obj,null, 5)'); diff --git a/test/built-ins/JSON/stringify/15.12.3-7-a-1.js b/test/built-ins/JSON/stringify/15.12.3-7-a-1.js deleted file mode 100644 index fd579d854d..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-7-a-1.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-7-a-1 -description: > - JSON.stringify only uses the first 10 characters of a string space - arguments. ----*/ - -var obj = { - a1: { - b1: [1, 2, 3, 4], - b2: { - c1: 1, - c2: 2 - } - }, - a2: 'a2' -}; - -assert.sameValue(JSON.stringify(obj, null, '0123456789xxxxxxxxx'), JSON.stringify(obj, null, '0123456789'), 'JSON.stringify(obj,null, "0123456789xxxxxxxxx")'); diff --git a/test/built-ins/JSON/stringify/15.12.3-8-a-1.js b/test/built-ins/JSON/stringify/15.12.3-8-a-1.js deleted file mode 100644 index 7fc0583f61..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-8-a-1.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-8-a-1 -description: > - JSON.stringify treats an empty string space argument the same as a - missing space argument. ----*/ - -var obj = { - a1: { - b1: [1, 2, 3, 4], - b2: { - c1: 1, - c2: 2 - } - }, - a2: 'a2' -}; - -assert.sameValue(JSON.stringify(obj), JSON.stringify(obj, null, ''), 'JSON.stringify(obj)'); diff --git a/test/built-ins/JSON/stringify/15.12.3-8-a-2.js b/test/built-ins/JSON/stringify/15.12.3-8-a-2.js deleted file mode 100644 index eacd51d52c..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-8-a-2.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-8-a-2 -description: > - JSON.stringify treats an Boolean space argument the same as a - missing space argument. ----*/ - -var obj = { - a1: { - b1: [1, 2, 3, 4], - b2: { - c1: 1, - c2: 2 - } - }, - a2: 'a2' -}; - -assert.sameValue(JSON.stringify(obj), JSON.stringify(obj, null, true), 'JSON.stringify(obj)'); diff --git a/test/built-ins/JSON/stringify/15.12.3-8-a-3.js b/test/built-ins/JSON/stringify/15.12.3-8-a-3.js deleted file mode 100644 index 072eb9d536..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-8-a-3.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-8-a-3 -description: > - JSON.stringify treats an null space argument the same as a missing - space argument. ----*/ - -var obj = { - a1: { - b1: [1, 2, 3, 4], - b2: { - c1: 1, - c2: 2 - } - }, - a2: 'a2' -}; - -assert.sameValue(JSON.stringify(obj), JSON.stringify(obj, null, null), 'JSON.stringify(obj)'); diff --git a/test/built-ins/JSON/stringify/15.12.3-8-a-4.js b/test/built-ins/JSON/stringify/15.12.3-8-a-4.js deleted file mode 100644 index 7ac1a28ecf..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-8-a-4.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-8-a-4 -description: > - JSON.stringify treats an Boolean wrapper space argument the same - as a missing space argument. ----*/ - -var obj = { - a1: { - b1: [1, 2, 3, 4], - b2: { - c1: 1, - c2: 2 - } - }, - a2: 'a2' -}; - -assert.sameValue(JSON.stringify(obj), JSON.stringify(obj, null, new Boolean(true)), 'JSON.stringify(obj)'); diff --git a/test/built-ins/JSON/stringify/15.12.3-8-a-5.js b/test/built-ins/JSON/stringify/15.12.3-8-a-5.js deleted file mode 100644 index 4f05d178f9..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3-8-a-5.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3-8-a-5 -description: > - JSON.stringify treats non-Number or String object space arguments - the same as a missing space argument. ----*/ - -var obj = { - a1: { - b1: [1, 2, 3, 4], - b2: { - c1: 1, - c2: 2 - } - }, - a2: 'a2' -}; - -assert.sameValue(JSON.stringify(obj), JSON.stringify(obj, null, obj), 'JSON.stringify(obj)'); diff --git a/test/built-ins/JSON/stringify/15.12.3_2-2-b-i-1.js b/test/built-ins/JSON/stringify/15.12.3_2-2-b-i-1.js deleted file mode 100644 index 447652a8b1..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3_2-2-b-i-1.js +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3_2-2-b-i-1 -description: > - JSON.stringify converts string wrapper objects returned from a - toJSON call to literal strings. ----*/ - -var obj = { - prop: 42, - toJSON: function() { - return 'fortytwo objects' - } -}; - -assert.sameValue(JSON.stringify([obj]), '["fortytwo objects"]', 'JSON.stringify([obj])'); diff --git a/test/built-ins/JSON/stringify/15.12.3_2-2-b-i-2.js b/test/built-ins/JSON/stringify/15.12.3_2-2-b-i-2.js deleted file mode 100644 index aa418fefd5..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3_2-2-b-i-2.js +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3_2-2-b-i-2 -description: > - JSON.stringify converts Number wrapper objects returned from a - toJSON call to literal Number. ----*/ - -var obj = { - prop: 42, - toJSON: function() { - return new Number(42) - } -}; - -assert.sameValue(JSON.stringify([obj]), '[42]', 'JSON.stringify([obj])'); diff --git a/test/built-ins/JSON/stringify/15.12.3_2-2-b-i-3.js b/test/built-ins/JSON/stringify/15.12.3_2-2-b-i-3.js deleted file mode 100644 index 6f4eaccdf1..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3_2-2-b-i-3.js +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3_2-2-b-i-3 -description: > - JSON.stringify converts Boolean wrapper objects returned from a - toJSON call to literal Boolean values. ----*/ - -var obj = { - prop: 42, - toJSON: function() { - return new Boolean(true) - } -}; - -assert.sameValue(JSON.stringify([obj]), '[true]', 'JSON.stringify([obj])'); diff --git a/test/built-ins/JSON/stringify/15.12.3_2-3-a-1.js b/test/built-ins/JSON/stringify/15.12.3_2-3-a-1.js deleted file mode 100644 index aefb5d77ca..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3_2-3-a-1.js +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3_2-3-a-1 -description: > - JSON.stringify converts string wrapper objects returned from - replacer functions to literal strings. ----*/ - -assert.sameValue(JSON.stringify([42], function(k, v) { - return v === 42 ? new String('fortytwo') : v -}), '["fortytwo"]', 'JSON.stringify([42], function(k,v) {return v===42? new String("fortytwo"):v})'); diff --git a/test/built-ins/JSON/stringify/15.12.3_2-3-a-2.js b/test/built-ins/JSON/stringify/15.12.3_2-3-a-2.js deleted file mode 100644 index 87b0df0ac0..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3_2-3-a-2.js +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3_2-3-a-2 -description: > - JSON.stringify converts Number wrapper objects returned from - replacer functions to literal numbers. ----*/ - -assert.sameValue(JSON.stringify([42], function(k, v) { - return v === 42 ? new Number(84) : v -}), '[84]', 'JSON.stringify([42], function(k,v) {return v===42? new Number(84):v})'); diff --git a/test/built-ins/JSON/stringify/15.12.3_2-3-a-3.js b/test/built-ins/JSON/stringify/15.12.3_2-3-a-3.js deleted file mode 100644 index a26ae4b2f0..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3_2-3-a-3.js +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3_2-3-a-3 -description: > - JSON.stringify converts Boolean wrapper objects returned from - replacer functions to literal numbers. ----*/ - -assert.sameValue(JSON.stringify([42], function(k, v) { - return v === 42 ? new Boolean(false) : v -}), '[false]', 'JSON.stringify([42], function(k,v) {return v===42? new Boolean(false):v})'); diff --git a/test/built-ins/JSON/stringify/15.12.3_4-1-1.js b/test/built-ins/JSON/stringify/15.12.3_4-1-1.js deleted file mode 100644 index 636b52e563..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3_4-1-1.js +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3_4-1-1 -description: JSON.stringify of a circular object throws a TypeError ----*/ - -var obj = {}; -obj.prop = obj; - -assert.throws(TypeError, function() { - JSON.stringify(obj); -}); diff --git a/test/built-ins/JSON/stringify/15.12.3_4-1-2.js b/test/built-ins/JSON/stringify/15.12.3_4-1-2.js deleted file mode 100644 index dfd81c7d2a..0000000000 --- a/test/built-ins/JSON/stringify/15.12.3_4-1-2.js +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2012 Ecma International. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es5id: 15.12.3_4-1-2 -description: JSON.stringify of an indirectly circular object throws a TypeError ----*/ - -var obj = { - p1: { - p2: {} - } -}; -obj.p1.p2.prop = obj; - -assert.throws(TypeError, function() { - JSON.stringify(obj); -}); diff --git a/test/built-ins/JSON/stringify/builtin.js b/test/built-ins/JSON/stringify/builtin.js new file mode 100644 index 0000000000..20761f1c4d --- /dev/null +++ b/test/built-ins/JSON/stringify/builtin.js @@ -0,0 +1,17 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-json.stringify +description: > + Tests that JSON.stringify meets the requirements + for built-in objects defined by the introduction of chapter 17 of + the ECMAScript Language Specification. +includes: [isConstructor.js] +features: [Reflect.construct] +---*/ + +assert(Object.isExtensible(JSON.stringify)); +assert.sameValue(Object.prototype.toString.call(JSON.stringify), '[object Function]'); +assert.sameValue(Object.getPrototypeOf(JSON.stringify), Function.prototype); +assert.sameValue(JSON.stringify.hasOwnProperty('prototype'), false); +assert.sameValue(isConstructor(JSON.stringify), false); diff --git a/test/built-ins/JSON/stringify/length.js b/test/built-ins/JSON/stringify/length.js new file mode 100644 index 0000000000..e39803f2a1 --- /dev/null +++ b/test/built-ins/JSON/stringify/length.js @@ -0,0 +1,25 @@ +// Copyright (C) 2012 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-json.stringify +description: > + JSON.stringify.length is 3. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + The "length" property of the stringify function is 3. + + ECMAScript Standard Built-in Objects + + Unless otherwise specified, the length property of a built-in Function + object has the attributes { [[Writable]]: false, [[Enumerable]]: false, + [[Configurable]]: true }. +includes: [propertyHelper.js] +---*/ + +verifyProperty(JSON.stringify, 'length', { + value: 3, + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/test/built-ins/JSON/stringify/name.js b/test/built-ins/JSON/stringify/name.js index 70d1b374b8..e28c3b6225 100644 --- a/test/built-ins/JSON/stringify/name.js +++ b/test/built-ins/JSON/stringify/name.js @@ -2,7 +2,7 @@ // This code is governed by the BSD license found in the LICENSE file. /*--- -es6id: 24.3.2 +esid: sec-json.stringify description: > JSON.stringify.name is "stringify". info: | @@ -19,8 +19,9 @@ info: | includes: [propertyHelper.js] ---*/ -assert.sameValue(JSON.stringify.name, "stringify"); - -verifyNotEnumerable(JSON.stringify, "name"); -verifyNotWritable(JSON.stringify, "name"); -verifyConfigurable(JSON.stringify, "name"); +verifyProperty(JSON.stringify, 'name', { + value: 'stringify', + writable: false, + enumerable: false, + configurable: true, +}); diff --git a/test/built-ins/JSON/stringify/prop-desc.js b/test/built-ins/JSON/stringify/prop-desc.js new file mode 100644 index 0000000000..5826d76c0a --- /dev/null +++ b/test/built-ins/JSON/stringify/prop-desc.js @@ -0,0 +1,20 @@ +// Copyright (C) 2012 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-json.stringify +description: > + Property descriptor of JSON.stringify. +info: | + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 18 through 26 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +includes: [propertyHelper.js] +---*/ + +verifyProperty(JSON, 'stringify', { + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/test/built-ins/JSON/stringify/replacer-array-abrupt.js b/test/built-ins/JSON/stringify/replacer-array-abrupt.js new file mode 100644 index 0000000000..9d37397c4e --- /dev/null +++ b/test/built-ins/JSON/stringify/replacer-array-abrupt.js @@ -0,0 +1,59 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-json.stringify +description: > + Abrupt completion from Get. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 4. If Type(replacer) is Object, then + [...] + 2. Let len be ? LengthOfArrayLike(replacer). + 3. Let k be 0. + 4. Repeat, while k < len, + a. Let v be ? Get(replacer, ! ToString(k)). +features: [Proxy] +---*/ + +var abruptLength = new Proxy([], { + get: function(_target, key) { + if (key === 'length') { + throw new Test262Error(); + } + }, +}); + +assert.throws(Test262Error, function() { + JSON.stringify(null, abruptLength); +}); + +var abruptToPrimitive = { + valueOf: function() { + throw new Test262Error(); + }, +}; + +var abruptToLength = new Proxy([], { + get: function(_target, key) { + if (key === 'length') { + return abruptToPrimitive; + } + }, +}); + +assert.throws(Test262Error, function() { + JSON.stringify([], abruptToLength); +}); + +var abruptIndex = new Array(1); +Object.defineProperty(abruptIndex, '0', { + get: function() { + throw new Test262Error(); + }, +}); + +assert.throws(Test262Error, function() { + JSON.stringify({}, abruptIndex); +}); diff --git a/test/built-ins/JSON/stringify/replacer-array-duplicates.js b/test/built-ins/JSON/stringify/replacer-array-duplicates.js new file mode 100644 index 0000000000..265b95eb7a --- /dev/null +++ b/test/built-ins/JSON/stringify/replacer-array-duplicates.js @@ -0,0 +1,29 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-json.stringify +description: > + Replacer array is deduped before Get. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 4. If Type(replacer) is Object, then + [...] + 4. Repeat, while k < len, + a. Let v be ? Get(replacer, ! ToString(k)). + [...] + f. If item is not undefined and item is not currently an element of PropertyList, then + i. Append item to the end of PropertyList. +---*/ + +var getCalls = 0; +var value = { + get key() { + getCalls += 1; + return true; + }, +}; + +assert.sameValue(JSON.stringify(value, ['key', 'key']), '{"key":true}'); +assert.sameValue(getCalls, 1); diff --git a/test/built-ins/JSON/stringify/replacer-array-empty.js b/test/built-ins/JSON/stringify/replacer-array-empty.js new file mode 100644 index 0000000000..c09479df38 --- /dev/null +++ b/test/built-ins/JSON/stringify/replacer-array-empty.js @@ -0,0 +1,40 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonobject +description: > + Objects are serialized to {} if replacer array is empty. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + [...] + 10. If Type(value) is Object and IsCallable(value) is false, then + [...] + c. Return ? SerializeJSONObject(value). + + SerializeJSONObject ( value ) + + [...] + 5. If PropertyList is not undefined, then + a. Let K be PropertyList. +---*/ + +assert.sameValue( + JSON.stringify({a: 1, b: 2}, []), + '{}' +); + +assert.sameValue( + JSON.stringify({a: 1, b: {c: 2}}, []), + '{}' +); + +assert.sameValue( + JSON.stringify([1, {a: 2}], []), + '[1,{}]' +); diff --git a/test/built-ins/JSON/stringify/replacer-array-number-object.js b/test/built-ins/JSON/stringify/replacer-array-number-object.js new file mode 100644 index 0000000000..0a4754bd56 --- /dev/null +++ b/test/built-ins/JSON/stringify/replacer-array-number-object.js @@ -0,0 +1,31 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-json.stringify +description: > + Converts Number objects from replacer array to primitives using ToString. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 4. If Type(replacer) is Object, then + [...] + 4. Repeat, while k < len, + a. Let v be ? Get(replacer, ! ToString(k)). + [...] + e. Else if Type(v) is Object, then + i. If v has a [[StringData]] or [[NumberData]] internal slot, + set item to ? ToString(v). +---*/ + +var num = new Number(10); +num.toString = function() { return 'toString'; }; +num.valueOf = function() { throw new Test262Error('should not be called'); }; + +var value = { + 10: 1, + toString: 2, + valueOf: 3, +}; + +assert.sameValue(JSON.stringify(value, [num]), '{"toString":2}'); diff --git a/test/built-ins/JSON/stringify/replacer-array-number.js b/test/built-ins/JSON/stringify/replacer-array-number.js new file mode 100644 index 0000000000..3f0416d15b --- /dev/null +++ b/test/built-ins/JSON/stringify/replacer-array-number.js @@ -0,0 +1,40 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-json.stringify +description: > + Converts number primitives from replacer array to strings. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 4. If Type(replacer) is Object, then + [...] + 4. Repeat, while k < len, + a. Let v be ? Get(replacer, ! ToString(k)). + [...] + d. Else if Type(v) is Number, set item to ! ToString(v). +---*/ + +var obj = { + '0': 0, + '1': 1, + '-4': 2, + '0.3': 3, + '-Infinity': 4, + 'NaN': 5, +}; + +var replacer = [ + -0, + 1, + -4, + 0.3, + -Infinity, + NaN, +]; + +assert.sameValue( + JSON.stringify(obj, replacer), + JSON.stringify(obj) +); diff --git a/test/built-ins/JSON/stringify/replacer-array-order.js b/test/built-ins/JSON/stringify/replacer-array-order.js new file mode 100644 index 0000000000..4c9e507252 --- /dev/null +++ b/test/built-ins/JSON/stringify/replacer-array-order.js @@ -0,0 +1,37 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonobject +description: > + Keys order of serialized objects is determined by replacer array. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + [...] + 10. If Type(value) is Object and IsCallable(value) is false, then + [...] + c. Return ? SerializeJSONObject(value). + + SerializeJSONObject ( value ) + + [...] + 5. If PropertyList is not undefined, then + a. Let K be PropertyList. +---*/ + +var replacer = ['c', 'b', 'a']; + +assert.sameValue( + JSON.stringify({b: 1, a: 2, c: 3}, replacer), + '{"c":3,"b":1,"a":2}' +); + +assert.sameValue( + JSON.stringify({a: {b: 2, c: 3}}, replacer), + '{"a":{"c":3,"b":2}}' +); diff --git a/test/built-ins/JSON/stringify/replacer-array-proxy-revoked-realm.js b/test/built-ins/JSON/stringify/replacer-array-proxy-revoked-realm.js new file mode 100644 index 0000000000..ba9f3573df --- /dev/null +++ b/test/built-ins/JSON/stringify/replacer-array-proxy-revoked-realm.js @@ -0,0 +1,35 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-json.stringify +description: > + Revoked proxy of array as replacer produces a TypeError + (honoring the realm of the current execution context). +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 4. If Type(replacer) is Object, then + a. If IsCallable(replacer) is true, then + i. Let ReplacerFunction be replacer. + b. Else, + i. Let isArray be ? IsArray(replacer). + + IsArray ( argument ) + + [...] + 3. If argument is a Proxy exotic object, then + a. If argument.[[ProxyHandler]] is null, throw a TypeError exception. + b. Let target be argument.[[ProxyTarget]]. + c. Return ? IsArray(target). +features: [cross-realm, Proxy] +---*/ + +var OProxy = $262.createRealm().global.Proxy; +var handle = OProxy.revocable([], {}); + +handle.revoke(); + +assert.throws(TypeError, function() { + JSON.stringify({}, handle.proxy); +}); diff --git a/test/built-ins/JSON/stringify/replacer-proxy-revoked.js b/test/built-ins/JSON/stringify/replacer-array-proxy-revoked.js similarity index 93% rename from test/built-ins/JSON/stringify/replacer-proxy-revoked.js rename to test/built-ins/JSON/stringify/replacer-array-proxy-revoked.js index 2014261ab2..1ca55a35c5 100644 --- a/test/built-ins/JSON/stringify/replacer-proxy-revoked.js +++ b/test/built-ins/JSON/stringify/replacer-array-proxy-revoked.js @@ -2,7 +2,7 @@ // This code is governed by the BSD license found in the LICENSE file. /*--- esid: sec-json.stringify -description: Revoked proxy value produces a TypeError +description: Revoked proxy value produces a TypeError. info: | [...] 4. If Type(replacer) is Object, then diff --git a/test/built-ins/JSON/stringify/replacer-array-proxy.js b/test/built-ins/JSON/stringify/replacer-array-proxy.js new file mode 100644 index 0000000000..488035f465 --- /dev/null +++ b/test/built-ins/JSON/stringify/replacer-array-proxy.js @@ -0,0 +1,30 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-json.stringify +description: > + Array proxy replacer serves as whitelist of object keys. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 4. If Type(replacer) is Object, then + a. If IsCallable(replacer) is true, then + i. Let ReplacerFunction be replacer. + b. Else, + i. Let isArray be ? IsArray(replacer). + + IsArray ( argument ) + + [...] + 3. If argument is a Proxy exotic object, then + a. If argument.[[ProxyHandler]] is null, throw a TypeError exception. + b. Let target be argument.[[ProxyTarget]]. + c. Return ? IsArray(target). +features: [Proxy] +---*/ + +var replacer = new Proxy(['b'], {}); + +assert.sameValue(JSON.stringify({a: 1, b: 2}, replacer), '{"b":2}'); +assert.sameValue(JSON.stringify({b: {a: 3, b: 4}}, replacer), '{"b":{"b":4}}'); diff --git a/test/built-ins/JSON/stringify/replacer-array-string-object.js b/test/built-ins/JSON/stringify/replacer-array-string-object.js new file mode 100644 index 0000000000..899e5c590b --- /dev/null +++ b/test/built-ins/JSON/stringify/replacer-array-string-object.js @@ -0,0 +1,31 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-json.stringify +description: > + Converts String objects from replacer array to primitives using ToString. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 4. If Type(replacer) is Object, then + [...] + 4. Repeat, while k < len, + a. Let v be ? Get(replacer, ! ToString(k)). + [...] + e. Else if Type(v) is Object, then + i. If v has a [[StringData]] or [[NumberData]] internal slot, + set item to ? ToString(v). +---*/ + +var str = new String('str'); +str.toString = function() { return 'toString'; }; +str.valueOf = function() { throw new Test262Error('should not be called'); }; + +var value = { + str: 1, + toString: 2, + valueOf: 3, +}; + +assert.sameValue(JSON.stringify(value, [str]), '{"toString":2}'); diff --git a/test/built-ins/JSON/stringify/replacer-array-undefined.js b/test/built-ins/JSON/stringify/replacer-array-undefined.js new file mode 100644 index 0000000000..22e5684359 --- /dev/null +++ b/test/built-ins/JSON/stringify/replacer-array-undefined.js @@ -0,0 +1,29 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-json.stringify +description: > + Undefined values in replacer array are ignored. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 4. If Type(replacer) is Object, then + [...] + 4. Repeat, while k < len, + a. Let v be ? Get(replacer, ! ToString(k)). + [...] + f. If item is not undefined and item is not currently an element of PropertyList, then + i. Append item to the end of PropertyList. +---*/ + +assert.sameValue(JSON.stringify({undefined: 1}, [undefined]), '{}'); +assert.sameValue(JSON.stringify({key: 1, undefined: 2}, [,,,]), '{}'); + +var sparse = new Array(3); +sparse[1] = 'key'; + +assert.sameValue( + JSON.stringify({undefined: 1, key: 2}, sparse), + '{"key":2}' +); diff --git a/test/built-ins/JSON/stringify/replacer-array-wrong-type.js b/test/built-ins/JSON/stringify/replacer-array-wrong-type.js new file mode 100644 index 0000000000..6c418f4b26 --- /dev/null +++ b/test/built-ins/JSON/stringify/replacer-array-wrong-type.js @@ -0,0 +1,37 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-json.stringify +description: > + Values that are neither strings nor numbers are ignored. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 4. If Type(replacer) is Object, then + [...] + 4. Repeat, while k < len, + a. Let v be ? Get(replacer, ! ToString(k)). + [...] + f. If item is not undefined and item is not currently an element of PropertyList, then + i. Append item to the end of PropertyList. +features: [Proxy, Symbol] +---*/ + +var obj = new Proxy({}, { + get: function(_target, key) { + if (key !== 'toJSON') { + throw new Test262Error(); + } + }, +}); + +var replacer = [ + true, + false, + null, + {toString: function() { return 'toString'; }}, + Symbol(), +]; + +assert.sameValue(JSON.stringify(obj, replacer), '{}'); diff --git a/test/built-ins/JSON/stringify/replacer-function-abrupt.js b/test/built-ins/JSON/stringify/replacer-function-abrupt.js new file mode 100644 index 0000000000..1be7ca9f93 --- /dev/null +++ b/test/built-ins/JSON/stringify/replacer-function-abrupt.js @@ -0,0 +1,28 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonproperty +description: > + Abrupt completion from Call. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 4. If Type(replacer) is Object, then + a. If IsCallable(replacer) is true, then + i. Let ReplacerFunction be replacer. + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + [...] + 3. If ReplacerFunction is not undefined, then + a. Set value to ? Call(ReplacerFunction, holder, « key, value »). +---*/ + +assert.throws(Test262Error, function() { + JSON.stringify({}, function() { + throw new Test262Error(); + }); +}); diff --git a/test/built-ins/JSON/stringify/replacer-function-arguments.js b/test/built-ins/JSON/stringify/replacer-function-arguments.js new file mode 100644 index 0000000000..e09c6ffa94 --- /dev/null +++ b/test/built-ins/JSON/stringify/replacer-function-arguments.js @@ -0,0 +1,53 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonproperty +description: > + Replacer function is called with correct context and arguments. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + 1. Let value be ? Get(holder, key). + [...] + 3. If ReplacerFunction is not undefined, then + a. Set value to ? Call(ReplacerFunction, holder, « key, value »). +includes: [compareArray.js] +---*/ + +var calls = []; +var replacer = function(key, value) { + if (key !== '') { + calls.push([this, key, value]); + } + + return value; +}; + +var b1 = [1, 2]; +var b2 = {c1: true, c2: false}; +var a1 = { + b1: b1, + b2: { + toJSON: function() { return b2; }, + }, +}; +var obj = {a1: a1, a2: 'a2'}; + +assert.sameValue( + JSON.stringify(obj, replacer), + JSON.stringify(obj) +); + +assert.compareArray(calls[0], [obj, 'a1', a1]); +assert.compareArray(calls[1], [a1, 'b1', b1]); +assert.compareArray(calls[2], [b1, '0', 1]); +assert.compareArray(calls[3], [b1, '1', 2]); +assert.compareArray(calls[4], [a1, 'b2', b2]); +assert.compareArray(calls[5], [b2, 'c1', true]); +assert.compareArray(calls[6], [b2, 'c2', false]); +assert.compareArray(calls[7], [obj, 'a2', 'a2']); diff --git a/test/built-ins/JSON/stringify/replacer-function-array-circular.js b/test/built-ins/JSON/stringify/replacer-function-array-circular.js new file mode 100644 index 0000000000..1af92fcea1 --- /dev/null +++ b/test/built-ins/JSON/stringify/replacer-function-array-circular.js @@ -0,0 +1,53 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonarray +description: > + Circular array value (returned from replacer function) throws a TypeError. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + [...] + 3. If ReplacerFunction is not undefined, then + a. Set value to ? Call(ReplacerFunction, holder, « key, value »). + [...] + 10. If Type(value) is Object and IsCallable(value) is false, then + a. Let isArray be ? IsArray(value). + b. If isArray is true, return ? SerializeJSONArray(value). + + SerializeJSONArray ( value ) + + 1. If stack contains value, throw a TypeError exception because the structure is cyclical. +---*/ + +var direct = []; +var directReplacer = function(_key, value) { + if (value === direct) { + return [direct]; + } + + return value; +}; + +assert.throws(TypeError, function() { + JSON.stringify(direct, directReplacer); +}); + +var arr = []; +var indirect = [[arr]]; +var indirectReplacer = function(_key, value) { + if (value === arr) { + return [indirect]; + } + + return value; +}; + +assert.throws(TypeError, function() { + JSON.stringify(indirect, indirectReplacer); +}); diff --git a/test/built-ins/JSON/stringify/replacer-function-object-circular.js b/test/built-ins/JSON/stringify/replacer-function-object-circular.js new file mode 100644 index 0000000000..cba4ac2478 --- /dev/null +++ b/test/built-ins/JSON/stringify/replacer-function-object-circular.js @@ -0,0 +1,52 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonobject +description: > + Circular object value (returned from replacer function) throws a TypeError. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + [...] + 3. If ReplacerFunction is not undefined, then + a. Set value to ? Call(ReplacerFunction, holder, « key, value »). + [...] + 10. If Type(value) is Object and IsCallable(value) is false, then + [...] + c. Return ? SerializeJSONObject(value). + + SerializeJSONObject ( value ) + + 1. If stack contains value, throw a TypeError exception because the structure is cyclical. +---*/ + +var direct = {}; +var directReplacer = function(_key, value) { + if (value === direct) { + return {prop: direct}; + } + + return value; +}; + +assert.throws(TypeError, function() { + JSON.stringify(direct, directReplacer); +}); + +var indirect = {p1: {p2: {}}}; +var indirectReplacer = function(_key, value) { + if (value === indirect.p1.p2) { + return {p3: indirect}; + } + + return value; +}; + +assert.throws(TypeError, function() { + JSON.stringify(indirect, indirectReplacer); +}); diff --git a/test/built-ins/JSON/stringify/replacer-function-result-undefined.js b/test/built-ins/JSON/stringify/replacer-function-result-undefined.js new file mode 100644 index 0000000000..51125e385c --- /dev/null +++ b/test/built-ins/JSON/stringify/replacer-function-result-undefined.js @@ -0,0 +1,34 @@ +// Copyright (C) 2012 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonproperty +description: > + Result of replacer function is stringified. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + [...] + 3. If ReplacerFunction is not undefined, then + a. Set value to ? Call(ReplacerFunction, holder, « key, value »). +---*/ + +assert.sameValue(JSON.stringify(1, function() {}), undefined); +assert.sameValue(JSON.stringify([1], function() {}), undefined); +assert.sameValue(JSON.stringify({prop: 1}, function() {}), undefined); + +var replacer = function(_key, value) { + return value === 1 ? undefined : value; +}; + +assert.sameValue(JSON.stringify([1], replacer), '[null]'); +assert.sameValue(JSON.stringify({prop: 1}, replacer), '{}'); +assert.sameValue(JSON.stringify({ + a: { + b: [1], + }, +}, replacer), '{"a":{"b":[null]}}'); diff --git a/test/built-ins/JSON/stringify/replacer-function-result.js b/test/built-ins/JSON/stringify/replacer-function-result.js new file mode 100644 index 0000000000..3e507eef0b --- /dev/null +++ b/test/built-ins/JSON/stringify/replacer-function-result.js @@ -0,0 +1,54 @@ +// Copyright (C) 2012 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonproperty +description: > + Result of replacer function is stringified. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + [...] + 3. If ReplacerFunction is not undefined, then + a. Set value to ? Call(ReplacerFunction, holder, « key, value »). +---*/ + +var obj = { + a1: { + b1: [1, 2], + b2: { + c1: true, + c2: false, + }, + }, + a2: 'a2', +}; + +var replacer = function(key, value) { + assert.sameValue(value, null); + + switch (key) { + case '': return {a1: null, a2: null}; + case 'a1': return {b1: null, b2: null}; + case 'a2': return 'a2'; + + case 'b1': return [null, null]; + case 'b2': return {c1: null, c2: null}; + + case '0': return 1; + case '1': return 2; + case 'c1': return true; + case 'c2': return false; + } + + throw new Test262Error('unreachable'); +}; + +assert.sameValue( + JSON.stringify(null, replacer), + JSON.stringify(obj) +); diff --git a/test/built-ins/JSON/stringify/replacer-function-tojson.js b/test/built-ins/JSON/stringify/replacer-function-tojson.js new file mode 100644 index 0000000000..bb7819b2fb --- /dev/null +++ b/test/built-ins/JSON/stringify/replacer-function-tojson.js @@ -0,0 +1,52 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonproperty +description: > + Replacer function is called on result of toJSON method. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 4. If Type(replacer) is Object, then + a. If IsCallable(replacer) is true, then + i. Let ReplacerFunction be replacer. + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + [...] + 2. If Type(value) is Object, then + a. Let toJSON be ? Get(value, "toJSON"). + b. If IsCallable(toJSON) is true, then + i. Set value to ? Call(toJSON, value, « key »). + 3. If ReplacerFunction is not undefined, then + a. Set value to ? Call(ReplacerFunction, holder, « key, value »). +---*/ + +assert.sameValue( + JSON.stringify({ + toJSON: function() { + return 'toJSON'; + }, + }, function(_key, value) { + return value + '|replacer'; + }), + '"toJSON|replacer"' +); + +assert.sameValue( + JSON.stringify({ + toJSON: function() { + return {calls: 'toJSON'}; + }, + }, function(_key, value) { + if (value && value.calls) { + value.calls += '|replacer'; + } + + return value; + }), + '{"calls":"toJSON|replacer"}' +); diff --git a/test/built-ins/JSON/stringify/replacer-function-wrapper.js b/test/built-ins/JSON/stringify/replacer-function-wrapper.js new file mode 100644 index 0000000000..d96e6ad8e5 --- /dev/null +++ b/test/built-ins/JSON/stringify/replacer-function-wrapper.js @@ -0,0 +1,38 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-json.stringify +description: > + Wrapper is plain extensible object with single data property. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 9. Let wrapper be ObjectCreate(%ObjectPrototype%). + 10. Let status be CreateDataProperty(wrapper, the empty String, value). +includes: [propertyHelper.js] +---*/ + +Object.defineProperty(Object.prototype, '', { + set: function() { + throw new Test262Error('[[Set]] should not be called.'); + }, +}); + +var value = {}; +var wrapper; +JSON.stringify(value, function() { + wrapper = this; +}); + +assert.sameValue(typeof wrapper, 'object'); +assert.sameValue(Object.getPrototypeOf(wrapper), Object.prototype); +assert.sameValue(Object.getOwnPropertyNames(wrapper).length, 1); +assert(Object.isExtensible(wrapper)); + +verifyProperty(wrapper, '', { + value: value, + writable: true, + enumerable: true, + configurable: true, +}); diff --git a/test/built-ins/JSON/stringify/replacer-proxy.js b/test/built-ins/JSON/stringify/replacer-proxy.js deleted file mode 100644 index 2c4819b2ee..0000000000 --- a/test/built-ins/JSON/stringify/replacer-proxy.js +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (C) 2016 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-json.stringify -description: Proxy of an array is treated as an array -info: | - [...] - 12. Return ? SerializeJSONProperty(the empty String, wrapper). - - 24.3.2.1 Runtime Semantics: SerializeJSONProperty - - [...] - 10. If Type(value) is Object and IsCallable(value) is false, then - a. Let isArray be ? IsArray(value). - b. If isArray is true, return ? SerializeJSONArray(value). - c. Else, return ? SerializeJSONObject(value). - [...] - - 7.2.2 IsArray - - [...] - 3. If argument is a Proxy exotic object, then - a. If the value of the [[ProxyHandler]] internal slot of argument is null, - throw a TypeError exception. - b. Let target be the value of the [[ProxyTarget]] internal slot of - argument. - c. Return ? IsArray(target). -features: [Proxy] ----*/ - -var objectProxy = new Proxy({}, {}); -var arrayProxy = new Proxy([], {}); -var arrayProxyProxy = new Proxy(arrayProxy, {}); - -assert.sameValue(JSON.stringify(objectProxy), '{}'); -assert.sameValue(JSON.stringify(arrayProxy), '[]', 'proxy for an array'); -assert.sameValue( - JSON.stringify([[arrayProxy]]), '[[[]]]', 'proxy for an array (nested)' -); -assert.sameValue( - JSON.stringify([[arrayProxyProxy]]), - '[[[]]]', - 'proxy for a proxy for an array (nested)' -); diff --git a/test/built-ins/JSON/stringify/replacer-wrong-type.js b/test/built-ins/JSON/stringify/replacer-wrong-type.js new file mode 100644 index 0000000000..3903857e91 --- /dev/null +++ b/test/built-ins/JSON/stringify/replacer-wrong-type.js @@ -0,0 +1,32 @@ +// Copyright (C) 2012 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-json.stringify +description: > + Replacer paramter of wrong type is silently ignored. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 4. If Type(replacer) is Object, then + a. If IsCallable(replacer) is true, then + i. Set ReplacerFunction to replacer. + b. Else, + i. Let isArray be ? IsArray(replacer). + ii. If isArray is true, then + 1. Set PropertyList to a new empty List. +features: [Symbol] +---*/ + +var obj = {key: [1]}; +var json = '{"key":[1]}'; + +assert.sameValue(JSON.stringify(obj, {}), json); +assert.sameValue(JSON.stringify(obj, new String('str')), json); +assert.sameValue(JSON.stringify(obj, new Number(6.1)), json); + +assert.sameValue(JSON.stringify(obj, null), json); +assert.sameValue(JSON.stringify(obj, ''), json); +assert.sameValue(JSON.stringify(obj, 0), json); +assert.sameValue(JSON.stringify(obj, Symbol()), json); +assert.sameValue(JSON.stringify(obj, true), json); diff --git a/test/built-ins/JSON/stringify/space-number-float.js b/test/built-ins/JSON/stringify/space-number-float.js new file mode 100644 index 0000000000..d6e94a9b92 --- /dev/null +++ b/test/built-ins/JSON/stringify/space-number-float.js @@ -0,0 +1,39 @@ +// Copyright (C) 2012 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-json.stringify +description: > + Numeric space parameter is truncated to integer part. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 6. If Type(space) is Number, then + a. Set space to min(10, ! ToInteger(space)). +---*/ + +var obj = { + a1: { + b1: [1, 2, 3, 4], + b2: { + c1: 1, + c2: 2, + }, + }, + a2: 'a2', +}; + +assert.sameValue( + JSON.stringify(obj, null, -1.99999), + JSON.stringify(obj, null, -1) +); + +assert.sameValue( + JSON.stringify(obj, null, new Number(5.11111)), + JSON.stringify(obj, null, 5) +); + +assert.sameValue( + JSON.stringify(obj, null, 6.99999), + JSON.stringify(obj, null, 6) +); diff --git a/test/built-ins/JSON/stringify/space-number-object.js b/test/built-ins/JSON/stringify/space-number-object.js new file mode 100644 index 0000000000..754e0aa584 --- /dev/null +++ b/test/built-ins/JSON/stringify/space-number-object.js @@ -0,0 +1,47 @@ +// Copyright (C) 2012 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-json.stringify +description: > + Number objects are converted to primitives using ToNumber. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 5. If Type(space) is Object, then + a. If space has a [[NumberData]] internal slot, then + i. Set space to ? ToNumber(space). +---*/ + +var obj = { + a1: { + b1: [1, 2, 3, 4], + b2: { + c1: 1, + c2: 2, + }, + }, + a2: 'a2', +}; + +assert.sameValue( + JSON.stringify(obj, null, new Number(1)), + JSON.stringify(obj, null, 1) +); + +var num = new Number(1); +num.toString = function() { throw new Test262Error('should not be called'); }; +num.valueOf = function() { return 3; }; + +assert.sameValue( + JSON.stringify(obj, null, num), + JSON.stringify(obj, null, 3) +); + +var abrupt = new Number(4); +abrupt.toString = function() { throw new Test262Error(); }; +abrupt.valueOf = function() { throw new Test262Error(); }; + +assert.throws(Test262Error, function() { + JSON.stringify(obj, null, abrupt); +}); diff --git a/test/built-ins/JSON/stringify/space-number-range.js b/test/built-ins/JSON/stringify/space-number-range.js new file mode 100644 index 0000000000..b2dfd267dc --- /dev/null +++ b/test/built-ins/JSON/stringify/space-number-range.js @@ -0,0 +1,36 @@ +// Copyright (C) 2012 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-json.stringify +description: > + Numeric space parameter is clamped to 0..10 range. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 6. If Type(space) is Number, then + a. Set space to min(10, ! ToInteger(space)). + b. If space < 1, let gap be the empty String; otherwise let gap be the + String value containing space occurrences of the code unit 0x0020 (SPACE). +---*/ + +var obj = { + a1: { + b1: [1, 2, 3, 4], + b2: { + c1: 1, + c2: 2, + }, + }, + a2: 'a2', +}; + +assert.sameValue( + JSON.stringify(obj, null, new Number(-5)), + JSON.stringify(obj, null, 0) +); + +assert.sameValue( + JSON.stringify(obj, null, 10), + JSON.stringify(obj, null, 100) +); diff --git a/test/built-ins/JSON/stringify/space-number.js b/test/built-ins/JSON/stringify/space-number.js new file mode 100644 index 0000000000..b0834e8908 --- /dev/null +++ b/test/built-ins/JSON/stringify/space-number.js @@ -0,0 +1,37 @@ +// Copyright (C) 2012 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-json.stringify +description: > + Numeric space parameter (integer in range 0..10) is equivalent + to string of spaces of that length. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 6. If Type(space) is Number, then + [...] + b. If space < 1, let gap be the empty String; otherwise let gap be the + String value containing space occurrences of the code unit 0x0020 (SPACE). +---*/ + +var obj = { + a1: { + b1: [1, 2, 3, 4], + b2: { + c1: 1, + c2: 2, + }, + }, + a2: 'a2', +}; + +assert.sameValue( + JSON.stringify(obj, null, 0), + JSON.stringify(obj, null, '') +); + +assert.sameValue( + JSON.stringify(obj, null, 4), + JSON.stringify(obj, null, ' ') // 4 spaces +); diff --git a/test/built-ins/JSON/stringify/space-string-object.js b/test/built-ins/JSON/stringify/space-string-object.js new file mode 100644 index 0000000000..636c21ef3b --- /dev/null +++ b/test/built-ins/JSON/stringify/space-string-object.js @@ -0,0 +1,48 @@ +// Copyright (C) 2012 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-json.stringify +description: > + String exotic objects are converted to primitives using ToString. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 5. If Type(space) is Object, then + [...] + b. Else if space has a [[StringData]] internal slot, then + i. Set space to ? ToString(space). +---*/ + +var obj = { + a1: { + b1: [1, 2, 3, 4], + b2: { + c1: 1, + c2: 2, + }, + }, + a2: 'a2', +}; + +assert.sameValue( + JSON.stringify(obj, null, new String('xxx')), + JSON.stringify(obj, null, 'xxx') +); + +var str = new String('xxx'); +str.toString = function() { return '---'; }; +str.valueOf = function() { throw new Test262Error('should not be called'); }; + +assert.sameValue( + JSON.stringify(obj, null, str), + JSON.stringify(obj, null, '---') +); + +var abrupt = new String('xxx'); +abrupt.toString = function() { throw new Test262Error(); }; +abrupt.valueOf = function() { throw new Test262Error(); }; + +assert.throws(Test262Error, function() { + JSON.stringify(obj, null, abrupt); +}); diff --git a/test/built-ins/JSON/stringify/space-string-range.js b/test/built-ins/JSON/stringify/space-string-range.js new file mode 100644 index 0000000000..ea2f99cac9 --- /dev/null +++ b/test/built-ins/JSON/stringify/space-string-range.js @@ -0,0 +1,30 @@ +// Copyright (C) 2012 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-json.stringify +description: > + Only first 10 code units of string space parameter are used. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 7. Else if Type(space) is String, then + a. If the length of space is 10 or less, let gap be space; otherwise + let gap be the String value consisting of the first 10 code units of space. +---*/ + +var obj = { + a1: { + b1: [1, 2, 3, 4], + b2: { + c1: 1, + c2: 2, + }, + }, + a2: 'a2', +}; + +assert.sameValue( + JSON.stringify(obj, null, '0123456789xxxxxxxxx'), + JSON.stringify(obj, null, '0123456789') +); diff --git a/test/built-ins/JSON/stringify/space-string.js b/test/built-ins/JSON/stringify/space-string.js new file mode 100644 index 0000000000..fdd55bc81a --- /dev/null +++ b/test/built-ins/JSON/stringify/space-string.js @@ -0,0 +1,44 @@ +// Copyright (C) 2012 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-json.stringify +description: > + String space is used as gap. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 7. Else if Type(space) is String, then + a. If the length of space is 10 or less, let gap be space; otherwise + let gap be the String value consisting of the first 10 code units of space. +---*/ + +var obj = { + a1: { + b1: [1, 2, 3, 4], + b2: { + c1: 1, + c2: 2, + }, + }, + a2: 'a2', +}; + +assert.sameValue(JSON.stringify(obj, null, ''), JSON.stringify(obj)); +assert.sameValue(JSON.stringify(obj, null, ' '), [ + '{' +, ' "a1": {' +, ' "b1": [' +, ' 1,' +, ' 2,' +, ' 3,' +, ' 4' +, ' ],' +, ' "b2": {' +, ' "c1": 1,' +, ' "c2": 2' +, ' }' +, ' },' +, ' "a2": "a2"' +, '}' +].join('\n')); diff --git a/test/built-ins/JSON/stringify/space-wrong-type.js b/test/built-ins/JSON/stringify/space-wrong-type.js new file mode 100644 index 0000000000..d488d1e0fb --- /dev/null +++ b/test/built-ins/JSON/stringify/space-wrong-type.js @@ -0,0 +1,31 @@ +// Copyright (C) 2012 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-json.stringify +description: > + Space parameter of wrong type is silently ignored. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 8. Else, + a. Let gap be the empty String. +features: [Symbol] +---*/ + +var obj = { + a1: { + b1: [1, 2, 3, 4], + b2: { + c1: 1, + c2: 2, + }, + }, + a2: 'a2', +}; + +assert.sameValue(JSON.stringify(obj), JSON.stringify(obj, null, null)); +assert.sameValue(JSON.stringify(obj), JSON.stringify(obj, null, true)); +assert.sameValue(JSON.stringify(obj), JSON.stringify(obj, null, new Boolean(false))); +assert.sameValue(JSON.stringify(obj), JSON.stringify(obj, null, Symbol())); +assert.sameValue(JSON.stringify(obj), JSON.stringify(obj, null, {})); diff --git a/test/built-ins/JSON/stringify/value-array-abrupt.js b/test/built-ins/JSON/stringify/value-array-abrupt.js new file mode 100644 index 0000000000..f84db212b1 --- /dev/null +++ b/test/built-ins/JSON/stringify/value-array-abrupt.js @@ -0,0 +1,66 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonarray +description: > + Abrupt completion from Get. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + [...] + 10. If Type(value) is Object and IsCallable(value) is false, then + a. Let isArray be ? IsArray(value). + b. If isArray is true, return ? SerializeJSONArray(value). + + SerializeJSONArray ( value ) + + [...] + 6. Let len be ? LengthOfArrayLike(value). +features: [Proxy] +---*/ + +var abruptLength = new Proxy([], { + get: function(_target, key) { + if (key === 'length') { + throw new Test262Error(); + } + }, +}); + +assert.throws(Test262Error, function() { + JSON.stringify(abruptLength); +}); + +var abruptToPrimitive = { + valueOf: function() { + throw new Test262Error(); + }, +}; + +var abruptToLength = new Proxy([], { + get: function(_target, key) { + if (key === 'length') { + return abruptToPrimitive; + } + }, +}); + +assert.throws(Test262Error, function() { + JSON.stringify([abruptToLength]); +}); + +var abruptIndex = new Array(1); +Object.defineProperty(abruptIndex, '0', { + get: function() { + throw new Test262Error(); + }, +}); + +assert.throws(Test262Error, function() { + JSON.stringify({key: abruptIndex}); +}); diff --git a/test/built-ins/JSON/stringify/value-array-circular.js b/test/built-ins/JSON/stringify/value-array-circular.js new file mode 100644 index 0000000000..8c154dc604 --- /dev/null +++ b/test/built-ins/JSON/stringify/value-array-circular.js @@ -0,0 +1,37 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonarray +description: > + Circular array value throws a TypeError. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + [...] + 10. If Type(value) is Object and IsCallable(value) is false, then + a. Let isArray be ? IsArray(value). + b. If isArray is true, return ? SerializeJSONArray(value). + + SerializeJSONArray ( value ) + + 1. If stack contains value, throw a TypeError exception because the structure is cyclical. +---*/ + +var direct = []; +direct.push(direct); + +assert.throws(TypeError, function() { + JSON.stringify(direct); +}); + +var indirect = []; +indirect.push([[indirect]]); + +assert.throws(TypeError, function() { + JSON.stringify(indirect); +}); diff --git a/test/built-ins/JSON/stringify/value-proxy-revoked.js b/test/built-ins/JSON/stringify/value-array-proxy-revoked.js similarity index 55% rename from test/built-ins/JSON/stringify/value-proxy-revoked.js rename to test/built-ins/JSON/stringify/value-array-proxy-revoked.js index 1c7c126573..140aea8700 100644 --- a/test/built-ins/JSON/stringify/value-proxy-revoked.js +++ b/test/built-ins/JSON/stringify/value-array-proxy-revoked.js @@ -2,29 +2,25 @@ // This code is governed by the BSD license found in the LICENSE file. /*--- esid: sec-json.stringify -description: Revoked proxy value produces a TypeError +description: > + Revoked array proxy value produces a TypeError. info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + [...] 12. Return ? SerializeJSONProperty(the empty String, wrapper). - 24.3.2.1 Runtime Semantics: SerializeJSONProperty + SerializeJSONProperty ( key, holder ) [...] 10. If Type(value) is Object and IsCallable(value) is false, then - a. Let isArray be ? IsArray(value). - b. If isArray is true, return ? SerializeJSONArray(value). - c. Else, return ? SerializeJSONObject(value). - [...] + a. Let isArray be ? IsArray(value). - 7.2.2 IsArray + IsArray ( argument ) [...] 3. If argument is a Proxy exotic object, then - a. If the value of the [[ProxyHandler]] internal slot of argument is null, - throw a TypeError exception. - b. Let target be the value of the [[ProxyTarget]] internal slot of - argument. - c. Return ? IsArray(target). + a. If argument.[[ProxyHandler]] is null, throw a TypeError exception. features: [Proxy] ---*/ diff --git a/test/built-ins/JSON/stringify/value-array-proxy.js b/test/built-ins/JSON/stringify/value-array-proxy.js new file mode 100644 index 0000000000..7270d267fd --- /dev/null +++ b/test/built-ins/JSON/stringify/value-array-proxy.js @@ -0,0 +1,49 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonarray +description: > + Proxy of an array is treated as an array. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + [...] + 10. If Type(value) is Object and IsCallable(value) is false, then + a. Let isArray be ? IsArray(value). + b. If isArray is true, return ? SerializeJSONArray(value). + + SerializeJSONArray ( value ) + + [...] + 6. Let len be ? LengthOfArrayLike(value). + 7. Let index be 0. + 8. Repeat, while index < len + a. Let strP be ? SerializeJSONProperty(! ToString(index), value). +features: [Proxy] +---*/ + +var arrayProxy = new Proxy([], { + get: function(_target, key) { + if (key === 'length') return 2; + return Number(key); + }, +}); + +assert.sameValue( + JSON.stringify(arrayProxy), '[0,1]', 'proxy for an array' +); +assert.sameValue( + JSON.stringify([[arrayProxy]]), '[[[0,1]]]', 'proxy for an array (nested)' +); + +var arrayProxyProxy = new Proxy(arrayProxy, {}); +assert.sameValue( + JSON.stringify([[arrayProxyProxy]]), + '[[[0,1]]]', + 'proxy for a proxy for an array (nested)' +); diff --git a/test/built-ins/JSON/stringify/bigint-cross-realm.js b/test/built-ins/JSON/stringify/value-bigint-cross-realm.js similarity index 100% rename from test/built-ins/JSON/stringify/bigint-cross-realm.js rename to test/built-ins/JSON/stringify/value-bigint-cross-realm.js diff --git a/test/built-ins/JSON/stringify/bigint-order.js b/test/built-ins/JSON/stringify/value-bigint-order.js similarity index 100% rename from test/built-ins/JSON/stringify/bigint-order.js rename to test/built-ins/JSON/stringify/value-bigint-order.js diff --git a/test/built-ins/JSON/stringify/bigint-replacer.js b/test/built-ins/JSON/stringify/value-bigint-replacer.js similarity index 100% rename from test/built-ins/JSON/stringify/bigint-replacer.js rename to test/built-ins/JSON/stringify/value-bigint-replacer.js diff --git a/test/built-ins/JSON/stringify/bigint-tojson-receiver.js b/test/built-ins/JSON/stringify/value-bigint-tojson-receiver.js similarity index 100% rename from test/built-ins/JSON/stringify/bigint-tojson-receiver.js rename to test/built-ins/JSON/stringify/value-bigint-tojson-receiver.js diff --git a/test/built-ins/JSON/stringify/bigint-tojson.js b/test/built-ins/JSON/stringify/value-bigint-tojson.js similarity index 100% rename from test/built-ins/JSON/stringify/bigint-tojson.js rename to test/built-ins/JSON/stringify/value-bigint-tojson.js diff --git a/test/built-ins/JSON/stringify/bigint.js b/test/built-ins/JSON/stringify/value-bigint.js similarity index 100% rename from test/built-ins/JSON/stringify/bigint.js rename to test/built-ins/JSON/stringify/value-bigint.js diff --git a/test/built-ins/JSON/stringify/value-boolean-object.js b/test/built-ins/JSON/stringify/value-boolean-object.js new file mode 100644 index 0000000000..6a10b0c10f --- /dev/null +++ b/test/built-ins/JSON/stringify/value-boolean-object.js @@ -0,0 +1,38 @@ +// Copyright (C) 2012 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonproperty +description: > + Boolean objects are converted to primitives using [[BooleanData]]. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + [...] + 4. If Type(value) is Object, then + [...] + c. Else if value has a [[BooleanData]] internal slot, then + i. Set value to value.[[BooleanData]]. + [...] + 6. If value is true, return "true". + 7. If value is false, return "false". +---*/ + +assert.sameValue(JSON.stringify(new Boolean(true)), 'true'); + +assert.sameValue( + JSON.stringify({ + toJSON: function() { + return {key: new Boolean(false)}; + }, + }), + '{"key":false}' +); + +assert.sameValue(JSON.stringify([1], function(_k, v) { + return v === 1 ? new Boolean(true) : v; +}), '[true]'); diff --git a/test/built-ins/JSON/stringify/value-function.js b/test/built-ins/JSON/stringify/value-function.js new file mode 100644 index 0000000000..aeb76df2ac --- /dev/null +++ b/test/built-ins/JSON/stringify/value-function.js @@ -0,0 +1,23 @@ +// Copyright (C) 2012 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonproperty +description: > + Function values are ignored. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + [...] + 10. If Type(value) is Object and IsCallable(value) is false, then + [...] + 11. Return undefined. +---*/ + +assert.sameValue(JSON.stringify(function() {}), undefined); +assert.sameValue(JSON.stringify([function() {}]), '[null]'); +assert.sameValue(JSON.stringify({key: function() {}}), '{}'); diff --git a/test/built-ins/JSON/stringify/value-number-negative-zero.js b/test/built-ins/JSON/stringify/value-number-negative-zero.js new file mode 100644 index 0000000000..5cae54eb36 --- /dev/null +++ b/test/built-ins/JSON/stringify/value-number-negative-zero.js @@ -0,0 +1,27 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonproperty +description: > + Negative zero numbers are stringified to "0". +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + [...] + 9. If Type(value) is Number, then + a. If value is finite, return ! ToString(value). + + NumberToString ( m ) + + [...] + 2. If m is +0 or -0, return the String "0". +---*/ + +assert.sameValue(JSON.stringify(-0), '0'); +assert.sameValue(JSON.stringify(['-0', 0, -0]), '["-0",0,0]'); +assert.sameValue(JSON.stringify({key: -0}), '{"key":0}'); diff --git a/test/built-ins/JSON/stringify/value-number-non-finite.js b/test/built-ins/JSON/stringify/value-number-non-finite.js new file mode 100644 index 0000000000..e8f03f7373 --- /dev/null +++ b/test/built-ins/JSON/stringify/value-number-non-finite.js @@ -0,0 +1,27 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonproperty +description: > + Non-finite numbers as serialized as null. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + [...] + 4. If Type(value) is Object, then + a. If value has a [[NumberData]] internal slot, then + i. Set value to ? ToNumber(value). + [...] + 9. If Type(value) is Number, then + a. If value is finite, return ! ToString(value). + b. Return "null". +---*/ + +assert.sameValue(JSON.stringify(Infinity), 'null'); +assert.sameValue(JSON.stringify({key: -Infinity}), '{"key":null}'); +assert.sameValue(JSON.stringify([NaN]), '[null]'); diff --git a/test/built-ins/JSON/stringify/value-number-object.js b/test/built-ins/JSON/stringify/value-number-object.js new file mode 100644 index 0000000000..84fa4da8d5 --- /dev/null +++ b/test/built-ins/JSON/stringify/value-number-object.js @@ -0,0 +1,52 @@ +// Copyright (C) 2012 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonproperty +description: > + Number objects are converted to primitives using ToNumber. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + [...] + 4. If Type(value) is Object, then + a. If value has a [[NumberData]] internal slot, then + i. Set value to ? ToNumber(value). + [...] + 9. If Type(value) is Number, then + a. If value is finite, return ! ToString(value). +---*/ + +assert.sameValue(JSON.stringify(new Number(8.5)), '8.5'); + +var toPrimitiveReplacer = function(_key, value) { + if (value === 'str') { + var num = new Number(42); + num.toString = function() { throw new Test262Error('should not be called'); }; + num.valueOf = function() { return 2; }; + return num; + } + + return value; +}; + +assert.sameValue(JSON.stringify(['str'], toPrimitiveReplacer), '[2]'); + +var abruptToJSON = function() { + var num = new Number(3.14); + num.toString = function() { throw new Test262Error(); }; + num.valueOf = function() { throw new Test262Error(); }; + return num; +}; + +assert.throws(Test262Error, function() { + JSON.stringify({ + key: { + toJSON: abruptToJSON, + }, + }); +}); diff --git a/test/built-ins/JSON/stringify/value-object-abrupt.js b/test/built-ins/JSON/stringify/value-object-abrupt.js new file mode 100644 index 0000000000..55fd0a61ff --- /dev/null +++ b/test/built-ins/JSON/stringify/value-object-abrupt.js @@ -0,0 +1,24 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonproperty +description: > + Abrupt completion from Get. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + 1. Let value be ? Get(holder, key). +---*/ + +assert.throws(Test262Error, function() { + JSON.stringify({ + get key() { + throw new Test262Error(); + }, + }); +}); diff --git a/test/built-ins/JSON/stringify/value-object-circular.js b/test/built-ins/JSON/stringify/value-object-circular.js new file mode 100644 index 0000000000..d65c585525 --- /dev/null +++ b/test/built-ins/JSON/stringify/value-object-circular.js @@ -0,0 +1,44 @@ +// Copyright (C) 2012 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonobject +description: > + Circular object value throws a TypeError. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + [...] + 10. If Type(value) is Object and IsCallable(value) is false, then + [...] + c. Return ? SerializeJSONObject(value). + + SerializeJSONObject ( value ) + + 1. If stack contains value, throw a TypeError exception because the structure is cyclical. +---*/ + +var direct = {}; +direct.prop = direct; + +assert.throws(TypeError, function() { + JSON.stringify(direct); +}); + +var indirect = { + p1: { + p2: { + get p3() { + return indirect; + }, + }, + }, +}; + +assert.throws(TypeError, function() { + JSON.stringify(indirect); +}); diff --git a/test/built-ins/JSON/stringify/value-object-proxy-revoked.js b/test/built-ins/JSON/stringify/value-object-proxy-revoked.js new file mode 100644 index 0000000000..92a1259d4b --- /dev/null +++ b/test/built-ins/JSON/stringify/value-object-proxy-revoked.js @@ -0,0 +1,38 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonobject +description: > + Revoked object proxy value produces a TypeError. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + [...] + 10. If Type(value) is Object and IsCallable(value) is false, then + [...] + c. Return ? SerializeJSONObject(value). + + SerializeJSONObject ( value ) + + [...] + 6. Else, + a. Let K be ? EnumerableOwnPropertyNames(value, "key"). +features: [Proxy] +---*/ + +var handle = Proxy.revocable({}, {}); + +handle.revoke(); + +assert.throws(TypeError, function() { + JSON.stringify(handle.proxy); +}, 'top-level value'); + +assert.throws(TypeError, function() { + JSON.stringify({a: {b: handle.proxy}}); +}, 'nested value'); diff --git a/test/built-ins/JSON/stringify/value-object-proxy.js b/test/built-ins/JSON/stringify/value-object-proxy.js new file mode 100644 index 0000000000..a228644530 --- /dev/null +++ b/test/built-ins/JSON/stringify/value-object-proxy.js @@ -0,0 +1,57 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonobject +description: > + Proxy of an object is treated as regular object. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + [...] + 10. If Type(value) is Object and IsCallable(value) is false, then + [...] + c. Return ? SerializeJSONObject(value). + + SerializeJSONObject ( value ) + + [...] + 6. Else, + a. Let K be ? EnumerableOwnPropertyNames(value, "key"). + 7. Let partial be a new empty List. + 8. For each element P of K, do + a. Let strP be ? SerializeJSONProperty(P, value). +features: [Proxy] +---*/ + +var objectProxy = new Proxy({}, { + getOwnPropertyDescriptor: function() { + return {value: 1, writable: true, enumerable: true, configurable: true}; + }, + get: function() { + return 1; + }, + ownKeys: function() { + return ['a', 'b']; + }, +}); + +assert.sameValue( + JSON.stringify(objectProxy), '{"a":1,"b":1}', 'proxy for an object' +); +assert.sameValue( + JSON.stringify({l1: {l2: objectProxy}}), + '{"l1":{"l2":{"a":1,"b":1}}}', + 'proxy for an object (nested)' +); + +var objectProxyProxy = new Proxy(objectProxy, {}); +assert.sameValue( + JSON.stringify({l1: {l2: objectProxyProxy}}), + '{"l1":{"l2":{"a":1,"b":1}}}', + 'proxy for a proxy for an object (nested)' +); diff --git a/test/built-ins/JSON/stringify/value-primitive-top-level.js b/test/built-ins/JSON/stringify/value-primitive-top-level.js new file mode 100644 index 0000000000..a313e54e3c --- /dev/null +++ b/test/built-ins/JSON/stringify/value-primitive-top-level.js @@ -0,0 +1,31 @@ +// Copyright (C) 2012 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonproperty +description: > + Top-level primitive values are stringified correctly. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + [...] + 5. If value is null, return "null". + 6. If value is true, return "true". + 7. If value is false, return "false". + 8. If Type(value) is String, return QuoteJSONString(value). + 9. If Type(value) is Number, then + a. If value is finite, return ! ToString(value). + [...] + 11. Return undefined. +---*/ + +assert.sameValue(JSON.stringify(null), 'null'); +assert.sameValue(JSON.stringify(true), 'true'); +assert.sameValue(JSON.stringify(false), 'false'); +assert.sameValue(JSON.stringify('str'), '"str"'); +assert.sameValue(JSON.stringify(123), '123'); +assert.sameValue(JSON.stringify(undefined), undefined); diff --git a/test/built-ins/JSON/stringify/value-proxy.js b/test/built-ins/JSON/stringify/value-proxy.js deleted file mode 100644 index 3365fefc58..0000000000 --- a/test/built-ins/JSON/stringify/value-proxy.js +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (C) 2016 the V8 project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-object.prototype.tostring -description: Proxy of an array is treated as an array -info: | - [...] - 3. Let O be ToObject(this value). - 4. Let isArray be ? IsArray(O). - 5. If isArray is true, let builtinTag be "Array". - [...] - - 7.2.2 IsArray - - [...] - 3. If argument is a Proxy exotic object, then - a. If the value of the [[ProxyHandler]] internal slot of argument is null, - throw a TypeError exception. - b. Let target be the value of the [[ProxyTarget]] internal slot of - argument. - c. Return ? IsArray(target). -features: [Proxy] ----*/ - -var objectProxy = new Proxy({}, {}); -var arrayProxy = new Proxy([], {}); -var arrayProxyProxy = new Proxy(arrayProxy, {}); - -assert.sameValue( - Object.prototype.toString.call(objectProxy), '[object Object]' -); -assert.sameValue( - Object.prototype.toString.call(arrayProxy), '[object Array]', 'array proxy' -); -assert.sameValue( - Object.prototype.toString.call(arrayProxyProxy), - '[object Array]', - 'proxy for array proxy' -); diff --git a/test/built-ins/JSON/stringify/string-escape-ascii.js b/test/built-ins/JSON/stringify/value-string-escape-ascii.js similarity index 100% rename from test/built-ins/JSON/stringify/string-escape-ascii.js rename to test/built-ins/JSON/stringify/value-string-escape-ascii.js diff --git a/test/built-ins/JSON/stringify/string-escape-unicode.js b/test/built-ins/JSON/stringify/value-string-escape-unicode.js similarity index 100% rename from test/built-ins/JSON/stringify/string-escape-unicode.js rename to test/built-ins/JSON/stringify/value-string-escape-unicode.js diff --git a/test/built-ins/JSON/stringify/value-string-object.js b/test/built-ins/JSON/stringify/value-string-object.js new file mode 100644 index 0000000000..0d008610af --- /dev/null +++ b/test/built-ins/JSON/stringify/value-string-object.js @@ -0,0 +1,55 @@ +// Copyright (C) 2012 Ecma International. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonproperty +description: > + String exotic objects are converted to primitives using ToString. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + [...] + 4. If Type(value) is Object, then + [...] + b. Else if value has a [[StringData]] internal slot, then + i. Set value to ? ToString(value). + [...] + 8. If Type(value) is String, return QuoteJSONString(value). +---*/ + +assert.sameValue(JSON.stringify(new String('str')), '"str"'); + +var toJSON = function() { + var str = new String('str'); + str.toString = function() { return 'toString'; }; + str.valueOf = function() { throw new Test262Error('should not be called'); }; + return str; +}; + +assert.sameValue( + JSON.stringify({ + key: { + toJSON: toJSON, + }, + }), + '{"key":"toString"}' +); + +var abruptReplacer = function(_key, value) { + if (value === true) { + var str = new String('str'); + str.toString = function() { throw new Test262Error(); }; + str.valueOf = function() { throw new Test262Error(); }; + return str; + } + + return value; +}; + +assert.throws(Test262Error, function() { + JSON.stringify([true], abruptReplacer); +}); diff --git a/test/built-ins/JSON/stringify/value-symbol.js b/test/built-ins/JSON/stringify/value-symbol.js new file mode 100644 index 0000000000..6bba27aecb --- /dev/null +++ b/test/built-ins/JSON/stringify/value-symbol.js @@ -0,0 +1,27 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonproperty +description: > + Symbol primitives are ignored, both as keys and as values. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + [...] + 11. Return undefined. +features: [Symbol] +---*/ + +var sym = Symbol('desc'); +assert.sameValue(JSON.stringify(sym), undefined); +assert.sameValue(JSON.stringify([sym]), '[null]'); +assert.sameValue(JSON.stringify({key: sym}), '{}'); + +var obj = {}; +obj[sym] = 1; +assert.sameValue(JSON.stringify(obj), '{}'); diff --git a/test/built-ins/JSON/stringify/value-tojson-abrupt.js b/test/built-ins/JSON/stringify/value-tojson-abrupt.js new file mode 100644 index 0000000000..dec8810f7c --- /dev/null +++ b/test/built-ins/JSON/stringify/value-tojson-abrupt.js @@ -0,0 +1,36 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonproperty +description: > + Abrupt completions from Get and Call. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + [...] + 2. If Type(value) is Object, then + a. Let toJSON be ? Get(value, "toJSON"). + b. If IsCallable(toJSON) is true, then + i. Set value to ? Call(toJSON, value, « key »). +---*/ + +assert.throws(Test262Error, function() { + JSON.stringify({ + get toJSON() { + throw new Test262Error(); + }, + }); +}); + +assert.throws(Test262Error, function() { + JSON.stringify({ + toJSON() { + throw new Test262Error(); + }, + }); +}); diff --git a/test/built-ins/JSON/stringify/value-tojson-arguments.js b/test/built-ins/JSON/stringify/value-tojson-arguments.js new file mode 100644 index 0000000000..bed1c13267 --- /dev/null +++ b/test/built-ins/JSON/stringify/value-tojson-arguments.js @@ -0,0 +1,45 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonproperty +description: > + toJSON is called with correct context and arguments. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + [...] + 2. If Type(value) is Object, then + a. Let toJSON be ? Get(value, "toJSON"). + b. If IsCallable(toJSON) is true, then + i. Set value to ? Call(toJSON, value, « key »). +---*/ + +var callCount = 0; +var _this, _key; +var obj = { + toJSON: function(key) { + callCount += 1; + _this = this; + _key = key; + }, +}; + +assert.sameValue(JSON.stringify(obj), undefined); +assert.sameValue(callCount, 1); +assert.sameValue(_this, obj); +assert.sameValue(_key, ''); + +assert.sameValue(JSON.stringify([1, obj, 3]), '[1,null,3]'); +assert.sameValue(callCount, 2); +assert.sameValue(_this, obj); +assert.sameValue(_key, '1'); + +assert.sameValue(JSON.stringify({key: obj}), '{}'); +assert.sameValue(callCount, 3); +assert.sameValue(_this, obj); +assert.sameValue(_key, 'key'); diff --git a/test/built-ins/JSON/stringify/value-tojson-array-circular.js b/test/built-ins/JSON/stringify/value-tojson-array-circular.js new file mode 100644 index 0000000000..54b052736d --- /dev/null +++ b/test/built-ins/JSON/stringify/value-tojson-array-circular.js @@ -0,0 +1,47 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonarray +description: > + Circular array value (returned from toJSON method) throws a TypeError. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + [...] + 2. If Type(value) is Object, then + a. Let toJSON be ? Get(value, "toJSON"). + b. If IsCallable(toJSON) is true, then + i. Set value to ? Call(toJSON, value, « key »). + [...] + 10. If Type(value) is Object and IsCallable(value) is false, then + a. Let isArray be ? IsArray(value). + b. If isArray is true, return ? SerializeJSONArray(value). + + SerializeJSONArray ( value ) + + 1. If stack contains value, throw a TypeError exception because the structure is cyclical. +---*/ + +var direct = []; +direct.toJSON = function() { + return [direct]; +}; + +assert.throws(TypeError, function() { + JSON.stringify(direct); +}); + +var arr = []; +arr.toJSON = function() { + return [indirect]; +}; +var indirect = [[arr]]; + +assert.throws(TypeError, function() { + JSON.stringify(indirect); +}); diff --git a/test/built-ins/JSON/stringify/value-tojson-not-function.js b/test/built-ins/JSON/stringify/value-tojson-not-function.js new file mode 100644 index 0000000000..9a25009186 --- /dev/null +++ b/test/built-ins/JSON/stringify/value-tojson-not-function.js @@ -0,0 +1,25 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonproperty +description: > + toJSON value is not callable. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + [...] + 2. If Type(value) is Object, then + a. Let toJSON be ? Get(value, "toJSON"). + b. If IsCallable(toJSON) is true, then + i. Set value to ? Call(toJSON, value, « key »). +---*/ + +assert.sameValue(JSON.stringify({toJSON: null}), '{"toJSON":null}'); +assert.sameValue(JSON.stringify({toJSON: false}), '{"toJSON":false}'); +assert.sameValue(JSON.stringify({toJSON: []}), '{"toJSON":[]}'); +assert.sameValue(JSON.stringify({toJSON: /re/}), '{"toJSON":{}}'); diff --git a/test/built-ins/JSON/stringify/value-tojson-object-circular.js b/test/built-ins/JSON/stringify/value-tojson-object-circular.js new file mode 100644 index 0000000000..2d20b92fd3 --- /dev/null +++ b/test/built-ins/JSON/stringify/value-tojson-object-circular.js @@ -0,0 +1,52 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonobject +description: > + Circular object value (returned from toJSON method) throws a TypeError. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + [...] + 2. If Type(value) is Object, then + a. Let toJSON be ? Get(value, "toJSON"). + b. If IsCallable(toJSON) is true, then + i. Set value to ? Call(toJSON, value, « key »). + [...] + 10. If Type(value) is Object and IsCallable(value) is false, then + [...] + c. Return ? SerializeJSONObject(value). + + SerializeJSONObject ( value ) + + 1. If stack contains value, throw a TypeError exception because the structure is cyclical. +---*/ + +var direct = { + toJSON: function() { + return {prop: direct}; + }, +}; + +assert.throws(TypeError, function() { + JSON.stringify(direct); +}); + +var indirect = { + p1: { + p2: { + toJSON: function() { + return {p3: indirect}; + }, + }, + }, +}; + +assert.throws(TypeError, function() { + JSON.stringify(indirect); +}); diff --git a/test/built-ins/JSON/stringify/value-tojson-result.js b/test/built-ins/JSON/stringify/value-tojson-result.js new file mode 100644 index 0000000000..33409452b4 --- /dev/null +++ b/test/built-ins/JSON/stringify/value-tojson-result.js @@ -0,0 +1,39 @@ +// Copyright (C) 2019 Aleksey Shvayka. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-serializejsonproperty +description: > + Result of toJSON method is stringified. +info: | + JSON.stringify ( value [ , replacer [ , space ] ] ) + + [...] + 12. Return ? SerializeJSONProperty(the empty String, wrapper). + + SerializeJSONProperty ( key, holder ) + + [...] + 2. If Type(value) is Object, then + a. Let toJSON be ? Get(value, "toJSON"). + b. If IsCallable(toJSON) is true, then + i. Set value to ? Call(toJSON, value, « key »). +---*/ + +assert.sameValue( + JSON.stringify({ + toJSON: function() { return [false]; }, + }), + '[false]' +); + +var arr = [true]; +arr.toJSON = function() {}; +assert.sameValue(JSON.stringify(arr), undefined); + +var str = new String('str'); +str.toJSON = function() { return null; }; +assert.sameValue(JSON.stringify({key: str}), '{"key":null}'); + +var num = new Number(14); +num.toJSON = function() { return {key: 7}; }; +assert.sameValue(JSON.stringify([num]), '[{"key":7}]');