diff --git a/features.txt b/features.txt index 26df0d69829..e0cf8e874e6 100644 --- a/features.txt +++ b/features.txt @@ -128,6 +128,11 @@ export-star-as-namespace-from-module # https://github.com/tc39/proposal-import-meta import.meta +# WeakRef +# https://github.com/tc39/proposal-weakref +WeakRef +FinalizationGroup + ## Standard language features # # Language features that have been included in a published version of the diff --git a/test/built-ins/FinalizationGroup/constructor.js b/test/built-ins/FinalizationGroup/constructor.js new file mode 100644 index 00000000000..651ae8918eb --- /dev/null +++ b/test/built-ins/FinalizationGroup/constructor.js @@ -0,0 +1,15 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group-constructor +description: > + The FinalizationGroup constructor is the %FinalizationGroup% intrinsic object and the initial + value of the FinalizationGroup property of the global object. +features: [FinalizationGroup] +---*/ + +assert.sameValue( + typeof FinalizationGroup, 'function', + 'typeof FinalizationGroup is function' +); diff --git a/test/built-ins/FinalizationGroup/instance-extensible.js b/test/built-ins/FinalizationGroup/instance-extensible.js new file mode 100644 index 00000000000..cf1187d61c6 --- /dev/null +++ b/test/built-ins/FinalizationGroup/instance-extensible.js @@ -0,0 +1,30 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group-target +description: Instances of FinalizationGroup are extensible +info: | + FinalizationGroup ( cleanupCallback ) + + ... + 3. Let finalizationGroup be ? OrdinaryCreateFromConstructor(NewTarget, "%FinalizationGroupPrototype%", « [[Realm]], [[CleanupCallback]], [[Cells]], [[IsFinalizationGroupCleanupJobActive]] »). + ... + 9. Return finalizationGroup. + + OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] ) + + ... + 2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto). + 3. Return ObjectCreate(proto, internalSlotsList). + + ObjectCreate ( proto [ , internalSlotsList ] ) + + 4. Set obj.[[Prototype]] to proto. + 5. Set obj.[[Extensible]] to true. + 6. Return obj. +features: [FinalizationGroup] +---*/ + +var fg = new FinalizationGroup(function() {}); +assert.sameValue(Object.isExtensible(fg), true); diff --git a/test/built-ins/FinalizationGroup/length.js b/test/built-ins/FinalizationGroup/length.js new file mode 100644 index 00000000000..88e0d59ce82 --- /dev/null +++ b/test/built-ins/FinalizationGroup/length.js @@ -0,0 +1,32 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group-target +description: FinalizationGroup.length property descriptor +info: | + FinalizationGroup ( cleanupCallback ) + + 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] +features: [FinalizationGroup] +---*/ + +verifyProperty(FinalizationGroup, 'length', { + value: 1, + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/FinalizationGroup/name.js b/test/built-ins/FinalizationGroup/name.js new file mode 100644 index 00000000000..517a3442fe8 --- /dev/null +++ b/test/built-ins/FinalizationGroup/name.js @@ -0,0 +1,31 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group-target +description: FinalizationGroup.name property descriptor +info: | + FinalizationGroup ( value ) + + 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, 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. [...] + + 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] +features: [FinalizationGroup] +---*/ + +verifyProperty(FinalizationGroup, 'name', { + value: 'FinalizationGroup', + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/FinalizationGroup/newtarget-prototype-is-not-object.js b/test/built-ins/FinalizationGroup/newtarget-prototype-is-not-object.js new file mode 100644 index 00000000000..9c2d7f7e90d --- /dev/null +++ b/test/built-ins/FinalizationGroup/newtarget-prototype-is-not-object.js @@ -0,0 +1,58 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group-target +description: > + [[Prototype]] defaults to %FinalizationGroupPrototype% if NewTarget.prototype is not an object. +info: | + FinalizationGroup ( cleanupCallback ) + + ... + 3. Let finalizationGroup be ? OrdinaryCreateFromConstructor(NewTarget, "%FinalizationGroupPrototype%", « [[Realm]], [[CleanupCallback]], [[Cells]], [[IsFinalizationGroupCleanupJobActive]] »). + ... + 9. Return finalizationGroup. + + OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] ) + + ... + 2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto). + 3. Return ObjectCreate(proto, internalSlotsList). + + GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto ) + + 3. Let proto be ? Get(constructor, 'prototype'). + 4. If Type(proto) is not Object, then + a. Let realm be ? GetFunctionRealm(constructor). + b. Set proto to realm's intrinsic object named intrinsicDefaultProto. + 5. Return proto. +features: [FinalizationGroup, Reflect.construct, Symbol] +---*/ + +var fg; +function newTarget() {} +function fn() {} + +newTarget.prototype = undefined; +fg = Reflect.construct(FinalizationGroup, [fn], newTarget); +assert.sameValue(Object.getPrototypeOf(fg), FinalizationGroup.prototype, 'newTarget.prototype is undefined'); + +newTarget.prototype = null; +fg = Reflect.construct(FinalizationGroup, [fn], newTarget); +assert.sameValue(Object.getPrototypeOf(fg), FinalizationGroup.prototype, 'newTarget.prototype is null'); + +newTarget.prototype = true; +fg = Reflect.construct(FinalizationGroup, [fn], newTarget); +assert.sameValue(Object.getPrototypeOf(fg), FinalizationGroup.prototype, 'newTarget.prototype is a Boolean'); + +newTarget.prototype = ''; +fg = Reflect.construct(FinalizationGroup, [fn], newTarget); +assert.sameValue(Object.getPrototypeOf(fg), FinalizationGroup.prototype, 'newTarget.prototype is a String'); + +newTarget.prototype = Symbol(); +fg = Reflect.construct(FinalizationGroup, [fn], newTarget); +assert.sameValue(Object.getPrototypeOf(fg), FinalizationGroup.prototype, 'newTarget.prototype is a Symbol'); + +newTarget.prototype = 1; +fg = Reflect.construct(FinalizationGroup, [fn], newTarget); +assert.sameValue(Object.getPrototypeOf(fg), FinalizationGroup.prototype, 'newTarget.prototype is a Number'); diff --git a/test/built-ins/FinalizationGroup/prop-desc.js b/test/built-ins/FinalizationGroup/prop-desc.js new file mode 100644 index 00000000000..e5bd1adfd81 --- /dev/null +++ b/test/built-ins/FinalizationGroup/prop-desc.js @@ -0,0 +1,22 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group-constructor +description: > + Property descriptor of FinalizationGroup +info: | + 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] +features: [FinalizationGroup] +---*/ + +verifyProperty(this, 'FinalizationGroup', { + enumerable: false, + writable: true, + configurable: true +}); diff --git a/test/built-ins/FinalizationGroup/proto-from-ctor-realm.js b/test/built-ins/FinalizationGroup/proto-from-ctor-realm.js new file mode 100644 index 00000000000..836351fa416 --- /dev/null +++ b/test/built-ins/FinalizationGroup/proto-from-ctor-realm.js @@ -0,0 +1,59 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group-target +description: Default [[Prototype]] value derived from realm of the newTarget +info: | + FinalizationGroup ( cleanupCallback ) + + ... + 3. Let finalizationGroup be ? OrdinaryCreateFromConstructor(NewTarget, "%FinalizationGroupPrototype%", « [[Realm]], [[CleanupCallback]], [[Cells]], [[IsFinalizationGroupCleanupJobActive]] »). + ... + 9. Return finalizationGroup. + + OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] ) + + ... + 2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto). + 3. Return ObjectCreate(proto, internalSlotsList). + + GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto ) + + 3. Let proto be ? Get(constructor, 'prototype'). + 4. If Type(proto) is not Object, then + a. Let realm be ? GetFunctionRealm(constructor). + b. Set proto to realm's intrinsic object named intrinsicDefaultProto. + 5. Return proto. +features: [FinalizationGroup, cross-realm, Reflect] +---*/ + +var other = $262.createRealm().global; +var newTarget = new other.Function(); +function fn() {} +var fg; + +newTarget.prototype = undefined; +fg = Reflect.construct(FinalizationGroup, [fn], newTarget); +assert.sameValue(Object.getPrototypeOf(fg), other.FinalizationGroup.prototype, 'newTarget.prototype is undefined'); + +newTarget.prototype = null; +fg = Reflect.construct(FinalizationGroup, [fn], newTarget); +assert.sameValue(Object.getPrototypeOf(fg), other.FinalizationGroup.prototype, 'newTarget.prototype is null'); + +newTarget.prototype = true; +fg = Reflect.construct(FinalizationGroup, [fn], newTarget); +assert.sameValue(Object.getPrototypeOf(fg), other.FinalizationGroup.prototype, 'newTarget.prototype is a Boolean'); + +newTarget.prototype = ''; +fg = Reflect.construct(FinalizationGroup, [fn], newTarget); +assert.sameValue(Object.getPrototypeOf(fg), other.FinalizationGroup.prototype, 'newTarget.prototype is a String'); + +newTarget.prototype = Symbol(); +fg = Reflect.construct(FinalizationGroup, [fn], newTarget); +assert.sameValue(Object.getPrototypeOf(fg), other.FinalizationGroup.prototype, 'newTarget.prototype is a Symbol'); + +newTarget.prototype = 1; +fg = Reflect.construct(FinalizationGroup, [fn], newTarget); +assert.sameValue(Object.getPrototypeOf(fg), other.FinalizationGroup.prototype, 'newTarget.prototype is a Number'); + diff --git a/test/built-ins/FinalizationGroup/proto.js b/test/built-ins/FinalizationGroup/proto.js new file mode 100644 index 00000000000..05cab8f7625 --- /dev/null +++ b/test/built-ins/FinalizationGroup/proto.js @@ -0,0 +1,18 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-properties-of-the-finalization-group-constructor +description: > + The prototype of FinalizationGroup is Object.prototype +info: | + The value of the [[Prototype]] internal slot of the FinalizationGroup object is the + intrinsic object %FunctionPrototype%. +features: [FinalizationGroup] +---*/ + +assert.sameValue( + Object.getPrototypeOf(FinalizationGroup), + Function.prototype, + 'Object.getPrototypeOf(FinalizationGroup) returns the value of `Function.prototype`' +); diff --git a/test/built-ins/FinalizationGroup/prototype-from-newtarget-abrupt.js b/test/built-ins/FinalizationGroup/prototype-from-newtarget-abrupt.js new file mode 100644 index 00000000000..31aff1aafce --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype-from-newtarget-abrupt.js @@ -0,0 +1,41 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group-target +description: > + Return abrupt from getting the NewTarget prototype +info: | + FinalizationGroup ( cleanupCallback ) + + ... + 3. Let finalizationGroup be ? OrdinaryCreateFromConstructor(NewTarget, "%FinalizationGroupPrototype%", « [[Realm]], [[CleanupCallback]], [[Cells]], [[IsFinalizationGroupCleanupJobActive]] »). + ... + 9. Return finalizationGroup. + + OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] ) + + ... + 2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto). + 3. Return ObjectCreate(proto, internalSlotsList). + + GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto ) + + 3. Let proto be ? Get(constructor, 'prototype'). +features: [FinalizationGroup, Reflect.construct] +---*/ + +var calls = 0; +var newTarget = function() {}.bind(null); +Object.defineProperty(newTarget, 'prototype', { + get: function() { + calls += 1; + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + Reflect.construct(FinalizationGroup, [function() {}], newTarget); +}); + +assert.sameValue(calls, 1); diff --git a/test/built-ins/FinalizationGroup/prototype-from-newtarget-custom.js b/test/built-ins/FinalizationGroup/prototype-from-newtarget-custom.js new file mode 100644 index 00000000000..ef5be6067db --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype-from-newtarget-custom.js @@ -0,0 +1,44 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group-target +description: > + The [[Prototype]] internal slot is computed from NewTarget. +info: | + FinalizationGroup ( cleanupCallback ) + + ... + 3. Let finalizationGroup be ? OrdinaryCreateFromConstructor(NewTarget, "%FinalizationGroupPrototype%", « [[Realm]], [[CleanupCallback]], [[Cells]], [[IsFinalizationGroupCleanupJobActive]] »). + ... + 9. Return finalizationGroup. + + OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] ) + + ... + 2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto). + 3. Return ObjectCreate(proto, internalSlotsList). + + GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto ) + + 3. Let proto be ? Get(constructor, 'prototype'). + 4. If Type(proto) is not Object, then + a. Let realm be ? GetFunctionRealm(constructor). + b. Set proto to realm's intrinsic object named intrinsicDefaultProto. + 5. Return proto. +features: [FinalizationGroup, Reflect.construct] +---*/ + +var fg; + +fg = Reflect.construct(FinalizationGroup, [function() {}], Object); +assert.sameValue(Object.getPrototypeOf(fg), Object.prototype, 'NewTarget is built-in Object constructor'); + +var newTarget = function() {}.bind(null); +Object.defineProperty(newTarget, 'prototype', { + get: function() { + return Array.prototype; + } +}); +fg = Reflect.construct(FinalizationGroup, [function() {}], newTarget); +assert.sameValue(Object.getPrototypeOf(fg), Array.prototype, 'NewTarget is BoundFunction with accessor'); diff --git a/test/built-ins/FinalizationGroup/prototype-from-newtarget.js b/test/built-ins/FinalizationGroup/prototype-from-newtarget.js new file mode 100644 index 00000000000..dd376b71f89 --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype-from-newtarget.js @@ -0,0 +1,33 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group-target +description: > + The [[Prototype]] internal slot is computed from NewTarget. +info: | + FinalizationGroup ( cleanupCallback ) + + ... + 3. Let finalizationGroup be ? OrdinaryCreateFromConstructor(NewTarget, "%FinalizationGroupPrototype%", « [[Realm]], [[CleanupCallback]], [[Cells]], [[IsFinalizationGroupCleanupJobActive]] »). + ... + 9. Return finalizationGroup. + + OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] ) + + ... + 2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto). + 3. Return ObjectCreate(proto, internalSlotsList). + + GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto ) + + 3. Let proto be ? Get(constructor, 'prototype'). + 4. If Type(proto) is not Object, then + a. Let realm be ? GetFunctionRealm(constructor). + b. Set proto to realm's intrinsic object named intrinsicDefaultProto. + 5. Return proto. +features: [FinalizationGroup] +---*/ + +var fg = new FinalizationGroup(function() {}); +assert.sameValue(Object.getPrototypeOf(fg), FinalizationGroup.prototype); diff --git a/test/built-ins/FinalizationGroup/prototype/Symbol.toStringTag.js b/test/built-ins/FinalizationGroup/prototype/Symbol.toStringTag.js new file mode 100644 index 00000000000..d505aa46792 --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/Symbol.toStringTag.js @@ -0,0 +1,23 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group-@@tostringtag +description: > + `Symbol.toStringTag` property descriptor +info: | + The initial value of the @@toStringTag property is the String value + 'FinalizationGroup'. + + This property has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [FinalizationGroup, Symbol, Symbol.toStringTag] +---*/ + +verifyProperty(FinalizationGroup.prototype, Symbol.toStringTag, { + value: 'FinalizationGroup', + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/FinalizationGroup/prototype/cleanupSome/callback-not-callable-throws.js b/test/built-ins/FinalizationGroup/prototype/cleanupSome/callback-not-callable-throws.js new file mode 100644 index 00000000000..e963368d26c --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/cleanupSome/callback-not-callable-throws.js @@ -0,0 +1,53 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group.prototype.cleanupSome +description: Throws a TypeError if callback is not callable +info: | + FinalizationGroup.prototype.cleanupSome ( [ callback ] ) + + 1. Let finalizationGroup be the this value. + 2. If Type(finalizationGroup) is not Object, throw a TypeError exception. + 3. If finalizationGroup does not have a [[Cells]] internal slot, throw a TypeError exception. + 4. If callback is not undefined and IsCallable(callback) is false, throw a TypeError exception. + ... +features: [FinalizationGroup] +---*/ + +assert.sameValue(typeof FinalizationGroup.prototype.cleanupSome, 'function'); + +var fg = new FinalizationGroup(function() {}); + +assert.throws(TypeError, function() { + fg.cleanupSome(null); +}, 'null'); + +assert.throws(TypeError, function() { + fg.cleanupSome(true); +}, 'true'); + +assert.throws(TypeError, function() { + fg.cleanupSome(false); +}, 'false'); + +assert.throws(TypeError, function() { + fg.cleanupSome(1); +}, 'number'); + +assert.throws(TypeError, function() { + fg.cleanupSome('object'); +}, 'string'); + +var s = Symbol(); +assert.throws(TypeError, function() { + fg.cleanupSome(s); +}, 'symbol'); + +assert.throws(TypeError, function() { + fg.cleanupSome({}); +}, 'object'); + +assert.throws(TypeError, function() { + fg.cleanupSome(FinalizationGroup.prototype); +}, 'FinalizationGroup.prototype'); diff --git a/test/built-ins/FinalizationGroup/prototype/cleanupSome/custom-this.js b/test/built-ins/FinalizationGroup/prototype/cleanupSome/custom-this.js new file mode 100644 index 00000000000..d9de47abffa --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/cleanupSome/custom-this.js @@ -0,0 +1,26 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group.prototype.cleanupSome +description: Return values applying custom this +info: | + FinalizationGroup.prototype.cleanupSome ( [ callback ] ) + + 1. Let finalizationGroup be the this value. + 2. If Type(finalizationGroup) is not Object, throw a TypeError exception. + 3. If finalizationGroup does not have a [[Cells]] internal slot, throw a TypeError exception. + 4. If callback is not undefined and IsCallable(callback) is false, throw a TypeError exception. + 5. Perform ! CleanupFinalizationGroup(finalizationGroup, callback). + 6. Return undefined. +features: [FinalizationGroup] +---*/ + +var fn = function() {}; +var cleanupSome = FinalizationGroup.prototype.cleanupSome; +var fg = new FinalizationGroup(fn); + +var cb = function() {}; + +assert.sameValue(cleanupSome.call(fg, cb), undefined); +assert.sameValue(cleanupSome.call(fg, fn), undefined), 'reuse the same cleanup callback fn'; diff --git a/test/built-ins/FinalizationGroup/prototype/cleanupSome/length.js b/test/built-ins/FinalizationGroup/prototype/cleanupSome/length.js new file mode 100644 index 00000000000..47748346bda --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/cleanupSome/length.js @@ -0,0 +1,32 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group.prototype.cleanupSome +description: FinalizationGroup.prototype.cleanupSome.length property descriptor +info: | + FinalizationGroup.prototype.cleanupSome ( [ callback ] ) + + 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] +features: [FinalizationGroup] +---*/ + +verifyProperty(FinalizationGroup.prototype.cleanupSome, 'length', { + value: 0, + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/FinalizationGroup/prototype/cleanupSome/name.js b/test/built-ins/FinalizationGroup/prototype/cleanupSome/name.js new file mode 100644 index 00000000000..370a34f70f5 --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/cleanupSome/name.js @@ -0,0 +1,31 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group.prototype.cleanupSome +description: FinalizationGroup.prototype.cleanupSome.name property descriptor +info: | + FinalizationGroup.prototype.cleanupSome.name value and property descriptor + + 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, 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. [...] + + 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] +features: [FinalizationGroup] +---*/ + +verifyProperty(FinalizationGroup.prototype.cleanupSome, 'name', { + value: 'cleanupSome', + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/FinalizationGroup/prototype/cleanupSome/prop-desc.js b/test/built-ins/FinalizationGroup/prototype/cleanupSome/prop-desc.js new file mode 100644 index 00000000000..f2b269c998f --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/cleanupSome/prop-desc.js @@ -0,0 +1,24 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group.prototype.cleanupSome +description: > + Property descriptor of FinalizationGroup.prototype.cleanupSome +info: | + 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] +features: [FinalizationGroup] +---*/ + +assert.sameValue(typeof FinalizationGroup.prototype.cleanupSome, 'function'); + +verifyProperty(FinalizationGroup.prototype, 'cleanupSome', { + enumerable: false, + writable: true, + configurable: true +}); diff --git a/test/built-ins/FinalizationGroup/prototype/cleanupSome/return-undefined.js b/test/built-ins/FinalizationGroup/prototype/cleanupSome/return-undefined.js new file mode 100644 index 00000000000..1a01f1df970 --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/cleanupSome/return-undefined.js @@ -0,0 +1,41 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group.prototype.cleanupSome +description: Return undefined regardless the result of CleanupFinalizationGroup +info: | + FinalizationGroup.prototype.cleanupSome ( [ callback ] ) + + 1. Let finalizationGroup be the this value. + 2. If Type(finalizationGroup) is not Object, throw a TypeError exception. + 3. If finalizationGroup does not have a [[Cells]] internal slot, throw a TypeError exception. + 4. If callback is not undefined and IsCallable(callback) is false, throw a TypeError exception. + 5. Perform ! CleanupFinalizationGroup(finalizationGroup, callback). + 6. Return undefined. +features: [FinalizationGroup, arrow-function, async-functions, async-iteration, class] +---*/ + +var fn = function() {}; +var cb = function() {}; +var poisoned = function() { throw new Test262Error(); }; +var fg = new FinalizationGroup(fn); + +assert.sameValue(fg.cleanupSome(cb), undefined, 'regular callback'); +assert.sameValue(fg.cleanupSome(fn), undefined, 'regular callback, same FG cleanup function'); + +assert.sameValue(fg.cleanupSome(() => {}), undefined, 'arrow function'); +assert.sameValue(fg.cleanupSome(fg.cleanupSome), undefined, 'cleanupSome itself'); +assert.sameValue(fg.cleanupSome(poisoned), undefined, 'poisoned'); +assert.sameValue(fg.cleanupSome(class {}), undefined, 'class expression'); +assert.sameValue(fg.cleanupSome(async function() {}), undefined, 'async function'); +assert.sameValue(fg.cleanupSome(function *() {}), undefined, 'generator'); +assert.sameValue(fg.cleanupSome(async function *() {}), undefined, 'async generator'); + +assert.sameValue(fg.cleanupSome(), undefined, 'undefined, implicit'); +assert.sameValue(fg.cleanupSome(undefined), undefined, 'undefined, explicit'); + +var poisonedFg = new FinalizationGroup(poisoned); + +assert.sameValue(poisonedFg.cleanupSome(cb), undefined, 'regular callback on poisoned FG cleanup callback'); +assert.sameValue(poisonedFg.cleanupSome(poisoned), undefined, 'poisoned callback on poisoned FG cleanup callback'); diff --git a/test/built-ins/FinalizationGroup/prototype/cleanupSome/this-does-not-have-internal-cells-throws.js b/test/built-ins/FinalizationGroup/prototype/cleanupSome/this-does-not-have-internal-cells-throws.js new file mode 100644 index 00000000000..954fdf06ad8 --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/cleanupSome/this-does-not-have-internal-cells-throws.js @@ -0,0 +1,48 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group.prototype.cleanupSome +description: Throws a TypeError if this does not have a [[Cells]] internal slot +info: | + FinalizationGroup.prototype.cleanupSome ( [ callback ] ) + + 1. Let finalizationGroup be the this value. + 2. If Type(finalizationGroup) is not Object, throw a TypeError exception. + 3. If finalizationGroup does not have a [[Cells]] internal slot, throw a TypeError exception. + 4. If callback is not undefined and IsCallable(callback) is false, throw a TypeError exception. + ... +features: [FinalizationGroup, WeakRef] +---*/ + +assert.sameValue(typeof FinalizationGroup.prototype.cleanupSome, 'function'); + +var cleanupSome = FinalizationGroup.prototype.cleanupSome; +var cb = function() {}; + +assert.throws(TypeError, function() { + cleanupSome.call({ ['[[Cells]]']: {} }, cb); +}, 'Ordinary object without [[Cells]]'); + +assert.throws(TypeError, function() { + cleanupSome.call(WeakRef.prototype, cb); +}, 'WeakRef.prototype does not have a [[Cells]] internal slot'); + +assert.throws(TypeError, function() { + cleanupSome.call(WeakRef, cb); +}, 'WeakRef does not have a [[Cells]] internal slot'); + +var wr = new WeakRef({}); +assert.throws(TypeError, function() { + cleanupSome.call(wr, cb); +}, 'WeakRef instance'); + +var wm = new WeakMap(); +assert.throws(TypeError, function() { + cleanupSome.call(wm, cb); +}, 'WeakMap instance'); + +var ws = new WeakSet(); +assert.throws(TypeError, function() { + cleanupSome.call(ws, cb); +}, 'WeakSet instance'); diff --git a/test/built-ins/FinalizationGroup/prototype/cleanupSome/this-not-object-throws.js b/test/built-ins/FinalizationGroup/prototype/cleanupSome/this-not-object-throws.js new file mode 100644 index 00000000000..2de7e87e53e --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/cleanupSome/this-not-object-throws.js @@ -0,0 +1,50 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group.prototype.cleanupSome +description: Throws a TypeError if this is not an Object +info: | + FinalizationGroup.prototype.cleanupSome ( [ callback ] ) + + 1. Let finalizationGroup be the this value. + 2. If Type(finalizationGroup) is not Object, throw a TypeError exception. + 3. If finalizationGroup does not have a [[Cells]] internal slot, throw a TypeError exception. + 4. If callback is not undefined and IsCallable(callback) is false, throw a TypeError exception. + ... +features: [FinalizationGroup] +---*/ + +assert.sameValue(typeof FinalizationGroup.prototype.cleanupSome, 'function'); + +var cleanupSome = FinalizationGroup.prototype.cleanupSome; +var cb = function() {}; + +assert.throws(TypeError, function() { + cleanupSome.call(undefined, cb); +}, 'undefined'); + +assert.throws(TypeError, function() { + cleanupSome.call(null, cb); +}, 'null'); + +assert.throws(TypeError, function() { + cleanupSome.call(true, cb); +}, 'true'); + +assert.throws(TypeError, function() { + cleanupSome.call(false, cb); +}, 'false'); + +assert.throws(TypeError, function() { + cleanupSome.call(1, cb); +}, 'number'); + +assert.throws(TypeError, function() { + cleanupSome.call('object', cb); +}, 'string'); + +var s = Symbol(); +assert.throws(TypeError, function() { + cleanupSome.call(s, cb); +}, 'symbol'); diff --git a/test/built-ins/FinalizationGroup/prototype/constructor.js b/test/built-ins/FinalizationGroup/prototype/constructor.js new file mode 100644 index 00000000000..e1c94daee18 --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/constructor.js @@ -0,0 +1,23 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group.prototype.constructor +description: FinalizationGroup.prototype.constructor property descriptor +info: | + FinalizationGroup.prototype.constructor + + The initial value of FinalizationGroup.prototype.constructor is the intrinsic + object %FinalizationGroup%. + + 17 ECMAScript Standard Built-in Objects +includes: [propertyHelper.js] +features: [FinalizationGroup] +---*/ + +verifyProperty(FinalizationGroup.prototype, 'constructor', { + value: FinalizationGroup, + writable: true, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/FinalizationGroup/prototype/prop-desc.js b/test/built-ins/FinalizationGroup/prototype/prop-desc.js new file mode 100644 index 00000000000..dfe39b4548e --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/prop-desc.js @@ -0,0 +1,18 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: The property descriptor FinalizationGroup.prototype +esid: sec-finalization-group.prototype +info: | + This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, + [[Configurable]]: false }. +features: [FinalizationGroup] +includes: [propertyHelper.js] +---*/ + +verifyProperty(FinalizationGroup, 'prototype', { + writable: false, + enumerable: false, + configurable: false +}); diff --git a/test/built-ins/FinalizationGroup/prototype/proto.js b/test/built-ins/FinalizationGroup/prototype/proto.js new file mode 100644 index 00000000000..7a2f4aea181 --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/proto.js @@ -0,0 +1,14 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: The prototype of FinalizationGroup.prototype is Object.prototype +esid: sec-properties-of-the-finalization-group-prototype-object +info: | + The value of the [[Prototype]] internal slot of the FinalizationGroup prototype object + is the intrinsic object %ObjectPrototype%. +features: [FinalizationGroup] +---*/ + +var proto = Object.getPrototypeOf(FinalizationGroup.prototype); +assert.sameValue(proto, Object.prototype); diff --git a/test/built-ins/FinalizationGroup/prototype/register/custom-this.js b/test/built-ins/FinalizationGroup/prototype/register/custom-this.js new file mode 100644 index 00000000000..f9d86ec4f84 --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/register/custom-this.js @@ -0,0 +1,28 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group.prototype.register +description: Return undefined (applying custom this) +info: | + FinalizationGroup.prototype.register ( target , holdings [, unregisterToken ] ) + + 1. Let finalizationGroup be the this value. + 2. If Type(finalizationGroup) is not Object, throw a TypeError exception. + 3. If Type(target) is not Object, throw a TypeError exception. + 4. If finalizationGroup does not have a [[Cells]] internal slot, throw a TypeError exception. + 5. If Type(unregisterToken) is not Object, + a. If unregisterToken is not undefined, throw a TypeError exception. + b. Set unregisterToken to empty. + 6. Let cell be the Record { [[Target]] : target, [[Holdings]]: holdings, [[UnregisterToken]]: unregisterToken }. + 7. Append cell to finalizationGroup.[[Cells]]. + 8. Return undefined. +features: [FinalizationGroup] +---*/ + +var fn = function() {}; +var register = FinalizationGroup.prototype.register; +var fg = new FinalizationGroup(fn); + +var target = {}; +assert.sameValue(register.call(fg, target), undefined); diff --git a/test/built-ins/FinalizationGroup/prototype/register/holdings-any-value-type.js b/test/built-ins/FinalizationGroup/prototype/register/holdings-any-value-type.js new file mode 100644 index 00000000000..a399a4bdb35 --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/register/holdings-any-value-type.js @@ -0,0 +1,37 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group.prototype.register +description: No restriction for the value or type of holdings +info: | + FinalizationGroup.prototype.register ( target , holdings [, unregisterToken ] ) + + 1. Let finalizationGroup be the this value. + 2. If Type(finalizationGroup) is not Object, throw a TypeError exception. + 3. If Type(target) is not Object, throw a TypeError exception. + 4. If finalizationGroup does not have a [[Cells]] internal slot, throw a TypeError exception. + 5. If Type(unregisterToken) is not Object, + a. If unregisterToken is not undefined, throw a TypeError exception. + b. Set unregisterToken to empty. + 6. Let cell be the Record { [[Target]] : target, [[Holdings]]: holdings, [[UnregisterToken]]: unregisterToken }. + 7. Append cell to finalizationGroup.[[Cells]]. + 8. Return undefined. +features: [FinalizationGroup] +---*/ + +var fn = function() {}; +var fg = new FinalizationGroup(fn); + +var target = {}; +assert.sameValue(fg.register(target, undefined), undefined, 'undefined'); +assert.sameValue(fg.register(target, null), undefined, 'null'); +assert.sameValue(fg.register(target, false), undefined, 'false'); +assert.sameValue(fg.register(target, true), undefined, 'true'); +assert.sameValue(fg.register(target, Symbol()), undefined, 'symbol'); +assert.sameValue(fg.register(target, {}), undefined, 'object'); +assert.sameValue(fg.register(target, target), undefined, 'same as target'); +assert.sameValue(fg.register(target, fg), undefined, 'same as fg instance'); +assert.sameValue(fg.register(target, target, target), undefined, 'target, and same as unregisterToken'); +assert.sameValue(fg.register(target, 1), undefined, 'number'); +assert.sameValue(fg.register(target, 'holdings'), undefined, 'string'); diff --git a/test/built-ins/FinalizationGroup/prototype/register/length.js b/test/built-ins/FinalizationGroup/prototype/register/length.js new file mode 100644 index 00000000000..5c18110acef --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/register/length.js @@ -0,0 +1,32 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group.prototype.register +description: FinalizationGroup.prototype.register.length property descriptor +info: | + FinalizationGroup.prototype.register ( target , holdings [, unregisterToken ] ) + + 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] +features: [FinalizationGroup] +---*/ + +verifyProperty(FinalizationGroup.prototype.register, 'length', { + value: 2, + enumerable: false, + writable: false, + configurable: true +}); diff --git a/test/built-ins/FinalizationGroup/prototype/register/name.js b/test/built-ins/FinalizationGroup/prototype/register/name.js new file mode 100644 index 00000000000..d70988d2923 --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/register/name.js @@ -0,0 +1,31 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group.prototype.register +description: FinalizationGroup.prototype.register.name property descriptor +info: | + FinalizationGroup.prototype.register.name value and property descriptor + + 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, 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. [...] + + 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] +features: [FinalizationGroup] +---*/ + +verifyProperty(FinalizationGroup.prototype.register, 'name', { + value: 'register', + enumerable: false, + writable: false, + configurable: true +}); diff --git a/test/built-ins/FinalizationGroup/prototype/register/prop-desc.js b/test/built-ins/FinalizationGroup/prototype/register/prop-desc.js new file mode 100644 index 00000000000..4814634d2ac --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/register/prop-desc.js @@ -0,0 +1,24 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group.prototype.register +description: > + Property descriptor of FinalizationGroup.prototype.register +info: | + 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] +features: [FinalizationGroup] +---*/ + +assert.sameValue(typeof FinalizationGroup.prototype.register, 'function'); + +verifyProperty(FinalizationGroup.prototype, 'register', { + enumerable: false, + writable: true, + configurable: true +}); diff --git a/test/built-ins/FinalizationGroup/prototype/register/return-undefined-register-itself.js b/test/built-ins/FinalizationGroup/prototype/register/return-undefined-register-itself.js new file mode 100644 index 00000000000..a507f6eb17c --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/register/return-undefined-register-itself.js @@ -0,0 +1,28 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group.prototype.register +description: Return undefined after registering itself +info: | + FinalizationGroup.prototype.register ( target , holdings [, unregisterToken ] ) + + 1. Let finalizationGroup be the this value. + 2. If Type(finalizationGroup) is not Object, throw a TypeError exception. + 3. If Type(target) is not Object, throw a TypeError exception. + 4. If finalizationGroup does not have a [[Cells]] internal slot, throw a TypeError exception. + 5. If Type(unregisterToken) is not Object, + a. If unregisterToken is not undefined, throw a TypeError exception. + b. Set unregisterToken to empty. + 6. Let cell be the Record { [[Target]] : target, [[Holdings]]: holdings, [[UnregisterToken]]: unregisterToken }. + 7. Append cell to finalizationGroup.[[Cells]]. + 8. Return undefined. +features: [FinalizationGroup] +---*/ + +var fn = function() {}; +var fg = new FinalizationGroup(fn); + +assert.sameValue(fg.register(fg), undefined, 'Register itself'); +assert.sameValue(fg.register(fg, fg), undefined, 'Register itself with holdings'); +assert.sameValue(fg.register(fg, fg, fg), undefined, 'Register itself with holdings and unregisterToken'); diff --git a/test/built-ins/FinalizationGroup/prototype/register/return-undefined.js b/test/built-ins/FinalizationGroup/prototype/register/return-undefined.js new file mode 100644 index 00000000000..bedf933e000 --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/register/return-undefined.js @@ -0,0 +1,42 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group.prototype.register +description: Return undefined after registering +info: | + FinalizationGroup.prototype.register ( target , holdings [, unregisterToken ] ) + + 1. Let finalizationGroup be the this value. + 2. If Type(finalizationGroup) is not Object, throw a TypeError exception. + 3. If Type(target) is not Object, throw a TypeError exception. + 4. If finalizationGroup does not have a [[Cells]] internal slot, throw a TypeError exception. + 5. If Type(unregisterToken) is not Object, + a. If unregisterToken is not undefined, throw a TypeError exception. + b. Set unregisterToken to empty. + 6. Let cell be the Record { [[Target]] : target, [[Holdings]]: holdings, [[UnregisterToken]]: unregisterToken }. + 7. Append cell to finalizationGroup.[[Cells]]. + 8. Return undefined. +features: [FinalizationGroup] +---*/ + +var fn = function() {}; +var fg = new FinalizationGroup(fn); + +var target = {}; +assert.sameValue(fg.register(target), undefined, 'Register a targer'); +assert.sameValue(fg.register(target), undefined, 'Register the same target again'); +assert.sameValue(fg.register(target), undefined, 'Register the same target again and again'); + +assert.sameValue(fg.register({}), undefined, 'Register other targets'); + +assert.sameValue(fg.register(target, undefined, {}), undefined, 'Register target with unregisterToken'); +assert.sameValue( + fg.register(target, undefined, target), + undefined, + 'Register target with unregisterToken being the registered target' +); + +assert.sameValue(fg.register(target, undefined, undefined), undefined, 'Register target with explicit undefined unregisterToken'); + +assert.sameValue(fg.register(fn), undefined, 'register the cleanup callback fn'); diff --git a/test/built-ins/FinalizationGroup/prototype/register/target-not-object-throws.js b/test/built-ins/FinalizationGroup/prototype/register/target-not-object-throws.js new file mode 100644 index 00000000000..f128d11531c --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/register/target-not-object-throws.js @@ -0,0 +1,52 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group.prototype.register +description: Throws a TypeError if target is not an Object +info: | + FinalizationGroup.prototype.register ( target , holdings [, unregisterToken ] ) + + 1. Let finalizationGroup be the this value. + 2. If Type(finalizationGroup) is not Object, throw a TypeError exception. + 3. If Type(target) is not Object, throw a TypeError exception. + 4. If finalizationGroup does not have a [[Cells]] internal slot, throw a TypeError exception. + 5. If Type(unregisterToken) is not Object, + a. If unregisterToken is not undefined, throw a TypeError exception. + b. Set unregisterToken to empty. + ... +features: [FinalizationGroup] +---*/ + +assert.sameValue(typeof FinalizationGroup.prototype.register, 'function'); + +var fg = new FinalizationGroup(function() {}); + +assert.throws(TypeError, function() { + fg.register(undefined); +}, 'undefined'); + +assert.throws(TypeError, function() { + fg.register(null); +}, 'null'); + +assert.throws(TypeError, function() { + fg.register(true); +}, 'true'); + +assert.throws(TypeError, function() { + fg.register(false); +}, 'false'); + +assert.throws(TypeError, function() { + fg.register(1); +}, 'number'); + +assert.throws(TypeError, function() { + fg.register('object'); +}, 'string'); + +var s = Symbol(); +assert.throws(TypeError, function() { + fg.register(s); +}, 'symbol'); diff --git a/test/built-ins/FinalizationGroup/prototype/register/this-does-not-have-internal-target-throws.js b/test/built-ins/FinalizationGroup/prototype/register/this-does-not-have-internal-target-throws.js new file mode 100644 index 00000000000..c1b509a159b --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/register/this-does-not-have-internal-target-throws.js @@ -0,0 +1,48 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group.prototype.register +description: Throws a TypeError if this does not have a [[Cells]] internal slot +info: | + FinalizationGroup.prototype.register ( target , holdings [, unregisterToken ] ) + + 1. Let finalizationGroup be the this value. + 2. If Type(finalizationGroup) is not Object, throw a TypeError exception. + 3. If Type(target) is not Object, throw a TypeError exception. + 4. If finalizationGroup does not have a [[Cells]] internal slot, throw a TypeError exception. + ... +features: [FinalizationGroup, WeakRef] +---*/ + +assert.sameValue(typeof FinalizationGroup.prototype.register, 'function'); + +var register = FinalizationGroup.prototype.register; +var target = {}; + +assert.throws(TypeError, function() { + register.call({ ['[[Cells]]']: {} }, target); +}, 'Ordinary object without [[Cells]]'); + +assert.throws(TypeError, function() { + register.call(WeakRef.prototype, target); +}, 'WeakRef.prototype does not have a [[Cells]] internal slot'); + +assert.throws(TypeError, function() { + register.call(WeakRef, target); +}, 'WeakRef does not have a [[Cells]] internal slot'); + +var wr = new WeakRef({}); +assert.throws(TypeError, function() { + register.call(wr, target); +}, 'WeakRef instance'); + +var wm = new WeakMap(); +assert.throws(TypeError, function() { + register.call(wm, target); +}, 'WeakMap instance'); + +var ws = new WeakSet(); +assert.throws(TypeError, function() { + register.call(ws, target); +}, 'WeakSet instance'); diff --git a/test/built-ins/FinalizationGroup/prototype/register/this-not-object-throws.js b/test/built-ins/FinalizationGroup/prototype/register/this-not-object-throws.js new file mode 100644 index 00000000000..7635230b1b8 --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/register/this-not-object-throws.js @@ -0,0 +1,51 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group.prototype.register +description: Throws a TypeError if this is not an Object +info: | + FinalizationGroup.prototype.register ( target , holdings [, unregisterToken ] ) + + 1. Let finalizationGroup be the this value. + 2. If Type(finalizationGroup) is not Object, throw a TypeError exception. + 3. If Type(target) is not Object, throw a TypeError exception. + 4. If finalizationGroup does not have a [[Cells]] internal slot, throw a TypeError exception. + 5. If Type(unregisterToken) is not Object, + a. If unregisterToken is not undefined, throw a TypeError exception. + ... +features: [FinalizationGroup] +---*/ + +assert.sameValue(typeof FinalizationGroup.prototype.register, 'function'); + +var register = FinalizationGroup.prototype.register; + +assert.throws(TypeError, function() { + register.call(undefined, {}); +}, 'undefined'); + +assert.throws(TypeError, function() { + register.call(null, {}); +}, 'null'); + +assert.throws(TypeError, function() { + register.call(true, {}); +}, 'true'); + +assert.throws(TypeError, function() { + register.call(false, {}); +}, 'false'); + +assert.throws(TypeError, function() { + register.call(1, {}); +}, 'number'); + +assert.throws(TypeError, function() { + register.call('object', {}); +}, 'string'); + +var s = Symbol(); +assert.throws(TypeError, function() { + register.call(s, {}); +}, 'symbol'); diff --git a/test/built-ins/FinalizationGroup/prototype/register/unregisterToken-not-object-or-undefined-throws.js b/test/built-ins/FinalizationGroup/prototype/register/unregisterToken-not-object-or-undefined-throws.js new file mode 100644 index 00000000000..b0b942ead4d --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/register/unregisterToken-not-object-or-undefined-throws.js @@ -0,0 +1,48 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group.prototype.register +description: Throws a TypeError if unregisterToken is not an Object or undefined +info: | + FinalizationGroup.prototype.register ( target , holdings [, unregisterToken ] ) + + 1. Let finalizationGroup be the this value. + 2. If Type(finalizationGroup) is not Object, throw a TypeError exception. + 3. If Type(target) is not Object, throw a TypeError exception. + 4. If finalizationGroup does not have a [[Cells]] internal slot, throw a TypeError exception. + 5. If Type(unregisterToken) is not Object, + a. If unregisterToken is not undefined, throw a TypeError exception. + ... +features: [FinalizationGroup] +---*/ + +assert.sameValue(typeof FinalizationGroup.prototype.register, 'function'); + +var fg = new FinalizationGroup(function() {}); +var target = {}; + +assert.throws(TypeError, function() { + fg.register(target, undefined, null); +}, 'null'); + +assert.throws(TypeError, function() { + fg.register(target, undefined, true); +}, 'true'); + +assert.throws(TypeError, function() { + fg.register(target, undefined, false); +}, 'false'); + +assert.throws(TypeError, function() { + fg.register(target, undefined, 1); +}, 'number'); + +assert.throws(TypeError, function() { + fg.register(target, undefined, 'object'); +}, 'string'); + +var s = Symbol(); +assert.throws(TypeError, function() { + fg.register(target, undefined, s); +}, 'symbol'); diff --git a/test/built-ins/FinalizationGroup/prototype/unregister/custom-this.js b/test/built-ins/FinalizationGroup/prototype/unregister/custom-this.js new file mode 100644 index 00000000000..1534707a024 --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/unregister/custom-this.js @@ -0,0 +1,47 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group.prototype.unregister +description: Return values applying custom this +info: | + FinalizationGroup.prototype.unregister ( unregisterToken ) + + 1. Let finalizationGroup be the this value. + 2. If Type(finalizationGroup) is not Object, throw a TypeError exception. + 3. If finalizationGroup does not have a [[Cells]] internal slot, throw a TypeError exception. + 4. If Type(unregisterToken) is not Object, throw a TypeError exception. + 5. Let removed be false. + 6. For each Record { [[Target]], [[Holdings]], [[UnregisterToken]] } cell that is an element of finalizationGroup.[[Cells]], do + a. If SameValue(cell.[[UnregisterToken]], unregisterToken) is true, then + i. Remove cell from finalizationGroup.[[Cells]]. + ii. Set removed to true. + 7. Return removed. +features: [FinalizationGroup] +---*/ + +var fn = function() {}; +var unregister = FinalizationGroup.prototype.unregister; +var fg = new FinalizationGroup(fn); + +var target1 = {}; +var target2 = {}; +var target3 = {}; +var token1 = {}; +var token2 = {}; + +assert.sameValue(unregister.call(fg, token1), false, 'unregistering token1 from empty fg'); +assert.sameValue(unregister.call(fg, token2), false, 'unregistering token2 from empty fg'); + +fg.register(target1, undefined, token1); +fg.register(target2, undefined, token2); +fg.register(target3, undefined, token2); + +assert.sameValue(unregister.call(fg, target1), false, 'own target does not work on unregister, #1'); +assert.sameValue(unregister.call(fg, target2), false, 'own target does not work on unregister, #2'); +assert.sameValue(unregister.call(fg, target3), false, 'own target does not work on unregister, #3'); + +assert.sameValue(unregister.call(fg, token1), true, 'unregistering token1 from fg'); +assert.sameValue(unregister.call(fg, token1), false, 'unregistering token1 again from fg'); +assert.sameValue(unregister.call(fg, token2), true, 'unregistering token2 to remove target2 and target3'); +assert.sameValue(unregister.call(fg, token2), false, 'unregistering token2 from empty fg'); diff --git a/test/built-ins/FinalizationGroup/prototype/unregister/length.js b/test/built-ins/FinalizationGroup/prototype/unregister/length.js new file mode 100644 index 00000000000..b3a1df3d88b --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/unregister/length.js @@ -0,0 +1,32 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group.prototype.unregister +description: FinalizationGroup.prototype.unregister.length property descriptor +info: | + FinalizationGroup.prototype.unregister ( unregisterToken ) + + 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] +features: [FinalizationGroup] +---*/ + +verifyProperty(FinalizationGroup.prototype.unregister, 'length', { + value: 1, + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/FinalizationGroup/prototype/unregister/name.js b/test/built-ins/FinalizationGroup/prototype/unregister/name.js new file mode 100644 index 00000000000..94db099a238 --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/unregister/name.js @@ -0,0 +1,31 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group.prototype.unregister +description: FinalizationGroup.prototype.unregister.name property descriptor +info: | + FinalizationGroup.prototype.unregister.name value and property descriptor + + 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, 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. [...] + + 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] +features: [FinalizationGroup] +---*/ + +verifyProperty(FinalizationGroup.prototype.unregister, 'name', { + value: 'unregister', + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/FinalizationGroup/prototype/unregister/prop-desc.js b/test/built-ins/FinalizationGroup/prototype/unregister/prop-desc.js new file mode 100644 index 00000000000..fa2e487a077 --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/unregister/prop-desc.js @@ -0,0 +1,24 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group.prototype.unregister +description: > + Property descriptor of FinalizationGroup.prototype.unregister +info: | + 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] +features: [FinalizationGroup] +---*/ + +assert.sameValue(typeof FinalizationGroup.prototype.unregister, 'function'); + +verifyProperty(FinalizationGroup.prototype, 'unregister', { + enumerable: false, + writable: true, + configurable: true +}); diff --git a/test/built-ins/FinalizationGroup/prototype/unregister/this-does-not-have-internal-cells-throws.js b/test/built-ins/FinalizationGroup/prototype/unregister/this-does-not-have-internal-cells-throws.js new file mode 100644 index 00000000000..eff37a272c9 --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/unregister/this-does-not-have-internal-cells-throws.js @@ -0,0 +1,48 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group.prototype.unregister +description: Throws a TypeError if this does not have a [[Cells]] internal slot +info: | + FinalizationGroup.prototype.unregister ( unregisterToken ) + + 1. Let finalizationGroup be the this value. + 2. If Type(finalizationGroup) is not Object, throw a TypeError exception. + 3. If finalizationGroup does not have a [[Cells]] internal slot, throw a TypeError exception. + 4. If Type(unregisterToken) is not Object, throw a TypeError exception. + ... +features: [FinalizationGroup, WeakRef] +---*/ + +assert.sameValue(typeof FinalizationGroup.prototype.unregister, 'function'); + +var unregister = FinalizationGroup.prototype.unregister; +var token = {}; + +assert.throws(TypeError, function() { + unregister.call({ ['[[Cells]]']: {} }, token); +}, 'Ordinary object without [[Cells]]'); + +assert.throws(TypeError, function() { + unregister.call(WeakRef.prototype, token); +}, 'WeakRef.prototype does not have a [[Cells]] internal slot'); + +assert.throws(TypeError, function() { + unregister.call(WeakRef, token); +}, 'WeakRef does not have a [[Cells]] internal slot'); + +var wr = new WeakRef({}); +assert.throws(TypeError, function() { + unregister.call(wr, token); +}, 'WeakRef instance'); + +var wm = new WeakMap(); +assert.throws(TypeError, function() { + unregister.call(wm, token); +}, 'WeakMap instance'); + +var ws = new WeakSet(); +assert.throws(TypeError, function() { + unregister.call(ws, token); +}, 'WeakSet instance'); diff --git a/test/built-ins/FinalizationGroup/prototype/unregister/this-not-object-throws.js b/test/built-ins/FinalizationGroup/prototype/unregister/this-not-object-throws.js new file mode 100644 index 00000000000..63da68aac68 --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/unregister/this-not-object-throws.js @@ -0,0 +1,49 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group.prototype.unregister +description: Throws a TypeError if this is not an Object +info: | + FinalizationGroup.prototype.unregister ( unregisterToken ) + + 1. Let finalizationGroup be the this value. + 2. If Type(finalizationGroup) is not Object, throw a TypeError exception. + 3. If finalizationGroup does not have a [[Cells]] internal slot, throw a TypeError exception. + 4. If Type(unregisterToken) is not Object, throw a TypeError exception. + ... +features: [FinalizationGroup] +---*/ + +assert.sameValue(typeof FinalizationGroup.prototype.unregister, 'function'); + +var unregister = FinalizationGroup.prototype.unregister; + +assert.throws(TypeError, function() { + unregister.call(undefined, {}); +}, 'undefined'); + +assert.throws(TypeError, function() { + unregister.call(null, {}); +}, 'null'); + +assert.throws(TypeError, function() { + unregister.call(true, {}); +}, 'true'); + +assert.throws(TypeError, function() { + unregister.call(false, {}); +}, 'false'); + +assert.throws(TypeError, function() { + unregister.call(1, {}); +}, 'number'); + +assert.throws(TypeError, function() { + unregister.call('object', {}); +}, 'string'); + +var s = Symbol(); +assert.throws(TypeError, function() { + unregister.call(s, {}); +}, 'symbol'); diff --git a/test/built-ins/FinalizationGroup/prototype/unregister/unregister.js b/test/built-ins/FinalizationGroup/prototype/unregister/unregister.js new file mode 100644 index 00000000000..703415c3619 --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/unregister/unregister.js @@ -0,0 +1,56 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group.prototype.unregister +description: Return boolean values indicating unregistering of values from given token +info: | + FinalizationGroup.prototype.unregister ( unregisterToken ) + + 1. Let finalizationGroup be the this value. + 2. If Type(finalizationGroup) is not Object, throw a TypeError exception. + 3. If finalizationGroup does not have a [[Cells]] internal slot, throw a TypeError exception. + 4. If Type(unregisterToken) is not Object, throw a TypeError exception. + 5. Let removed be false. + 6. For each Record { [[Target]], [[Holdings]], [[UnregisterToken]] } cell that is an element of finalizationGroup.[[Cells]], do + a. If SameValue(cell.[[UnregisterToken]], unregisterToken) is true, then + i. Remove cell from finalizationGroup.[[Cells]]. + ii. Set removed to true. + 7. Return removed. +features: [FinalizationGroup] +---*/ + +var fn = function() {}; +var fg = new FinalizationGroup(fn); + +var target1 = {}; +var target2 = {}; +var target3 = {}; +var token1 = {}; +var token2 = {}; + +assert.sameValue(fg.unregister(token1), false, 'unregistering token1 from empty fg'); +assert.sameValue(fg.unregister(token2), false, 'unregistering token2 from empty fg'); + +fg.register(target1, undefined, token1); +fg.register(target1, undefined, token1); // Repeat registering un purpose +fg.register(target2, undefined, token2); +fg.register(target3, undefined, token2); + +assert.sameValue(fg.unregister(target1), false, 'own target does not work on unregister, #1'); +assert.sameValue(fg.unregister(target2), false, 'own target does not work on unregister, #2'); +assert.sameValue(fg.unregister(target3), false, 'own target does not work on unregister, #3'); + +assert.sameValue(fg.unregister(token1), true, 'unregistering token1 from fg'); +assert.sameValue(fg.unregister(token1), false, 'unregistering token1 again from fg'); +assert.sameValue(fg.unregister(token2), true, 'unregistering token2 to remove target2 and target3'); +assert.sameValue(fg.unregister(token2), false, 'unregistering token2 from empty fg'); + +// Notice these assertions take advantage of adding targets previously added with a token, +// but now they got no token so it won't be used to remove them. +fg.register(target1, token1); // holdings, not unregisterToken +fg.register(target2, token2); // holdings, not unregisterToken +fg.register(target3); + +assert.sameValue(fg.unregister(token1), false, 'nothing to remove without a set unregisterToken #1'); +assert.sameValue(fg.unregister(token2), false, 'nothing to remove without a set unregisterToken #2'); diff --git a/test/built-ins/FinalizationGroup/prototype/unregister/unregisterToken-not-object-throws.js b/test/built-ins/FinalizationGroup/prototype/unregister/unregisterToken-not-object-throws.js new file mode 100644 index 00000000000..de3b8ef5981 --- /dev/null +++ b/test/built-ins/FinalizationGroup/prototype/unregister/unregisterToken-not-object-throws.js @@ -0,0 +1,49 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group.prototype.unregister +description: Throws a TypeError if unregisterToken is not an Object +info: | + FinalizationGroup.prototype.unregister ( unregisterToken ) + + 1. Let finalizationGroup be the this value. + 2. If Type(finalizationGroup) is not Object, throw a TypeError exception. + 3. If finalizationGroup does not have a [[Cells]] internal slot, throw a TypeError exception. + 4. If Type(unregisterToken) is not Object, throw a TypeError exception. + ... +features: [FinalizationGroup] +---*/ + +assert.sameValue(typeof FinalizationGroup.prototype.unregister, 'function'); + +var fg = new FinalizationGroup(function() {}); + +assert.throws(TypeError, function() { + fg.unregister(undefined); +}, 'undefined'); + +assert.throws(TypeError, function() { + fg.unregister(null); +}, 'null'); + +assert.throws(TypeError, function() { + fg.unregister(true); +}, 'true'); + +assert.throws(TypeError, function() { + fg.unregister(false); +}, 'false'); + +assert.throws(TypeError, function() { + fg.unregister(1); +}, 'number'); + +assert.throws(TypeError, function() { + fg.unregister('object'); +}, 'string'); + +var s = Symbol(); +assert.throws(TypeError, function() { + fg.unregister(s); +}, 'symbol'); diff --git a/test/built-ins/FinalizationGroup/returns-new-object-from-constructor.js b/test/built-ins/FinalizationGroup/returns-new-object-from-constructor.js new file mode 100644 index 00000000000..c63f6c5ebf8 --- /dev/null +++ b/test/built-ins/FinalizationGroup/returns-new-object-from-constructor.js @@ -0,0 +1,39 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group-target +description: > + Returns a new ordinary object from the FinalizationGroup constructor +info: | + FinalizationGroup ( cleanupCallback ) + + ... + 3. Let finalizationGroup be ? OrdinaryCreateFromConstructor(NewTarget, "%FinalizationGroupPrototype%", « [[Realm]], [[CleanupCallback]], [[Cells]], [[IsFinalizationGroupCleanupJobActive]] »). + ... + 9. Return finalizationGroup. + + OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] ) + + ... + 2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto). + 3. Return ObjectCreate(proto, internalSlotsList). +features: [FinalizationGroup, for-of] +---*/ + +var cleanupCallback = function() {}; +var fg = new FinalizationGroup(cleanupCallback); + +assert.sameValue(Object.getPrototypeOf(fg), FinalizationGroup.prototype); +assert.notSameValue(fg, cleanupCallback, 'does not return the same function'); +assert.sameValue(fg instanceof FinalizationGroup, true, 'instanceof'); + +for (let key of Object.getOwnPropertyNames(fg)) { + assert(false, `should not set any own named properties: ${key}`); +} + +for (let key of Object.getOwnPropertySymbols(fg)) { + assert(false, `should not set any own symbol properties: ${String(key)}`); +} + +assert.sameValue(Object.getPrototypeOf(fg), FinalizationGroup.prototype); diff --git a/test/built-ins/FinalizationGroup/target-not-callable-throws.js b/test/built-ins/FinalizationGroup/target-not-callable-throws.js new file mode 100644 index 00000000000..d71fbe55825 --- /dev/null +++ b/test/built-ins/FinalizationGroup/target-not-callable-throws.js @@ -0,0 +1,69 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group-target +description: > + Throws a TypeError if target is not callable +info: | + FinalizationGroup ( cleanupCallback ) + + 1. If NewTarget is undefined, throw a TypeError exception. + 2. If IsCallable(cleanupCallback) is false, throw a TypeError exception. + ... +features: [FinalizationGroup] +---*/ + +assert.sameValue( + typeof FinalizationGroup, 'function', + 'typeof FinalizationGroup is function' +); + +assert.throws(TypeError, function() { + new FinalizationGroup({}); +}, 'ordinary object'); + +assert.throws(TypeError, function() { + new FinalizationGroup(WeakRef.prototype); +}, 'WeakRef.prototype'); + +assert.throws(TypeError, function() { + new FinalizationGroup(FinalizationGroup.prototype); +}, 'FinalizationGroup.prototype'); + +assert.throws(TypeError, function() { + new FinalizationGroup([]); +}, 'Array'); + +assert.throws(TypeError, function() { + new FinalizationGroup(); +}, 'implicit undefined'); + +assert.throws(TypeError, function() { + new FinalizationGroup(undefined); +}, 'explicit undefined'); + +assert.throws(TypeError, function() { + new FinalizationGroup(null); +}, 'null'); + +assert.throws(TypeError, function() { + new FinalizationGroup(1); +}, 'number'); + +assert.throws(TypeError, function() { + new FinalizationGroup('Object'); +}, 'string'); + +var s = Symbol(); +assert.throws(TypeError, function() { + new FinalizationGroup(s); +}, 'symbol'); + +assert.throws(TypeError, function() { + new FinalizationGroup(true); +}, 'Boolean, true'); + +assert.throws(TypeError, function() { + new FinalizationGroup(false); +}, 'Boolean, false'); diff --git a/test/built-ins/FinalizationGroup/undefined-newtarget-throws.js b/test/built-ins/FinalizationGroup/undefined-newtarget-throws.js new file mode 100644 index 00000000000..6f402734864 --- /dev/null +++ b/test/built-ins/FinalizationGroup/undefined-newtarget-throws.js @@ -0,0 +1,28 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group-target +description: > + Throws a TypeError if NewTarget is undefined. +info: | + FinalizationGroup ( cleanupCallback ) + + 1. If NewTarget is undefined, throw a TypeError exception. + 2. If IsCallable(cleanupCallback) is false, throw a TypeError exception. + ... +features: [FinalizationGroup] +---*/ + +assert.sameValue( + typeof FinalizationGroup, 'function', + 'typeof FinalizationGroup is function' +); + +assert.throws(TypeError, function() { + FinalizationGroup(); +}); + +assert.throws(TypeError, function() { + FinalizationGroup(function() {}); +}); diff --git a/test/built-ins/FinalizationGroup/unnaffected-by-poisoned-cleanupCallback.js b/test/built-ins/FinalizationGroup/unnaffected-by-poisoned-cleanupCallback.js new file mode 100644 index 00000000000..5b1d1cf9111 --- /dev/null +++ b/test/built-ins/FinalizationGroup/unnaffected-by-poisoned-cleanupCallback.js @@ -0,0 +1,33 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-finalization-group-target +description: > + Normal completion even if the cleanupCallback fn is poisoned +info: | + FinalizationGroup ( cleanupCallback ) + + ... + 3. Let finalizationGroup be ? OrdinaryCreateFromConstructor(NewTarget, "%FinalizationGroupPrototype%", « [[Realm]], [[CleanupCallback]], [[Cells]], [[IsFinalizationGroupCleanupJobActive]] »). + ... + 9. Return finalizationGroup. +features: [FinalizationGroup] +---*/ + +var cleanupCallback = function() { throw new Test262Error('should not throw yet'); }; +var fg = new FinalizationGroup(cleanupCallback); + +assert.sameValue(Object.getPrototypeOf(fg), FinalizationGroup.prototype); +assert.notSameValue(fg, cleanupCallback, 'does not return the same function'); +assert.sameValue(fg instanceof FinalizationGroup, true, 'instanceof'); + +for (let key of Object.getOwnPropertyNames(fg)) { + assert(false, `should not set any own named properties: ${key}`); +} + +for (let key of Object.getOwnPropertySymbols(fg)) { + assert(false, `should not set any own symbol properties: ${String(key)}`); +} + +assert.sameValue(Object.getPrototypeOf(fg), FinalizationGroup.prototype); diff --git a/test/built-ins/WeakRef/constructor.js b/test/built-ins/WeakRef/constructor.js new file mode 100644 index 00000000000..cfc74fe3e17 --- /dev/null +++ b/test/built-ins/WeakRef/constructor.js @@ -0,0 +1,14 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-weak-ref-constructor +description: > + The WeakRef constructor is the %WeakRef% intrinsic object and the initial + value of the WeakRef property of the global object. +---*/ + +assert.sameValue( + typeof WeakRef, 'function', + 'typeof WeakRef is function' +); diff --git a/test/built-ins/WeakRef/instance-extensible.js b/test/built-ins/WeakRef/instance-extensible.js new file mode 100644 index 00000000000..d6249e22ee9 --- /dev/null +++ b/test/built-ins/WeakRef/instance-extensible.js @@ -0,0 +1,31 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-weak-ref-target +description: Instances of WeakRef are extensible +info: | + WeakRef( target ) + + ... + 3. Let weakRef be ? OrdinaryCreateFromConstructor(NewTarget, "%WeakRefPrototype%", « [[Target]] »). + 4. Perfom ! KeepDuringJob(target). + 5. Set weakRef.[[Target]] to target. + 6. Return weakRef. + + OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] ) + + ... + 2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto). + 3. Return ObjectCreate(proto, internalSlotsList). + + ObjectCreate ( proto [ , internalSlotsList ] ) + + 4. Set obj.[[Prototype]] to proto. + 5. Set obj.[[Extensible]] to true. + 6. Return obj. +features: [WeakRef, Reflect] +---*/ + +var wr = new WeakRef({}); +assert.sameValue(Object.isExtensible(wr), true); diff --git a/test/built-ins/WeakRef/length.js b/test/built-ins/WeakRef/length.js new file mode 100644 index 00000000000..9ced86beb43 --- /dev/null +++ b/test/built-ins/WeakRef/length.js @@ -0,0 +1,32 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-weak-ref-target +description: WeakRef.length property descriptor +info: | + WeakRef ( target ) + + 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] +features: [WeakRef] +---*/ + +verifyProperty(WeakRef, 'length', { + value: 1, + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/WeakRef/name.js b/test/built-ins/WeakRef/name.js new file mode 100644 index 00000000000..d47b73b5df0 --- /dev/null +++ b/test/built-ins/WeakRef/name.js @@ -0,0 +1,31 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-weak-ref-target +description: WeakRef.name property descriptor +info: | + WeakRef ( value ) + + 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, 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. [...] + + 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] +features: [WeakRef] +---*/ + +verifyProperty(WeakRef, 'name', { + value: 'WeakRef', + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/WeakRef/newtarget-prototype-is-not-object.js b/test/built-ins/WeakRef/newtarget-prototype-is-not-object.js new file mode 100644 index 00000000000..0313813aca1 --- /dev/null +++ b/test/built-ins/WeakRef/newtarget-prototype-is-not-object.js @@ -0,0 +1,58 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-weak-ref-target +description: > + [[Prototype]] defaults to %WeakRefPrototype% if NewTarget.prototype is not an object. +info: | + WeakRef( target ) + + ... + 3. Let weakRef be ? OrdinaryCreateFromConstructor(NewTarget, "%WeakRefPrototype%", « [[Target]] »). + 4. Perfom ! KeepDuringJob(target). + 5. Set weakRef.[[Target]] to target. + 6. Return weakRef. + + OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] ) + + ... + 2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto). + 3. Return ObjectCreate(proto, internalSlotsList). + + GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto ) + + 3. Let proto be ? Get(constructor, 'prototype'). + 4. If Type(proto) is not Object, then + a. Let realm be ? GetFunctionRealm(constructor). + b. Set proto to realm's intrinsic object named intrinsicDefaultProto. + 5. Return proto. +features: [WeakRef, Reflect.construct, Symbol] +---*/ + +var wr; +function newTarget() {} + +newTarget.prototype = undefined; +wr = Reflect.construct(WeakRef, [{}], newTarget); +assert.sameValue(Object.getPrototypeOf(wr), WeakRef.prototype, 'newTarget.prototype is undefined'); + +newTarget.prototype = null; +wr = Reflect.construct(WeakRef, [{}], newTarget); +assert.sameValue(Object.getPrototypeOf(wr), WeakRef.prototype, 'newTarget.prototype is null'); + +newTarget.prototype = true; +wr = Reflect.construct(WeakRef, [{}], newTarget); +assert.sameValue(Object.getPrototypeOf(wr), WeakRef.prototype, 'newTarget.prototype is a Boolean'); + +newTarget.prototype = ''; +wr = Reflect.construct(WeakRef, [{}], newTarget); +assert.sameValue(Object.getPrototypeOf(wr), WeakRef.prototype, 'newTarget.prototype is a String'); + +newTarget.prototype = Symbol(); +wr = Reflect.construct(WeakRef, [{}], newTarget); +assert.sameValue(Object.getPrototypeOf(wr), WeakRef.prototype, 'newTarget.prototype is a Symbol'); + +newTarget.prototype = 1; +wr = Reflect.construct(WeakRef, [{}], newTarget); +assert.sameValue(Object.getPrototypeOf(wr), WeakRef.prototype, 'newTarget.prototype is a Number'); diff --git a/test/built-ins/WeakRef/prop-desc.js b/test/built-ins/WeakRef/prop-desc.js new file mode 100644 index 00000000000..26a9b2933ef --- /dev/null +++ b/test/built-ins/WeakRef/prop-desc.js @@ -0,0 +1,22 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-weak-ref-constructor +description: > + Property descriptor of WeakRef +info: | + 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] +features: [WeakRef] +---*/ + +verifyProperty(this, 'WeakRef', { + enumerable: false, + writable: true, + configurable: true +}); diff --git a/test/built-ins/WeakRef/proto-from-ctor-realm.js b/test/built-ins/WeakRef/proto-from-ctor-realm.js new file mode 100644 index 00000000000..4345e095d14 --- /dev/null +++ b/test/built-ins/WeakRef/proto-from-ctor-realm.js @@ -0,0 +1,59 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-weak-ref-target +description: Default [[Prototype]] value derived from realm of the newTarget +info: | + WeakRef( target ) + + ... + 3. Let weakRef be ? OrdinaryCreateFromConstructor(NewTarget, '%WeakRefPrototype%', « [[Target]] »). + 4. Perfom ! KeepDuringJob(target). + 5. Set weakRef.[[Target]] to target. + 6. Return weakRef. + + OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] ) + + ... + 2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto). + 3. Return ObjectCreate(proto, internalSlotsList). + + GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto ) + + 3. Let proto be ? Get(constructor, 'prototype'). + 4. If Type(proto) is not Object, then + a. Let realm be ? GetFunctionRealm(constructor). + b. Set proto to realm's intrinsic object named intrinsicDefaultProto. + 5. Return proto. +features: [WeakRef, cross-realm, Reflect] +---*/ + +var other = $262.createRealm().global; +var newTarget = new other.Function(); +var wr; + +newTarget.prototype = undefined; +wr = Reflect.construct(WeakRef, [{}], newTarget); +assert.sameValue(Object.getPrototypeOf(wr), other.WeakRef.prototype, 'newTarget.prototype is undefined'); + +newTarget.prototype = null; +wr = Reflect.construct(WeakRef, [{}], newTarget); +assert.sameValue(Object.getPrototypeOf(wr), other.WeakRef.prototype, 'newTarget.prototype is null'); + +newTarget.prototype = true; +wr = Reflect.construct(WeakRef, [{}], newTarget); +assert.sameValue(Object.getPrototypeOf(wr), other.WeakRef.prototype, 'newTarget.prototype is a Boolean'); + +newTarget.prototype = ''; +wr = Reflect.construct(WeakRef, [{}], newTarget); +assert.sameValue(Object.getPrototypeOf(wr), other.WeakRef.prototype, 'newTarget.prototype is a String'); + +newTarget.prototype = Symbol(); +wr = Reflect.construct(WeakRef, [{}], newTarget); +assert.sameValue(Object.getPrototypeOf(wr), other.WeakRef.prototype, 'newTarget.prototype is a Symbol'); + +newTarget.prototype = 1; +wr = Reflect.construct(WeakRef, [{}], newTarget); +assert.sameValue(Object.getPrototypeOf(wr), other.WeakRef.prototype, 'newTarget.prototype is a Number'); + diff --git a/test/built-ins/WeakRef/proto.js b/test/built-ins/WeakRef/proto.js new file mode 100644 index 00000000000..aee0662d8eb --- /dev/null +++ b/test/built-ins/WeakRef/proto.js @@ -0,0 +1,18 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-properties-of-the-weak-ref-constructor +description: > + The prototype of WeakRef is Object.prototype +info: | + The value of the [[Prototype]] internal slot of the WeakRef object is the + intrinsic object %FunctionPrototype%. +features: [WeakRef] +---*/ + +assert.sameValue( + Object.getPrototypeOf(WeakRef), + Function.prototype, + 'Object.getPrototypeOf(WeakRef) returns the value of `Function.prototype`' +); diff --git a/test/built-ins/WeakRef/prototype-from-newtarget-abrupt.js b/test/built-ins/WeakRef/prototype-from-newtarget-abrupt.js new file mode 100644 index 00000000000..952b2afb8cb --- /dev/null +++ b/test/built-ins/WeakRef/prototype-from-newtarget-abrupt.js @@ -0,0 +1,42 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-weak-ref-target +description: > + Return abrupt from getting the NewTarget prototype +info: | + WeakRef ( target ) + + ... + 3. Let weakRef be ? OrdinaryCreateFromConstructor(NewTarget, "%WeakRefPrototype%", « [[Target]] »). + 4. Perfom ! KeepDuringJob(target). + 5. Set weakRef.[[Target]] to target. + 6. Return weakRef. + + OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] ) + + ... + 2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto). + 3. Return ObjectCreate(proto, internalSlotsList). + + GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto ) + + 3. Let proto be ? Get(constructor, 'prototype'). +features: [WeakRef, Reflect.construct] +---*/ + +var calls = 0; +var newTarget = function() {}.bind(null); +Object.defineProperty(newTarget, 'prototype', { + get: function() { + calls += 1; + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + Reflect.construct(WeakRef, [{}], newTarget); +}); + +assert.sameValue(calls, 1); \ No newline at end of file diff --git a/test/built-ins/WeakRef/prototype-from-newtarget-custom.js b/test/built-ins/WeakRef/prototype-from-newtarget-custom.js new file mode 100644 index 00000000000..104781f5074 --- /dev/null +++ b/test/built-ins/WeakRef/prototype-from-newtarget-custom.js @@ -0,0 +1,45 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-weak-ref-target +description: > + The [[Prototype]] internal slot is computed from NewTarget. +info: | + WeakRef ( target ) + + ... + 3. Let weakRef be ? OrdinaryCreateFromConstructor(NewTarget, "%WeakRefPrototype%", « [[Target]] »). + 4. Perfom ! KeepDuringJob(target). + 5. Set weakRef.[[Target]] to target. + 6. Return weakRef. + + OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] ) + + ... + 2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto). + 3. Return ObjectCreate(proto, internalSlotsList). + + GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto ) + + 3. Let proto be ? Get(constructor, 'prototype'). + 4. If Type(proto) is not Object, then + a. Let realm be ? GetFunctionRealm(constructor). + b. Set proto to realm's intrinsic object named intrinsicDefaultProto. + 5. Return proto. +features: [WeakRef, Reflect.construct] +---*/ + +var wr; + +wr = Reflect.construct(WeakRef, [{}], Object); +assert.sameValue(Object.getPrototypeOf(wr), Object.prototype, 'NewTarget is built-in Object constructor'); + +var newTarget = function() {}.bind(null); +Object.defineProperty(newTarget, 'prototype', { + get: function() { + return Array.prototype; + } +}); +wr = Reflect.construct(WeakRef, [{}], newTarget); +assert.sameValue(Object.getPrototypeOf(wr), Array.prototype, 'NewTarget is BoundFunction with accessor'); diff --git a/test/built-ins/WeakRef/prototype-from-newtarget.js b/test/built-ins/WeakRef/prototype-from-newtarget.js new file mode 100644 index 00000000000..e7aa89dba19 --- /dev/null +++ b/test/built-ins/WeakRef/prototype-from-newtarget.js @@ -0,0 +1,34 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-weak-ref-target +description: > + The [[Prototype]] internal slot is computed from NewTarget. +info: | + WeakRef ( target ) + + ... + 3. Let weakRef be ? OrdinaryCreateFromConstructor(NewTarget, "%WeakRefPrototype%", « [[Target]] »). + 4. Perfom ! KeepDuringJob(target). + 5. Set weakRef.[[Target]] to target. + 6. Return weakRef. + + OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] ) + + ... + 2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto). + 3. Return ObjectCreate(proto, internalSlotsList). + + GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto ) + + 3. Let proto be ? Get(constructor, 'prototype'). + 4. If Type(proto) is not Object, then + a. Let realm be ? GetFunctionRealm(constructor). + b. Set proto to realm's intrinsic object named intrinsicDefaultProto. + 5. Return proto. +features: [WeakRef] +---*/ + +var wr = new WeakRef({}); +assert.sameValue(Object.getPrototypeOf(wr), WeakRef.prototype); diff --git a/test/built-ins/WeakRef/prototype/Symbol.toStringTag.js b/test/built-ins/WeakRef/prototype/Symbol.toStringTag.js new file mode 100644 index 00000000000..a6d4e11d865 --- /dev/null +++ b/test/built-ins/WeakRef/prototype/Symbol.toStringTag.js @@ -0,0 +1,23 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-weak-ref-@@tostringtag +description: > + `Symbol.toStringTag` property descriptor +info: | + The initial value of the @@toStringTag property is the String value + 'WeakRef'. + + This property has the attributes { [[Writable]]: false, [[Enumerable]]: + false, [[Configurable]]: true }. +includes: [propertyHelper.js] +features: [WeakRef, Symbol, Symbol.toStringTag] +---*/ + +verifyProperty(WeakRef.prototype, Symbol.toStringTag, { + value: 'WeakRef', + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/WeakRef/prototype/constructor.js b/test/built-ins/WeakRef/prototype/constructor.js new file mode 100644 index 00000000000..d9c1e5c55b6 --- /dev/null +++ b/test/built-ins/WeakRef/prototype/constructor.js @@ -0,0 +1,31 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-properties-of-the-weak-ref-prototype-object +description: WeakRef.prototype.constructor +info: | + WeakRef.prototype.constructor + + Normative Optional + + The initial value of WeakRef.prototype.constructor is the intrinsic object %WeakRef%. + + This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }. + + This section is to be treated identically to the "Annex B" of ECMA-262, but to be written in-line with the main specification. +includes: [propertyHelper.js] +features: [WeakRef] +---*/ + +var actual = WeakRef.prototype.hasOwnProperty('constructor'); + +// If implemented, it should conform to the spec text +if (actual) { + verifyProperty(WeakRef.prototype, 'constructor', { + value: WeakRef, + writable: true, + enumerable: false, + configurable: true + }); +} diff --git a/test/built-ins/WeakRef/prototype/deref/custom-this.js b/test/built-ins/WeakRef/prototype/deref/custom-this.js new file mode 100644 index 00000000000..44d571d171f --- /dev/null +++ b/test/built-ins/WeakRef/prototype/deref/custom-this.js @@ -0,0 +1,27 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-weak-ref.prototype.deref +description: Return target if weakRef.[[Target]] is not empty (applying custom this) +info: | + WeakRef.prototype.deref () + + 1. Let weakRef be the this value. + ... + 4. Let target be the value of weakRef.[[Target]]. + 5. If target is not empty, + a. Perform ! KeepDuringJob(target). + b. Return target. + 6. Return undefined. +features: [WeakRef] +---*/ + +var target = {}; +var deref = WeakRef.prototype.deref; +var wref = new WeakRef(target); + +assert.sameValue(deref.call(wref), target, 'returns target'); +assert.sameValue(deref.call(wref), target, '[[Target]] is not emptied #1'); +assert.sameValue(deref.call(wref), target, '[[Target]] is not emptied #2'); +assert.sameValue(deref.call(wref), target, '[[Target]] is not emptied #3'); diff --git a/test/built-ins/WeakRef/prototype/deref/length.js b/test/built-ins/WeakRef/prototype/deref/length.js new file mode 100644 index 00000000000..f9103c0cf5c --- /dev/null +++ b/test/built-ins/WeakRef/prototype/deref/length.js @@ -0,0 +1,32 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-weak-ref.prototype.deref +description: WeakRef.prototype.deref.length property descriptor +info: | + WeakRef.prototype.deref () + + 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] +features: [WeakRef] +---*/ + +verifyProperty(WeakRef.prototype.deref, 'length', { + value: 0, + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/WeakRef/prototype/deref/name.js b/test/built-ins/WeakRef/prototype/deref/name.js new file mode 100644 index 00000000000..5d512bb03db --- /dev/null +++ b/test/built-ins/WeakRef/prototype/deref/name.js @@ -0,0 +1,31 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-weak-ref.prototype.deref +description: WeakRef.prototype.deref.name property descriptor +info: | + WeakRef.prototype.deref.name value and property descriptor + + 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, 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. [...] + + 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] +features: [WeakRef] +---*/ + +verifyProperty(WeakRef.prototype.deref, 'name', { + value: 'deref', + writable: false, + enumerable: false, + configurable: true +}); diff --git a/test/built-ins/WeakRef/prototype/deref/prop-desc.js b/test/built-ins/WeakRef/prototype/deref/prop-desc.js new file mode 100644 index 00000000000..e8d03591498 --- /dev/null +++ b/test/built-ins/WeakRef/prototype/deref/prop-desc.js @@ -0,0 +1,24 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-weak-ref.prototype.deref +description: > + Property descriptor of WeakRef.prototype.deref +info: | + 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] +features: [WeakRef] +---*/ + +assert.sameValue(typeof WeakRef.prototype.deref, 'function'); + +verifyProperty(WeakRef.prototype, 'deref', { + enumerable: false, + writable: true, + configurable: true +}); diff --git a/test/built-ins/WeakRef/prototype/deref/return-target.js b/test/built-ins/WeakRef/prototype/deref/return-target.js new file mode 100644 index 00000000000..19bb5e6204b --- /dev/null +++ b/test/built-ins/WeakRef/prototype/deref/return-target.js @@ -0,0 +1,25 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-weak-ref.prototype.deref +description: Return target if weakRef.[[Target]] is not empty +info: | + WeakRef.prototype.deref () + + ... + 4. Let target be the value of weakRef.[[Target]]. + 5. If target is not empty, + a. Perform ! KeepDuringJob(target). + b. Return target. + 6. Return undefined. +features: [WeakRef] +---*/ + +var target = {}; +var wref = new WeakRef(target); + +assert.sameValue(wref.deref(), target, 'returns target'); +assert.sameValue(wref.deref(), target, '[[Target]] is not emptied #1'); +assert.sameValue(wref.deref(), target, '[[Target]] is not emptied #2'); +assert.sameValue(wref.deref(), target, '[[Target]] is not emptied #3'); diff --git a/test/built-ins/WeakRef/prototype/deref/this-does-not-have-internal-target-throws.js b/test/built-ins/WeakRef/prototype/deref/this-does-not-have-internal-target-throws.js new file mode 100644 index 00000000000..c21d0485123 --- /dev/null +++ b/test/built-ins/WeakRef/prototype/deref/this-does-not-have-internal-target-throws.js @@ -0,0 +1,50 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-weak-ref.prototype.deref +description: Throws a TypeError if this does not have a [[Target]] internal slot +info: | + WeakRef.prototype.deref () + + 1. Let weakRef be the this value. + 2. If Type(weakRef) is not Object, throw a TypeError exception. + 3. If weakRef does not have a [[Target]] internal slot, throw a TypeError exception. + 4. Let target be the value of weakRef.[[Target]]. + 5. If target is not empty, + a. Perform ! KeepDuringJob(target). + b. Return target. + 6. Return undefined. +features: [WeakRef, FinalizationGroup] +---*/ + +assert.sameValue(typeof WeakRef.prototype.deref, 'function'); + +var deref = WeakRef.prototype.deref; + +assert.throws(TypeError, function() { + deref.call({ ['[[Target]]']: {} }); +}, 'Ordinary object without [[Target]]'); + +assert.throws(TypeError, function() { + deref.call(WeakRef.prototype); +}, 'WeakRef.prototype does not have a [[Target]] internal slot'); + +assert.throws(TypeError, function() { + deref.call(WeakRef); +}, 'WeakRef does not have a [[Target]] internal slot'); + +var fg = new FinalizationGroup(function() {}); +assert.throws(TypeError, function() { + deref.call(fg); +}, 'FinalizationGroup instance'); + +var wm = new WeakMap(); +assert.throws(TypeError, function() { + deref.call(wm); +}, 'WeakMap instance'); + +var ws = new WeakSet(); +assert.throws(TypeError, function() { + deref.call(ws); +}, 'WeakSet instance'); diff --git a/test/built-ins/WeakRef/prototype/deref/this-not-object-throws.js b/test/built-ins/WeakRef/prototype/deref/this-not-object-throws.js new file mode 100644 index 00000000000..05adca195a0 --- /dev/null +++ b/test/built-ins/WeakRef/prototype/deref/this-not-object-throws.js @@ -0,0 +1,52 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-weak-ref.prototype.deref +description: Throws a TypeError if this is not an Object +info: | + WeakRef.prototype.deref () + + 1. Let weakRef be the this value. + 2. If Type(weakRef) is not Object, throw a TypeError exception. + 3. If weakRef does not have a [[Target]] internal slot, throw a TypeError exception. + 4. Let target be the value of weakRef.[[Target]]. + 5. If target is not empty, + a. Perform ! KeepDuringJob(target). + b. Return target. + 6. Return undefined. +features: [WeakRef] +---*/ + +assert.sameValue(typeof WeakRef.prototype.deref, 'function'); + +var deref = WeakRef.prototype.deref; + +assert.throws(TypeError, function() { + deref.call(undefined); +}, 'undefined'); + +assert.throws(TypeError, function() { + deref.call(null); +}, 'null'); + +assert.throws(TypeError, function() { + deref.call(true); +}, 'true'); + +assert.throws(TypeError, function() { + deref.call(false); +}, 'false'); + +assert.throws(TypeError, function() { + deref.call(1); +}, 'number'); + +assert.throws(TypeError, function() { + deref.call('object'); +}, 'string'); + +var s = Symbol(); +assert.throws(TypeError, function() { + deref.call(s); +}, 'symbol'); diff --git a/test/built-ins/WeakRef/prototype/prop-desc.js b/test/built-ins/WeakRef/prototype/prop-desc.js new file mode 100644 index 00000000000..8f4bacc735a --- /dev/null +++ b/test/built-ins/WeakRef/prototype/prop-desc.js @@ -0,0 +1,18 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: The property descriptor WeakRef.prototype +esid: sec-weak-ref.prototype +info: | + This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, + [[Configurable]]: false }. +features: [WeakRef] +includes: [propertyHelper.js] +---*/ + +verifyProperty(WeakRef, 'prototype', { + writable: false, + enumerable: false, + configurable: false +}); diff --git a/test/built-ins/WeakRef/prototype/proto.js b/test/built-ins/WeakRef/prototype/proto.js new file mode 100644 index 00000000000..8df09824be5 --- /dev/null +++ b/test/built-ins/WeakRef/prototype/proto.js @@ -0,0 +1,14 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +description: The prototype of WeakRef.prototype is Object.prototype +esid: sec-properties-of-the-weak-ref-prototype-object +info: | + The value of the [[Prototype]] internal slot of the WeakRef prototype object + is the intrinsic object %ObjectPrototype%. +features: [WeakRef] +---*/ + +var proto = Object.getPrototypeOf(WeakRef.prototype); +assert.sameValue(proto, Object.prototype); diff --git a/test/built-ins/WeakRef/returns-new-object-from-constructor.js b/test/built-ins/WeakRef/returns-new-object-from-constructor.js new file mode 100644 index 00000000000..9e52f88d6bb --- /dev/null +++ b/test/built-ins/WeakRef/returns-new-object-from-constructor.js @@ -0,0 +1,49 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-weak-ref-target +description: > + Returns a new ordinary object from the WeakRef constructor +info: | + WeakRef ( target ) + + ... + 3. Let weakRef be ? OrdinaryCreateFromConstructor(NewTarget, "%WeakRefPrototype%", « [[Target]] »). + 4. Perfom ! KeepDuringJob(target). + 5. Set weakRef.[[Target]] to target. + 6. Return weakRef. + + OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] ) + + ... + 2. Let proto be ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto). + 3. Return ObjectCreate(proto, internalSlotsList). + + GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto ) + + 3. Let proto be ? Get(constructor, 'prototype'). + 4. If Type(proto) is not Object, then + a. Let realm be ? GetFunctionRealm(constructor). + b. Set proto to realm's intrinsic object named intrinsicDefaultProto. + 5. Return proto. +features: [WeakRef] +---*/ + +var target = {}; +var wr = new WeakRef(target); + +assert.notSameValue(wr, target, 'does not return the same object'); +assert.sameValue(wr instanceof WeakRef, true, 'instanceof'); + +for (let key of Object.getOwnPropertyNames(wr)) { + assert(false, `should not set any own named properties: ${key}`); +} + +for (let key of Object.getOwnPropertySymbols(wr)) { + assert(false, `should not set any own symbol properties: ${String(key)}`); +} + +assert.sameValue(Object.getPrototypeOf(wr), WeakRef.prototype); + + diff --git a/test/built-ins/WeakRef/target-not-object-throws.js b/test/built-ins/WeakRef/target-not-object-throws.js new file mode 100644 index 00000000000..53227704494 --- /dev/null +++ b/test/built-ins/WeakRef/target-not-object-throws.js @@ -0,0 +1,53 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-weak-ref-target +description: > + Throws a TypeError if target is not Object +info: | + WeakRef ( target ) + + 1. If NewTarget is undefined, throw a TypeError exception. + 2. If Type(target) is not Object, throw a TypeError exception. + ... +features: [WeakRef] +---*/ + +assert.sameValue( + typeof WeakRef, 'function', + 'typeof WeakRef is function' +); + +assert.throws(TypeError, function() { + new WeakRef(); +}, 'implicit undefined'); + +assert.throws(TypeError, function() { + new WeakRef(undefined); +}, 'explicit undefined'); + +assert.throws(TypeError, function() { + new WeakRef(null); +}, 'null'); + +assert.throws(TypeError, function() { + new WeakRef(1); +}, 'number'); + +assert.throws(TypeError, function() { + new WeakRef('Object'); +}, 'string'); + +var s = Symbol(); +assert.throws(TypeError, function() { + new WeakRef(s); +}, 'symbol'); + +assert.throws(TypeError, function() { + new WeakRef(true); +}, 'Boolean, true'); + +assert.throws(TypeError, function() { + new WeakRef(false); +}, 'Boolean, false'); diff --git a/test/built-ins/WeakRef/undefined-newtarget-throws.js b/test/built-ins/WeakRef/undefined-newtarget-throws.js new file mode 100644 index 00000000000..942a0706939 --- /dev/null +++ b/test/built-ins/WeakRef/undefined-newtarget-throws.js @@ -0,0 +1,28 @@ +// Copyright (C) 2019 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-weak-ref-target +description: > + Throws a TypeError if NewTarget is undefined. +info: | + WeakRef ( target ) + + 1. If NewTarget is undefined, throw a TypeError exception. + 2. If Type(target) is not Object, throw a TypeError exception. + ... +features: [WeakRef] +---*/ + +assert.sameValue( + typeof WeakRef, 'function', + 'typeof WeakRef is function' +); + +assert.throws(TypeError, function() { + WeakRef(); +}); + +assert.throws(TypeError, function() { + WeakRef({}); +});