Skip to content

Commit

Permalink
update constructor and Symbol.toStringTag properties on Iterator.prot…
Browse files Browse the repository at this point in the history
…otype (#3970)

* update constructor and toStringTag properties on Iterator.prototype

* includes cannot be empty for some reason

* update description

* add esid

* updates

* freeze Iterator.prototype

* don't try to use real GeneratorPrototype for these tests
  • Loading branch information
michaelficarra authored Jan 15, 2024
1 parent bebce4a commit 17ba9ae
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 12 deletions.
22 changes: 10 additions & 12 deletions test/built-ins/Iterator/prototype/Symbol.toStringTag/prop-desc.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
// Copyright (C) 2023 Michael Ficarra. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
es6id: 25.1.2.1
esid: sec-iteratorprototype-@@tostringtag
description: Property descriptor
info: |
ES6 Section 17
Every other data property described in clauses 18 through 26 and in Annex
B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false,
[[Configurable]]: true } unless otherwise specified.
`Iterator.prototype[@@toStringTag]` is an accessor property with attributes { [[Enumerable]]: *false*, [[Configurable]]: *true* }
features: [iterator-helpers]
includes: [propertyHelper.js]
---*/
verifyProperty(Iterator.prototype, Symbol.toStringTag, {
value: 'Iterator',
writable: true,
enumerable: false,
configurable: true,
});
verifyConfigurable(Iterator.prototype, Symbol.toStringTag);
verifyNotEnumerable(Iterator.prototype, Symbol.toStringTag);

let desc = Object.getOwnPropertyDescriptor(Iterator.prototype, Symbol.toStringTag);
assert.sameValue(typeof desc.get, 'function');
assert.sameValue(typeof desc.set, 'function');
assert.sameValue(desc.value, undefined);
assert.sameValue(desc.writable, undefined);
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright (C) 2023 Michael Ficarra. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-set-iteratorprototype-@@tostringtag
description: weird setter
info: |
The value of the [[Get]] attribute is a built-in function that requires no arguments. It performs the following steps when called:
1. Return *"Iterator"*.
The value of the [[Set]] attribute is a built-in function that takes an argument _v_. It performs the following steps when called:
1. Perform ? SetterThatIgnoresPrototypeProperties(%Iterator.prototype%, %Symbol.toStringTag%, _v_).
2. Return *undefined*.
features: [iterator-helpers]
---*/

let IteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))

let sentinel = 'a';

let { get, set } = Object.getOwnPropertyDescriptor(Iterator.prototype, Symbol.toStringTag);

assert.sameValue(Iterator.prototype[Symbol.toStringTag], 'Iterator');
assert.sameValue(get.call(), 'Iterator');

// 1. If _this_ is not an Object, then
// 1. Throw a *TypeError* exception.
assert.throws(() => set.call(undefined, ''));
assert.throws(() => set.call(null, ''));
assert.throws(() => set.call(true, ''));

// 1. If _this_ is _home_, then
// 1. NOTE: Throwing here emulates assignment to a non-writable data property on the _home_ object in strict mode code.
// 1. Throw a *TypeError* exception.
assert.throws(() => set.call(IteratorPrototype, ''));
assert.throws(() => IteratorPrototype[Symbol.toStringTag] = '');

assert.sameValue(Iterator.prototype[Symbol.toStringTag], 'Iterator');
assert.sameValue(get.call(), 'Iterator');

// 1. If _desc_ is *undefined*, then
// 1. Perform ? CreateDataPropertyOrThrow(_this_, _p_, _v_).
let FakeGeneratorPrototype = Object.create(IteratorPrototype);
Object.freeze(IteratorPrototype);
FakeGeneratorPrototype[Symbol.toStringTag] = sentinel;
assert.sameValue(FakeGeneratorPrototype[Symbol.toStringTag], sentinel);

assert.sameValue(Iterator.prototype[Symbol.toStringTag], 'Iterator');
assert.sameValue(get.call(), 'Iterator');

// 1. Else,
// 1. Perform ? Set(_this_, _p_, _v_, *true*).
let o = { [Symbol.toStringTag]: sentinel + 'a' };
set.call(o, sentinel);
assert.sameValue(o[Symbol.toStringTag], sentinel);

assert.sameValue(Iterator.prototype[Symbol.toStringTag], 'Iterator');
assert.sameValue(get.call(), 'Iterator');
18 changes: 18 additions & 0 deletions test/built-ins/Iterator/prototype/constructor/prop-desc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (C) 2023 Michael Ficarra. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-iteratorprototype.constructor
description: Property descriptor
info: |
`Iterator.prototype.constructor` is an accessor property with attributes { [[Enumerable]]: *false*, [[Configurable]]: *true* }
features: [iterator-helpers]
includes: [propertyHelper.js]
---*/
verifyConfigurable(Iterator.prototype, 'constructor');
verifyNotEnumerable(Iterator.prototype, 'constructor');

let desc = Object.getOwnPropertyDescriptor(Iterator.prototype, 'constructor');
assert.sameValue(typeof desc.get, 'function');
assert.sameValue(typeof desc.set, 'function');
assert.sameValue(desc.value, undefined);
assert.sameValue(desc.writable, undefined);
57 changes: 57 additions & 0 deletions test/built-ins/Iterator/prototype/constructor/weird-setter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright (C) 2023 Michael Ficarra. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-set-iteratorprototype-constructor
description: weird setter
info: |
The value of the [[Get]] attribute is a built-in function that requires no arguments. It performs the following steps when called:
1. Return %Iterator%.
The value of the [[Set]] attribute is a built-in function that takes an argument _v_. It performs the following steps when called:
1. Perform ? SetterThatIgnoresPrototypeProperties(%Iterator.prototype%, *"constructor"*, _v_).
2. Return *undefined*.
features: [iterator-helpers]
---*/

let IteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))

let sentinel = {};

let { get, set } = Object.getOwnPropertyDescriptor(Iterator.prototype, 'constructor');

assert.sameValue(Iterator.prototype.constructor, Iterator);
assert.sameValue(get.call(), Iterator);

// 1. If _this_ is not an Object, then
// 1. Throw a *TypeError* exception.
assert.throws(() => set.call(undefined, ''));
assert.throws(() => set.call(null, ''));
assert.throws(() => set.call(true, ''));

// 1. If _this_ is _home_, then
// 1. NOTE: Throwing here emulates assignment to a non-writable data property on the _home_ object in strict mode code.
// 1. Throw a *TypeError* exception.
assert.throws(() => set.call(IteratorPrototype, ''));
assert.throws(() => IteratorPrototype.constructor = '');

assert.sameValue(Iterator.prototype.constructor, Iterator);
assert.sameValue(get.call(), Iterator);

// 1. If _desc_ is *undefined*, then
// 1. Perform ? CreateDataPropertyOrThrow(_this_, _p_, _v_).
let FakeGeneratorPrototype = Object.create(IteratorPrototype);
Object.freeze(IteratorPrototype);
FakeGeneratorPrototype.constructor = sentinel;
assert.sameValue(FakeGeneratorPrototype.constructor, sentinel);

assert.sameValue(Iterator.prototype.constructor, Iterator);
assert.sameValue(get.call(), Iterator);

// 1. Else,
// 1. Perform ? Set(_this_, _p_, _v_, *true*).
let o = { constructor: sentinel + 'a' };
set.call(o, sentinel);
assert.sameValue(o.constructor, sentinel);

assert.sameValue(Iterator.prototype.constructor, Iterator);
assert.sameValue(get.call(), Iterator);

0 comments on commit 17ba9ae

Please sign in to comment.