From dcac20d8edf92b158ef8481c95dd8d5fb9beed53 Mon Sep 17 00:00:00 2001 From: Leo Balter Date: Fri, 7 Jun 2019 17:32:34 -0400 Subject: [PATCH] Add tests for FG register/unregister --- .../prototype/register/custom-this.js | 28 ++++++++++ .../register/holdings-any-value-type.js | 37 ++++++++++++ .../prototype/register/length.js | 32 +++++++++++ .../prototype/register/name.js | 31 ++++++++++ .../prototype/register/prop-desc.js | 24 ++++++++ .../return-undefined-register-itself.js | 28 ++++++++++ .../prototype/register/return-undefined.js | 42 ++++++++++++++ .../register/target-not-object-throws.js | 52 +++++++++++++++++ ...is-does-not-have-internal-target-throws.js | 48 ++++++++++++++++ .../register/this-not-object-throws.js | 51 +++++++++++++++++ ...terToken-not-object-or-undefined-throws.js | 48 ++++++++++++++++ .../prototype/unregister/custom-this.js | 47 ++++++++++++++++ .../prototype/unregister/length.js | 32 +++++++++++ .../prototype/unregister/name.js | 31 ++++++++++ .../prototype/unregister/prop-desc.js | 24 ++++++++ ...his-does-not-have-internal-cells-throws.js | 48 ++++++++++++++++ .../unregister/this-not-object-throws.js | 49 ++++++++++++++++ .../prototype/unregister/unregister.js | 56 +++++++++++++++++++ .../unregisterToken-not-object-throws.js | 49 ++++++++++++++++ .../returns-new-object-from-constructor.js | 40 +++++++++++++ ...is-does-not-have-internal-target-throws.js | 19 ++++--- .../prototype/deref/this-not-object-throws.js | 16 +++--- 22 files changed, 817 insertions(+), 15 deletions(-) create mode 100644 test/built-ins/FinalizationGroup/prototype/register/custom-this.js create mode 100644 test/built-ins/FinalizationGroup/prototype/register/holdings-any-value-type.js create mode 100644 test/built-ins/FinalizationGroup/prototype/register/length.js create mode 100644 test/built-ins/FinalizationGroup/prototype/register/name.js create mode 100644 test/built-ins/FinalizationGroup/prototype/register/prop-desc.js create mode 100644 test/built-ins/FinalizationGroup/prototype/register/return-undefined-register-itself.js create mode 100644 test/built-ins/FinalizationGroup/prototype/register/return-undefined.js create mode 100644 test/built-ins/FinalizationGroup/prototype/register/target-not-object-throws.js create mode 100644 test/built-ins/FinalizationGroup/prototype/register/this-does-not-have-internal-target-throws.js create mode 100644 test/built-ins/FinalizationGroup/prototype/register/this-not-object-throws.js create mode 100644 test/built-ins/FinalizationGroup/prototype/register/unregisterToken-not-object-or-undefined-throws.js create mode 100644 test/built-ins/FinalizationGroup/prototype/unregister/custom-this.js create mode 100644 test/built-ins/FinalizationGroup/prototype/unregister/length.js create mode 100644 test/built-ins/FinalizationGroup/prototype/unregister/name.js create mode 100644 test/built-ins/FinalizationGroup/prototype/unregister/prop-desc.js create mode 100644 test/built-ins/FinalizationGroup/prototype/unregister/this-does-not-have-internal-cells-throws.js create mode 100644 test/built-ins/FinalizationGroup/prototype/unregister/this-not-object-throws.js create mode 100644 test/built-ins/FinalizationGroup/prototype/unregister/unregister.js create mode 100644 test/built-ins/FinalizationGroup/prototype/unregister/unregisterToken-not-object-throws.js create mode 100644 test/built-ins/FinalizationGroup/returns-new-object-from-constructor.js 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 0000000000..f9d86ec4f8 --- /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 0000000000..a399a4bdb3 --- /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 0000000000..ea38fe4def --- /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, + writable: false, + enumerable: 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 0000000000..c4f4bb44b6 --- /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', + writable: false, + enumerable: 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 0000000000..4814634d2a --- /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 0000000000..a507f6eb17 --- /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 0000000000..bedf933e00 --- /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 0000000000..88efca3984 --- /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(undefined); +}, 'undefined'); + +assert.throws(TypeError, function() { + fg(null); +}, 'null'); + +assert.throws(TypeError, function() { + fg(true); +}, 'true'); + +assert.throws(TypeError, function() { + fg(false); +}, 'false'); + +assert.throws(TypeError, function() { + fg(1); +}, 'number'); + +assert.throws(TypeError, function() { + fg('object'); +}, 'string'); + +var s = Symbol(); +assert.throws(TypeError, function() { + fg(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 0000000000..c1b509a159 --- /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 0000000000..7635230b1b --- /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 0000000000..10b73b9eee --- /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(target, undefined, null); +}, 'null'); + +assert.throws(TypeError, function() { + fg(target, undefined, true); +}, 'true'); + +assert.throws(TypeError, function() { + fg(target, undefined, false); +}, 'false'); + +assert.throws(TypeError, function() { + fg(target, undefined, 1); +}, 'number'); + +assert.throws(TypeError, function() { + fg(target, undefined, 'object'); +}, 'string'); + +var s = Symbol(); +assert.throws(TypeError, function() { + fg(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 0000000000..1534707a02 --- /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 0000000000..b3a1df3d88 --- /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 0000000000..94db099a23 --- /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 0000000000..fa2e487a07 --- /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 0000000000..eff37a272c --- /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 0000000000..63da68aac6 --- /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 0000000000..703415c361 --- /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 0000000000..683b6d5ced --- /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(undefined); +}, 'undefined'); + +assert.throws(TypeError, function() { + fg(null); +}, 'null'); + +assert.throws(TypeError, function() { + fg(true); +}, 'true'); + +assert.throws(TypeError, function() { + fg(false); +}, 'false'); + +assert.throws(TypeError, function() { + fg(1); +}, 'number'); + +assert.throws(TypeError, function() { + fg('object'); +}, 'string'); + +var s = Symbol(); +assert.throws(TypeError, function() { + fg(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 0000000000..4a906946b3 --- /dev/null +++ b/test/built-ins/FinalizationGroup/returns-new-object-from-constructor.js @@ -0,0 +1,40 @@ +// 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 WeakRef 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] +---*/ + +var cleanupCallback = function() {}; +var fg = new FinalizationGroup(cleanupCallback); + +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/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 index adc9020dff..c21d048512 100644 --- 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 @@ -15,31 +15,36 @@ info: | a. Perform ! KeepDuringJob(target). b. Return target. 6. Return undefined. -features: [WeakRef] +features: [WeakRef, FinalizationGroup] ---*/ assert.sameValue(typeof WeakRef.prototype.deref, 'function'); -var defer = WeakRef.prototype.defer; +var deref = WeakRef.prototype.deref; assert.throws(TypeError, function() { - defer.call({ ['[[Target]]']: {} }); + deref.call({ ['[[Target]]']: {} }); }, 'Ordinary object without [[Target]]'); assert.throws(TypeError, function() { - defer.call(WeakRef.prototype); + deref.call(WeakRef.prototype); }, 'WeakRef.prototype does not have a [[Target]] internal slot'); assert.throws(TypeError, function() { - defer.call(WeakRef); + 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() { - defer.call(wm); + deref.call(wm); }, 'WeakMap instance'); var ws = new WeakSet(); assert.throws(TypeError, function() { - defer.call(ws); + 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 index cee1e70baf..05adca195a 100644 --- a/test/built-ins/WeakRef/prototype/deref/this-not-object-throws.js +++ b/test/built-ins/WeakRef/prototype/deref/this-not-object-throws.js @@ -20,33 +20,33 @@ features: [WeakRef] assert.sameValue(typeof WeakRef.prototype.deref, 'function'); -var defer = WeakRef.prototype.defer; +var deref = WeakRef.prototype.deref; assert.throws(TypeError, function() { - defer.call(undefined); + deref.call(undefined); }, 'undefined'); assert.throws(TypeError, function() { - defer.call(null); + deref.call(null); }, 'null'); assert.throws(TypeError, function() { - defer.call(true); + deref.call(true); }, 'true'); assert.throws(TypeError, function() { - defer.call(false); + deref.call(false); }, 'false'); assert.throws(TypeError, function() { - defer.call(1); + deref.call(1); }, 'number'); assert.throws(TypeError, function() { - defer.call('object'); + deref.call('object'); }, 'string'); var s = Symbol(); assert.throws(TypeError, function() { - defer.call(s); + deref.call(s); }, 'symbol');