diff --git a/harness/builtin.js b/harness/builtin.js new file mode 100644 index 00000000000..8edbafd23a5 --- /dev/null +++ b/harness/builtin.js @@ -0,0 +1,158 @@ +// Copyright (C) 2025 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: | + Functions to test built-in function and constructor objects. +defines: + - verifyBuiltinFunction + - verifyBuiltinConstructor +---*/ + +// Capture primordial functions that are used in verification but might be +// destroyed *by* that process itself. +var __Function = Function; +var __Proxy = Proxy; +var __Reflect_construct = Reflect.construct; +var __Reflect_getPrototypeOf = Reflect.getPrototypeOf; +var __Reflect_isExtensible = Reflect.isExtensible; +var __Reflect_ownKeys = Reflect.ownKeys; + +/** + * Verify `fun` is a normal built-in function object with the default + * properties as defined in + * . + */ +function verifyBuiltinFunction(fun, name, length) { + // Unless specified otherwise, a built-in object that is callable as a + // function is a built-in function object with the characteristics described + // in 10.3. + assert.sameValue(typeof fun, "function"); + + // Unless otherwise specified every built-in function and every built-in + // constructor has the Function prototype object, which is the initial value + // of the expression Function.prototype (20.2.3), as the value of its + // [[Prototype]] internal slot. + assert.sameValue(__Reflect_getPrototypeOf(fun), __Function.prototype); + + // Unless specified otherwise, the [[Extensible]] internal slot of a built-in + // object initially has the value true. + assert.sameValue(__Reflect_isExtensible(fun), true); + + // Built-in function objects that are not constructors do not have a + // "prototype" property unless otherwise specified in the description of a + // particular function. + // + // NOTE: |verifyBuiltinFunction| is more strict and allows only exactly two + // own properties: "name" and "length". + assert.sameValue(__Reflect_ownKeys(fun).length, 2); + + // Unless otherwise specified, the "name" property of a built-in function + // object has the attributes { [[Writable]]: false, [[Enumerable]]: false, + // [[Configurable]]: true }. + verifyPrimordialProperty(fun, "name", { + value: name, + writable: false, + enumerable: false, + configurable: true, + }); + + // Unless otherwise specified, the "length" property of a built-in function + // object has the attributes { [[Writable]]: false, [[Enumerable]]: false, + // [[Configurable]]: true }. + verifyPrimordialProperty(fun, "length", { + value: length, + writable: false, + enumerable: false, + configurable: true, + }); + + // Built-in function objects that are not identified as constructors do not + // implement the [[Construct]] internal method unless otherwise specified in + // the description of a particular function. + assert.throws(TypeError, function() { + // Reflect.construct throws a TypeError if `fun` is not a constructor. Use + // the Proxy constructor because it ignores `NewTarget`. + // + // Two alternatives which also ensure no additional operations are called: + // + // 1. Create a Proxy for `fun` with a "construct" trap. Then call `new` on + // the newly created Proxy object. + // ``` + // var p = new Proxy(fun, {construct(){ return {}; }}); + // assert.throws(TypeError, function() { new p; }); + // ``` + // + // 2. Use a derived class object. + // ``` + // class C extends null { constructor() { return {}; } }; + // assert.throws(TypeError, function() { + // __Reflect_construct(C, [], fun); + // }); + // ``` + __Reflect_construct(__Proxy, [{}, {}], fun); + }); + assert.throws(TypeError, function() { + // Test with `new` expression in addition to Reflect.construct. + new fun(); + }); +} + +/** + * Verify `fun` is a normal built-in constructor function object with the + * default properties as defined in + * . + */ +function verifyBuiltinConstructor(fun, name, length, prototype) { + // Unless specified otherwise, a built-in object that is callable as a + // function is a built-in function object with the characteristics described + // in 10.3. + assert.sameValue(typeof fun, "function"); + + // Unless otherwise specified every built-in function and every built-in + // constructor has the Function prototype object, which is the initial value + // of the expression Function.prototype (20.2.3), as the value of its + // [[Prototype]] internal slot. + if (prototype === undefined) { + prototype = __Function.prototype; + } + assert.sameValue(__Reflect_getPrototypeOf(fun), prototype); + + // Unless specified otherwise, the [[Extensible]] internal slot of a built-in + // object initially has the value true. + assert.sameValue(__Reflect_isExtensible(fun), true); + + // Unless otherwise specified, the "name" property of a built-in function + // object has the attributes { [[Writable]]: false, [[Enumerable]]: false, + // [[Configurable]]: true }. + verifyPrimordialProperty(fun, "name", { + value: name, + writable: false, + enumerable: false, + configurable: true, + }); + + // Unless otherwise specified, the "length" property of a built-in function + // object has the attributes { [[Writable]]: false, [[Enumerable]]: false, + // [[Configurable]]: true }. + verifyPrimordialProperty(fun, "length", { + value: length, + writable: false, + enumerable: false, + configurable: true, + }); + + // Built-in function objects that are not identified as constructors do not + // implement the [[Construct]] internal method unless otherwise specified in + // the description of a particular function. + + // Reflect.construct throws a TypeError if `fun` is not a constructor. + // + // See verifyBuiltinFunction for why Proxy is used here. + assert.throws(Test262Error, function() { + __Reflect_construct(__Proxy, [{}, {}], fun); + + // Throw the expected error. + throw new Test262Error(); + }); +} diff --git a/harness/features.yml b/harness/features.yml index 333af083bed..a12ab716b8c 100644 --- a/harness/features.yml +++ b/harness/features.yml @@ -1,4 +1,5 @@ atomicsHelper: [Atomics] +builtin.js: [Proxy, Reflect, Reflect.construct] typeCoercion.js: [Symbol.toPrimitive, BigInt] testAtomics.js: [ArrayBuffer, Atomics, DataView, SharedArrayBuffer, Symbol, TypedArray] testBigIntTypedArray.js: [BigInt, TypedArray] diff --git a/harness/propertyHelper.js b/harness/propertyHelper.js index 51cc80c8808..038b809b3f2 100644 --- a/harness/propertyHelper.js +++ b/harness/propertyHelper.js @@ -101,7 +101,7 @@ function verifyProperty(obj, name, desc, options) { } } - if (__hasOwnProperty(desc, 'enumerable') && desc.enumerable !== undefined) { + if (__hasOwnProperty(desc, 'enumerable')) { if (desc.enumerable !== originalDesc.enumerable || desc.enumerable !== isEnumerable(obj, name)) { __push(failures, "obj['" + nameStr + "'] descriptor should " + (desc.enumerable ? '' : 'not ') + "be enumerable"); @@ -110,14 +110,14 @@ function verifyProperty(obj, name, desc, options) { // Operations past this point are potentially destructive! - if (__hasOwnProperty(desc, 'writable') && desc.writable !== undefined) { + if (__hasOwnProperty(desc, 'writable')) { if (desc.writable !== originalDesc.writable || desc.writable !== isWritable(obj, name)) { __push(failures, "obj['" + nameStr + "'] descriptor should " + (desc.writable ? '' : 'not ') + "be writable"); } } - if (__hasOwnProperty(desc, 'configurable') && desc.configurable !== undefined) { + if (__hasOwnProperty(desc, 'configurable')) { if (desc.configurable !== originalDesc.configurable || desc.configurable !== isConfigurable(obj, name)) { __push(failures, "obj['" + nameStr + "'] descriptor should " + (desc.configurable ? '' : 'not ') + "be configurable"); diff --git a/test/built-ins/Number/15.7.3-1.js b/test/built-ins/Number/15.7.3-1.js deleted file mode 100644 index 9f302fe5d95..00000000000 --- a/test/built-ins/Number/15.7.3-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.7.3-1 -description: Number constructor - [[Prototype]] is the Function prototype object ----*/ - -assert.sameValue(Function.prototype.isPrototypeOf(Number), true, 'Function.prototype.isPrototypeOf(Number)'); diff --git a/test/built-ins/Number/15.7.3-2.js b/test/built-ins/Number/15.7.3-2.js deleted file mode 100644 index e867affdb88..00000000000 --- a/test/built-ins/Number/15.7.3-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.7.3-2 -description: > - Number constructor - [[Prototype]] is the Function prototype - object (using getPrototypeOf) ----*/ - -var p = Object.getPrototypeOf(Number); - -assert.sameValue(p, Function.prototype, 'p'); diff --git a/test/built-ins/Number/EPSILON.js b/test/built-ins/Number/EPSILON.js index 65619d6240c..4bd2ee01093 100644 --- a/test/built-ins/Number/EPSILON.js +++ b/test/built-ins/Number/EPSILON.js @@ -14,7 +14,6 @@ info: | This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }. -includes: [propertyHelper.js] ---*/ assert( @@ -25,9 +24,3 @@ assert( Number.EPSILON < 0.000001, "value is smaller than 0.000001" ); - -verifyProperty(Number, "EPSILON", { - writable: false, - enumerable: false, - configurable: false, -}); diff --git a/test/built-ins/Number/EPSILON/prop-desc.js b/test/built-ins/Number/EPSILON/prop-desc.js new file mode 100644 index 00000000000..dd3b6fdf60f --- /dev/null +++ b/test/built-ins/Number/EPSILON/prop-desc.js @@ -0,0 +1,29 @@ +// Test generated by: property-test-generator + +/*--- +esid: sec-number.epsilon +description: Property test for Number.EPSILON +info: | + Number.EPSILON + - The value of `Number.EPSILON` is the Number value for the magnitude of the + difference between 1 and the smallest value greater than 1 that is + representable as a Number value, which is approximately + 2.2204460492503130808472633361816 × 10-16. + - This property has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: false }. + + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +flags: [generated] +includes: [propertyHelper.js] +---*/ + +verifyPrimordialProperty(Number, "EPSILON", { + value: 2.2204460492503130808472633361816e-16, + writable: false, + enumerable: false, + configurable: false, +}); diff --git a/test/built-ins/Number/MAX_SAFE_INTEGER.js b/test/built-ins/Number/MAX_SAFE_INTEGER.js deleted file mode 100644 index 7668e6c60a9..00000000000 --- a/test/built-ins/Number/MAX_SAFE_INTEGER.js +++ /dev/null @@ -1,22 +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. -/*--- -description: Property descriptor for `Number.MAX_SAFE_INTEGER` -esid: sec-number.max_safe_integer -info: | - The value of Number.MAX_SAFE_INTEGER is 9007199254740991 - - This property has the attributes { [[Writable]]: false, [[Enumerable]]: - false, [[Configurable]]: false }. -includes: [propertyHelper.js] ----*/ - -var desc = Object.getOwnPropertyDescriptor(Number, 'MAX_SAFE_INTEGER'); - -assert.sameValue(desc.set, undefined, 'Does not define a `get` accessor'); -assert.sameValue(desc.get, undefined, 'Does not define a `set` accessor'); -assert.sameValue(desc.value, 9007199254740991); - -verifyNotEnumerable(Number, 'MAX_SAFE_INTEGER'); -verifyNotWritable(Number, 'MAX_SAFE_INTEGER'); -verifyNotConfigurable(Number, 'MAX_SAFE_INTEGER'); diff --git a/test/built-ins/Number/MAX_SAFE_INTEGER/prop-desc.js b/test/built-ins/Number/MAX_SAFE_INTEGER/prop-desc.js new file mode 100644 index 00000000000..b0e624065de --- /dev/null +++ b/test/built-ins/Number/MAX_SAFE_INTEGER/prop-desc.js @@ -0,0 +1,26 @@ +// Test generated by: property-test-generator + +/*--- +esid: sec-number.max_safe_integer +description: Property test for Number.MAX_SAFE_INTEGER +info: | + Number.MAX_SAFE_INTEGER + - The value of `Number.MAX_SAFE_INTEGER` is 9007199254740991𝔽 (𝔽(253 - 1)). + - This property has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: false }. + + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +flags: [generated] +includes: [propertyHelper.js] +---*/ + +verifyPrimordialProperty(Number, "MAX_SAFE_INTEGER", { + value: 9007199254740991, + writable: false, + enumerable: false, + configurable: false, +}); diff --git a/test/built-ins/Number/MAX_VALUE/S15.7.3.2_A2.js b/test/built-ins/Number/MAX_VALUE/S15.7.3.2_A2.js deleted file mode 100644 index 69dd2780fbe..00000000000 --- a/test/built-ins/Number/MAX_VALUE/S15.7.3.2_A2.js +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2009 the Sputnik authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -info: Number.MAX_VALUE is ReadOnly -es5id: 15.7.3.2_A2 -description: Checking if varying Number.MAX_VALUE fails -includes: [propertyHelper.js] ----*/ - -// CHECK#1 -var x = Number.MAX_VALUE; -verifyNotWritable(Number, "MAX_VALUE", null, 1); -assert.sameValue(Number.MAX_VALUE, x, 'The value of Number.MAX_VALUE is expected to equal the value of x'); - -// TODO: Convert to verifyProperty() format. diff --git a/test/built-ins/Number/MAX_VALUE/S15.7.3.2_A3.js b/test/built-ins/Number/MAX_VALUE/S15.7.3.2_A3.js deleted file mode 100644 index 6122ea2aff1..00000000000 --- a/test/built-ins/Number/MAX_VALUE/S15.7.3.2_A3.js +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2009 the Sputnik authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -info: Number.MAX_VALUE is DontDelete -es5id: 15.7.3.2_A3 -description: Checking if deleting Number.MAX_VALUE fails -includes: [propertyHelper.js] ----*/ - -verifyNotConfigurable(Number, "MAX_VALUE"); - -// CHECK#1 -try { - assert.sameValue(delete Number.MAX_VALUE, false); -} catch (e) { - if (e instanceof Test262Error) { - throw e; - } - assert(e instanceof TypeError); -} - -// TODO: Convert to verifyProperty() format. diff --git a/test/built-ins/Number/MAX_VALUE/S15.7.3.2_A4.js b/test/built-ins/Number/MAX_VALUE/S15.7.3.2_A4.js deleted file mode 100644 index 3e837c6f41b..00000000000 --- a/test/built-ins/Number/MAX_VALUE/S15.7.3.2_A4.js +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2009 the Sputnik authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -info: Number.MAX_VALUE has the attribute DontEnum -es5id: 15.7.3.2_A4 -description: Checking if enumerating Number.MAX_VALUE fails ----*/ - -for (var x in Number) { - assert.notSameValue(x, "MAX_VALUE", 'The value of x is not "MAX_VALUE"'); -} - -assert( - !Number.propertyIsEnumerable('MAX_VALUE'), - 'The value of !Number.propertyIsEnumerable(\'MAX_VALUE\') is expected to be true' -); - -// TODO: Convert to verifyProperty() format. diff --git a/test/built-ins/Number/MAX_VALUE/prop-desc.js b/test/built-ins/Number/MAX_VALUE/prop-desc.js new file mode 100644 index 00000000000..1b2117e60a0 --- /dev/null +++ b/test/built-ins/Number/MAX_VALUE/prop-desc.js @@ -0,0 +1,27 @@ +// Test generated by: property-test-generator + +/*--- +esid: sec-number.max_value +description: Property test for Number.MAX_VALUE +info: | + Number.MAX_VALUE + - The value of `Number.MAX_VALUE` is the largest positive finite value of the + Number type, which is approximately 1.7976931348623157 × 10308. + - This property has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: false }. + + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +flags: [generated] +includes: [propertyHelper.js] +---*/ + +verifyPrimordialProperty(Number, "MAX_VALUE", { + value: 1.7976931348623157e308, + writable: false, + enumerable: false, + configurable: false, +}); diff --git a/test/built-ins/Number/MIN_SAFE_INTEGER.js b/test/built-ins/Number/MIN_SAFE_INTEGER.js deleted file mode 100644 index a90b8056e49..00000000000 --- a/test/built-ins/Number/MIN_SAFE_INTEGER.js +++ /dev/null @@ -1,22 +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. -/*--- -description: Property descriptor for `Number.MIN_SAFE_INTEGER` -esid: sec-number.min_safe_integer -info: | - The value of Number.MIN_SAFE_INTEGER is −9007199254740991 - - This property has the attributes { [[Writable]]: false, [[Enumerable]]: - false, [[Configurable]]: false }. -includes: [propertyHelper.js] ----*/ - -var desc = Object.getOwnPropertyDescriptor(Number, 'MIN_SAFE_INTEGER'); - -assert.sameValue(desc.set, undefined, 'Does not define a `get` accessor'); -assert.sameValue(desc.get, undefined, 'Does not define a `set` accessor'); -assert.sameValue(desc.value, -9007199254740991); - -verifyNotEnumerable(Number, 'MIN_SAFE_INTEGER'); -verifyNotWritable(Number, 'MIN_SAFE_INTEGER'); -verifyNotConfigurable(Number, 'MIN_SAFE_INTEGER'); diff --git a/test/built-ins/Number/MIN_SAFE_INTEGER/prop-desc.js b/test/built-ins/Number/MIN_SAFE_INTEGER/prop-desc.js new file mode 100644 index 00000000000..c5f47f21730 --- /dev/null +++ b/test/built-ins/Number/MIN_SAFE_INTEGER/prop-desc.js @@ -0,0 +1,27 @@ +// Test generated by: property-test-generator + +/*--- +esid: sec-number.min_safe_integer +description: Property test for Number.MIN_SAFE_INTEGER +info: | + Number.MIN_SAFE_INTEGER + - The value of `Number.MIN_SAFE_INTEGER` is -9007199254740991𝔽 (𝔽(-(253 - + 1))). + - This property has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: false }. + + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +flags: [generated] +includes: [propertyHelper.js] +---*/ + +verifyPrimordialProperty(Number, "MIN_SAFE_INTEGER", { + value: -9007199254740991, + writable: false, + enumerable: false, + configurable: false, +}); diff --git a/test/built-ins/Number/MIN_VALUE/S15.7.3.3_A2.js b/test/built-ins/Number/MIN_VALUE/S15.7.3.3_A2.js deleted file mode 100644 index 3c4b0cc0a54..00000000000 --- a/test/built-ins/Number/MIN_VALUE/S15.7.3.3_A2.js +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2009 the Sputnik authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -info: Number.MIN_VALUE is ReadOnly -es5id: 15.7.3.3_A2 -description: Checking if varying Number.MIN_VALUE fails -includes: [propertyHelper.js] ----*/ - -// CHECK#1 -var x = Number.MIN_VALUE; -verifyNotWritable(Number, "MIN_VALUE", null, 1); -assert.sameValue(Number.MIN_VALUE, x, 'The value of Number.MIN_VALUE is expected to equal the value of x'); - -// TODO: Convert to verifyProperty() format. diff --git a/test/built-ins/Number/MIN_VALUE/S15.7.3.3_A3.js b/test/built-ins/Number/MIN_VALUE/S15.7.3.3_A3.js deleted file mode 100644 index 96a993d12e2..00000000000 --- a/test/built-ins/Number/MIN_VALUE/S15.7.3.3_A3.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2009 the Sputnik authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -info: Number.MIN_VALUE is DontDelete -es5id: 15.7.3.3_A3 -description: Checking if deleting Number.MIN_VALUE fails -includes: [propertyHelper.js] ----*/ - -verifyNotConfigurable(Number, "MIN_VALUE"); - -try { - assert.sameValue(delete Number.MIN_VALUE, false); -} catch (e) { - if (e instanceof Test262Error) { - throw e; - } - assert(e instanceof TypeError); -} - -// TODO: Convert to verifyProperty() format. diff --git a/test/built-ins/Number/MIN_VALUE/S15.7.3.3_A4.js b/test/built-ins/Number/MIN_VALUE/S15.7.3.3_A4.js deleted file mode 100644 index 9b99292835e..00000000000 --- a/test/built-ins/Number/MIN_VALUE/S15.7.3.3_A4.js +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2009 the Sputnik authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -info: Number.MIN_VALUE has the attribute DontEnum -es5id: 15.7.3.3_A4 -description: Checking if enumerating Number.MIN_VALUE fails ----*/ - -for (var x in Number) { - assert.notSameValue(x, "MIN_VALUE", 'The value of x is not "MIN_VALUE"'); -} - -assert( - !Number.propertyIsEnumerable('MIN_VALUE'), - 'The value of !Number.propertyIsEnumerable(\'MIN_VALUE\') is expected to be true' -); - -// TODO: Convert to verifyProperty() format. diff --git a/test/built-ins/Number/MIN_VALUE/prop-desc.js b/test/built-ins/Number/MIN_VALUE/prop-desc.js new file mode 100644 index 00000000000..08a8749c969 --- /dev/null +++ b/test/built-ins/Number/MIN_VALUE/prop-desc.js @@ -0,0 +1,32 @@ +// Test generated by: property-test-generator + +/*--- +esid: sec-number.min_value +description: Property test for Number.MIN_VALUE +info: | + Number.MIN_VALUE + - The value of `Number.MIN_VALUE` is the smallest positive value of the Number + type, which is approximately 5 × 10-324. + - In the IEEE 754-2019 double precision binary representation, the smallest + possible value is a denormalized number. If an implementation does not + support denormalized values, the value of `Number.MIN_VALUE` must be the + smallest non-zero positive value that can actually be represented by the + implementation. + - This property has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: false }. + + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +flags: [generated] +includes: [propertyHelper.js] +---*/ + +verifyPrimordialProperty(Number, "MIN_VALUE", { + value: 5e-324, + writable: false, + enumerable: false, + configurable: false, +}); diff --git a/test/built-ins/Number/NEGATIVE_INFINITY/S15.7.3.5_A2.js b/test/built-ins/Number/NEGATIVE_INFINITY/S15.7.3.5_A2.js deleted file mode 100644 index 6f62aca2a43..00000000000 --- a/test/built-ins/Number/NEGATIVE_INFINITY/S15.7.3.5_A2.js +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2009 the Sputnik authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -info: Number.NEGATIVE_INFINITY is ReadOnly -es5id: 15.7.3.5_A2 -description: Checking if varying Number.NEGATIVE_INFINITY fails -includes: [propertyHelper.js] ----*/ - -// CHECK#1 -verifyNotWritable(Number, "NEGATIVE_INFINITY", null, 1); - -assert( - !isFinite(Number.NEGATIVE_INFINITY), - 'The value of !isFinite(Number.NEGATIVE_INFINITY) is expected to be true' -); - -// TODO: Convert to verifyProperty() format. diff --git a/test/built-ins/Number/NEGATIVE_INFINITY/prop-desc.js b/test/built-ins/Number/NEGATIVE_INFINITY/prop-desc.js index 47592d2181a..9d655484f5c 100644 --- a/test/built-ins/Number/NEGATIVE_INFINITY/prop-desc.js +++ b/test/built-ins/Number/NEGATIVE_INFINITY/prop-desc.js @@ -1,18 +1,26 @@ -// Copyright (C) 2016 The V8 Project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. +// Test generated by: property-test-generator /*--- esid: sec-number.negative_infinity -description: > - "NEGATIVE_INFINITY" property of Number +description: Property test for Number.NEGATIVE_INFINITY info: | Number.NEGATIVE_INFINITY + - The value of `Number.NEGATIVE_INFINITY` is -∞𝔽. + - This property has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: false }. - This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, - [[Configurable]]: false }. + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +flags: [generated] includes: [propertyHelper.js] ---*/ -verifyNotEnumerable(Number, "NEGATIVE_INFINITY"); -verifyNotWritable(Number, "NEGATIVE_INFINITY"); -verifyNotConfigurable(Number, "NEGATIVE_INFINITY"); +verifyPrimordialProperty(Number, "NEGATIVE_INFINITY", { + value: -1/0, + writable: false, + enumerable: false, + configurable: false, +}); diff --git a/test/built-ins/Number/NEGATIVE_INFINITY/value.js b/test/built-ins/Number/NEGATIVE_INFINITY/value.js deleted file mode 100644 index a7f0b65fec6..00000000000 --- a/test/built-ins/Number/NEGATIVE_INFINITY/value.js +++ /dev/null @@ -1,14 +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-number.negative_infinity -description: > - The value of Number.NEGATIVE_INFINITY is -Infinity -info: | - Number.NEGATIVE_INFINITY - - The value of Number.NEGATIVE_INFINITY is -∞. ----*/ - -assert.sameValue(Number.NEGATIVE_INFINITY, -Infinity); diff --git a/test/built-ins/Number/NaN.js b/test/built-ins/Number/NaN.js deleted file mode 100644 index 40349cbfd08..00000000000 --- a/test/built-ins/Number/NaN.js +++ /dev/null @@ -1,24 +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-number.nan -description: > - "NaN" property descriptor and value of Number -info: | - 20.1.2.10 Number.NaN - - The value of Number.NaN is NaN. - - This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, - [[Configurable]]: false }. -includes: [propertyHelper.js] ----*/ - -assert.sameValue(Number.NaN, NaN); - -verifyProperty(Number, "NaN", { - writable: false, - enumerable: false, - configurable: false, -}); diff --git a/test/built-ins/Number/NaN/prop-desc.js b/test/built-ins/Number/NaN/prop-desc.js new file mode 100644 index 00000000000..ba73ef8d608 --- /dev/null +++ b/test/built-ins/Number/NaN/prop-desc.js @@ -0,0 +1,26 @@ +// Test generated by: property-test-generator + +/*--- +esid: sec-number.nan +description: Property test for Number.NaN +info: | + Number.NaN + - The value of `Number.NaN` is NaN. + - This property has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: false }. + + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +flags: [generated] +includes: [propertyHelper.js] +---*/ + +verifyPrimordialProperty(Number, "NaN", { + value: 0/0, + writable: false, + enumerable: false, + configurable: false, +}); diff --git a/test/built-ins/Number/POSITIVE_INFINITY/S15.7.3.6_A2.js b/test/built-ins/Number/POSITIVE_INFINITY/S15.7.3.6_A2.js deleted file mode 100644 index c817dc97610..00000000000 --- a/test/built-ins/Number/POSITIVE_INFINITY/S15.7.3.6_A2.js +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2009 the Sputnik authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -info: Number.POSITIVE_INFINITY is ReadOnly -es5id: 15.7.3.6_A2 -description: Checking if varying Number.POSITIVE_INFINITY fails -includes: [propertyHelper.js] ----*/ - -// CHECK#1 -verifyNotWritable(Number, "POSITIVE_INFINITY", null, 1); - -assert( - !isFinite(Number.POSITIVE_INFINITY), - 'The value of !isFinite(Number.POSITIVE_INFINITY) is expected to be true' -); - -// TODO: Convert to verifyProperty() format. diff --git a/test/built-ins/Number/POSITIVE_INFINITY/prop-desc.js b/test/built-ins/Number/POSITIVE_INFINITY/prop-desc.js index 0cc42dbf932..1298f08d1c1 100644 --- a/test/built-ins/Number/POSITIVE_INFINITY/prop-desc.js +++ b/test/built-ins/Number/POSITIVE_INFINITY/prop-desc.js @@ -1,18 +1,26 @@ -// Copyright (C) 2016 The V8 Project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. +// Test generated by: property-test-generator /*--- esid: sec-number.positive_infinity -description: > - "POSITIVE_INFINITY" property of Number +description: Property test for Number.POSITIVE_INFINITY info: | Number.POSITIVE_INFINITY + - The value of `Number.POSITIVE_INFINITY` is +∞𝔽. + - This property has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: false }. - This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, - [[Configurable]]: false }. + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +flags: [generated] includes: [propertyHelper.js] ---*/ -verifyNotEnumerable(Number, "POSITIVE_INFINITY"); -verifyNotWritable(Number, "POSITIVE_INFINITY"); -verifyNotConfigurable(Number, "POSITIVE_INFINITY"); +verifyPrimordialProperty(Number, "POSITIVE_INFINITY", { + value: 1/0, + writable: false, + enumerable: false, + configurable: false, +}); diff --git a/test/built-ins/Number/POSITIVE_INFINITY/value.js b/test/built-ins/Number/POSITIVE_INFINITY/value.js deleted file mode 100644 index 96d2c2da762..00000000000 --- a/test/built-ins/Number/POSITIVE_INFINITY/value.js +++ /dev/null @@ -1,14 +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-number.positive_infinity -description: > - The value of Number.POSITIVE_INFINITY is +Infinity -info: | - Number.POSITIVE_INFINITY - - The value of Number.POSITIVE_INFINITY is +∞. ----*/ - -assert.sameValue(Number.POSITIVE_INFINITY, Infinity); diff --git a/test/built-ins/Number/S15.7.3_A1.js b/test/built-ins/Number/S15.7.3_A1.js deleted file mode 100644 index 9c3b8f51821..00000000000 --- a/test/built-ins/Number/S15.7.3_A1.js +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2009 the Sputnik authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -info: The Number constructor has the property "prototype" -es5id: 15.7.3_A1 -description: Checking existence of the property "prototype" ----*/ -assert(Number.hasOwnProperty("prototype"), 'Number.hasOwnProperty("prototype") must return true'); diff --git a/test/built-ins/Number/S15.7.3_A2.js b/test/built-ins/Number/S15.7.3_A2.js deleted file mode 100644 index 739832bd22d..00000000000 --- a/test/built-ins/Number/S15.7.3_A2.js +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2009 the Sputnik authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -info: The Number constructor has the property "MAX_VALUE" -es5id: 15.7.3_A2 -description: Checking existence of the property "MAX_VALUE" ----*/ -assert(Number.hasOwnProperty("MAX_VALUE"), 'Number.hasOwnProperty("MAX_VALUE") must return true'); diff --git a/test/built-ins/Number/S15.7.3_A3.js b/test/built-ins/Number/S15.7.3_A3.js deleted file mode 100644 index 216fe9434b8..00000000000 --- a/test/built-ins/Number/S15.7.3_A3.js +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2009 the Sputnik authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -info: The Number constructor has the property "MIN_VALUE" -es5id: 15.7.3_A3 -description: Checking existence of the property "MIN_VALUE" ----*/ -assert(Number.hasOwnProperty("MIN_VALUE"), 'Number.hasOwnProperty("MIN_VALUE") must return true'); diff --git a/test/built-ins/Number/S15.7.3_A4.js b/test/built-ins/Number/S15.7.3_A4.js deleted file mode 100644 index 3e6340f1bcd..00000000000 --- a/test/built-ins/Number/S15.7.3_A4.js +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2009 the Sputnik authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -info: The Number constructor has the property "NaN" -es5id: 15.7.3_A4 -description: Checking existence of the property "NaN" ----*/ -assert(Number.hasOwnProperty("NaN"), 'Number.hasOwnProperty("NaN") must return true'); diff --git a/test/built-ins/Number/S15.7.3_A5.js b/test/built-ins/Number/S15.7.3_A5.js deleted file mode 100644 index fbcde06b723..00000000000 --- a/test/built-ins/Number/S15.7.3_A5.js +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2009 the Sputnik authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -info: The Number constructor has the property "NEGATIVE_INFINITY" -es5id: 15.7.3_A5 -description: Checking existence of the property "NEGATIVE_INFINITY" ----*/ -assert( - Number.hasOwnProperty("NEGATIVE_INFINITY"), - 'Number.hasOwnProperty("NEGATIVE_INFINITY") must return true' -); diff --git a/test/built-ins/Number/S15.7.3_A6.js b/test/built-ins/Number/S15.7.3_A6.js deleted file mode 100644 index 76896c6b8df..00000000000 --- a/test/built-ins/Number/S15.7.3_A6.js +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2009 the Sputnik authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -info: The Number constructor has the property "POSITIVE_INFINITY" -es5id: 15.7.3_A6 -description: Checking existence of the property "POSITIVE_INFINITY" ----*/ -assert( - Number.hasOwnProperty("POSITIVE_INFINITY"), - 'Number.hasOwnProperty("POSITIVE_INFINITY") must return true' -); diff --git a/test/built-ins/Number/S15.7.3_A7.js b/test/built-ins/Number/S15.7.3_A7.js deleted file mode 100644 index 0a2153ff241..00000000000 --- a/test/built-ins/Number/S15.7.3_A7.js +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2009 the Sputnik authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -info: | - The value of the internal [[Prototype]] property of the Number - constructor is the Function prototype object -es5id: 15.7.3_A7 -description: Checking Function.prototype.isPrototypeOf(Number) ----*/ -assert( - Function.prototype.isPrototypeOf(Number), - 'Function.prototype.isPrototypeOf(Number) must return true' -); diff --git a/test/built-ins/Number/S15.7.3_A8.js b/test/built-ins/Number/S15.7.3_A8.js deleted file mode 100644 index a5b8c854819..00000000000 --- a/test/built-ins/Number/S15.7.3_A8.js +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2009 the Sputnik authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -info: Number constructor has length property whose value is 1 -es5id: 15.7.3_A8 -description: Checking Number.length property ----*/ -assert(Number.hasOwnProperty("length"), 'Number.hasOwnProperty("length") must return true'); -assert.sameValue(Number.length, 1, 'The value of Number.length is expected to be 1'); diff --git a/test/built-ins/Number/ctor.js b/test/built-ins/Number/ctor.js new file mode 100644 index 00000000000..d0c85e98e7d --- /dev/null +++ b/test/built-ins/Number/ctor.js @@ -0,0 +1,18 @@ +// Test generated by: property-test-generator + +/*--- +esid: sec-number-constructor +description: Property test for Number +info: | + The Number Constructor + + Number ( value ) + + Properties of the Number Constructor + - has a [[Prototype]] internal slot whose value is %Function.prototype%. +flags: [generated] +includes: [builtin.js, propertyHelper.js] +features: [Proxy, Reflect, Reflect.construct] +---*/ + +verifyBuiltinConstructor(Number, "Number", 1, Function.prototype); diff --git a/test/built-ins/Number/isFinite/length.js b/test/built-ins/Number/isFinite/length.js deleted file mode 100644 index f48c960eb56..00000000000 --- a/test/built-ins/Number/isFinite/length.js +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2015 André Bargull. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es6id: 20.1.2.2 -description: > - Number.isFinite.length is 1. -info: | - Number.isFinite ( number ) - - 17 ECMAScript Standard Built-in Objects: - Every built-in Function object, including constructors, 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 - subclause headings for the function description, including optional - parameters. However, rest parameters shown using the form “...name” - are not included in the default argument count. - - 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(Number.isFinite, "length", { - value: 1, - writable: false, - enumerable: false, - configurable: true -}); diff --git a/test/built-ins/Number/isFinite/name.js b/test/built-ins/Number/isFinite/name.js deleted file mode 100644 index 51ef8b19c95..00000000000 --- a/test/built-ins/Number/isFinite/name.js +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2015 André Bargull. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es6id: 20.1.2.2 -description: > - Number.isFinite.name is "isFinite". -info: | - Number.isFinite ( number ) - - 17 ECMAScript Standard Built-in Objects: - Every built-in Function object, including constructors, that is not - identified as an anonymous function has a name property whose value - is a String. - - Unless otherwise specified, the name property of a built-in Function - object, if it exists, has the attributes { [[Writable]]: false, - [[Enumerable]]: false, [[Configurable]]: true }. -includes: [propertyHelper.js] ----*/ - -verifyProperty(Number.isFinite, "name", { - value: "isFinite", - writable: false, - enumerable: false, - configurable: true -}); diff --git a/test/built-ins/Number/isFinite/not-a-constructor.js b/test/built-ins/Number/isFinite/not-a-constructor.js deleted file mode 100644 index 18343cc72e7..00000000000 --- a/test/built-ins/Number/isFinite/not-a-constructor.js +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (C) 2020 Rick Waldron. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-ecmascript-standard-built-in-objects -description: > - Number.isFinite does not implement [[Construct]], is not new-able -info: | - ECMAScript Function Objects - - Built-in function objects that are not identified as constructors do not - implement the [[Construct]] internal method unless otherwise specified in - the description of a particular function. - - sec-evaluatenew - - ... - 7. If IsConstructor(constructor) is false, throw a TypeError exception. - ... -includes: [isConstructor.js] -features: [Reflect.construct, arrow-function] ----*/ - -assert.sameValue(isConstructor(Number.isFinite), false, 'isConstructor(Number.isFinite) must return false'); - -assert.throws(TypeError, () => { - new Number.isFinite(); -}); - diff --git a/test/built-ins/Number/isFinite/prop-desc.js b/test/built-ins/Number/isFinite/prop-desc.js index 8211d60467c..62fe257e471 100644 --- a/test/built-ins/Number/isFinite/prop-desc.js +++ b/test/built-ins/Number/isFinite/prop-desc.js @@ -1,21 +1,26 @@ -// Copyright (C) 2016 The V8 Project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. +// Test generated by: property-test-generator /*--- esid: sec-number.isfinite -description: > - "isFinite" property of Number +description: Property test for Number.isFinite info: | - 17 ECMAScript Standard Built-in Objects: + Number.isFinite ( number ) - Every other data property described in clauses 18 through 26 and in Annex B.2 + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true } unless otherwise specified. -includes: [propertyHelper.js] +flags: [generated] +includes: [builtin.js, propertyHelper.js] +features: [Proxy, Reflect, Reflect.construct] ---*/ -verifyProperty(Number, "isFinite", { +verifyBuiltinFunction(Number.isFinite, "isFinite", 1); + +verifyPrimordialProperty(Number, "isFinite", { + value: Number.isFinite, writable: true, enumerable: false, - configurable: true + configurable: true, }); diff --git a/test/built-ins/Number/isInteger/length.js b/test/built-ins/Number/isInteger/length.js deleted file mode 100644 index 858209dea19..00000000000 --- a/test/built-ins/Number/isInteger/length.js +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2015 André Bargull. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es6id: 20.1.2.3 -description: > - Number.isInteger.length is 1. -info: | - Number.isInteger ( number ) - - 17 ECMAScript Standard Built-in Objects: - Every built-in Function object, including constructors, 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 - subclause headings for the function description, including optional - parameters. However, rest parameters shown using the form “...name” - are not included in the default argument count. - - 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(Number.isInteger, "length", { - value: 1, - writable: false, - enumerable: false, - configurable: true -}); diff --git a/test/built-ins/Number/isInteger/name.js b/test/built-ins/Number/isInteger/name.js deleted file mode 100644 index f9e4fe0defe..00000000000 --- a/test/built-ins/Number/isInteger/name.js +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2015 André Bargull. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es6id: 20.1.2.3 -description: > - Number.isInteger.name is "isInteger". -info: | - Number.isInteger ( number ) - - 17 ECMAScript Standard Built-in Objects: - Every built-in Function object, including constructors, that is not - identified as an anonymous function has a name property whose value - is a String. - - Unless otherwise specified, the name property of a built-in Function - object, if it exists, has the attributes { [[Writable]]: false, - [[Enumerable]]: false, [[Configurable]]: true }. -includes: [propertyHelper.js] ----*/ - -verifyProperty(Number.isInteger, "name", { - value: "isInteger", - writable: false, - enumerable: false, - configurable: true -}); diff --git a/test/built-ins/Number/isInteger/not-a-constructor.js b/test/built-ins/Number/isInteger/not-a-constructor.js deleted file mode 100644 index 6a4ebe18d69..00000000000 --- a/test/built-ins/Number/isInteger/not-a-constructor.js +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (C) 2020 Rick Waldron. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-ecmascript-standard-built-in-objects -description: > - Number.isInteger does not implement [[Construct]], is not new-able -info: | - ECMAScript Function Objects - - Built-in function objects that are not identified as constructors do not - implement the [[Construct]] internal method unless otherwise specified in - the description of a particular function. - - sec-evaluatenew - - ... - 7. If IsConstructor(constructor) is false, throw a TypeError exception. - ... -includes: [isConstructor.js] -features: [Reflect.construct, arrow-function] ----*/ - -assert.sameValue(isConstructor(Number.isInteger), false, 'isConstructor(Number.isInteger) must return false'); - -assert.throws(TypeError, () => { - new Number.isInteger(); -}); - diff --git a/test/built-ins/Number/isInteger/prop-desc.js b/test/built-ins/Number/isInteger/prop-desc.js index 36945ab8bc3..6afda314917 100644 --- a/test/built-ins/Number/isInteger/prop-desc.js +++ b/test/built-ins/Number/isInteger/prop-desc.js @@ -1,21 +1,26 @@ -// Copyright (C) 2016 The V8 Project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. +// Test generated by: property-test-generator /*--- esid: sec-number.isinteger -description: > - "isInteger" property of Number +description: Property test for Number.isInteger info: | - 17 ECMAScript Standard Built-in Objects: + Number.isInteger ( number ) - Every other data property described in clauses 18 through 26 and in Annex B.2 + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true } unless otherwise specified. -includes: [propertyHelper.js] +flags: [generated] +includes: [builtin.js, propertyHelper.js] +features: [Proxy, Reflect, Reflect.construct] ---*/ -verifyProperty(Number, "isInteger", { +verifyBuiltinFunction(Number.isInteger, "isInteger", 1); + +verifyPrimordialProperty(Number, "isInteger", { + value: Number.isInteger, writable: true, enumerable: false, - configurable: true + configurable: true, }); diff --git a/test/built-ins/Number/isNaN/length.js b/test/built-ins/Number/isNaN/length.js deleted file mode 100644 index 69914a24691..00000000000 --- a/test/built-ins/Number/isNaN/length.js +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2015 André Bargull. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es6id: 20.1.2.4 -description: > - Number.isNaN.length is 1. -info: | - Number.isNaN ( number ) - - 17 ECMAScript Standard Built-in Objects: - Every built-in Function object, including constructors, 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 - subclause headings for the function description, including optional - parameters. However, rest parameters shown using the form “...name” - are not included in the default argument count. - - 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(Number.isNaN, "length", { - value: 1, - writable: false, - enumerable: false, - configurable: true -}); diff --git a/test/built-ins/Number/isNaN/name.js b/test/built-ins/Number/isNaN/name.js deleted file mode 100644 index 1f57ac357b2..00000000000 --- a/test/built-ins/Number/isNaN/name.js +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2015 André Bargull. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es6id: 20.1.2.4 -description: > - Number.isNaN.name is "isNaN". -info: | - Number.isNaN ( number ) - - 17 ECMAScript Standard Built-in Objects: - Every built-in Function object, including constructors, that is not - identified as an anonymous function has a name property whose value - is a String. - - Unless otherwise specified, the name property of a built-in Function - object, if it exists, has the attributes { [[Writable]]: false, - [[Enumerable]]: false, [[Configurable]]: true }. -includes: [propertyHelper.js] ----*/ - -verifyProperty(Number.isNaN, "name", { - value: "isNaN", - writable: false, - enumerable: false, - configurable: true -}); diff --git a/test/built-ins/Number/isNaN/not-a-constructor.js b/test/built-ins/Number/isNaN/not-a-constructor.js deleted file mode 100644 index 57f4584146c..00000000000 --- a/test/built-ins/Number/isNaN/not-a-constructor.js +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (C) 2020 Rick Waldron. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-ecmascript-standard-built-in-objects -description: > - Number.isNaN does not implement [[Construct]], is not new-able -info: | - ECMAScript Function Objects - - Built-in function objects that are not identified as constructors do not - implement the [[Construct]] internal method unless otherwise specified in - the description of a particular function. - - sec-evaluatenew - - ... - 7. If IsConstructor(constructor) is false, throw a TypeError exception. - ... -includes: [isConstructor.js] -features: [Reflect.construct, arrow-function] ----*/ - -assert.sameValue(isConstructor(Number.isNaN), false, 'isConstructor(Number.isNaN) must return false'); - -assert.throws(TypeError, () => { - new Number.isNaN(); -}); - diff --git a/test/built-ins/Number/isNaN/prop-desc.js b/test/built-ins/Number/isNaN/prop-desc.js index 96d984dd5bd..02a018400e2 100644 --- a/test/built-ins/Number/isNaN/prop-desc.js +++ b/test/built-ins/Number/isNaN/prop-desc.js @@ -1,21 +1,26 @@ -// Copyright (C) 2016 The V8 Project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. +// Test generated by: property-test-generator /*--- esid: sec-number.isnan -description: > - "isNaN" property of Number +description: Property test for Number.isNaN info: | - 17 ECMAScript Standard Built-in Objects: + Number.isNaN ( number ) - Every other data property described in clauses 18 through 26 and in Annex B.2 + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true } unless otherwise specified. -includes: [propertyHelper.js] +flags: [generated] +includes: [builtin.js, propertyHelper.js] +features: [Proxy, Reflect, Reflect.construct] ---*/ -verifyProperty(Number, "isNaN", { +verifyBuiltinFunction(Number.isNaN, "isNaN", 1); + +verifyPrimordialProperty(Number, "isNaN", { + value: Number.isNaN, writable: true, enumerable: false, - configurable: true + configurable: true, }); diff --git a/test/built-ins/Number/isSafeInteger/length.js b/test/built-ins/Number/isSafeInteger/length.js deleted file mode 100644 index ab73312e4aa..00000000000 --- a/test/built-ins/Number/isSafeInteger/length.js +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2015 André Bargull. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es6id: 20.1.2.5 -description: > - Number.isSafeInteger.length is 1. -info: | - Number.isSafeInteger ( number ) - - 17 ECMAScript Standard Built-in Objects: - Every built-in Function object, including constructors, 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 - subclause headings for the function description, including optional - parameters. However, rest parameters shown using the form “...name” - are not included in the default argument count. - - 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(Number.isSafeInteger, "length", { - value: 1, - writable: false, - enumerable: false, - configurable: true -}); diff --git a/test/built-ins/Number/isSafeInteger/name.js b/test/built-ins/Number/isSafeInteger/name.js deleted file mode 100644 index 0ef1237b8b7..00000000000 --- a/test/built-ins/Number/isSafeInteger/name.js +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2015 André Bargull. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es6id: 20.1.2.5 -description: > - Number.isSafeInteger.name is "isSafeInteger". -info: | - Number.isSafeInteger ( number ) - - 17 ECMAScript Standard Built-in Objects: - Every built-in Function object, including constructors, that is not - identified as an anonymous function has a name property whose value - is a String. - - Unless otherwise specified, the name property of a built-in Function - object, if it exists, has the attributes { [[Writable]]: false, - [[Enumerable]]: false, [[Configurable]]: true }. -includes: [propertyHelper.js] ----*/ - -verifyProperty(Number.isSafeInteger, "name", { - value: "isSafeInteger", - writable: false, - enumerable: false, - configurable: true -}); diff --git a/test/built-ins/Number/isSafeInteger/not-a-constructor.js b/test/built-ins/Number/isSafeInteger/not-a-constructor.js deleted file mode 100644 index da6b090bbb7..00000000000 --- a/test/built-ins/Number/isSafeInteger/not-a-constructor.js +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (C) 2020 Rick Waldron. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-ecmascript-standard-built-in-objects -description: > - Number.isSafeInteger does not implement [[Construct]], is not new-able -info: | - ECMAScript Function Objects - - Built-in function objects that are not identified as constructors do not - implement the [[Construct]] internal method unless otherwise specified in - the description of a particular function. - - sec-evaluatenew - - ... - 7. If IsConstructor(constructor) is false, throw a TypeError exception. - ... -includes: [isConstructor.js] -features: [Reflect.construct, arrow-function] ----*/ - -assert.sameValue(isConstructor(Number.isSafeInteger), false, 'isConstructor(Number.isSafeInteger) must return false'); - -assert.throws(TypeError, () => { - new Number.isSafeInteger(); -}); - diff --git a/test/built-ins/Number/isSafeInteger/prop-desc.js b/test/built-ins/Number/isSafeInteger/prop-desc.js index 8243e68f46d..fe38de39352 100644 --- a/test/built-ins/Number/isSafeInteger/prop-desc.js +++ b/test/built-ins/Number/isSafeInteger/prop-desc.js @@ -1,21 +1,26 @@ -// Copyright (C) 2016 The V8 Project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. +// Test generated by: property-test-generator /*--- esid: sec-number.issafeinteger -description: > - "isSafeInteger" property of Number +description: Property test for Number.isSafeInteger info: | - 17 ECMAScript Standard Built-in Objects: + Number.isSafeInteger ( number ) - Every other data property described in clauses 18 through 26 and in Annex B.2 + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true } unless otherwise specified. -includes: [propertyHelper.js] +flags: [generated] +includes: [builtin.js, propertyHelper.js] +features: [Proxy, Reflect, Reflect.construct] ---*/ -verifyProperty(Number, "isSafeInteger", { +verifyBuiltinFunction(Number.isSafeInteger, "isSafeInteger", 1); + +verifyPrimordialProperty(Number, "isSafeInteger", { + value: Number.isSafeInteger, writable: true, enumerable: false, - configurable: true + configurable: true, }); diff --git a/test/built-ins/Number/parseFloat.js b/test/built-ins/Number/parseFloat.js deleted file mode 100644 index 51e0a68a694..00000000000 --- a/test/built-ins/Number/parseFloat.js +++ /dev/null @@ -1,29 +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-number.parsefloat -description: > - "parseFloat" property descriptor and value of Number -info: | - Number.parseFloat - - The value of the Number.parseFloat data property is the same built-in function - object that is the value of the parseFloat property of the global object - defined in 18.2.4. - - 17 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] ----*/ - -assert.sameValue(Number.parseFloat, parseFloat); - -verifyProperty(Number, "parseFloat", { - writable: true, - enumerable: false, - configurable: true -}); diff --git a/test/built-ins/Number/parseFloat/not-a-constructor.js b/test/built-ins/Number/parseFloat/not-a-constructor.js deleted file mode 100644 index b38f4fb4f1f..00000000000 --- a/test/built-ins/Number/parseFloat/not-a-constructor.js +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (C) 2020 Rick Waldron. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-ecmascript-standard-built-in-objects -description: > - Number.parseFloat does not implement [[Construct]], is not new-able -info: | - ECMAScript Function Objects - - Built-in function objects that are not identified as constructors do not - implement the [[Construct]] internal method unless otherwise specified in - the description of a particular function. - - sec-evaluatenew - - ... - 7. If IsConstructor(constructor) is false, throw a TypeError exception. - ... -includes: [isConstructor.js] -features: [Reflect.construct, arrow-function] ----*/ - -assert.sameValue(isConstructor(Number.parseFloat), false, 'isConstructor(Number.parseFloat) must return false'); - -assert.throws(TypeError, () => { - new Number.parseFloat(); -}); - diff --git a/test/built-ins/Number/parseFloat/prop-desc.js b/test/built-ins/Number/parseFloat/prop-desc.js new file mode 100644 index 00000000000..6c84a1d5eca --- /dev/null +++ b/test/built-ins/Number/parseFloat/prop-desc.js @@ -0,0 +1,26 @@ +// Test generated by: property-test-generator + +/*--- +esid: sec-number.parsefloat +description: Property test for Number.parseFloat +info: | + Number.parseFloat ( string ) + - The initial value of the "parseFloat" property is %parseFloat%. + + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +flags: [generated] +includes: [propertyHelper.js] +---*/ + +assert.sameValue(Number.parseFloat, parseFloat); + +verifyPrimordialProperty(Number, "parseFloat", { + value: parseFloat, + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/test/built-ins/Number/parseInt.js b/test/built-ins/Number/parseInt.js deleted file mode 100644 index 12b65f38214..00000000000 --- a/test/built-ins/Number/parseInt.js +++ /dev/null @@ -1,29 +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-number.parseint -description: > - "parseInt" property descriptor and value of Number -info: | - Number.parseInt - - The value of the Number.parseInt data property is the same built-in function - object that is the value of the parseInt property of the global object - defined in 18.2.4. - - 17 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] ----*/ - -assert.sameValue(Number.parseInt, parseInt); - -verifyProperty(Number, "parseInt", { - writable: true, - enumerable: false, - configurable: true -}); diff --git a/test/built-ins/Number/parseInt/not-a-constructor.js b/test/built-ins/Number/parseInt/not-a-constructor.js deleted file mode 100644 index 6c68b2b6dd5..00000000000 --- a/test/built-ins/Number/parseInt/not-a-constructor.js +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (C) 2020 Rick Waldron. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-ecmascript-standard-built-in-objects -description: > - Number.parseInt does not implement [[Construct]], is not new-able -info: | - ECMAScript Function Objects - - Built-in function objects that are not identified as constructors do not - implement the [[Construct]] internal method unless otherwise specified in - the description of a particular function. - - sec-evaluatenew - - ... - 7. If IsConstructor(constructor) is false, throw a TypeError exception. - ... -includes: [isConstructor.js] -features: [Reflect.construct, arrow-function] ----*/ - -assert.sameValue(isConstructor(Number.parseInt), false, 'isConstructor(Number.parseInt) must return false'); - -assert.throws(TypeError, () => { - new Number.parseInt(); -}); - diff --git a/test/built-ins/Number/parseInt/prop-desc.js b/test/built-ins/Number/parseInt/prop-desc.js new file mode 100644 index 00000000000..1618df9ffa0 --- /dev/null +++ b/test/built-ins/Number/parseInt/prop-desc.js @@ -0,0 +1,26 @@ +// Test generated by: property-test-generator + +/*--- +esid: sec-number.parseint +description: Property test for Number.parseInt +info: | + Number.parseInt ( string, radix ) + - The initial value of the "parseInt" property is %parseInt%. + + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +flags: [generated] +includes: [propertyHelper.js] +---*/ + +assert.sameValue(Number.parseInt, parseInt); + +verifyPrimordialProperty(Number, "parseInt", { + value: parseInt, + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/test/built-ins/Number/prop-desc.js b/test/built-ins/Number/prop-desc.js index 7f79f43323a..f3435bf7eb3 100644 --- a/test/built-ins/Number/prop-desc.js +++ b/test/built-ins/Number/prop-desc.js @@ -1,21 +1,23 @@ -// Copyright (C) 2016 The V8 Project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. +// Test generated by: property-test-generator /*--- -esid: sec-number-constructor-number-value -description: > - Property descriptor of Number +esid: sec-constructor-properties-of-the-global-object-number +description: Property test for Number info: | - 17 ECMAScript Standard Built-in Objects: + Number ( . . . ) - Every other data property described in clauses 18 through 26 and in Annex B.2 + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true } unless otherwise specified. +flags: [generated] includes: [propertyHelper.js] ---*/ -verifyProperty(this, "Number", { +verifyPrimordialProperty(this, "Number", { + value: Number, writable: true, enumerable: false, - configurable: true + configurable: true, }); diff --git a/test/built-ins/Number/prototype/S15.7.4_A3.1.js b/test/built-ins/Number/prototype/S15.7.4_A3.1.js deleted file mode 100644 index 4b2983b5f86..00000000000 --- a/test/built-ins/Number/prototype/S15.7.4_A3.1.js +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2009 the Sputnik authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -info: The Number prototype object has the property constructor -es5id: 15.7.4_A3.1 -description: The test uses hasOwnProperty() method ----*/ -assert.sameValue( - Number.prototype.hasOwnProperty("constructor"), - true, - 'Number.prototype.hasOwnProperty("constructor") must return true' -); diff --git a/test/built-ins/Number/prototype/S15.7.4_A3.2.js b/test/built-ins/Number/prototype/S15.7.4_A3.2.js deleted file mode 100644 index 6069d9a360e..00000000000 --- a/test/built-ins/Number/prototype/S15.7.4_A3.2.js +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2009 the Sputnik authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -info: The Number prototype object has the property toString -es5id: 15.7.4_A3.2 -description: The test uses hasOwnProperty() method ----*/ -assert.sameValue( - Number.prototype.hasOwnProperty("toString"), - true, - 'Number.prototype.hasOwnProperty("toString") must return true' -); diff --git a/test/built-ins/Number/prototype/S15.7.4_A3.3.js b/test/built-ins/Number/prototype/S15.7.4_A3.3.js deleted file mode 100644 index ffc3eae8e27..00000000000 --- a/test/built-ins/Number/prototype/S15.7.4_A3.3.js +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2009 the Sputnik authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -info: The Number prototype object has the property toLocaleString -es5id: 15.7.4_A3.3 -description: The test uses hasOwnProperty() method ----*/ -assert.sameValue( - Number.prototype.hasOwnProperty("toLocaleString"), - true, - 'Number.prototype.hasOwnProperty("toLocaleString") must return true' -); diff --git a/test/built-ins/Number/prototype/S15.7.4_A3.4.js b/test/built-ins/Number/prototype/S15.7.4_A3.4.js deleted file mode 100644 index 6bd7de9c7a9..00000000000 --- a/test/built-ins/Number/prototype/S15.7.4_A3.4.js +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2009 the Sputnik authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -info: The Number prototype object has the property valueOf -es5id: 15.7.4_A3.4 -description: The test uses hasOwnProperty() method ----*/ -assert.sameValue( - Number.prototype.hasOwnProperty("valueOf"), - true, - 'Number.prototype.hasOwnProperty("valueOf") must return true' -); diff --git a/test/built-ins/Number/prototype/S15.7.4_A3.5.js b/test/built-ins/Number/prototype/S15.7.4_A3.5.js deleted file mode 100644 index d5fe3b759b6..00000000000 --- a/test/built-ins/Number/prototype/S15.7.4_A3.5.js +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2009 the Sputnik authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -info: The Number prototype object has the property toFixed -es5id: 15.7.4_A3.5 -description: The test uses hasOwnProperty() method ----*/ -assert.sameValue( - Number.prototype.hasOwnProperty("toFixed"), - true, - 'Number.prototype.hasOwnProperty("toFixed") must return true' -); diff --git a/test/built-ins/Number/prototype/S15.7.4_A3.6.js b/test/built-ins/Number/prototype/S15.7.4_A3.6.js deleted file mode 100644 index a7d9b85c3af..00000000000 --- a/test/built-ins/Number/prototype/S15.7.4_A3.6.js +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2009 the Sputnik authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -info: The Number prototype object has the property toExponential -es5id: 15.7.4_A3.6 -description: The test uses hasOwnProperty() method ----*/ -assert.sameValue( - Number.prototype.hasOwnProperty("toExponential"), - true, - 'Number.prototype.hasOwnProperty("toExponential") must return true' -); diff --git a/test/built-ins/Number/prototype/S15.7.4_A3.7.js b/test/built-ins/Number/prototype/S15.7.4_A3.7.js deleted file mode 100644 index 93f3b038039..00000000000 --- a/test/built-ins/Number/prototype/S15.7.4_A3.7.js +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2009 the Sputnik authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -info: The Number prototype object has the property toPrecision -es5id: 15.7.4_A3.7 -description: The test uses hasOwnProperty() method ----*/ -assert.sameValue( - Number.prototype.hasOwnProperty("toPrecision"), - true, - 'Number.prototype.hasOwnProperty("toPrecision") must return true' -); diff --git a/test/built-ins/Number/prototype/constructor.js b/test/built-ins/Number/prototype/constructor.js index 119d3a892c6..11fa52e71cb 100644 --- a/test/built-ins/Number/prototype/constructor.js +++ b/test/built-ins/Number/prototype/constructor.js @@ -1,21 +1,23 @@ -// Copyright (C) 2009 the Sputnik authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. +// Test generated by: property-test-generator /*--- esid: sec-number.prototype.constructor -description: > - Property descriptor and value for Number.prototype.constructor +description: Property test for Number.prototype.constructor info: | Number.prototype.constructor + - The initial value of `Number.prototype.constructor` is %Number%. - The initial value of Number.prototype.constructor is the intrinsic object - %Number%. + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +flags: [generated] includes: [propertyHelper.js] ---*/ -assert.sameValue(Number.prototype.constructor, Number); - -verifyProperty(Number.prototype, "constructor", { +verifyPrimordialProperty(Number.prototype, "constructor", { + value: Number, writable: true, enumerable: false, configurable: true, diff --git a/test/built-ins/Number/prototype/prop-desc.js b/test/built-ins/Number/prototype/prop-desc.js index 854696d37b1..53a3775d504 100644 --- a/test/built-ins/Number/prototype/prop-desc.js +++ b/test/built-ins/Number/prototype/prop-desc.js @@ -1,19 +1,24 @@ -// Copyright (C) 2016 The V8 Project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. +// Test generated by: property-test-generator /*--- esid: sec-number.prototype -description: > - "prototype" property of Number +description: Property test for Number.prototype info: | Number.prototype + - The initial value of `Number.prototype` is the Number prototype object. + - This property has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: false }. - This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, - [[Configurable]]: false }. + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +flags: [generated] includes: [propertyHelper.js] ---*/ -verifyProperty(Number, "prototype", { +verifyPrimordialProperty(Number, "prototype", { writable: false, enumerable: false, configurable: false, diff --git a/test/built-ins/Number/prototype/proto.js b/test/built-ins/Number/prototype/proto.js new file mode 100644 index 00000000000..bd822c3b978 --- /dev/null +++ b/test/built-ins/Number/prototype/proto.js @@ -0,0 +1,26 @@ +// Test generated by: property-test-generator + +/*--- +esid: sec-properties-of-the-number-prototype-object +description: Property test for Number.prototype +info: | + Properties of the Number Prototype Object + - is %Number.prototype%. + - is an ordinary object. + - is itself a Number object; it has a [[NumberData]] internal slot with the + value +0𝔽. + - has a [[Prototype]] internal slot whose value is %Object.prototype%. + + Unless specified otherwise, the [[Extensible]] internal slot of a built-in object + initially has the value true. + + Unless otherwise specified every built-in prototype object has the Object prototype + object, which is the initial value of the expression Object.prototype (20.1.3), + as the value of its [[Prototype]] internal slot, except the Object prototype object + itself. +flags: [generated] +---*/ + +assert.sameValue(Object.getPrototypeOf(Number.prototype), Object.prototype); +assert.sameValue(Object.isExtensible(Number.prototype), true); +assert.sameValue(typeof Number.prototype, "object"); diff --git a/test/built-ins/Number/prototype/toExponential/length.js b/test/built-ins/Number/prototype/toExponential/length.js deleted file mode 100644 index b38e7b94a8c..00000000000 --- a/test/built-ins/Number/prototype/toExponential/length.js +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2015 André Bargull. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es6id: 20.1.3.2 -description: > - Number.prototype.toExponential.length is 1. -info: | - Number.prototype.toExponential ( fractionDigits ) - - 17 ECMAScript Standard Built-in Objects: - Every built-in Function object, including constructors, 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 - subclause headings for the function description, including optional - parameters. However, rest parameters shown using the form “...name” - are not included in the default argument count. - - 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(Number.prototype.toExponential, "length", { - value: 1, - writable: false, - enumerable: false, - configurable: true -}); diff --git a/test/built-ins/Number/prototype/toExponential/name.js b/test/built-ins/Number/prototype/toExponential/name.js deleted file mode 100644 index 127c89adc77..00000000000 --- a/test/built-ins/Number/prototype/toExponential/name.js +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2015 André Bargull. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es6id: 20.1.3.2 -description: > - Number.prototype.toExponential.name is "toExponential". -info: | - Number.prototype.toExponential ( fractionDigits ) - - 17 ECMAScript Standard Built-in Objects: - Every built-in Function object, including constructors, that is not - identified as an anonymous function has a name property whose value - is a String. - - Unless otherwise specified, the name property of a built-in Function - object, if it exists, has the attributes { [[Writable]]: false, - [[Enumerable]]: false, [[Configurable]]: true }. -includes: [propertyHelper.js] ----*/ - -verifyProperty(Number.prototype.toExponential, "name", { - value: "toExponential", - writable: false, - enumerable: false, - configurable: true -}); diff --git a/test/built-ins/Number/prototype/toExponential/not-a-constructor.js b/test/built-ins/Number/prototype/toExponential/not-a-constructor.js deleted file mode 100644 index 56d6e83201d..00000000000 --- a/test/built-ins/Number/prototype/toExponential/not-a-constructor.js +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2020 Rick Waldron. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-ecmascript-standard-built-in-objects -description: > - Number.prototype.toExponential does not implement [[Construct]], is not new-able -info: | - ECMAScript Function Objects - - Built-in function objects that are not identified as constructors do not - implement the [[Construct]] internal method unless otherwise specified in - the description of a particular function. - - sec-evaluatenew - - ... - 7. If IsConstructor(constructor) is false, throw a TypeError exception. - ... -includes: [isConstructor.js] -features: [Reflect.construct, arrow-function] ----*/ - -assert.sameValue( - isConstructor(Number.prototype.toExponential), - false, - 'isConstructor(Number.prototype.toExponential) must return false' -); - -assert.throws(TypeError, () => { - new Number.prototype.toExponential(); -}); - diff --git a/test/built-ins/Number/prototype/toExponential/prop-desc.js b/test/built-ins/Number/prototype/toExponential/prop-desc.js index 0e3d29c6f1a..811459e59a1 100644 --- a/test/built-ins/Number/prototype/toExponential/prop-desc.js +++ b/test/built-ins/Number/prototype/toExponential/prop-desc.js @@ -1,18 +1,32 @@ -// Copyright (C) 2016 The V8 Project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. +// Test generated by: property-test-generator /*--- esid: sec-number.prototype.toexponential -description: > - "toExponential" property of Number.prototype +description: Property test for Number.prototype.toExponential info: | - ES6 section 17: 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] + Number.prototype.toExponential ( fractionDigits ) + - This method returns a String containing this Number value represented in + decimal exponential notation with one digit before the significand's + decimal point and fractionDigits digits after the significand's decimal + point. If fractionDigits is undefined, it includes as many significand + digits as necessary to uniquely specify the Number (just like in ToString + except that in this case the Number is always output in exponential + notation). + + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +flags: [generated] +includes: [builtin.js, propertyHelper.js] +features: [Proxy, Reflect, Reflect.construct] ---*/ -verifyProperty(Number.prototype, "toExponential", { +verifyBuiltinFunction(Number.prototype.toExponential, "toExponential", 1); + +verifyPrimordialProperty(Number.prototype, "toExponential", { + value: Number.prototype.toExponential, writable: true, enumerable: false, configurable: true, diff --git a/test/built-ins/Number/prototype/toFixed/S15.7.4.5_A2_T01.js b/test/built-ins/Number/prototype/toFixed/S15.7.4.5_A2_T01.js deleted file mode 100644 index d1421225ccf..00000000000 --- a/test/built-ins/Number/prototype/toFixed/S15.7.4.5_A2_T01.js +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2009 the Sputnik authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -info: The length property of the toFixed method is 1 -es5id: 15.7.4.5_A2_T01 -description: Checking Number prototype itself ----*/ -assert.sameValue( - Number.prototype.toFixed.hasOwnProperty("length"), - true, - 'Number.prototype.toFixed.hasOwnProperty("length") must return true' -); - -assert.sameValue( - Number.prototype.toFixed.length, - 1, - 'The value of Number.prototype.toFixed.length is expected to be 1' -); diff --git a/test/built-ins/Number/prototype/toFixed/length.js b/test/built-ins/Number/prototype/toFixed/length.js deleted file mode 100644 index 0ff44dc64a6..00000000000 --- a/test/built-ins/Number/prototype/toFixed/length.js +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2017 Michael "Z" Goddard. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-number.prototype.tofixed -description: > - Number.prototype.toFixed.length is 1. -info: | - Number.prototype.toFixed ( fractionDigits ) - - 17 ECMAScript Standard Built-in Objects: - Every built-in Function object, including constructors, 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 - subclause headings for the function description, including optional - parameters. However, rest parameters shown using the form “...name” - are not included in the default argument count. - - 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(Number.prototype.toFixed, "length", { - value: 1, - writable: false, - enumerable: false, - configurable: true -}); diff --git a/test/built-ins/Number/prototype/toFixed/name.js b/test/built-ins/Number/prototype/toFixed/name.js deleted file mode 100644 index 3eb7bd7b534..00000000000 --- a/test/built-ins/Number/prototype/toFixed/name.js +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2015 André Bargull. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es6id: 20.1.3.3 -description: > - Number.prototype.toFixed.name is "toFixed". -info: | - Number.prototype.toFixed ( fractionDigits ) - - 17 ECMAScript Standard Built-in Objects: - Every built-in Function object, including constructors, that is not - identified as an anonymous function has a name property whose value - is a String. - - Unless otherwise specified, the name property of a built-in Function - object, if it exists, has the attributes { [[Writable]]: false, - [[Enumerable]]: false, [[Configurable]]: true }. -includes: [propertyHelper.js] ----*/ - -verifyProperty(Number.prototype.toFixed, "name", { - value: "toFixed", - writable: false, - enumerable: false, - configurable: true -}); diff --git a/test/built-ins/Number/prototype/toFixed/not-a-constructor.js b/test/built-ins/Number/prototype/toFixed/not-a-constructor.js deleted file mode 100644 index 915a52fa168..00000000000 --- a/test/built-ins/Number/prototype/toFixed/not-a-constructor.js +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2020 Rick Waldron. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-ecmascript-standard-built-in-objects -description: > - Number.prototype.toFixed does not implement [[Construct]], is not new-able -info: | - ECMAScript Function Objects - - Built-in function objects that are not identified as constructors do not - implement the [[Construct]] internal method unless otherwise specified in - the description of a particular function. - - sec-evaluatenew - - ... - 7. If IsConstructor(constructor) is false, throw a TypeError exception. - ... -includes: [isConstructor.js] -features: [Reflect.construct, arrow-function] ----*/ - -assert.sameValue( - isConstructor(Number.prototype.toFixed), - false, - 'isConstructor(Number.prototype.toFixed) must return false' -); - -assert.throws(TypeError, () => { - new Number.prototype.toFixed(); -}); - diff --git a/test/built-ins/Number/prototype/toFixed/prop-desc.js b/test/built-ins/Number/prototype/toFixed/prop-desc.js index fd6ccb2c85f..a72bdbd3825 100644 --- a/test/built-ins/Number/prototype/toFixed/prop-desc.js +++ b/test/built-ins/Number/prototype/toFixed/prop-desc.js @@ -1,20 +1,25 @@ -// Copyright (C) 2016 The V8 Project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. +// Test generated by: property-test-generator /*--- esid: sec-number.prototype.tofixed -description: > - "toFixed" property of Number.prototype +description: Property test for Number.prototype.toFixed info: | - 17 ECMAScript Standard Built-in Objects: + Number.prototype.toFixed ( fractionDigits ) - Every other data property described in clauses 18 through 26 and in Annex B.2 + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true } unless otherwise specified. -includes: [propertyHelper.js] +flags: [generated] +includes: [builtin.js, propertyHelper.js] +features: [Proxy, Reflect, Reflect.construct] ---*/ -verifyProperty(Number.prototype, "toFixed", { +verifyBuiltinFunction(Number.prototype.toFixed, "toFixed", 1); + +verifyPrimordialProperty(Number.prototype, "toFixed", { + value: Number.prototype.toFixed, writable: true, enumerable: false, configurable: true, diff --git a/test/built-ins/Number/prototype/toLocaleString/length.js b/test/built-ins/Number/prototype/toLocaleString/length.js deleted file mode 100644 index a07cc5ef797..00000000000 --- a/test/built-ins/Number/prototype/toLocaleString/length.js +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2015 André Bargull. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es6id: 20.1.3.4 -description: > - Number.prototype.toLocaleString.length is 0. -info: | - Number.prototype.toLocaleString( [ reserved1 [ , reserved2 ] ]) - - 17 ECMAScript Standard Built-in Objects: - Every built-in Function object, including constructors, 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 - subclause headings for the function description, including optional - parameters. However, rest parameters shown using the form “...name” - are not included in the default argument count. - - 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(Number.prototype.toLocaleString, "length", { - value: 0, - writable: false, - enumerable: false, - configurable: true -}); diff --git a/test/built-ins/Number/prototype/toLocaleString/name.js b/test/built-ins/Number/prototype/toLocaleString/name.js deleted file mode 100644 index faa9fba00c8..00000000000 --- a/test/built-ins/Number/prototype/toLocaleString/name.js +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2015 André Bargull. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es6id: 20.1.3.4 -description: > - Number.prototype.toLocaleString.name is "toLocaleString". -info: | - Number.prototype.toLocaleString( [ reserved1 [ , reserved2 ] ]) - - 17 ECMAScript Standard Built-in Objects: - Every built-in Function object, including constructors, that is not - identified as an anonymous function has a name property whose value - is a String. - - Unless otherwise specified, the name property of a built-in Function - object, if it exists, has the attributes { [[Writable]]: false, - [[Enumerable]]: false, [[Configurable]]: true }. -includes: [propertyHelper.js] ----*/ - -verifyProperty(Number.prototype.toLocaleString, "name", { - value: "toLocaleString", - writable: false, - enumerable: false, - configurable: true -}); diff --git a/test/built-ins/Number/prototype/toLocaleString/not-a-constructor.js b/test/built-ins/Number/prototype/toLocaleString/not-a-constructor.js deleted file mode 100644 index cc998dfacd4..00000000000 --- a/test/built-ins/Number/prototype/toLocaleString/not-a-constructor.js +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2020 Rick Waldron. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-ecmascript-standard-built-in-objects -description: > - Number.prototype.toLocaleString does not implement [[Construct]], is not new-able -info: | - ECMAScript Function Objects - - Built-in function objects that are not identified as constructors do not - implement the [[Construct]] internal method unless otherwise specified in - the description of a particular function. - - sec-evaluatenew - - ... - 7. If IsConstructor(constructor) is false, throw a TypeError exception. - ... -includes: [isConstructor.js] -features: [Reflect.construct, arrow-function] ----*/ - -assert.sameValue( - isConstructor(Number.prototype.toLocaleString), - false, - 'isConstructor(Number.prototype.toLocaleString) must return false' -); - -assert.throws(TypeError, () => { - new Number.prototype.toLocaleString(); -}); - diff --git a/test/built-ins/Number/prototype/toLocaleString/prop-desc.js b/test/built-ins/Number/prototype/toLocaleString/prop-desc.js index c6bdba1374a..8ecb362f97b 100644 --- a/test/built-ins/Number/prototype/toLocaleString/prop-desc.js +++ b/test/built-ins/Number/prototype/toLocaleString/prop-desc.js @@ -1,20 +1,32 @@ -// Copyright (C) 2016 The V8 Project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. +// Test generated by: property-test-generator /*--- esid: sec-number.prototype.tolocalestring -description: > - "toLocaleString" property of Number.prototype +description: Property test for Number.prototype.toLocaleString info: | - 17 ECMAScript Standard Built-in Objects: + Number.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] ) + - This method produces a String value that represents this Number value + formatted according to the conventions of the host environment's current + locale. This method is implementation-defined, and it is permissible, but + not encouraged, for it to return the same thing as `toString`. + - The meanings of the optional parameters to this method are defined in the + ECMA-402 specification; implementations that do not include ECMA-402 + support must not use those parameter positions for anything else. - Every other data property described in clauses 18 through 26 and in Annex B.2 + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true } unless otherwise specified. -includes: [propertyHelper.js] +flags: [generated] +includes: [builtin.js, propertyHelper.js] +features: [Proxy, Reflect, Reflect.construct] ---*/ -verifyProperty(Number.prototype, "toLocaleString", { +verifyBuiltinFunction(Number.prototype.toLocaleString, "toLocaleString", 0); + +verifyPrimordialProperty(Number.prototype, "toLocaleString", { + value: Number.prototype.toLocaleString, writable: true, enumerable: false, configurable: true, diff --git a/test/built-ins/Number/prototype/toPrecision/length.js b/test/built-ins/Number/prototype/toPrecision/length.js deleted file mode 100644 index 240c1dd3606..00000000000 --- a/test/built-ins/Number/prototype/toPrecision/length.js +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2015 André Bargull. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es6id: 20.1.3.5 -description: > - Number.prototype.toPrecision.length is 1. -info: | - Number.prototype.toPrecision ( precision ) - - 17 ECMAScript Standard Built-in Objects: - Every built-in Function object, including constructors, 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 - subclause headings for the function description, including optional - parameters. However, rest parameters shown using the form “...name” - are not included in the default argument count. - - 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(Number.prototype.toPrecision, "length", { - value: 1, - writable: false, - enumerable: false, - configurable: true -}); diff --git a/test/built-ins/Number/prototype/toPrecision/name.js b/test/built-ins/Number/prototype/toPrecision/name.js deleted file mode 100644 index 22624249ba6..00000000000 --- a/test/built-ins/Number/prototype/toPrecision/name.js +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2015 André Bargull. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es6id: 20.1.3.5 -description: > - Number.prototype.toPrecision.name is "toPrecision". -info: | - Number.prototype.toPrecision ( precision ) - - 17 ECMAScript Standard Built-in Objects: - Every built-in Function object, including constructors, that is not - identified as an anonymous function has a name property whose value - is a String. - - Unless otherwise specified, the name property of a built-in Function - object, if it exists, has the attributes { [[Writable]]: false, - [[Enumerable]]: false, [[Configurable]]: true }. -includes: [propertyHelper.js] ----*/ - -verifyProperty(Number.prototype.toPrecision, "name", { - value: "toPrecision", - writable: false, - enumerable: false, - configurable: true -}); diff --git a/test/built-ins/Number/prototype/toPrecision/not-a-constructor.js b/test/built-ins/Number/prototype/toPrecision/not-a-constructor.js deleted file mode 100644 index aad7f5ff75f..00000000000 --- a/test/built-ins/Number/prototype/toPrecision/not-a-constructor.js +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2020 Rick Waldron. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-ecmascript-standard-built-in-objects -description: > - Number.prototype.toPrecision does not implement [[Construct]], is not new-able -info: | - ECMAScript Function Objects - - Built-in function objects that are not identified as constructors do not - implement the [[Construct]] internal method unless otherwise specified in - the description of a particular function. - - sec-evaluatenew - - ... - 7. If IsConstructor(constructor) is false, throw a TypeError exception. - ... -includes: [isConstructor.js] -features: [Reflect.construct, arrow-function] ----*/ - -assert.sameValue( - isConstructor(Number.prototype.toPrecision), - false, - 'isConstructor(Number.prototype.toPrecision) must return false' -); - -assert.throws(TypeError, () => { - new Number.prototype.toPrecision(); -}); - diff --git a/test/built-ins/Number/prototype/toPrecision/prop-desc.js b/test/built-ins/Number/prototype/toPrecision/prop-desc.js index feae3df0ac9..279501bf220 100644 --- a/test/built-ins/Number/prototype/toPrecision/prop-desc.js +++ b/test/built-ins/Number/prototype/toPrecision/prop-desc.js @@ -1,18 +1,30 @@ -// Copyright (C) 2016 The V8 Project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. +// Test generated by: property-test-generator /*--- esid: sec-number.prototype.toprecision -description: > - "toPrecision" property of Number.prototype +description: Property test for Number.prototype.toPrecision info: | - ES6 section 17: 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] + Number.prototype.toPrecision ( precision ) + - This method returns a String containing this Number value represented either + in decimal exponential notation with one digit before the significand's + decimal point and precision - 1 digits after the significand's decimal + point or in decimal fixed notation with precision significant digits. If + precision is undefined, it calls ToString instead. + + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +flags: [generated] +includes: [builtin.js, propertyHelper.js] +features: [Proxy, Reflect, Reflect.construct] ---*/ -verifyProperty(Number.prototype, "toPrecision", { +verifyBuiltinFunction(Number.prototype.toPrecision, "toPrecision", 1); + +verifyPrimordialProperty(Number.prototype, "toPrecision", { + value: Number.prototype.toPrecision, writable: true, enumerable: false, configurable: true, diff --git a/test/built-ins/Number/prototype/toString/length.js b/test/built-ins/Number/prototype/toString/length.js deleted file mode 100644 index c21a5a717fa..00000000000 --- a/test/built-ins/Number/prototype/toString/length.js +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2015 André Bargull. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es6id: 20.1.3.6 -description: > - Number.prototype.toString.length is 1. -info: | - Number.prototype.toString ( [ radix ] ) - - 17 ECMAScript Standard Built-in Objects: - Every built-in Function object, including constructors, 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 - subclause headings for the function description, including optional - parameters. However, rest parameters shown using the form “...name” - are not included in the default argument count. - - 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(Number.prototype.toString, "length", { - value: 1, - writable: false, - enumerable: false, - configurable: true -}); diff --git a/test/built-ins/Number/prototype/toString/name.js b/test/built-ins/Number/prototype/toString/name.js deleted file mode 100644 index aa72ee558cc..00000000000 --- a/test/built-ins/Number/prototype/toString/name.js +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2015 André Bargull. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es6id: 20.1.3.6 -description: > - Number.prototype.toString.name is "toString". -info: | - Number.prototype.toString ( [ radix ] ) - - 17 ECMAScript Standard Built-in Objects: - Every built-in Function object, including constructors, that is not - identified as an anonymous function has a name property whose value - is a String. - - Unless otherwise specified, the name property of a built-in Function - object, if it exists, has the attributes { [[Writable]]: false, - [[Enumerable]]: false, [[Configurable]]: true }. -includes: [propertyHelper.js] ----*/ - -verifyProperty(Number.prototype.toString, "name", { - value: "toString", - writable: false, - enumerable: false, - configurable: true -}); diff --git a/test/built-ins/Number/prototype/toString/not-a-constructor.js b/test/built-ins/Number/prototype/toString/not-a-constructor.js deleted file mode 100644 index 2312bc09aa9..00000000000 --- a/test/built-ins/Number/prototype/toString/not-a-constructor.js +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2020 Rick Waldron. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-ecmascript-standard-built-in-objects -description: > - Number.prototype.toString does not implement [[Construct]], is not new-able -info: | - ECMAScript Function Objects - - Built-in function objects that are not identified as constructors do not - implement the [[Construct]] internal method unless otherwise specified in - the description of a particular function. - - sec-evaluatenew - - ... - 7. If IsConstructor(constructor) is false, throw a TypeError exception. - ... -includes: [isConstructor.js] -features: [Reflect.construct, arrow-function] ----*/ - -assert.sameValue( - isConstructor(Number.prototype.toString), - false, - 'isConstructor(Number.prototype.toString) must return false' -); - -assert.throws(TypeError, () => { - new Number.prototype.toString(); -}); - diff --git a/test/built-ins/Number/prototype/toString/prop-desc.js b/test/built-ins/Number/prototype/toString/prop-desc.js index ea1955ee221..d00f32db7f5 100644 --- a/test/built-ins/Number/prototype/toString/prop-desc.js +++ b/test/built-ins/Number/prototype/toString/prop-desc.js @@ -1,20 +1,29 @@ -// Copyright (C) 2016 The V8 Project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. +// Test generated by: property-test-generator /*--- esid: sec-number.prototype.tostring -description: > - "toString" property of Number.prototype +description: Property test for Number.prototype.toString info: | - 17 ECMAScript Standard Built-in Objects: + Number.prototype.toString ( [ radix ] ) + - This method is not generic; it throws a TypeError exception if its this + value is not a Number or a Number object. Therefore, it cannot be + transferred to other kinds of objects for use as a method. + - The "length" property of this method is 1𝔽. - Every other data property described in clauses 18 through 26 and in Annex B.2 + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true } unless otherwise specified. -includes: [propertyHelper.js] +flags: [generated] +includes: [builtin.js, propertyHelper.js] +features: [Proxy, Reflect, Reflect.construct] ---*/ -verifyProperty(Number.prototype, "toString", { +verifyBuiltinFunction(Number.prototype.toString, "toString", 1); + +verifyPrimordialProperty(Number.prototype, "toString", { + value: Number.prototype.toString, writable: true, enumerable: false, configurable: true, diff --git a/test/built-ins/Number/prototype/valueOf/length.js b/test/built-ins/Number/prototype/valueOf/length.js deleted file mode 100644 index d126b874186..00000000000 --- a/test/built-ins/Number/prototype/valueOf/length.js +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2015 André Bargull. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es6id: 20.1.3.7 -description: > - Number.prototype.valueOf.length is 0. -info: | - Number.prototype.valueOf ( ) - - 17 ECMAScript Standard Built-in Objects: - Every built-in Function object, including constructors, 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 - subclause headings for the function description, including optional - parameters. However, rest parameters shown using the form “...name” - are not included in the default argument count. - - 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(Number.prototype.valueOf, "length", { - value: 0, - writable: false, - enumerable: false, - configurable: true -}); diff --git a/test/built-ins/Number/prototype/valueOf/name.js b/test/built-ins/Number/prototype/valueOf/name.js deleted file mode 100644 index 7d9c9a1824e..00000000000 --- a/test/built-ins/Number/prototype/valueOf/name.js +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2015 André Bargull. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -es6id: 20.1.3.7 -description: > - Number.prototype.valueOf.name is "valueOf". -info: | - Number.prototype.valueOf ( ) - - 17 ECMAScript Standard Built-in Objects: - Every built-in Function object, including constructors, that is not - identified as an anonymous function has a name property whose value - is a String. - - Unless otherwise specified, the name property of a built-in Function - object, if it exists, has the attributes { [[Writable]]: false, - [[Enumerable]]: false, [[Configurable]]: true }. -includes: [propertyHelper.js] ----*/ - -verifyProperty(Number.prototype.valueOf, "name", { - value: "valueOf", - writable: false, - enumerable: false, - configurable: true -}); diff --git a/test/built-ins/Number/prototype/valueOf/not-a-constructor.js b/test/built-ins/Number/prototype/valueOf/not-a-constructor.js deleted file mode 100644 index 017f3fdc5cc..00000000000 --- a/test/built-ins/Number/prototype/valueOf/not-a-constructor.js +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2020 Rick Waldron. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sec-ecmascript-standard-built-in-objects -description: > - Number.prototype.valueOf does not implement [[Construct]], is not new-able -info: | - ECMAScript Function Objects - - Built-in function objects that are not identified as constructors do not - implement the [[Construct]] internal method unless otherwise specified in - the description of a particular function. - - sec-evaluatenew - - ... - 7. If IsConstructor(constructor) is false, throw a TypeError exception. - ... -includes: [isConstructor.js] -features: [Reflect.construct, arrow-function] ----*/ - -assert.sameValue( - isConstructor(Number.prototype.valueOf), - false, - 'isConstructor(Number.prototype.valueOf) must return false' -); - -assert.throws(TypeError, () => { - new Number.prototype.valueOf(); -}); - diff --git a/test/built-ins/Number/prototype/valueOf/prop-desc.js b/test/built-ins/Number/prototype/valueOf/prop-desc.js index 1695175ff0f..623dea82320 100644 --- a/test/built-ins/Number/prototype/valueOf/prop-desc.js +++ b/test/built-ins/Number/prototype/valueOf/prop-desc.js @@ -1,20 +1,25 @@ -// Copyright (C) 2016 The V8 Project authors. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. +// Test generated by: property-test-generator /*--- esid: sec-number.prototype.valueof -description: > - "valueOf" property of Number.prototype +description: Property test for Number.prototype.valueOf info: | - 17 ECMAScript Standard Built-in Objects: + Number.prototype.valueOf ( ) - Every other data property described in clauses 18 through 26 and in Annex B.2 + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true } unless otherwise specified. -includes: [propertyHelper.js] +flags: [generated] +includes: [builtin.js, propertyHelper.js] +features: [Proxy, Reflect, Reflect.construct] ---*/ -verifyProperty(Number.prototype, "valueOf", { +verifyBuiltinFunction(Number.prototype.valueOf, "valueOf", 0); + +verifyPrimordialProperty(Number.prototype, "valueOf", { + value: Number.prototype.valueOf, writable: true, enumerable: false, configurable: true, diff --git a/test/built-ins/Uint8Array/fromBase64/descriptor.js b/test/built-ins/Uint8Array/fromBase64/descriptor.js deleted file mode 100644 index a39b51cd82e..00000000000 --- a/test/built-ins/Uint8Array/fromBase64/descriptor.js +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (C) 2024 Kevin Gibbons. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-uint8array.frombase64 -description: > - Uint8Array.fromBase64 has default data property attributes. -includes: [propertyHelper.js] -features: [uint8array-base64, TypedArray] ----*/ - -verifyProperty(Uint8Array, 'fromBase64', { - enumerable: false, - writable: true, - configurable: true -}); diff --git a/test/built-ins/Uint8Array/fromBase64/length.js b/test/built-ins/Uint8Array/fromBase64/length.js deleted file mode 100644 index d251d7754f2..00000000000 --- a/test/built-ins/Uint8Array/fromBase64/length.js +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (C) 2024 Kevin Gibbons. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-uint8array.frombase64 -description: > - Uint8Array.fromBase64.length is 1. -includes: [propertyHelper.js] -features: [uint8array-base64, TypedArray] ----*/ - -verifyProperty(Uint8Array.fromBase64, 'length', { - value: 1, - enumerable: false, - writable: false, - configurable: true -}); diff --git a/test/built-ins/Uint8Array/fromBase64/name.js b/test/built-ins/Uint8Array/fromBase64/name.js deleted file mode 100644 index 71ed9a3b7d0..00000000000 --- a/test/built-ins/Uint8Array/fromBase64/name.js +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (C) 2024 Kevin Gibbons. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-uint8array.frombase64 -description: > - Uint8Array.fromBase64.name is "fromBase64". -includes: [propertyHelper.js] -features: [uint8array-base64, TypedArray] ----*/ - -verifyProperty(Uint8Array.fromBase64, 'name', { - value: 'fromBase64', - enumerable: false, - writable: false, - configurable: true -}); diff --git a/test/built-ins/Uint8Array/fromBase64/nonconstructor.js b/test/built-ins/Uint8Array/fromBase64/nonconstructor.js deleted file mode 100644 index 469e00400fa..00000000000 --- a/test/built-ins/Uint8Array/fromBase64/nonconstructor.js +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (C) 2024 Kevin Gibbons. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-uint8array.frombase64 -description: > - Uint8Array.fromBase64 is not a constructor function. -includes: [isConstructor.js] -features: [uint8array-base64, TypedArray, Reflect.construct] ----*/ - -assert(!isConstructor(Uint8Array.fromBase64), "Uint8Array.fromBase64 is not a constructor"); - -assert.throws(TypeError, function() { - new Uint8Array.fromBase64(''); -}); diff --git a/test/built-ins/Uint8Array/fromBase64/prop-desc.js b/test/built-ins/Uint8Array/fromBase64/prop-desc.js new file mode 100644 index 00000000000..56fe9debc31 --- /dev/null +++ b/test/built-ins/Uint8Array/fromBase64/prop-desc.js @@ -0,0 +1,26 @@ +// Test generated by: property-test-generator + +/*--- +esid: sec-uint8array.frombase64 +description: Property test for Uint8Array.fromBase64 +info: | + Uint8Array.fromBase64 ( string [ , options ] ) + + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +flags: [generated] +includes: [builtin.js, propertyHelper.js] +features: [Proxy, Reflect, Reflect.construct, TypedArray, uint8array-base64] +---*/ + +verifyBuiltinFunction(Uint8Array.fromBase64, "fromBase64", 1); + +verifyPrimordialProperty(Uint8Array, "fromBase64", { + value: Uint8Array.fromBase64, + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/test/built-ins/Uint8Array/fromHex/descriptor.js b/test/built-ins/Uint8Array/fromHex/descriptor.js deleted file mode 100644 index 44fdd904e17..00000000000 --- a/test/built-ins/Uint8Array/fromHex/descriptor.js +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (C) 2024 Kevin Gibbons. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-uint8array.fromhex -description: > - Uint8Array.fromHex has default data property attributes. -includes: [propertyHelper.js] -features: [uint8array-base64, TypedArray] ----*/ - -verifyProperty(Uint8Array, 'fromHex', { - enumerable: false, - writable: true, - configurable: true -}); diff --git a/test/built-ins/Uint8Array/fromHex/length.js b/test/built-ins/Uint8Array/fromHex/length.js deleted file mode 100644 index 0f52a22f3e8..00000000000 --- a/test/built-ins/Uint8Array/fromHex/length.js +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (C) 2024 Kevin Gibbons. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-uint8array.fromhex -description: > - Uint8Array.fromHex.length is 1. -includes: [propertyHelper.js] -features: [uint8array-base64, TypedArray] ----*/ - -verifyProperty(Uint8Array.fromHex, 'length', { - value: 1, - enumerable: false, - writable: false, - configurable: true -}); diff --git a/test/built-ins/Uint8Array/fromHex/name.js b/test/built-ins/Uint8Array/fromHex/name.js deleted file mode 100644 index 6397c3bd33c..00000000000 --- a/test/built-ins/Uint8Array/fromHex/name.js +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (C) 2024 Kevin Gibbons. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-uint8array.fromhex -description: > - Uint8Array.fromHex.name is "fromHex". -includes: [propertyHelper.js] -features: [uint8array-base64, TypedArray] ----*/ - -verifyProperty(Uint8Array.fromHex, 'name', { - value: 'fromHex', - enumerable: false, - writable: false, - configurable: true -}); diff --git a/test/built-ins/Uint8Array/fromHex/nonconstructor.js b/test/built-ins/Uint8Array/fromHex/nonconstructor.js deleted file mode 100644 index ca3b52a834e..00000000000 --- a/test/built-ins/Uint8Array/fromHex/nonconstructor.js +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (C) 2024 Kevin Gibbons. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-uint8array.fromhex -description: > - Uint8Array.fromHex is not a constructor function. -includes: [isConstructor.js] -features: [uint8array-base64, TypedArray, Reflect.construct] ----*/ - -assert(!isConstructor(Uint8Array.fromHex), "Uint8Array.fromHex is not a constructor"); - -assert.throws(TypeError, function() { - new Uint8Array.fromHex(''); -}); diff --git a/test/built-ins/Uint8Array/fromHex/prop-desc.js b/test/built-ins/Uint8Array/fromHex/prop-desc.js new file mode 100644 index 00000000000..b9e5adf2290 --- /dev/null +++ b/test/built-ins/Uint8Array/fromHex/prop-desc.js @@ -0,0 +1,26 @@ +// Test generated by: property-test-generator + +/*--- +esid: sec-uint8array.fromhex +description: Property test for Uint8Array.fromHex +info: | + Uint8Array.fromHex ( string ) + + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +flags: [generated] +includes: [builtin.js, propertyHelper.js] +features: [Proxy, Reflect, Reflect.construct, TypedArray, uint8array-base64] +---*/ + +verifyBuiltinFunction(Uint8Array.fromHex, "fromHex", 1); + +verifyPrimordialProperty(Uint8Array, "fromHex", { + value: Uint8Array.fromHex, + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/test/built-ins/Uint8Array/prototype/setFromBase64/descriptor.js b/test/built-ins/Uint8Array/prototype/setFromBase64/descriptor.js deleted file mode 100644 index 3bfc1a4ecda..00000000000 --- a/test/built-ins/Uint8Array/prototype/setFromBase64/descriptor.js +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (C) 2024 Kevin Gibbons. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-uint8array.prototype.setfrombase64 -description: > - Uint8Array.prototype.setFromBase64 has default data property attributes. -includes: [propertyHelper.js] -features: [uint8array-base64, TypedArray] ----*/ - -verifyProperty(Uint8Array.prototype, 'setFromBase64', { - enumerable: false, - writable: true, - configurable: true -}); diff --git a/test/built-ins/Uint8Array/prototype/setFromBase64/length.js b/test/built-ins/Uint8Array/prototype/setFromBase64/length.js deleted file mode 100644 index 23fe10c3526..00000000000 --- a/test/built-ins/Uint8Array/prototype/setFromBase64/length.js +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (C) 2024 Kevin Gibbons. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-uint8array.prototype.setfrombase64 -description: > - Uint8Array.prototype.setFromBase64.length is 1. -includes: [propertyHelper.js] -features: [uint8array-base64, TypedArray] ----*/ - -verifyProperty(Uint8Array.prototype.setFromBase64, 'length', { - value: 1, - enumerable: false, - writable: false, - configurable: true -}); diff --git a/test/built-ins/Uint8Array/prototype/setFromBase64/name.js b/test/built-ins/Uint8Array/prototype/setFromBase64/name.js deleted file mode 100644 index a80e8ffb3ff..00000000000 --- a/test/built-ins/Uint8Array/prototype/setFromBase64/name.js +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (C) 2024 Kevin Gibbons. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-uint8array.prototype.setfrombase64 -description: > - Uint8Array.prototype.setFromBase64.name is "setFromBase64". -includes: [propertyHelper.js] -features: [uint8array-base64, TypedArray] ----*/ - -verifyProperty(Uint8Array.prototype.setFromBase64, 'name', { - value: 'setFromBase64', - enumerable: false, - writable: false, - configurable: true -}); diff --git a/test/built-ins/Uint8Array/prototype/setFromBase64/nonconstructor.js b/test/built-ins/Uint8Array/prototype/setFromBase64/nonconstructor.js deleted file mode 100644 index e2344f2d26a..00000000000 --- a/test/built-ins/Uint8Array/prototype/setFromBase64/nonconstructor.js +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (C) 2024 Kevin Gibbons. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-uint8array.prototype.setfrombase64 -description: > - Uint8Array.prototype.setFromBase64 is not a constructor function. -includes: [isConstructor.js] -features: [uint8array-base64, TypedArray, Reflect.construct] ----*/ - -assert(!isConstructor(Uint8Array.prototype.setFromBase64), "Uint8Array.prototype.setFromBase64 is not a constructor"); - -assert.throws(TypeError, function() { - var target = new Uint8Array(10); - new target.setFromBase64(''); -}); diff --git a/test/built-ins/Uint8Array/prototype/setFromBase64/prop-desc.js b/test/built-ins/Uint8Array/prototype/setFromBase64/prop-desc.js new file mode 100644 index 00000000000..ed8922ce780 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromBase64/prop-desc.js @@ -0,0 +1,26 @@ +// Test generated by: property-test-generator + +/*--- +esid: sec-uint8array.prototype.setfrombase64 +description: Property test for Uint8Array.prototype.setFromBase64 +info: | + Uint8Array.prototype.setFromBase64 ( string [ , options ] ) + + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +flags: [generated] +includes: [builtin.js, propertyHelper.js] +features: [Proxy, Reflect, Reflect.construct, TypedArray, uint8array-base64] +---*/ + +verifyBuiltinFunction(Uint8Array.prototype.setFromBase64, "setFromBase64", 1); + +verifyPrimordialProperty(Uint8Array.prototype, "setFromBase64", { + value: Uint8Array.prototype.setFromBase64, + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/test/built-ins/Uint8Array/prototype/setFromHex/descriptor.js b/test/built-ins/Uint8Array/prototype/setFromHex/descriptor.js deleted file mode 100644 index 8d5e4f3321e..00000000000 --- a/test/built-ins/Uint8Array/prototype/setFromHex/descriptor.js +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (C) 2024 Kevin Gibbons. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-uint8array.prototype.setfromhex -description: > - Uint8Array.prototype.setFromHex has default data property attributes. -includes: [propertyHelper.js] -features: [uint8array-base64, TypedArray] ----*/ - -verifyProperty(Uint8Array.prototype, 'setFromHex', { - enumerable: false, - writable: true, - configurable: true -}); diff --git a/test/built-ins/Uint8Array/prototype/setFromHex/length.js b/test/built-ins/Uint8Array/prototype/setFromHex/length.js deleted file mode 100644 index 479d0f12d8b..00000000000 --- a/test/built-ins/Uint8Array/prototype/setFromHex/length.js +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (C) 2024 Kevin Gibbons. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-uint8array.prototype.setfromhex -description: > - Uint8Array.prototype.setFromHex.length is 1. -includes: [propertyHelper.js] -features: [uint8array-base64, TypedArray] ----*/ - -verifyProperty(Uint8Array.prototype.setFromHex, 'length', { - value: 1, - enumerable: false, - writable: false, - configurable: true -}); diff --git a/test/built-ins/Uint8Array/prototype/setFromHex/name.js b/test/built-ins/Uint8Array/prototype/setFromHex/name.js deleted file mode 100644 index 9967d38ee2e..00000000000 --- a/test/built-ins/Uint8Array/prototype/setFromHex/name.js +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (C) 2024 Kevin Gibbons. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-uint8array.prototype.setfromhex -description: > - Uint8Array.prototype.setFromHex.name is "setFromHex". -includes: [propertyHelper.js] -features: [uint8array-base64, TypedArray] ----*/ - -verifyProperty(Uint8Array.prototype.setFromHex, 'name', { - value: 'setFromHex', - enumerable: false, - writable: false, - configurable: true -}); diff --git a/test/built-ins/Uint8Array/prototype/setFromHex/nonconstructor.js b/test/built-ins/Uint8Array/prototype/setFromHex/nonconstructor.js deleted file mode 100644 index 4af13303912..00000000000 --- a/test/built-ins/Uint8Array/prototype/setFromHex/nonconstructor.js +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (C) 2024 Kevin Gibbons. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-uint8array.prototype.setfromhex -description: > - Uint8Array.prototype.setFromHex is not a constructor function. -includes: [isConstructor.js] -features: [uint8array-base64, TypedArray, Reflect.construct] ----*/ - -assert(!isConstructor(Uint8Array.prototype.setFromHex), "target.setFromHex is not a constructor"); - -assert.throws(TypeError, function() { - var target = new Uint8Array(10); - new target.setFromHex(''); -}); diff --git a/test/built-ins/Uint8Array/prototype/setFromHex/prop-desc.js b/test/built-ins/Uint8Array/prototype/setFromHex/prop-desc.js new file mode 100644 index 00000000000..f2da9a13dde --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/setFromHex/prop-desc.js @@ -0,0 +1,26 @@ +// Test generated by: property-test-generator + +/*--- +esid: sec-uint8array.prototype.setfromhex +description: Property test for Uint8Array.prototype.setFromHex +info: | + Uint8Array.prototype.setFromHex ( string ) + + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +flags: [generated] +includes: [builtin.js, propertyHelper.js] +features: [Proxy, Reflect, Reflect.construct, TypedArray, uint8array-base64] +---*/ + +verifyBuiltinFunction(Uint8Array.prototype.setFromHex, "setFromHex", 1); + +verifyPrimordialProperty(Uint8Array.prototype, "setFromHex", { + value: Uint8Array.prototype.setFromHex, + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/test/built-ins/Uint8Array/prototype/toBase64/descriptor.js b/test/built-ins/Uint8Array/prototype/toBase64/descriptor.js deleted file mode 100644 index 52ba4ecad15..00000000000 --- a/test/built-ins/Uint8Array/prototype/toBase64/descriptor.js +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (C) 2024 Kevin Gibbons. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-uint8array.prototype.tobase64 -description: > - Uint8Array.prototype.toBase64 has default data property attributes. -includes: [propertyHelper.js] -features: [uint8array-base64, TypedArray] ----*/ - -verifyProperty(Uint8Array.prototype, 'toBase64', { - enumerable: false, - writable: true, - configurable: true -}); diff --git a/test/built-ins/Uint8Array/prototype/toBase64/length.js b/test/built-ins/Uint8Array/prototype/toBase64/length.js deleted file mode 100644 index 8f08a291567..00000000000 --- a/test/built-ins/Uint8Array/prototype/toBase64/length.js +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (C) 2024 Kevin Gibbons. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-uint8array.prototype.tobase64 -description: > - Uint8Array.prototype.toBase64.length is 0. -includes: [propertyHelper.js] -features: [uint8array-base64, TypedArray] ----*/ - -verifyProperty(Uint8Array.prototype.toBase64, 'length', { - value: 0, - enumerable: false, - writable: false, - configurable: true -}); diff --git a/test/built-ins/Uint8Array/prototype/toBase64/name.js b/test/built-ins/Uint8Array/prototype/toBase64/name.js deleted file mode 100644 index 71cd95403c3..00000000000 --- a/test/built-ins/Uint8Array/prototype/toBase64/name.js +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (C) 2024 Kevin Gibbons. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-uint8array.prototype.tobase64 -description: > - Uint8Array.prototype.toBase64.name is "toBase64". -includes: [propertyHelper.js] -features: [uint8array-base64, TypedArray] ----*/ - -verifyProperty(Uint8Array.prototype.toBase64, 'name', { - value: 'toBase64', - enumerable: false, - writable: false, - configurable: true -}); diff --git a/test/built-ins/Uint8Array/prototype/toBase64/nonconstructor.js b/test/built-ins/Uint8Array/prototype/toBase64/nonconstructor.js deleted file mode 100644 index 9b07eb26604..00000000000 --- a/test/built-ins/Uint8Array/prototype/toBase64/nonconstructor.js +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (C) 2024 Kevin Gibbons. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-uint8array.prototype.tobase64 -description: > - Uint8Array.prototype.toBase64 is not a constructor function. -includes: [isConstructor.js] -features: [uint8array-base64, TypedArray, Reflect.construct] ----*/ - -assert(!isConstructor(Uint8Array.prototype.toBase64), "Uint8Array.prototype.toBase64 is not a constructor"); - -var uint8Array = new Uint8Array(8); -assert.throws(TypeError, function() { - new uint8Array.toBase64(); -}); diff --git a/test/built-ins/Uint8Array/prototype/toBase64/prop-desc.js b/test/built-ins/Uint8Array/prototype/toBase64/prop-desc.js new file mode 100644 index 00000000000..8b9493c9a52 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/toBase64/prop-desc.js @@ -0,0 +1,26 @@ +// Test generated by: property-test-generator + +/*--- +esid: sec-uint8array.prototype.tobase64 +description: Property test for Uint8Array.prototype.toBase64 +info: | + Uint8Array.prototype.toBase64 ( [ options ] ) + + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +flags: [generated] +includes: [builtin.js, propertyHelper.js] +features: [Proxy, Reflect, Reflect.construct, TypedArray, uint8array-base64] +---*/ + +verifyBuiltinFunction(Uint8Array.prototype.toBase64, "toBase64", 0); + +verifyPrimordialProperty(Uint8Array.prototype, "toBase64", { + value: Uint8Array.prototype.toBase64, + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/test/built-ins/Uint8Array/prototype/toHex/descriptor.js b/test/built-ins/Uint8Array/prototype/toHex/descriptor.js deleted file mode 100644 index c70b782539c..00000000000 --- a/test/built-ins/Uint8Array/prototype/toHex/descriptor.js +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (C) 2024 Kevin Gibbons. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-uint8array.prototype.tohex -description: > - Uint8Array.prototype.toHex has default data property attributes. -includes: [propertyHelper.js] -features: [uint8array-base64, TypedArray] ----*/ - -verifyProperty(Uint8Array.prototype, 'toHex', { - enumerable: false, - writable: true, - configurable: true -}); diff --git a/test/built-ins/Uint8Array/prototype/toHex/length.js b/test/built-ins/Uint8Array/prototype/toHex/length.js deleted file mode 100644 index 6bc061be014..00000000000 --- a/test/built-ins/Uint8Array/prototype/toHex/length.js +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (C) 2024 Kevin Gibbons. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-uint8array.prototype.tohex -description: > - Uint8Array.prototype.toHex.length is 0. -includes: [propertyHelper.js] -features: [uint8array-base64, TypedArray] ----*/ - -verifyProperty(Uint8Array.prototype.toHex, 'length', { - value: 0, - enumerable: false, - writable: false, - configurable: true -}); diff --git a/test/built-ins/Uint8Array/prototype/toHex/name.js b/test/built-ins/Uint8Array/prototype/toHex/name.js deleted file mode 100644 index 8cfa9528730..00000000000 --- a/test/built-ins/Uint8Array/prototype/toHex/name.js +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (C) 2024 Kevin Gibbons. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-uint8array.prototype.tohex -description: > - Uint8Array.prototype.toHex.name is "toHex". -includes: [propertyHelper.js] -features: [uint8array-base64, TypedArray] ----*/ - -verifyProperty(Uint8Array.prototype.toHex, 'name', { - value: 'toHex', - enumerable: false, - writable: false, - configurable: true -}); diff --git a/test/built-ins/Uint8Array/prototype/toHex/nonconstructor.js b/test/built-ins/Uint8Array/prototype/toHex/nonconstructor.js deleted file mode 100644 index bb3d9e155ad..00000000000 --- a/test/built-ins/Uint8Array/prototype/toHex/nonconstructor.js +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (C) 2024 Kevin Gibbons. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. -/*--- -esid: sec-uint8array.prototype.tohex -description: > - Uint8Array.prototype.toHex is not a constructor function. -includes: [isConstructor.js] -features: [uint8array-base64, TypedArray, Reflect.construct] ----*/ - -assert(!isConstructor(Uint8Array.prototype.toHex), "Uint8Array.prototype.toHex is not a constructor"); - -var uint8Array = new Uint8Array(8); -assert.throws(TypeError, function() { - new uint8Array.toHex(); -}); diff --git a/test/built-ins/Uint8Array/prototype/toHex/prop-desc.js b/test/built-ins/Uint8Array/prototype/toHex/prop-desc.js new file mode 100644 index 00000000000..6bb0d130019 --- /dev/null +++ b/test/built-ins/Uint8Array/prototype/toHex/prop-desc.js @@ -0,0 +1,26 @@ +// Test generated by: property-test-generator + +/*--- +esid: sec-uint8array.prototype.tohex +description: Property test for Uint8Array.prototype.toHex +info: | + Uint8Array.prototype.toHex ( ) + + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +flags: [generated] +includes: [builtin.js, propertyHelper.js] +features: [Proxy, Reflect, Reflect.construct, TypedArray, uint8array-base64] +---*/ + +verifyBuiltinFunction(Uint8Array.prototype.toHex, "toHex", 0); + +verifyPrimordialProperty(Uint8Array.prototype, "toHex", { + value: Uint8Array.prototype.toHex, + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/test/harness/builtin-constructor.js b/test/harness/builtin-constructor.js new file mode 100644 index 00000000000..8479c4fa5c3 --- /dev/null +++ b/test/harness/builtin-constructor.js @@ -0,0 +1,34 @@ +// Copyright (C) 2025 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + verifyBuiltinConstructor verifies built-in constructor function objects. +includes: [builtin.js, propertyHelper.js] +features: [Proxy, Reflect, Reflect.construct] +---*/ + +assert.sameValue(typeof verifyBuiltinConstructor, "function"); + +assert.throws(Test262Error, () => verifyBuiltinConstructor(), "no argument"); +assert.throws(Test262Error, () => verifyBuiltinConstructor(undefined), "undefined"); +assert.throws(Test262Error, () => verifyBuiltinConstructor(null), "null"); +assert.throws(Test262Error, () => verifyBuiltinConstructor(123), "number"); +assert.throws(Test262Error, () => verifyBuiltinConstructor(true), "boolean - true"); +assert.throws(Test262Error, () => verifyBuiltinConstructor(false), "boolean - false"); +assert.throws(Test262Error, () => verifyBuiltinConstructor("string"), "string"); + +assert.throws(Test262Error, () => verifyBuiltinConstructor({}), "Object instance"); +assert.throws(Test262Error, () => verifyBuiltinConstructor([]), "Array instance"); + +verifyBuiltinConstructor(Array, "Array", 1); +assert.throws( + Test262Error, + () => verifyBuiltinConstructor(Array.prototype.join, "join", 1), + "Array.prototype.join" +); +assert.throws( + Test262Error, + () => verifyBuiltinConstructor(Array.prototype[Symbol.iterator], "values", 0), + "Array.prototype[Symbol.iterator]" +); diff --git a/test/harness/builtin-function.js b/test/harness/builtin-function.js new file mode 100644 index 00000000000..e5254acbbb7 --- /dev/null +++ b/test/harness/builtin-function.js @@ -0,0 +1,30 @@ +// Copyright (C) 2025 André Bargull. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: > + verifyBuiltinFunction verifies built-in function objects. +includes: [builtin.js, propertyHelper.js] +features: [Proxy, Reflect, Reflect.construct] +---*/ + +assert.sameValue(typeof verifyBuiltinFunction, "function"); + +assert.throws(Test262Error, () => verifyBuiltinFunction(), "no argument"); +assert.throws(Test262Error, () => verifyBuiltinFunction(undefined), "undefined"); +assert.throws(Test262Error, () => verifyBuiltinFunction(null), "null"); +assert.throws(Test262Error, () => verifyBuiltinFunction(123), "number"); +assert.throws(Test262Error, () => verifyBuiltinFunction(true), "boolean - true"); +assert.throws(Test262Error, () => verifyBuiltinFunction(false), "boolean - false"); +assert.throws(Test262Error, () => verifyBuiltinFunction("string"), "string"); + +assert.throws(Test262Error, () => verifyBuiltinFunction({}), "Object instance"); +assert.throws(Test262Error, () => verifyBuiltinFunction([]), "Array instance"); + +assert.throws( + Test262Error, + () => verifyBuiltinFunction(Array, "Array", 1), + "Array constructor" +); +verifyBuiltinFunction(Array.prototype.join, "join", 1); +verifyBuiltinFunction(Array.prototype[Symbol.iterator], "values", 0); diff --git a/test/intl402/Number/prototype/toLocaleString/builtin.js b/test/intl402/Number/prototype/toLocaleString/builtin.js deleted file mode 100644 index 1475b376312..00000000000 --- a/test/intl402/Number/prototype/toLocaleString/builtin.js +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2012 Mozilla Corporation. All rights reserved. -// This code is governed by the license found in the LICENSE file. - -/*--- -es5id: 13.2.1_L15 -description: > - Tests that Number.prototype.toLocaleString meets the requirements - for built-in objects defined by the introduction of chapter 17 of - the ECMAScript Language Specification. -author: Norbert Lindenberg -includes: [isConstructor.js] -features: [Reflect.construct] ----*/ - -assert.sameValue(Object.prototype.toString.call(Number.prototype.toLocaleString), "[object Function]", - "The [[Class]] internal property of a built-in function must be " + - "\"Function\"."); - -assert(Object.isExtensible(Number.prototype.toLocaleString), - "Built-in objects must be extensible."); - -assert.sameValue(Object.getPrototypeOf(Number.prototype.toLocaleString), Function.prototype); - -assert.sameValue(Number.prototype.toLocaleString.hasOwnProperty("prototype"), false, - "Built-in functions that aren't constructors must not have a prototype property."); - -assert.sameValue(isConstructor(Number.prototype.toLocaleString), false, - "Built-in functions don't implement [[Construct]] unless explicitly specified."); diff --git a/test/intl402/Number/prototype/toLocaleString/length.js b/test/intl402/Number/prototype/toLocaleString/length.js deleted file mode 100644 index 48571eaaa60..00000000000 --- a/test/intl402/Number/prototype/toLocaleString/length.js +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (C) 2017 André Bargull. All rights reserved. -// This code is governed by the BSD license found in the LICENSE file. - -/*--- -esid: sup-number.prototype.tolocalestring -description: > - Number.prototype.toLocaleString.length is 0. -info: | - Number.prototype.toLocaleString ( [ locales [ , options ] ] ) - - 17 ECMAScript Standard Built-in Objects: - - Every built-in function object, including constructors, 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 - subclause headings for the function description. Optional parameters - (which are indicated with brackets: [ ]) or rest parameters (which - are shown using the form «...name») are not included in the default - argument count. - 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(Number.prototype.toLocaleString, 'length', { - value: 0, - writable: false, - enumerable: false, - configurable: true -}); diff --git a/test/intl402/Number/prototype/toLocaleString/prop-desc.js b/test/intl402/Number/prototype/toLocaleString/prop-desc.js new file mode 100644 index 00000000000..a1ec0a4003f --- /dev/null +++ b/test/intl402/Number/prototype/toLocaleString/prop-desc.js @@ -0,0 +1,27 @@ +// Test generated by: property-test-generator + +/*--- +esid: sup-number.prototype.tolocalestring +description: Property test for Number.prototype.toLocaleString +info: | + Number.prototype.toLocaleString ( [ locales [ , options ] ] ) + - This definition supersedes the definition provided in ECMA-262, . + + ECMAScript Standard Built-in Objects + + Every other data property described in clauses 19 through 28 and in Annex B.2 + has the attributes { [[Writable]]: true, [[Enumerable]]: false, + [[Configurable]]: true } unless otherwise specified. +flags: [generated] +includes: [builtin.js, propertyHelper.js] +features: [Proxy, Reflect, Reflect.construct] +---*/ + +verifyBuiltinFunction(Number.prototype.toLocaleString, "toLocaleString", 0); + +verifyPrimordialProperty(Number.prototype, "toLocaleString", { + value: Number.prototype.toLocaleString, + writable: true, + enumerable: false, + configurable: true, +}); diff --git a/tools/generation/generator.py b/tools/generation/generator.py index 030a9491ff2..4c8ff9efb79 100755 --- a/tools/generation/generator.py +++ b/tools/generation/generator.py @@ -17,6 +17,12 @@ def print_error(*values): print('ERROR:', *values, file=sys.stderr) +# Return true if `test` is a generated file from this generator. +def is_generated_from_template(test): + # Test must be marked as generated and include references to "case" and + # "template" files. + return test.is_generated() and ".case" in test.source and ".template" in test.source + # When a directory contains at least one file with a `.case` extension, it # should be interpreted as a "case directory" def is_case_dir(location): @@ -44,7 +50,7 @@ def clean(args): continue test = Test(fileName) test.load() - if test.is_generated(): + if is_generated_from_template(test): print('Deleting file "' + fileName + '"...') os.remove(fileName) @@ -71,7 +77,7 @@ def create(args): existing = Test(test_file) existing.load() - if not existing.is_generated(): + if not is_generated_from_template(existing): print_error( 'Refusing to overwrite non-generated file: ' + test.file_name) diff --git a/tools/property-test-generator/README.md b/tools/property-test-generator/README.md new file mode 100644 index 00000000000..42618aeefbb --- /dev/null +++ b/tools/property-test-generator/README.md @@ -0,0 +1,43 @@ +# Property Test Generator + +This tool generates standard property tests for built-in functions and objects. + +Supported options: + +- `--dry-run`: Don't write any output files. +- `--include`: Comma separated list of globs to filter which built-ins are included. +- `--exclude`: Comma separated list of globs to filter which built-ins are excluded. +- `--features`: Comma separated list of features from "features.txt". If not specified features are guessed based on files in the same directory. +- `--globals`: Spec files or directories defining additional global properties. Needed when generating tests for ECMA-402 or for proposals. + +Run with `--help` to show all available command line arguments: + +```sh +$ python tools/property-test-generator/main.py --help +``` + +Examples: + +- Generate property tests for all built-ins defined in "$ECMA262/spec.html": +```sh +$ python tools/property-test-generator/main.py $ECMA262/spec.html +``` + +- Generate property tests for the `Number` constructor, but not the `Number` prototype object: +```sh +$ python tools/property-test-generator/main.py --include=Number* --exclude=Number.prototype* $ECMA262/spec.html +``` + +- Generate property tests for all built-ins defined in "$ECMA402/spec": +```sh +python tools/property-test-generator/main.py --global=$ECMA262/spec.html $ECMA402/spec/ +``` + +The `--global` argument is necessary to correctly pick up global definitions from ECMA-262. + +- Generate property tests for all built-ins defined in the `Temporal` proposal: +```sh +python tools/property-test-generator/main.py --globals=$ECMA262/spec.html --globals=$ECMA402/spec/ --features=Temporal $PROPOSALS/proposal-temporal/spec/ +``` + +The `--features` argument adds `features: [Temporal]` to test metadata section. diff --git a/tools/property-test-generator/__init__.py b/tools/property-test-generator/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tools/property-test-generator/clause.py b/tools/property-test-generator/clause.py new file mode 100644 index 00000000000..932e129e975 --- /dev/null +++ b/tools/property-test-generator/clause.py @@ -0,0 +1,722 @@ +# Copyright (C) 2025 André Bargull. All rights reserved. +# This code is governed by the BSD license found in the LICENSE file. + +import logging +import re + +from idreference import IdReference as IdRef +from value import Value + +logger = logging.getLogger("test262." + __name__) + + +class Clause: + """Represents an or definition.""" + + def __init__(self, parent, elem): + self.parent = parent + self.elem = elem + self.subclauses = [] + if parent: + parent.subclauses.append(self) + + def __repr__(self): + return f"id={self.id()} (header={self.header()})" + + def id(self): + """Return the 'id' attribute of this clause.""" + return self.elem.find_attribute("id") + + def header(self): + """Return text content of this clauses' header.""" + h1 = next(self.elem.find_elements("h1"), None) + return h1.text_content() if h1 else "" + + def property_list(self): + return ( + li.normalized_text_content() + for ul in self.elem.find_elements("ul") + for li in ul.find_elements("li") + ) + + def property_paragraphs(self): + return (p.normalized_text_content() for p in self.elem.find_elements("p")) + + def is_operation(self): + """Return true if this clause is an abstract operation, sdo, etc.""" + # "abstract operation" in type or + # "sdo" in type or + # "concrete method" in type or + # "implementation-defined" in type or + # "host-defined" in type or + # "internal method" in type or + # "numeric method" in type + if self.elem.find_attribute("type") is not None: + return True + if self.elem.find_attribute("aoid") is not None: + return True + for p in self.elem.find_elements("p"): + if "concrete method" in p.text: + return True + return False + + def is_grammar(self): + """Return true if this clause is part of the grammar section.""" + return next(self.elem.find_elements("emu-grammar"), None) is not None + + def is_accessible(self): + """Return true if the current definition describes an accessible value.""" + for attr in self.property_list(): + if "is never directly accessible to ECMAScript code" in attr: + return False + return True + + re_target_name = re.compile( + r"(?:The\s+)?(?P[\w%\.]+?)\s*(?:\(.+?\))?(\s+Intrinsic)?(?:\s+(?:Object|Constructor)s?)?(\s+Structure)?" + ) + + def target_name(self): + """Short descriptive name of a clause.""" + if m := Clause.re_target_name.fullmatch(self.header()): + return m.group("name") + + def is_link(self): + """Return true if this clause is a link.""" + p = list(self.elem.find_elements("p")) + return len(p) == 1 and p[0].text.startswith("See") + + def is_annex_b(self): + """Return true if this clause is for Annex-B.""" + return self.elem.tag == "emu-annex" + + def is_optional(self): + """Return true if this clause describes an optional property.""" + return self.elem.has_attribute("normative-optional") + + def is_legacy(self): + """Return true if this clause describes a legacy property.""" + return self.elem.has_attribute("legacy") + + def is_override(self): + """Return true if this clause describes an override property.""" + for p in self.property_paragraphs(): + if p.startswith("This definition supersedes the definition provided in"): + return True + return False + + def is_properties(self): + """Return true if this clause is a 'Properties' definition clause.""" + return "Properties of the" in self.header() + + def property_clauses(self): + """Return all 'Property' definition sub-clauses.""" + return (sub for sub in self.subclauses if sub.is_properties()) + + def has_properties(self): + """Return true if this clause has any 'Property' definition sub-clauses.""" + return next(self.property_clauses(), None) is not None + + re_constructor = re.compile( + r"The\s+(?P.+?)\s+(Constructor|Constructors|Intrinsic Object)" + ) + + def is_constructor(self): + """Return true if this clause is a 'Constructor' definition clause.""" + return Clause.re_constructor.fullmatch(self.header()) is not None + + def constructor_clauses(self): + """Return all 'Constructor' definition sub-clauses.""" + return (sub for sub in self.subclauses if sub.is_constructor()) + + def has_constructor(self): + """Return true if this clause has any 'Constructor' definition sub-clauses.""" + return next(self.constructor_clauses(), None) is not None + + re_prototype = re.compile( + r"Properties of the\s+(?P.+?)\s+Prototype (Object|Objects)" + ) + + re_intrinsic_prototype = re.compile( + r"The\s+(?=%\w+Prototype%)(?P.+?)\s+Object" + ) + + def is_prototype(self): + """Return true if this clause is a 'Prototype' definition clause.""" + return ( + Clause.re_prototype.fullmatch(self.header()) is not None + or Clause.re_intrinsic_prototype.fullmatch(self.header()) is not None + ) + + def prototype_clauses(self): + """Return all 'Prototype' definition sub-clauses.""" + return (sub for sub in self.subclauses if sub.is_prototype()) + + def has_prototype(self): + """Return true if this clause has any 'Prototype' definition sub-clauses.""" + return next(self.prototype_clauses(), None) is not None + + re_object = re.compile(r"The\s+(?P.+?)\s+Object") + + def is_object(self): + """Return true if this clause is an 'Object' definition clause.""" + return ( + Clause.re_object.fullmatch(self.header()) is not None + and not self.is_constructor() + and not self.is_prototype() + ) + + def kind(self): + """Return the declaration kind of the current clause.""" + (kind, _, _) = self.declaration() + return kind + + def is_value(self): + """Return true if the current clause is a value definition.""" + return self.kind() == "value" + + def is_function(self): + """Return true if the current clause is a function definition.""" + return self.kind() == "function" + + def is_accessor(self): + """Return true if the current clause is an accessor definition.""" + return self.kind() == "accessor" + + def value_clauses(self): + """Return all value definition sub-clauses.""" + if self.is_grammar(): + return iter(()) + return (sub for sub in self.subclauses if sub.is_value()) + + def function_clauses(self): + """Return all function definition sub-clauses.""" + if self.is_grammar(): + return iter(()) + return (sub for sub in self.subclauses if sub.is_function()) + + def accessor_clauses(self): + """Return all accessor definition sub-clauses.""" + if self.is_grammar(): + return iter(()) + return (sub for sub in self.subclauses if sub.is_accessor()) + + def has_values(self): + """Return true if this clause has any value definition sub-clauses.""" + return next(self.value_clauses(), None) is not None + + def has_functions(self): + """Return true if this clause has any function definition sub-clauses.""" + return next(self.function_clauses(), None) is not None + + def has_accessors(self): + """Return true if this clause has any accessor definition sub-clauses.""" + return next(self.accessor_clauses(), None) is not None + + re_declaration = re.compile( + r"(?P(?:get|set)(?=\s))?(?P[\w%\.\[\]\s]+)(?P\(.*?\))?" + ) + + def declaration(self): + """Return the declaration kind of the current clause.""" + + # Ignore abstract operations or grammar clauses. + if self.is_operation() or self.is_grammar(): + return (None, None, None) + + m = Clause.re_declaration.fullmatch(self.header()) + if not m: + return (None, None, None) + + idref = IdRef.try_from(m.group("id")) + if idref is None: + return (None, None, None) + + params = m.group("params") + if params: + return ("function", idref, params[1:-1]) + + accessor_kind = m.group("accessor") + if m.group("accessor"): + return ("accessor", idref, accessor_kind) + + # Accessor declaration can match the value syntax. + for p in self.property_paragraphs(): + if "is an accessor property" in p: + return ("accessor", idref, None) + + # Value declaration must contain an initial value. + for p in self.property_paragraphs(): + if "value of" in p or "value for" in p: + return ("value", idref, None) + + # Value-typed links don't need an initial value. + if self.is_link(): + return ("value", idref, None) + + logger.debug(f"not a declaration: {self}") + return (None, None, None) + + def default_name_and_length(self): + """Return the default 'name' and 'length' property values of a function declaration.""" + (kind, idref, params) = self.declaration() + assert kind == "function" + + # https://tc39.es/ecma262/#sec-ecmascript-standard-built-in-objects + # + # Every built-in function object, including constructors, has a "name" property whose value is a String. Unless otherwise specified, this value is the name that is given to the function in this specification. + # For functions that are specified as properties of objects, the name value is the property name string used to access the function. + + # Last identifier part is the default name. + name = idref.to_function_name() + + # https://tc39.es/ecma262/#sec-ecmascript-standard-built-in-objects + # + # Every built-in function object, including constructors, has a "length" property whose value is a non-negative integral Number. Unless otherwise specified, this value is the number of required parameters shown in the subclause heading for the function description. Optional parameters and rest parameters are not included in the parameter count. + + # Remove optional and rest parameters + (params, _, _) = params.partition("[") + (params, _, _) = params.partition("...") + + # Split at "," and then count any non-empty string names. + length = len([k for k in params.split(",") if k.strip()]) + + return (idref, name, length) + + re_length_property = re.compile( + r'has a \*"length"\* property whose value is \*(?P\d+)\*𝔽?\.' + ) + re_name_property = re.compile( + r'has a \*"name"\* property whose value is \*"(?P.+?)"\*\.' + ) + re_prototype_internal_slot = re.compile( + r"has a \[\[Prototype\]\] internal slot whose value is (?:the intrinsic object )?(?P.+?)\." + ) + + @staticmethod + def prototype_internal_slot(text): + if m := Clause.re_prototype_internal_slot.fullmatch(text): + prototype = m.group("prototype") + if prototype == "*null*": + return Value.null() + return Value.intrinsic(prototype) + return None + + def constructor_function(self): + """Return the constructor function declaration in a 'Constructor' clause.""" + assert self.is_constructor() + return next(self.function_clauses(), None) + + def constructor_property_clause(self): + """Return the 'Property' definition clause for a 'Constructor' clause.""" + assert self.is_constructor() + + def is_constructor_clause(p): + return p.header().endswith( + ("Constructor", "Constructors", "Intrinsic Object") + ) + + # Find the first constructor property clause after |self|. + return next( + ( + p + for p in self.parent.property_clauses() + if is_constructor_clause(p) and p.elem > self.elem + ), + None, + ) + + def constructor_properties(self): + """Return a tuple describing this constructor function. Or None if no constructor function was found.""" + assert self.is_constructor() + + # Get the constructor function definition. + ctor_fun = self.constructor_function() + + # Return if no function definition was found. (This case can happen for + # proposal specs.) + if not ctor_fun: + return None + + prototype = None + (idref, name, length) = ctor_fun.default_name_and_length() + + # If constructor properties are present, check for relevant definitions. + if ctor_props := self.constructor_property_clause(): + for attr in ctor_props.property_list(): + if m := Clause.re_length_property.fullmatch(attr): + length = m.group("length") + elif m := Clause.re_name_property.fullmatch(attr): + name = m.group("name") + elif p := Clause.prototype_internal_slot(attr): + prototype = p + + # Check for "length" and "name" definitions at the constructor function. + for p in ctor_fun.property_paragraphs(): + if m := Clause.re_method_length.fullmatch(p): + length = m.group("length") + elif m := Clause.re_method_name.fullmatch(p): + name = m.group("name") + + return (idref, prototype, name, length) + + def prototype_id(self): + """Return the id-reference of this prototype clause.""" + assert self.is_prototype() + if m := Clause.re_prototype.fullmatch(self.header()): + return IdRef(m.group("name") + ".prototype") + if m := Clause.re_intrinsic_prototype.fullmatch(self.header()): + return IdRef(m.group("name")) + return None + + def prototype_properties(self): + """Return a tuple describing this prototype object.""" + assert self.is_prototype() + + # Ignore prototype clauses which aren't prototype definitions. + if ( + next(self.property_list(), None) is None + and next(self.property_paragraphs(), None) is None + ): + return None + + idref = self.prototype_id() + prototype = Value.intrinsic("Object.prototype") + is_callable = False + + for attr in self.property_list(): + if p := Clause.prototype_internal_slot(attr): + prototype = p + elif attr.startswith( + "is itself a built-in function object" + ) or attr.startswith("has a [[Call]] internal method"): + is_callable = True + + return (idref, prototype, is_callable) + + def object_id(self): + """Return the id-reference of this object clause.""" + assert self.is_object() + if m := Clause.re_object.fullmatch(self.header()): + name = m.group("name") + + # Use lowercase "global" to match existing tests. + if name == "Global": + name = "global" + + return IdRef(name) + return None + + def object_properties(self): + """Return a tuple describing this object definition.""" + assert self.is_object() + + # Ignore object clauses which aren't object definitions. + if ( + next(self.property_list(), None) is None + and next(self.property_paragraphs(), None) is None + ): + return None + + idref = self.object_id() + prototype = Value.intrinsic("Object.prototype") + + for attr in self.property_list(): + if attr.startswith( + "has a [[Prototype]] internal slot whose value is host-defined" + ): + prototype = None + elif p := Clause.prototype_internal_slot(attr): + prototype = p + else: + pass + + return (idref, prototype) + + re_method_name = re.compile( + r'The (?:initial )?value of the \*"name"\* property of this (?:method|function) is \*"(?P.+?)"\*\.' + ) + re_method_length = re.compile( + r'The \*"length"\* property of this (?:method|function) is \*(?P\d+)\*𝔽?\.' + ) + re_anonymous_function = re.compile(r"is an anonymous built-in function") + re_alias = re.compile( + r"The initial value of the (?P[\w\.%\"\*]+) property is (?P%[\w\.]+%)" + ) + re_property_attributes = re.compile( + r"This property has the attributes \{(?P.+?)\}\." + ) + + @staticmethod + def property_attributes(text): + """Generator function yielding property attributes from |text|.""" + m = Clause.re_property_attributes.search(text) + if m: + for attr in m.group("attributes").split(","): + (key, value) = attr.split(":") + + key = key.strip() + assert key.startswith("[[") and key.endswith("]]") + + key = key[2:-2] + assert key in ("Writable", "Enumerable", "Configurable") + + value = value.strip() + assert value in ("*false*", "*true*") + + yield (key, value == "*true*") + + def function_properties(self): + """Return a tuple describing this built-in function.""" + assert self.is_function() + + (idref, name, length) = self.default_name_and_length() + alias = None + + # + # + # Default attributes for data properties. + attributes = {"Writable": True, "Enumerable": False, "Configurable": True} + + has_explicit_name = False + + for p in self.property_paragraphs(): + if m := Clause.re_method_length.fullmatch(p): + length = m.group("length") + elif m := Clause.re_method_name.fullmatch(p): + name = m.group("name") + has_explicit_name = True + + if m := Clause.re_alias.match(p): + alias = IdRef(m.group("alias")) + + # + # + # Functions that are identified as anonymous functions use the empty String as the value of the "name" property. + if Clause.re_anonymous_function.search(p): + name = "" + has_explicit_name = True + + attributes.update(Clause.property_attributes(p)) + + if alias: + name = None + length = None + + # + # + # The value of the "name" property is explicitly specified for each built-in functions whose property key is a Symbol value. + if not alias and not has_explicit_name and idref.is_symbol_property_key(): + logger.warning( + f"Missing explicit function name for symbol-valued property: {idref.to_get()}" + ) + + return (idref, name, length, attributes, alias) + + def default_accessor_name(self): + """Return the default 'name' and 'length' property values of an accessor declaration.""" + (kind, idref, accessor_kind) = self.declaration() + assert kind == "accessor" + assert accessor_kind in ("get", "set"), accessor_kind + + # https://tc39.es/ecma262/#sec-ecmascript-standard-built-in-objects + # + # Every built-in function object, including constructors, has a "name" property whose value is a String. Unless otherwise specified, this value is the name that is given to the function in this specification. + # For functions that are specified as properties of objects, the name value is the property name string used to access the function. + # Functions that are specified as get or set accessor functions of built-in properties have "get" or "set" (respectively) passed to the prefix parameter when calling CreateBuiltinFunction. + + # Last identifier part is the default name + name = idref.to_function_name() + + return (idref, accessor_kind, f"{accessor_kind} {name}") + + re_getter_or_setter_undefined = re.compile( + r"is an accessor property whose (?Pset|get) accessor function is \*undefined\*" + ) + re_getter_or_setter_clause = re.compile( + r"The value of the \[\[(?PGet|Set)\]\] attribute" + ) + + def accessor_name(self, expected_kind): + """Return the 'name' property of an accessor function.""" + (idref, kind, name) = self.default_accessor_name() + assert kind == expected_kind + + has_explicit_name = False + + for p in self.property_paragraphs(): + if m := Clause.re_method_name.fullmatch(p): + name = m.group("name") + has_explicit_name = True + elif Clause.re_anonymous_function.search(p): + name = "" + + # + # + # The value of the "name" property is explicitly specified for each built-in functions whose property key is a Symbol value. + if not has_explicit_name and idref.is_symbol_property_key(): + logger.warning( + f"Missing explicit function name for symbol-valued property: {idref.to_get()}" + ) + + return name + + re_accessor_name = re.compile(r"(?Pget|set)\s+(?P[\w\.%\[\]\s]+)") + + def accessor_properties(self): + """Return a tuple describing this built-in accessor.""" + assert self.is_accessor() + + # + # + # Default attributes for accessor properties. + attributes = {"Enumerable": False, "Configurable": True} + + missing_accessor = None + + for p in self.property_paragraphs(): + if m := Clause.re_getter_or_setter_undefined.search(p): + missing_accessor = m.group("name") + + attributes.update(Clause.property_attributes(p)) + assert "Writable" not in attributes + + # + # + # If only a get accessor function is described, the set accessor function is the default value, undefined. If only a set accessor is described the get accessor is the default value, undefined. + get_clause = None + set_clause = None + + if missing_accessor is None: + idref = IdRef(self.header()) + + for clause in self.subclauses: + for p in clause.property_paragraphs(): + if m := Clause.re_getter_or_setter_clause.match(p): + if m.group("kind") == "Get": + get_clause = clause + else: + set_clause = clause + else: + m = Clause.re_accessor_name.fullmatch(self.header()) + assert m + idref = IdRef(m.group("id")) + + if missing_accessor == "set": + get_clause = self + else: + set_clause = self + + assert get_clause is not None or set_clause is not None + + if get_clause: + get_name = get_clause.accessor_name("get") + else: + get_name = None + + if set_clause: + set_name = set_clause.accessor_name("set") + else: + set_name = None + + return (idref, get_name, set_name, attributes) + + re_initial_string_typed_value = re.compile( + r"The (?:initial )?value of the [\w\.%`\*]+ property is the String value \*\"(?P.*?)\"\*\." + ) + re_initial_value_string = re.compile( + r"The (?:initial )?value of [\w\.%`\*]+ is \*\"(?P.*?)\"\*\." + ) + re_initial_value_empty_string = re.compile( + r"The (?:initial )?value of [\w\.%`\*]+ is the empty String\." + ) + re_initial_value_number = re.compile( + r"The (?:initial )?value of [\w\.%`\*]+ is \*(?P-∞|\+∞|NaN|-?\d+)\*𝔽?(?:\s*\(.*?\))?\." + ) + re_approx_number_value = re.compile( + r"The (?:initial|Number )?value (for|of) .*? is approximately (?P-?\d+(?:\.\d+)?(?:\s*×\s*10(?:-?\d+))?)\." + ) + re_initial_value_undefined = re.compile( + r"The (?:initial )?value of [\w\.%`\*]+ is \*(?Pundefined)\*(?:\s*\(.*?\))?\." + ) + re_initial_value_null = re.compile( + r"The (?:initial )?value of [\w\.%`\*]+ is \*(?Pnull)\*(?:\s*\(.*?\))?\." + ) + re_initial_value_intrinsic = re.compile( + r"The (?:initial )?value of [\w\.%`\*]+ is (?:the intrinsic object )?(?P%[\w\.]+%)\." + ) + re_initial_value_prototype_object = re.compile( + r"The (?:initial )?value of [\w\.%`\*]+ is the (?P[\w\.%]+) prototype object\." + ) + re_initial_value_well_known_symbol = re.compile( + r"The (?:initial )?value of [\w\.%`\*]+ is the well-known symbol (?P%[\w\.]+%) \(\)\." + ) + re_initial_value_well_known_symbol_old = re.compile( + r"The (?:initial )?value of [\w\.%`\*]+ is the well-known symbol (?P@@\w+) \(\)\." + ) + re_initial_value_link = re.compile(r"See \.") + re_initial_value_ieee_754_2019_double_precision = re.compile( + r"In the IEEE 754-2019 double precision binary representation.*" + ) + + @staticmethod + def value_property(text): + """Return a Value describing a value definition. Or None if not parsable.""" + matchers = [ + ("string", Clause.re_initial_string_typed_value), + ("string", Clause.re_initial_value_string), + ("string", Clause.re_initial_value_empty_string), + ("number", Clause.re_initial_value_number), + ("number", Clause.re_approx_number_value), + ("undefined", Clause.re_initial_value_undefined), + ("null", Clause.re_initial_value_null), + ("intrinsic", Clause.re_initial_value_intrinsic), + ("prototype", Clause.re_initial_value_prototype_object), + ("symbol", Clause.re_initial_value_well_known_symbol), + ("symbol", Clause.re_initial_value_well_known_symbol_old), + ("note", Clause.re_initial_value_link), + ("note", Clause.re_initial_value_ieee_754_2019_double_precision), + ] + + for kind, matcher in matchers: + if m := matcher.match(text): + if m.lastgroup: + assert m.lastgroup == "value" + return Value(kind, m.group("value")) + return Value(kind, "") + return None + + def value_properties(self): + """Return a tuple describing this value definition.""" + (kind, idref, _) = self.declaration() + assert kind == "value" + + # + # + # Default attributes for data properties. + attributes = {"Writable": True, "Enumerable": False, "Configurable": True} + + value = None + + for p in self.property_paragraphs(): + if v := Clause.value_property(p): + if v.kind != "note": + assert value is None, "unexpected duplicate value definition" + value = v + elif not p.startswith("This property has the attributes"): + if idref.is_template(): + # Template property values not yet supported. + pass + elif idref.to_get() in ( + "globalThis", + "Array.prototype[Symbol.unscopables]", + ): + # Property values which require special processing. + pass + else: + logger.warn( + f"Unsupported property value definition for {idref.to_get()}: {p}" + ) + + attributes.update(Clause.property_attributes(p)) + + return (idref, value, attributes) diff --git a/tools/property-test-generator/config.py b/tools/property-test-generator/config.py new file mode 100644 index 00000000000..d2609c9188b --- /dev/null +++ b/tools/property-test-generator/config.py @@ -0,0 +1,96 @@ +# Copyright (C) 2025 André Bargull. All rights reserved. +# This code is governed by the BSD license found in the LICENSE file. + +import fnmatch +import logging +import os +import re + +import yaml + +logger = logging.getLogger("test262." + __name__) + + +def load_test262parser(test262_dir): + """ + Loads the test262 test record parser. + """ + import importlib.machinery + import importlib.util + + packaging_dir = os.path.join(test262_dir, "tools", "packaging") + module_name = "parseTestRecord" + + # Create a FileFinder to load Python source files. + loader_details = ( + importlib.machinery.SourceFileLoader, + importlib.machinery.SOURCE_SUFFIXES, + ) + finder = importlib.machinery.FileFinder(packaging_dir, loader_details) + + # Find the module spec. + spec = finder.find_spec(module_name) + if spec is None: + raise RuntimeError("Can't find parseTestRecord module") + + # Create and execute the module. + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + + # Return the executed module + return module + + +def load_harness_features(test262_dir): + """ + Load the "harness/features.yml" file. + """ + with open( + os.path.join(test262_dir, "harness", "features.yml"), + encoding="utf-8", + ) as f: + return yaml.safe_load(f) + + +class Config: + def __init__(self): + self.re_include_matchers = None + self.re_exclude_matchers = None + + dir_path = os.path.dirname(__file__) + assert dir_path.split(os.sep)[-2:] == ["tools", "property-test-generator"] + + self.test262_dir = os.path.normpath(os.path.join(dir_path, "..", "..")) + assert os.path.isdir(self.test262_dir) + + self.test262parser = load_test262parser(self.test262_dir) + self.harness_features = load_harness_features(self.test262_dir) + + def include_matchers(self): + if self.include is not None and self.re_include_matchers is None: + self.re_include_matchers = [ + re.compile(fnmatch.translate(s)) for s in self.include.split(",") + ] + return self.re_include_matchers + + def exclude_matchers(self): + if self.exclude is not None and self.re_exclude_matchers is None: + self.re_exclude_matchers = [ + re.compile(fnmatch.translate(s)) for s in self.exclude.split(",") + ] + return self.re_exclude_matchers + + def is_included(self, test): + if matchers := self.include_matchers(): + k = test.idref.to_get() + return any(m.fullmatch(k) for m in matchers) + return True + + def is_excluded(self, test): + if matchers := self.exclude_matchers(): + k = test.idref.to_get() + return any(m.fullmatch(k) for m in matchers) + return False + + +cfg = Config() diff --git a/tools/property-test-generator/element.py b/tools/property-test-generator/element.py new file mode 100644 index 00000000000..30ae4f95a86 --- /dev/null +++ b/tools/property-test-generator/element.py @@ -0,0 +1,86 @@ +# Copyright (C) 2025 André Bargull. All rights reserved. +# This code is governed by the BSD license found in the LICENSE file. + +import logging + +logger = logging.getLogger("test262." + __name__) + + +class Element: + """HTML element node.""" + + def __init__(self, parent, tag, attrs, pos): + self.parent = parent + self.tag = tag + self.attrs = attrs + self.nodes = [] + self.elems = [] + self.text = "" + self.pos = pos + if parent: + parent.nodes.append(self) + parent.elems.append(self) + + def find_elements(self, tag): + """Return an iterator over all children with tag |tag|.""" + return (e for e in self.elems if e.tag == tag) + + def has_attribute(self, key): + """Return true if this element has an attribute named |key|.""" + return next((True for k, _ in self.attrs if k == key), False) + + def find_attribute(self, key): + """Return the value of the attribute named |key|. Or None if not found.""" + return next((v for k, v in self.attrs if k == key), None) + + def text_content(self): + """Return the text nodes of this elements and its descendants.""" + text = "" + for n in self.nodes: + if type(n) is str: + text += n + else: + text += n.text_content() + return text + + def normalized_text_content(self): + """Return the normalized text content with line breaks removed.""" + return " ".join( + line.strip() for line in self.text_content().splitlines() + ).strip() + + def __repr__(self): + text = self.text.strip() + if text: + return f"<{self.tag}>{text}@{self.pos}" + return f"<{self.tag}/>@{self.pos}" + + def __eq__(self, other): + if not isinstance(other, Element): + raise TypeError() + return self.pos == other.pos + + def __ne__(self, other): + if not isinstance(other, Element): + raise TypeError() + return self.pos != other.pos + + def __lt__(self, other): + if not isinstance(other, Element): + raise TypeError() + return self.pos < other.pos + + def __le__(self, other): + if not isinstance(other, Element): + raise TypeError() + return self.pos <= other.pos + + def __gt__(self, other): + if not isinstance(other, Element): + raise TypeError() + return self.pos > other.pos + + def __ge__(self, other): + if not isinstance(other, Element): + raise TypeError() + return self.pos >= other.pos diff --git a/tools/property-test-generator/generator.py b/tools/property-test-generator/generator.py new file mode 100644 index 00000000000..e2f5ea89a15 --- /dev/null +++ b/tools/property-test-generator/generator.py @@ -0,0 +1,624 @@ +# Copyright (C) 2025 André Bargull. All rights reserved. +# This code is governed by the BSD license found in the LICENSE file. + +import glob +import logging +import os +import re +import textwrap +from pathlib import Path + +from idreference import IdReference as IdRef +from template import NativeErrors, TypedArrayConstructors +from testfile import TestFile +from value import Value + +from config import cfg + +logger = logging.getLogger("test262." + __name__) + + +def recursive_properties_with_kind(target, kind): + """Yield all sub-clauses for |target| with declaration kind |kind|.""" + if target.is_grammar(): + return + if target.is_constructor(): + return + if not target.is_accessible(): + return + for sub in target.subclauses: + sub_kind = sub.kind() + if sub_kind == kind: + yield sub + elif sub_kind is None: + yield from recursive_properties_with_kind(sub, kind) + + +def expand_constructor_template(idref): + assert idref.is_template() + + if idref.template_name() == "_NativeError_": + for k in NativeErrors.keys(): + yield (idref.instantiate(k), k) + elif idref.template_name() == "_TypedArray_": + for k in TypedArrayConstructors.keys(): + yield (idref.instantiate(k), k) + else: + raise ValueError(f"Unexpected template type: {idref}") + + +def expand_prototype_template(idref): + assert idref.is_template() + + if idref.template_name() == "_NativeError_": + for k in NativeErrors.keys(): + yield idref.instantiate(k) + elif idref.template_name() == "_TypedArray_": + for k in TypedArrayConstructors.keys(): + yield idref.instantiate(k) + else: + raise ValueError(f"Unexpected template type: {idref}") + + +def expand_value_template(idref): + assert idref.is_template() + + key = idref.property_key() + + if idref.template_name() == "_NativeError_": + for k, p in NativeErrors.items(): + yield (idref.instantiate(k), Value(*p[key])) + elif idref.template_name() == "_TypedArray_": + for k, p in TypedArrayConstructors.items(): + yield (idref.instantiate(k), Value(*p[key])) + else: + raise ValueError(f"Unexpected template type: {idref}") + + +def expand_if_constructor_template(idref, name): + if not idref.is_template(): + yield (idref, name) + else: + yield from expand_constructor_template(idref) + + +def expand_if_prototype_template(idref): + if not idref.is_template(): + yield idref + else: + yield from expand_prototype_template(idref) + + +def expand_if_value_template(idref, value): + if not idref.is_template(): + yield (idref, value) + else: + yield from expand_value_template(idref) + + +re_var_with_markup = re.compile(r"\b_(\w+)_\b") + + +def remove_markup(text): + return re_var_with_markup.sub(r"\1", text.replace("*", "")) + + +ctor_info_text_wrapper = textwrap.TextWrapper(width=76, subsequent_indent=" " * 4) +info_text_wrapper = textwrap.TextWrapper(width=76, subsequent_indent=" " * 2) + + +def test_info_for_constructor(ctor): + test_info = f"""\ +{ctor.header()} + + {remove_markup(ctor.constructor_function().header())} +""" + + if ctor_prop_clause := ctor.constructor_property_clause(): + test_info += f""" + {ctor_prop_clause.header()}\ +""" + + for prop_text in ctor_prop_clause.property_list(): + # Skip over enumerations which don't get displayed anyway. + if prop_text.endswith(":"): + continue + + wrapped_text = ctor_info_text_wrapper.fill(remove_markup(prop_text)) + test_info += f""" + - {wrapped_text}\ +""" + + return test_info + + +def test_info_for_prototype(proto_clause, is_callable): + test_info = f"""\ +{proto_clause.header()} +""" + + for prop_text in proto_clause.property_list(): + # Skip over enumerations which don't get displayed anyway. + if prop_text.endswith(":"): + continue + + wrapped_text = info_text_wrapper.fill(remove_markup(prop_text)) + test_info += f"""\ +- {wrapped_text} +""" + + test_info += """ +Unless specified otherwise, the [[Extensible]] internal slot of a built-in object +initially has the value true. + +Unless otherwise specified every built-in prototype object has the Object prototype +object, which is the initial value of the expression Object.prototype (20.1.3), +as the value of its [[Prototype]] internal slot, except the Object prototype object +itself.\ +""" + + if is_callable: + test_info += """ + +Built-in function objects that are not identified as constructors do not implement +the [[Construct]] internal method unless otherwise specified in the description of +a particular function.\ +""" + + return test_info + + +def test_info_for_object(object_clause): + test_info = f"""\ +{object_clause.header()} +""" + + for prop_text in object_clause.property_list(): + # Skip over enumerations which don't get displayed anyway. + if prop_text.endswith(":"): + continue + + wrapped_text = info_text_wrapper.fill(remove_markup(prop_text)) + test_info += f"""\ +- {wrapped_text} +""" + + test_info += """ +Unless specified otherwise, the [[Extensible]] internal slot of a built-in object +initially has the value true. + +Unless otherwise specified every built-in prototype object has the Object prototype +object, which is the initial value of the expression Object.prototype (20.1.3), +as the value of its [[Prototype]] internal slot, except the Object prototype object +itself.\ +""" + + return test_info + + +def test_info_for_property_kind(clause): + test_info = f"""\ +{remove_markup(clause.header())} +""" + + if not clause.is_link(): + for prop_text in clause.property_paragraphs(): + # Skip over enumerations which don't get displayed anyway. + if prop_text.endswith(":"): + continue + + wrapped_text = info_text_wrapper.fill(remove_markup(prop_text)) + test_info += f"""\ +- {wrapped_text} +""" + + if not clause.is_accessor(): + test_info += """ +ECMAScript Standard Built-in Objects + +Every other data property described in clauses 19 through 28 and in Annex B.2 +has the attributes { [[Writable]]: true, [[Enumerable]]: false, +[[Configurable]]: true } unless otherwise specified.\ +""" + else: + test_info += """ +ECMAScript Standard Built-in Objects + +Every accessor property described in clauses 19 through 28 and in Annex B.2 has +the attributes { [[Enumerable]]: false, [[Configurable]]: true } unless +otherwise specified. If only a get accessor function is described, the set +accessor function is the default value, undefined. If only a set accessor is +described the get accessor is the default value, undefined.\ +""" + + return test_info + + +def make_constructor_test(target, global_props): + for ctor in target.constructor_clauses(): + ctor_props = ctor.constructor_properties() + if ctor_props is None: + continue + (idref, prototype, name, length) = ctor_props + from_template = idref.is_template() + + if prototype is not None: + prototype_name = prototype.to_script_value(global_props) + else: + prototype_name = "undefined" + + test_info = test_info_for_constructor(ctor) + + for idref, name in expand_if_constructor_template(idref, name): + var_name = idref.to_get(global_props) + + test_content = f"""\ +verifyBuiltinConstructor({var_name}, "{name}", {length}, {prototype_name}); +""" + + yield TestFile(ctor, idref, test_info, test_content, from_template) + + +def make_prototype_test(target, global_props): + if target.is_prototype(): + prototypes = [target] + else: + prototypes = target.prototype_clauses() + + for proto in prototypes: + proto_props = proto.prototype_properties() + if proto_props is None: + continue + (idref, prototype, is_callable) = proto_props + from_template = idref.is_template() + + # Ignore prototype clauses which contain overrides. There's already + # a prototype property test generated for the original definition. + if any(c.is_override() for c in proto.subclauses): + logger.debug(f"Skip prototype with overrides: {idref.to_get()}") + continue + + assert prototype is not None + prototype_name = prototype.to_script_value(global_props) + + test_info = test_info_for_prototype(proto, is_callable) + + for idref in expand_if_prototype_template(idref): + var_name = idref.to_get(global_props) + + test_content = "" + + if idref.has_intrinsic(global_props): + test_content += f"""\ +var proto = {var_name}; +""" + var_name = "proto" + + test_content += f"""\ +assert.sameValue(Object.getPrototypeOf({var_name}), {prototype_name}); +assert.sameValue(Object.isExtensible({var_name}), true); +""" + + if is_callable: + test_content += f"""\ +assert.sameValue(typeof {var_name}, "function"); +assert.sameValue(isConstructor({var_name}), false); +""" + else: + test_content += f"""\ +assert.sameValue(typeof {var_name}, "object"); +""" + + yield TestFile(proto, idref, test_info, test_content, from_template) + + +def make_object_test(target, global_props): + if not target.is_object(): + return + + object_props = target.object_properties() + if object_props is None: + return + (idref, prototype) = object_props + assert not idref.is_template(), "not implemented" + + if idref != IdRef("global"): + var_name = idref.to_get(global_props) + else: + # Access the global object through the |this| keyword. + var_name = "this" + + if prototype is not None: + prototype_name = prototype.to_script_value(global_props) + else: + prototype_name = None + + test_content = "" + + if idref.has_intrinsic(global_props): + test_content += f"""\ +var obj = {var_name}; +""" + var_name = "obj" + + if prototype is not None: + test_content += f"""\ +assert.sameValue(Object.getPrototypeOf({var_name}), {prototype_name}); +""" + + test_content += f"""\ +assert.sameValue(Object.isExtensible({var_name}), true); +assert.sameValue(typeof {var_name}, "object"); +""" + + test_info = test_info_for_object(target) + + yield TestFile(target, idref, test_info, test_content) + + +def make_function_test(clause, global_props): + for fun in recursive_properties_with_kind(clause, "function"): + assert not (fun.is_optional() and not fun.is_legacy()), ( + "not implemented: " + fun.header() + ) + (idref, name, length, attributes, alias) = fun.function_properties() + assert not idref.is_template(), "not implemented" + + var_name = idref.to_get(global_props) + (obj_name, key_name) = idref.to_get_own(global_props) + + test_info = test_info_for_property_kind(fun) + + if fun.is_link(): + test_content = "" + elif alias: + alias_var_name = alias.to_get(global_props) + test_content = f"""\ +assert.sameValue({var_name}, {alias_var_name}); + +""" + # Use the alias var-name below. + var_name = alias_var_name + else: + test_content = f"""\ +verifyBuiltinFunction({var_name}, "{name}", {length}); + +""" + + test_content += f"""\ +verifyPrimordialProperty({obj_name}, {key_name}, {{ + value: {var_name}, + writable: {"true" if attributes["Writable"] else "false"}, + enumerable: {"true" if attributes["Enumerable"] else "false"}, + configurable: {"true" if attributes["Configurable"] else "false"}, +}}); +""" + + yield TestFile(fun, idref, test_info, test_content) + + +def make_accessor_test(clause, global_props): + for acc in recursive_properties_with_kind(clause, "accessor"): + assert not (acc.is_optional() and not acc.is_legacy()), ( + "not implemented: " + acc.header() + ) + + (idref, get_name, set_name, attributes) = acc.accessor_properties() + assert not idref.is_template(), "not implemented" + + (obj_name, key_name) = idref.to_get_own(global_props) + + test_info = test_info_for_property_kind(acc) + + test_content = f"""\ +var desc = Object.getOwnPropertyDescriptor({obj_name}, {key_name}); + +""" + + if get_name is not None: + test_content += f"""\ +verifyBuiltinFunction(desc.get, "{get_name}", 0); + +""" + + if set_name is not None: + test_content += f"""\ +verifyBuiltinFunction(desc.set, "{set_name}", 1); + +""" + + test_content += f"""\ +verifyPrimordialProperty({obj_name}, {key_name}, {{ + get: {"desc.get" if get_name is not None else "undefined"}, + set: {"desc.set" if set_name is not None else "undefined"}, + enumerable: {"true" if attributes["Enumerable"] else "false"}, + configurable: {"true" if attributes["Configurable"] else "false"}, +}}); +""" + + yield TestFile(acc, idref, test_info, test_content) + + +def make_value_test(clause, global_props): + for val in recursive_properties_with_kind(clause, "value"): + (idref, value, attributes) = val.value_properties() + from_template = idref.is_template() + + test_info = test_info_for_property_kind(val) + + for idref, value in expand_if_value_template(idref, value): + (obj_name, key_name) = idref.to_get_own(global_props) + + script_value = ( + value.to_script_value(global_props) if value is not None else None + ) + + test_content = "" + + if script_value is not None: + test_content += f"""\ +verifyPrimordialProperty({obj_name}, {key_name}, {{ + value: {script_value}, + writable: {"true" if attributes["Writable"] else "false"}, + enumerable: {"true" if attributes["Enumerable"] else "false"}, + configurable: {"true" if attributes["Configurable"] else "false"}, +}}); +""" + else: + test_content += f"""\ +verifyPrimordialProperty({obj_name}, {key_name}, {{ + writable: {"true" if attributes["Writable"] else "false"}, + enumerable: {"true" if attributes["Enumerable"] else "false"}, + configurable: {"true" if attributes["Configurable"] else "false"}, +}}); +""" + + if val.is_optional(): + test_content = f"""\ +if ({obj_name}.hasOwnProperty({key_name})) {{ +{textwrap.indent(test_content, " " * 2)} +}} +""" + + yield TestFile(val, idref, test_info, test_content, from_template) + + +def make_tests_for(target, global_props): + yield from make_constructor_test(target, global_props) + yield from make_prototype_test(target, global_props) + yield from make_object_test(target, global_props) + + for clause in list(target.property_clauses()) or [target]: + yield from make_function_test(clause, global_props) + yield from make_accessor_test(clause, global_props) + yield from make_value_test(clause, global_props) + + +def try_parse_testfile(test262parser, source, test_name): + """ + Returns the result of test262parser.parseTestRecord() or None if a parser + error occured. + + See for an + overview of the returned test attributes. + """ + try: + return test262parser.parseTestRecord(source, test_name) + except Exception as err: + logger.warn(f"Error '{err}' in file: {test_name}") + logger.warn("Please report this error to the test262 GitHub repository!") + return None + + +def guess_features(test262_dir_path): + features = None + + for file_name in glob.glob("*.js", root_dir=test262_dir_path): + # Ignore non-test files. + if file_name.endswith("_FIXTURE.js"): + continue + + file_path = os.path.join(test262_dir_path, file_name) + + with open(file_path, encoding="utf-8") as test_file: + test_source = test_file.read() + + test_rec = try_parse_testfile(cfg.test262parser, test_source, file_name) + if test_rec is None: + continue + + test_features = set(test_rec.get("features", [])) + + if features is None: + features = test_features + else: + features = features & test_features + + if len(features) == 0: + break + + return features if features is not None else set() + + +def harness_features_for_includes(includes): + return { + feature + for include in includes + for feature in cfg.harness_features.get(include, []) + } + + +def generate_test(test, global_props): + test262_test = os.path.join(cfg.test262_dir, "test") + + file_path = test.file_path() + test262_file_path = os.path.join(test262_test, file_path) + test262_dir_path = os.path.dirname(test262_file_path) + + if cfg.features is None: + # Guess the feature tags from files in the same directory if no explicit + # features tags are present. + if os.path.isdir(test262_dir_path): + features = guess_features(test262_dir_path) + else: + features = set() + else: + features = set(cfg.features.split(",")) + + logger.info(f"Generate test for: {test.idref.to_get()}") + logger.debug(f" with path {file_path} and features '{features}'") + + includes = [] + if ( + "verifyBuiltinConstructor" in test.content + or "verifyBuiltinFunction" in test.content + ): + includes += ["builtin.js"] + includes += ["propertyHelper.js"] + elif "verifyPrimordialProperty" in test.content: + includes += ["propertyHelper.js"] + if "getWellKnownIntrinsicObject" in test.content: + includes += ["wellKnownIntrinsicObjects.js"] + if "isConstructor" in test.content: + includes += ["isConstructor.js"] + + # Add feature tags from includes. + features = features | harness_features_for_includes(includes) + + # Use a different output directory if requested. + if cfg.out: + test262_out_test = os.path.join(cfg.test262_dir, "test", cfg.out) + test262_file_path = os.path.join(test262_out_test, file_path) + + # Mark as generated to allow missing license block. + metadata = """\ +flags: [generated]\ +""" + + # Add includes if present. + if includes: + metadata += f""" +includes: [{", ".join(includes)}]\ +""" + + # Add features if present. + if features: + metadata += f""" +features: [{", ".join(sorted(features))}]\ +""" + + test_content = f"""\ +// Test generated by: {Path(__file__).parent.name} + +/*--- +esid: {test.clause.id()} +description: Property test for {test.idref.to_get()} +info: | +{textwrap.indent(test.info, " " * 2)} +{metadata} +---*/ + +{test.content}\ +""" + + return (test262_file_path, test_content) diff --git a/tools/property-test-generator/idreference.py b/tools/property-test-generator/idreference.py new file mode 100644 index 00000000000..2a50c6f09f8 --- /dev/null +++ b/tools/property-test-generator/idreference.py @@ -0,0 +1,165 @@ +# Copyright (C) 2025 André Bargull. All rights reserved. +# This code is governed by the BSD license found in the LICENSE file. + +import copy +import logging +import os +import re + +logger = logging.getLogger("test262." + __name__) + + +class IdReference: + re_idname_part = re.compile(r"\w+") + + def __init__(self, name): + self.parts = IdReference.into_parts(name) + + def __eq__(self, other): + if not isinstance(other, IdReference): + raise TypeError() + return self.parts == other.parts + + def __ne__(self, other): + if not isinstance(other, IdReference): + raise TypeError() + return self.parts != other.parts + + @staticmethod + def try_from(name): + """Return a new reference or None if the input can't be parsed.""" + try: + return IdReference(name) + except ValueError: + return None + + @staticmethod + def into_parts(name): + """Parse |name| into a list of parts. Raise ValueError if not parsable.""" + + # Remove leading and trailing whitespace and intrinsic notation + name = name.strip().replace("%", "") + + if len(name) == 0: + raise ValueError("empty string") + + stack = [] + parts = [] + while len(name): + m = IdReference.re_idname_part.match(name) + if m is None: + raise ValueError(f"{name} doesn't start with a word") + + parts.append(m.group(0)) + + if m.end() == len(name): + break + + name = name[m.end() :].lstrip() + + if name[0] not in (".", "[", "]"): + raise ValueError(f"unexpected character: {name[0]} in {name}") + + if name[0] == "[": + stack.append(parts) + parts = [] + elif name[0] == "]": + if len(stack) == 0: + raise ValueError("unmatched ']'") + if len(parts) == 0: + raise ValueError("empty []") + p = parts + parts = stack.pop() + parts.append(p) + elif name[0] == "." and len(name[1:].lstrip()) == 0: + raise ValueError("unexpected trailing '.'") + + # Remove leading whitespace from next part + name = name[1:].lstrip() + + if len(stack) > 0: + raise ValueError("unmatched '['") + + assert len(parts) > 0 + return parts + + @staticmethod + def parts_to_id(parts, global_props=None): + """Return a source string to access |parts|.""" + assert len(parts) > 0 + result = parts[0] + + if global_props is not None and result not in global_props: + result = f'getWellKnownIntrinsicObject("%{result}%")' + + for p in parts[1:]: + if type(p) is str: + result += f".{p}" + else: + result += f"[{IdReference.parts_to_id(p, global_props)}]" + return result + + def is_symbol_property_key(self): + """Return true if the last part is a symbol property key.""" + return type(self.parts[-1]) is not str + + def property_key(self): + """Return the last part as a property key.""" + last = self.parts[-1] + if type(last) is str: + return last + return IdReference.parts_to_id(last) + + def to_function_name(self): + """Return a string for the default function name.""" + last = self.parts[-1] + if type(last) is str: + return last + return f"[{IdReference.parts_to_id(last)}]" + + def to_get(self, global_props=None): + """Return a string for a direct script access to this reference.""" + return IdReference.parts_to_id(self.parts, global_props) + + def to_get_own(self, global_props=None): + """Return a tuple suitable for a Object.getOwnPropertyDescriptor call.""" + last = self.parts[-1] + if type(last) is str: + last = f'"{last}"' + else: + last = IdReference.parts_to_id(last, global_props) + if len(self.parts) > 1: + return (IdReference.parts_to_id(self.parts[:-1], global_props), last) + return ("this", last) + + def has_intrinsic(self, global_props): + """Return true if an intrinsic is referenced.""" + return "getWellKnownIntrinsicObject" in self.to_get(global_props) + + def is_template(self): + """Return true if this is a template reference.""" + return self.parts[0].startswith("_") + + def template_name(self): + """Return the name of a template reference.""" + assert self.is_template() + return self.parts[0] + + def instantiate(self, name): + """Instantiate this template reference for |name|.""" + assert self.is_template() + assert type(name) is str + + result = copy.deepcopy(self) + result.parts[0] = name + return result + + def file_path(self): + """Return the file path for this reference.""" + path = [] + for p in self.parts: + if type(p) is str: + path.append(p) + else: + path.append(".".join(p)) + return os.path.join(*path) diff --git a/tools/property-test-generator/main.py b/tools/property-test-generator/main.py new file mode 100644 index 00000000000..b87da5ecd70 --- /dev/null +++ b/tools/property-test-generator/main.py @@ -0,0 +1,330 @@ +# Copyright (C) 2025 André Bargull. All rights reserved. +# This code is governed by the BSD license found in the LICENSE file. + +import glob +import logging +import os +import re +import sys +from parser import SpecParser + +from clause import Clause +from generator import generate_test, make_tests_for + +from config import cfg + +logger = logging.getLogger("test262") + + +def initLogger(): + # Stream handler writing to |sys.stderr| for warnings and errors. + std_err = logging.StreamHandler(stream=sys.stderr) + std_err.setLevel(logging.WARNING) + std_err.setFormatter(logging.Formatter("%(levelname)s - %(message)s")) + + # Stream handler writing to |sys.stdout| for info and debug messages. + std_out = logging.StreamHandler(stream=sys.stdout) + std_out.setLevel(logging.DEBUG) + std_out.addFilter(lambda record: record.levelno <= logging.INFO) + std_out.setFormatter(logging.Formatter("%(message)s")) + + logger.addHandler(std_err) + logger.addHandler(std_out) + + +def read_spec_file(file_path): + logger.debug(f"Read spec file: {os.path.basename(file_path)}") + + with open(file_path, encoding="utf-8") as f: + text = f.read() + + # Read the spec html file. + parser = SpecParser() + parser.feed(text) + parser.close() + + # Assert all tags are properly closed. + assert parser.current_element == parser.root_element + + # Convert from elements to clauses. + return make_clause(None, parser.root_element) + + +def ignore_clause(elem): + for x, y in (("emu-alg", "ins"), ("ins", "emu-alg")): + emu_alg = next(elem.find_elements(x), None) + if emu_alg and next(emu_alg.find_elements(y), None): + return True + return False + + +def make_clause(parent_clause, elem): + """Create a new clause for |elem|.""" + clause = Clause(parent_clause, elem) + + for tag in ("emu-clause", "emu-annex"): + for child_elem in elem.find_elements(tag): + if ignore_clause(child_elem): + continue + make_clause(clause, child_elem) + + for ins in elem.find_elements("ins"): + for elem_clause in ins.find_elements("emu-clause"): + make_clause(clause, elem_clause) + + return clause + + +def collect_global_properties(clause): + """Generator yielding all properties reachable from |clause|.""" + for sc in clause.subclauses: + if sc.is_operation(): + continue + if sc.is_function(): + (idref, _, _, _, _) = sc.function_properties() + yield idref.property_key() + elif sc.is_value(): + (idref, _, _) = sc.value_properties() + yield idref.property_key() + elif len(sc.subclauses) > 0: + yield from collect_global_properties(sc) + else: + logger.warning(f"Unhandled sub-clause: {sc.header()}") + + +re_global_property = re.compile( + r"the initial value of the \*\"(?P\w+)\"\* property of the global object" +) + + +def global_properties(clause): + """Return a set of all global properties (recursively) defined in |clause|.""" + result = set() + + # Inline global property definition. + for ps in (clause.property_list(), clause.property_paragraphs()): + for p in ps: + if m := re_global_property.search(p): + result.add(m.group("name")) + + # Recursively search for global property definitions. + for sc in clause.subclauses: + if sc.header().endswith("Properties of the Global Object"): + result = result | set(collect_global_properties(sc)) + else: + result = result | global_properties(sc) + + return result + + +def target_clauses(clause): + """Iterator over all target clauses reachable from |clause|.""" + + if clause.has_properties(): + # Any clause with (accessible) properties is a relevant target. + if clause.is_accessible(): + yield clause + elif clause.has_functions() or clause.has_values() or clause.has_accessors(): + # Additionally check target name to skip over clauses which have function- + # or value-like definitions, but aren't definitions for built-in types. + if clause.is_accessible(): + if clause.target_name() is not None: + yield clause + elif clause.parent is None: + yield clause + else: + logger.debug(f"skip: {clause}") + + # Property and constructor clauses reachable from |clause| don't need to be + # tracked explicitly. + properties = list(clause.property_clauses()) + constructors = list(clause.constructor_clauses()) + + for sub in clause.subclauses: + if sub in properties or sub in constructors: + continue + yield from target_clauses(sub) + + +def write_test_files(root_clause, global_props): + """Write test files for all target clauses reachable from |root_clause|.""" + + # Find relevant targets clauses. + targets = [clause for clause in target_clauses(root_clause)] + if len(targets) == 0: + return + + for target in targets: + for test in make_tests_for(target, global_props): + if not cfg.is_included(test): + continue + + if cfg.is_excluded(test): + logger.debug(f"SKIP - {test.idref.to_get()} excluded") + continue + + (file_path, test_content) = generate_test(test, global_props) + + if cfg.dry_run: + continue + + os.makedirs(os.path.dirname(file_path), exist_ok=True) + + with open(file_path, "w", encoding="utf-8") as f: + f.write(test_content) + + +def main(): + initLogger() + + level = { + "debug": logging.DEBUG, + "info": logging.INFO, + "warning": logging.WARNING, + "warn": logging.WARNING, + "error": logging.ERROR, + }[cfg.log] + + logger.setLevel(level) + + logger.info("Generate test262 property tests with options:") + + for file_or_dir in cfg.globals: + logger.info(f" globals path: {file_or_dir}") + logger.info(f" spec: {cfg.spec}") + + if cfg.dry_run: + logger.info(f" dry-run: {cfg.dry_run}") + if cfg.include: + logger.info(f" include: {cfg.include}") + if cfg.exclude: + logger.info(f" exclude: {cfg.exclude}") + if cfg.features: + logger.info(f" features: {cfg.features}") + if cfg.out: + logger.info(f" out: {cfg.out}") + + # Check if optional output directory is valid. Also don't allow writing + # outside of the test262 directory. + if cfg.out: + test262_test = os.path.join(cfg.test262_dir, "test") + assert os.path.isabs(test262_test) and os.path.isdir(test262_test) + + out_path = os.path.join(test262_test, os.path.normpath(cfg.out)) + + actual_path = os.path.commonpath((test262_test, os.path.realpath(out_path))) + if actual_path != test262_test: + logger.error( + f"Can't write outside the test262/test directory to '{cfg.out}'!" + ) + return + + if os.path.exists(out_path) and not os.path.isdir(out_path): + logger.error(f"Can't overwrite existent non-directoy file '{cfg.out}'!") + return + + # First check all input files exist. + for file_or_dir_list in (cfg.globals, cfg.spec): + for file_or_dir in file_or_dir_list: + file_or_dir = os.path.expanduser(file_or_dir) # noqa: PLW2901 + if not os.path.isdir(file_or_dir) and not os.path.isfile(file_or_dir): + logger.error(f"{file_or_dir} does not exist") + return + + def read_file_or_directory(file_or_dir_list): + for file_or_dir in file_or_dir_list: + file_or_dir = os.path.expanduser(file_or_dir) # noqa: PLW2901 + if os.path.isfile(file_or_dir): + yield read_spec_file(file_or_dir) + else: + assert os.path.isdir(file_or_dir) + logger.debug(f"Read spec directory: {file_or_dir}") + + for file_name in glob.glob("*.html", root_dir=file_or_dir): + file_path = os.path.join(file_or_dir, file_name) + yield read_spec_file(file_path) + + # Read all spec files defining globals. + global_props = set() + for root_clause in read_file_or_directory(cfg.globals): + global_props = global_props | global_properties(root_clause) + + # Read all spec files. + root_clauses = list(read_file_or_directory(cfg.spec)) + + # Add globals from spec files. + for root_clause in root_clauses: + global_props = global_props | global_properties(root_clause) + + logger.debug(f"global_props: {sorted(global_props)}") + + # Generate property test files. + for root_clause in root_clauses: + write_test_files(root_clause, global_props) + + logger.debug("done!") + + +if __name__ == "__main__": + import argparse + + print(__file__) + + parser = argparse.ArgumentParser(description="test262 property test generator") + + parser.add_argument( + "-n", + "--dry-run", + action="store_true", + help="Don't write any output files.", + ) + + parser.add_argument( + "--include", + metavar="GLOB", + help="Include properties matching the pattern GLOB. Accepts a comma separated list.", + ) + + parser.add_argument( + "--exclude", + metavar="GLOB", + help="Exclude properties matching the pattern GLOB. Accepts a comma separated list.", + ) + + parser.add_argument( + "--log", + default="info", + choices=["debug", "info", "warning", "warn", "error"], + help="Log level", + ) + + parser.add_argument( + "--features", + help="Add FEATURES to the features frontmatter. Accepts a comma separated list.", + ) + + parser.add_argument( + "--globals", + nargs="*", + action="extend", + default=[], + help="Paths to spec files or directories defining global properties.", + ) + + parser.add_argument( + "--out", + metavar="PATH", + help="Write generated files to PATH, which is a path relative to test262/test.", + ) + + parser.add_argument( + "spec", + nargs="+", + action="extend", + help="Paths to a spec files or directories.", + ) + + parser.set_defaults(func=main) + + args = parser.parse_args(namespace=cfg) + args.func() diff --git a/tools/property-test-generator/parser.py b/tools/property-test-generator/parser.py new file mode 100644 index 00000000000..9409c41fe2e --- /dev/null +++ b/tools/property-test-generator/parser.py @@ -0,0 +1,50 @@ +# Copyright (C) 2025 André Bargull. All rights reserved. +# This code is governed by the BSD license found in the LICENSE file. + +import logging +from html.parser import HTMLParser + +from element import Element + +logger = logging.getLogger("test262." + __name__) + + +class SpecParser(HTMLParser): + def __init__(self): + super().__init__() + self.root_element = Element(None, None, [], None) + self.current_element = self.root_element + + @staticmethod + def ignorable_tag(tag): + """Tuple of tags which are ignored.""" + return tag in ("br", "img", "link", "html", "body", "meta", "input") + + def handle_starttag(self, tag, attrs): + if SpecParser.ignorable_tag(tag): + return + self.current_element = Element(self.current_element, tag, attrs, self.getpos()) + + def handle_endtag(self, tag): + if SpecParser.ignorable_tag(tag): + return + + if self.current_element.tag != tag: + logger.warn( + f"{self.current_element.tag} closed by {tag} at {self.getpos()}" + ) + + assert self.current_element.tag == tag + assert self.current_element.parent is not None + + # Remove leading and trailing whitespace from text elements. + self.current_element.text = self.current_element.text.strip() + + self.current_element = self.current_element.parent + + def handle_data(self, data): + self.current_element.nodes.append(data) + self.current_element.text += data + + def unknown_decl(self, data): + logger.warn(f"unknown declaration: {data}") diff --git a/tools/property-test-generator/template.py b/tools/property-test-generator/template.py new file mode 100644 index 00000000000..3cbd1a11476 --- /dev/null +++ b/tools/property-test-generator/template.py @@ -0,0 +1,108 @@ +# Copyright (C) 2025 André Bargull. All rights reserved. +# This code is governed by the BSD license found in the LICENSE file. + +# Template types defined in ECMA-262. + +# https://tc39.es/ecma262/#sec-native-error-types-used-in-this-standard +NativeErrors = { + "EvalError": { + "prototype": ("prototype", None), + "constructor": ("intrinsic", "EvalError"), + "message": ("string", ""), + "name": ("string", "EvalError"), + }, + "RangeError": { + "prototype": ("prototype", None), + "constructor": ("intrinsic", "RangeError"), + "message": ("string", ""), + "name": ("string", "RangeError"), + }, + "ReferenceError": { + "prototype": ("prototype", None), + "constructor": ("intrinsic", "ReferenceError"), + "message": ("string", ""), + "name": ("string", "ReferenceError"), + }, + "SyntaxError": { + "prototype": ("prototype", None), + "constructor": ("intrinsic", "SyntaxError"), + "message": ("string", ""), + "name": ("string", "SyntaxError"), + }, + "TypeError": { + "prototype": ("prototype", None), + "constructor": ("intrinsic", "TypeError"), + "message": ("string", ""), + "name": ("string", "TypeError"), + }, + "URIError": { + "prototype": ("prototype", None), + "constructor": ("intrinsic", "URIError"), + "message": ("string", ""), + "name": ("string", "URIError"), + }, +} + +# https://tc39.es/ecma262/#table-the-typedarray-constructors +TypedArrayConstructors = { + "Int8Array": { + "prototype": ("prototype", None), + "constructor": ("intrinsic", "Int8Array"), + "BYTES_PER_ELEMENT": ("number", "1"), + }, + "Uint8Array": { + "prototype": ("prototype", None), + "constructor": ("intrinsic", "Uint8Array"), + "BYTES_PER_ELEMENT": ("number", "1"), + }, + "Uint8ClampedArray": { + "prototype": ("prototype", None), + "constructor": ("intrinsic", "Uint8ClampedArray"), + "BYTES_PER_ELEMENT": ("number", "1"), + }, + "Int16Array": { + "prototype": ("prototype", None), + "constructor": ("intrinsic", "Int16Array"), + "BYTES_PER_ELEMENT": ("number", "2"), + }, + "Uint16Array": { + "prototype": ("prototype", None), + "constructor": ("intrinsic", "Uint16Array"), + "BYTES_PER_ELEMENT": ("number", "2"), + }, + "Int32Array": { + "prototype": ("prototype", None), + "constructor": ("intrinsic", "Int32Array"), + "BYTES_PER_ELEMENT": ("number", "4"), + }, + "Uint32Array": { + "prototype": ("prototype", None), + "constructor": ("intrinsic", "Uint32Array"), + "BYTES_PER_ELEMENT": ("number", "4"), + }, + "BigInt64Array": { + "prototype": ("prototype", None), + "constructor": ("intrinsic", "BigInt64Array"), + "BYTES_PER_ELEMENT": ("number", "8"), + }, + "BigUint64Array": { + "prototype": ("prototype", None), + "constructor": ("intrinsic", "BigUint64Array"), + "BYTES_PER_ELEMENT": ("number", "8"), + }, + "Float16Array": { + "prototype": ("prototype", None), + "constructor": ("intrinsic", "Float16Array"), + "BYTES_PER_ELEMENT": ("number", "2"), + }, + "Float32Array": { + "prototype": ("prototype", None), + "constructor": ("intrinsic", "Float32Array"), + "BYTES_PER_ELEMENT": ("number", "4"), + }, + "Float64Array": { + "prototype": ("prototype", None), + "constructor": ("intrinsic", "Float64Array"), + "BYTES_PER_ELEMENT": ("number", "8"), + }, +} diff --git a/tools/property-test-generator/testfile.py b/tools/property-test-generator/testfile.py new file mode 100644 index 00000000000..6f259ddfc2b --- /dev/null +++ b/tools/property-test-generator/testfile.py @@ -0,0 +1,70 @@ +# Copyright (C) 2025 André Bargull. All rights reserved. +# This code is governed by the BSD license found in the LICENSE file. + +import logging +import os + +from template import NativeErrors, TypedArrayConstructors + +logger = logging.getLogger("test262." + __name__) + + +class TestFile: + def __init__(self, clause, idref, info, content, from_template=False): + self.clause = clause + self.idref = idref + self.info = info + self.content = content + self.from_template = from_template + + def file_path(self): + # Select the correct test262 directory for this test. + if self.idref.parts[0].startswith("Intl") or self.clause.is_override(): + file_path = "intl402" + elif self.clause.is_annex_b(): + file_path = os.path.join("annexB", "built-ins") + else: + file_path = "built-ins" + + # NativeErrors and TypedArrayConstructors aren't placed into the + # top-level directory when generated from the template definition. Also + # write any top-level tests in the alternative directory. + if self.from_template or len(self.idref.parts) == 1: + if self.idref.parts[0] in NativeErrors.keys(): + file_path = os.path.join(file_path, "NativeErrors") + elif self.idref.parts[0] in TypedArrayConstructors.keys(): + file_path = os.path.join(file_path, "TypedArrayConstructors") + + idref_file_path = self.idref.file_path() + + # Remove leading "Intl" for intl402 tests, unless testing the "Intl" + # object itself. + if self.idref.parts[0] == "Intl": + # Write tests for constructors like "Intl.Collator" into "intl402/Collator". + if len(self.idref.parts) > 1 and self.idref.parts[1][0].isupper(): + assert idref_file_path.startswith("Intl" + os.path.sep) + idref_file_path = idref_file_path[len("Intl" + os.path.sep) :] + elif self.idref.parts[0].startswith("Intl"): + # Write tests for intrinsics like "IntlSegmentsPrototype" into "intl402/SegmentsPrototype". + idref_file_path = idref_file_path[len("Intl") :] + + if self.clause.is_constructor(): + file_name = "ctor.js" + elif self.clause.is_prototype(): + file_name = "proto.js" + elif self.clause.is_object(): + file_name = "object.js" + else: + file_name = "prop-desc.js" + + # Don't create sub-directories for these properties to match the + # current style. + if self.idref.property_key() in ( + "constructor", + "Symbol.toStringTag", + "BYTES_PER_ELEMENT", + ): + (idref_file_path, file_name) = os.path.split(idref_file_path) + file_name += ".js" + + return os.path.join(file_path, idref_file_path, file_name) diff --git a/tools/property-test-generator/value.py b/tools/property-test-generator/value.py new file mode 100644 index 00000000000..866f3fa8fe7 --- /dev/null +++ b/tools/property-test-generator/value.py @@ -0,0 +1,62 @@ +# Copyright (C) 2025 André Bargull. All rights reserved. +# This code is governed by the BSD license found in the LICENSE file. + +import logging +import re + +from idreference import IdReference as IdRef + +logger = logging.getLogger("test262." + __name__) + + +class Value: + def __init__(self, kind, value): + self.kind = kind + self.value = value + pass + + def __repr__(self): + return str((self.kind, self.value)) + + re_number_value = re.compile( + r"(?P-?\d+(?:\.\d+)?)(?:\s*×\s*10(?P-?\d+))?" + ) + + @staticmethod + def intrinsic(value): + return Value("intrinsic", value) + + @staticmethod + def null(): + return Value("null", "") + + def to_script_value(self, global_props=None): + """Return the script source representation for |value|.""" + if self.kind == "string": + return f'"{self.value}"' + if self.kind == "number": + if self.value == "NaN": + return "0/0" + if self.value == "-∞": + return "-1/0" + if self.value in ("∞", "+∞"): + return "1/0" + m = Value.re_number_value.fullmatch(self.value) + assert m + + base = m.group("base") + exp = m.group("exp") + + if exp is None: + return base + return f"{base}e{exp}" + if self.kind == "undefined": + return "undefined" + if self.kind == "null": + return "null" + if self.kind == "intrinsic": + return IdRef(self.value).to_get(global_props) + if self.kind in ("prototype", "symbol", "note"): + return None + logger.warn(f"Unhandled value kind: {self.kind}") + return None