mirror of
https://github.com/tc39/test262.git
synced 2025-07-28 08:24:23 +02:00
More set methods tests (#3966)
* add tests for difference, intersection, symmetricDifference * add tests for predicates * more tests for ordering of calls * fix copyrights * add missed -0 test * pass argument to methods, not just this * assert methods return new objects * typo in filename * fix parens * Update test/built-ins/Set/prototype/difference/add-not-called.js Co-authored-by: Jordan Harband <ljharb@gmail.com> * fix isSupersetOf/set-like-array.js * add tests for negative zero with isDisjointFrom and isSupersetOf * fix message in isSupersetOf/converts-negative-zero.js * address comments from review --------- Co-authored-by: Jordan Harband <ljharb@gmail.com>
This commit is contained in:
parent
80590ce79a
commit
c8cd136888
27
test/built-ins/Set/prototype/difference/add-not-called.js
vendored
Normal file
27
test/built-ins/Set/prototype/difference/add-not-called.js
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.difference
|
||||
description: Set.prototype.difference should not call Set.prototype.add
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = new Set([2, 3]);
|
||||
const expected = [1];
|
||||
|
||||
const originalAdd = Set.prototype.add;
|
||||
let count = 0;
|
||||
Set.prototype.add = function (...rest) {
|
||||
count++;
|
||||
return originalAdd.apply(this, rest);
|
||||
};
|
||||
|
||||
const combined = s1.difference(s2);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
||||
assert.sameValue(count, 0, "Add is never called");
|
||||
|
||||
Set.prototype.add = originalAdd;
|
35
test/built-ins/Set/prototype/difference/allows-set-like-class.js
vendored
Normal file
35
test/built-ins/Set/prototype/difference/allows-set-like-class.js
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.difference
|
||||
description: GetSetRecord allows instances of Set-like classes
|
||||
info: |
|
||||
1. If obj is not an Object, throw a TypeError exception.
|
||||
2. Let rawSize be ? Get(obj, "size").
|
||||
...
|
||||
7. Let has be ? Get(obj, "has").
|
||||
...
|
||||
9. Let keys be ? Get(obj, "keys").
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = new class {
|
||||
get size() {
|
||||
return 2;
|
||||
}
|
||||
has(v) {
|
||||
if (v === 1) return false;
|
||||
if (v === 2) return true;
|
||||
throw new Test262Error("Set.prototype.difference should only call its argument's has method with contents of this");
|
||||
}
|
||||
* keys() {
|
||||
throw new Test262Error("Set.prototype.difference should not call its argument's keys iterator when this.size ≤ arg.size");
|
||||
}
|
||||
};
|
||||
const expected = [1];
|
||||
const combined = s1.difference(s2);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
33
test/built-ins/Set/prototype/difference/allows-set-like-object.js
vendored
Normal file
33
test/built-ins/Set/prototype/difference/allows-set-like-object.js
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.difference
|
||||
description: GetSetRecord allows Set-like objects
|
||||
info: |
|
||||
1. If obj is not an Object, throw a TypeError exception.
|
||||
2. Let rawSize be ? Get(obj, "size").
|
||||
...
|
||||
7. Let has be ? Get(obj, "has").
|
||||
...
|
||||
9. Let keys be ? Get(obj, "keys").
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = {
|
||||
size: 2,
|
||||
has: (v) => {
|
||||
if (v === 1) return false;
|
||||
if (v === 2) return true;
|
||||
throw new Test262Error("Set.prototype.difference should only call its argument's has method with contents of this");
|
||||
},
|
||||
keys: function* keys() {
|
||||
throw new Test262Error("Set.prototype.difference should not call its argument's keys iterator when this.size ≤ arg.size");
|
||||
},
|
||||
};
|
||||
const expected = [1];
|
||||
const combined = s1.difference(s2);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
17
test/built-ins/Set/prototype/difference/array-throws.js
vendored
Normal file
17
test/built-ins/Set/prototype/difference/array-throws.js
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.difference
|
||||
description: Set.prototype.difference doesn't work with arrays
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = [3];
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.difference(s2);
|
||||
},
|
||||
"Throws an error when an array is used"
|
||||
);
|
25
test/built-ins/Set/prototype/difference/builtins.js
vendored
Normal file
25
test/built-ins/Set/prototype/difference/builtins.js
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.difference
|
||||
description: Tests that Set.prototype.difference meets the requirements for built-in objects
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
assert.sameValue(
|
||||
Object.isExtensible(Set.prototype.difference),
|
||||
true,
|
||||
"Built-in objects must be extensible."
|
||||
);
|
||||
|
||||
assert.sameValue(
|
||||
Object.prototype.toString.call(Set.prototype.difference),
|
||||
"[object Function]",
|
||||
"Object.prototype.toString"
|
||||
);
|
||||
|
||||
assert.sameValue(
|
||||
Object.getPrototypeOf(Set.prototype.difference),
|
||||
Function.prototype,
|
||||
"prototype"
|
||||
);
|
66
test/built-ins/Set/prototype/difference/called-with-object.js
vendored
Normal file
66
test/built-ins/Set/prototype/difference/called-with-object.js
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-getsetrecord
|
||||
description: GetSetRecord throws if obj is not an object
|
||||
info: |
|
||||
1. If obj is not an Object, throw a TypeError exception.
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
let s1 = new Set([1]);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.difference(1);
|
||||
},
|
||||
"number"
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.difference("");
|
||||
},
|
||||
"string"
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.difference(1n);
|
||||
},
|
||||
"bigint"
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.difference(false);
|
||||
},
|
||||
"boolean"
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.difference(undefined);
|
||||
},
|
||||
"undefined"
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.difference(null);
|
||||
},
|
||||
"null"
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.difference(Symbol("test"));
|
||||
},
|
||||
"symbol"
|
||||
);
|
19
test/built-ins/Set/prototype/difference/combines-Map.js
vendored
Normal file
19
test/built-ins/Set/prototype/difference/combines-Map.js
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.difference
|
||||
description: Set.prototype.difference combines with Map
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const m1 = new Map([
|
||||
[2, "two"],
|
||||
[3, "three"],
|
||||
]);
|
||||
const expected = [1];
|
||||
const combined = s1.difference(m1);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
32
test/built-ins/Set/prototype/difference/combines-empty-sets.js
vendored
Normal file
32
test/built-ins/Set/prototype/difference/combines-empty-sets.js
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.difference
|
||||
description: Set.prototype.difference can combine empty Sets
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([]);
|
||||
const s2 = new Set([1, 2]);
|
||||
let expected = [];
|
||||
let combined = s1.difference(s2);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
||||
|
||||
const s3 = new Set([1, 2]);
|
||||
const s4 = new Set([]);
|
||||
expected = [1, 2];
|
||||
combined = s3.difference(s4);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
||||
|
||||
const s5 = new Set([]);
|
||||
const s6 = new Set([]);
|
||||
expected = [];
|
||||
combined = s5.difference(s6);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
16
test/built-ins/Set/prototype/difference/combines-itself.js
vendored
Normal file
16
test/built-ins/Set/prototype/difference/combines-itself.js
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.difference
|
||||
description: Set.prototype.difference is successful when called on itself
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const expected = [];
|
||||
const combined = s1.difference(s1);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
||||
assert.sameValue(combined === s1, false, "The returned object is a new object");
|
18
test/built-ins/Set/prototype/difference/combines-same-sets.js
vendored
Normal file
18
test/built-ins/Set/prototype/difference/combines-same-sets.js
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.difference
|
||||
description: Set.prototype.difference can combine Sets that have the same content
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = new Set([1, 2]);
|
||||
const expected = [];
|
||||
const combined = s1.difference(s2);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
||||
assert.sameValue(combined === s1, false, "The returned object is a new object");
|
||||
assert.sameValue(combined === s2, false, "The returned object is a new object");
|
16
test/built-ins/Set/prototype/difference/combines-sets.js
vendored
Normal file
16
test/built-ins/Set/prototype/difference/combines-sets.js
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.difference
|
||||
description: Set.prototype.difference combines Sets
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = new Set([2, 3]);
|
||||
const expected = [1];
|
||||
const combined = s1.difference(s2);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
28
test/built-ins/Set/prototype/difference/converts-negative-zero.js
vendored
Normal file
28
test/built-ins/Set/prototype/difference/converts-negative-zero.js
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.difference
|
||||
description: Set.prototype.difference converts -0𝔽 to +0𝔽
|
||||
info: |
|
||||
7.b.ii If nextValue is -0𝔽, set nextValue to +0𝔽.
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
const setlikeWithMinusZero = {
|
||||
size: 1,
|
||||
has: function () {
|
||||
throw new Test262Error("Set.prototype.difference should not call its argument's has method when this.size > arg.size");
|
||||
},
|
||||
keys: function () {
|
||||
// we use an array here because the Set constructor would normalize away -0
|
||||
return [-0].values();
|
||||
},
|
||||
};
|
||||
|
||||
const s1 = new Set([+0, 1]);
|
||||
let expected = [1];
|
||||
let combined = s1.difference(setlikeWithMinusZero);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
20
test/built-ins/Set/prototype/difference/difference.js
vendored
Normal file
20
test/built-ins/Set/prototype/difference/difference.js
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.difference
|
||||
description: Set.prototype.difference properties
|
||||
includes: [propertyHelper.js]
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
assert.sameValue(
|
||||
typeof Set.prototype.difference,
|
||||
"function",
|
||||
"`typeof Set.prototype.difference` is `'function'`"
|
||||
);
|
||||
|
||||
verifyProperty(Set.prototype, "difference", {
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
configurable: true,
|
||||
});
|
36
test/built-ins/Set/prototype/difference/has-is-callable.js
vendored
Normal file
36
test/built-ins/Set/prototype/difference/has-is-callable.js
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-getsetrecord
|
||||
description: GetSetRecord throws an exception if the Set-like object's 'has' property is not callable
|
||||
info: |
|
||||
7. Let has be ? Get(obj, "has").
|
||||
8. If IsCallable(has) is false, throw a TypeError exception.
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = {
|
||||
size: 2,
|
||||
has: undefined,
|
||||
keys: function* keys() {
|
||||
yield 2;
|
||||
yield 3;
|
||||
},
|
||||
};
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.difference(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when has is undefined"
|
||||
);
|
||||
|
||||
s2.has = {};
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.difference(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when has is not callable"
|
||||
);
|
33
test/built-ins/Set/prototype/difference/keys-is-callable.js
vendored
Normal file
33
test/built-ins/Set/prototype/difference/keys-is-callable.js
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-getsetrecord
|
||||
description: GetSetRecord throws an exception if the Set-like object's 'keys' property is not callable
|
||||
info: |
|
||||
9. Let keys be ? Get(obj, "keys").
|
||||
10. If IsCallable(keys) is false, throw a TypeError exception.
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = {
|
||||
size: 2,
|
||||
has: () => {},
|
||||
keys: undefined,
|
||||
};
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.difference(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when keys is undefined"
|
||||
);
|
||||
|
||||
s2.keys = {};
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.difference(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when keys is not callable"
|
||||
);
|
18
test/built-ins/Set/prototype/difference/length.js
vendored
Normal file
18
test/built-ins/Set/prototype/difference/length.js
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.difference
|
||||
description: Set.prototype.difference length property
|
||||
info: |
|
||||
Set.prototype.difference ( other )
|
||||
includes: [propertyHelper.js]
|
||||
features: [set-methods]
|
||||
---*/
|
||||
assert.sameValue(typeof Set.prototype.difference, "function");
|
||||
|
||||
verifyProperty(Set.prototype.difference, "length", {
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
configurable: true,
|
||||
value: 1,
|
||||
});
|
18
test/built-ins/Set/prototype/difference/name.js
vendored
Normal file
18
test/built-ins/Set/prototype/difference/name.js
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.difference
|
||||
description: Set.prototype.difference name property
|
||||
info: |
|
||||
Set.prototype.difference ( other )
|
||||
includes: [propertyHelper.js]
|
||||
features: [set-methods]
|
||||
---*/
|
||||
assert.sameValue(typeof Set.prototype.difference, "function");
|
||||
|
||||
verifyProperty(Set.prototype.difference, "name", {
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
configurable: true,
|
||||
value: "difference",
|
||||
});
|
22
test/built-ins/Set/prototype/difference/not-a-constructor.js
vendored
Normal file
22
test/built-ins/Set/prototype/difference/not-a-constructor.js
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.difference
|
||||
description: Set.prototype.difference does not implement [[Construct]], is not new-able
|
||||
includes: [isConstructor.js]
|
||||
features: [Reflect.construct, set-methods]
|
||||
---*/
|
||||
|
||||
assert.sameValue(
|
||||
isConstructor(Set.prototype.difference),
|
||||
false,
|
||||
"isConstructor(Set.prototype.difference) must return false"
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
() => {
|
||||
new Set.prototype.difference();
|
||||
},
|
||||
"`new Set.prototype.difference()` throws TypeError"
|
||||
);
|
44
test/built-ins/Set/prototype/difference/receiver-not-set.js
vendored
Normal file
44
test/built-ins/Set/prototype/difference/receiver-not-set.js
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.difference
|
||||
description: Set.prototype.difference throws when receiver is not a Set
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
class MySetLike {
|
||||
constructor() {
|
||||
this.size = 2;
|
||||
this.has = () => {};
|
||||
this.keys = function* keys() {
|
||||
yield 2;
|
||||
yield 3;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const s1 = new MySetLike();
|
||||
const s2 = new Set();
|
||||
assert.throws(
|
||||
TypeError,
|
||||
() => {
|
||||
Set.prototype.difference.call(s1, s2);
|
||||
},
|
||||
"Set-like class"
|
||||
);
|
||||
|
||||
const s3 = {
|
||||
size: 2,
|
||||
has: () => {},
|
||||
keys: function* keys() {
|
||||
yield 2;
|
||||
yield 3;
|
||||
},
|
||||
};
|
||||
assert.throws(
|
||||
TypeError,
|
||||
() => {
|
||||
Set.prototype.difference.call(s3, s2);
|
||||
},
|
||||
"Set-like object"
|
||||
);
|
27
test/built-ins/Set/prototype/difference/require-internal-slot.js
vendored
Normal file
27
test/built-ins/Set/prototype/difference/require-internal-slot.js
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.difference
|
||||
description: Set.prototype.difference RequireInternalSlot
|
||||
info: |
|
||||
2. Perform ? RequireInternalSlot(O, [[SetData]])
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const difference = Set.prototype.difference;
|
||||
|
||||
assert.sameValue(typeof difference, "function");
|
||||
|
||||
const realSet = new Set([]);
|
||||
|
||||
assert.throws(TypeError, () => difference.call(undefined, realSet), "undefined");
|
||||
assert.throws(TypeError, () => difference.call(null, realSet), "null");
|
||||
assert.throws(TypeError, () => difference.call(true, realSet), "true");
|
||||
assert.throws(TypeError, () => difference.call("", realSet), "empty string");
|
||||
assert.throws(TypeError, () => difference.call(Symbol(), realSet), "symbol");
|
||||
assert.throws(TypeError, () => difference.call(1, realSet), "1");
|
||||
assert.throws(TypeError, () => difference.call(1n, realSet), "1n");
|
||||
assert.throws(TypeError, () => difference.call({}, realSet), "plain object");
|
||||
assert.throws(TypeError, () => difference.call([], realSet), "array");
|
||||
assert.throws(TypeError, () => difference.call(new Map(), realSet), "map");
|
||||
assert.throws(TypeError, () => difference.call(Set.prototype, realSet), "Set.prototype");
|
37
test/built-ins/Set/prototype/difference/result-order.js
vendored
Normal file
37
test/built-ins/Set/prototype/difference/result-order.js
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
// Copyright (C) 2023 Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.difference
|
||||
description: Set.prototype.difference orders results as in this, regardless of sizes
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
{
|
||||
const s1 = new Set([1, 2, 3, 4]);
|
||||
const s2 = new Set([6, 5, 3, 2]);
|
||||
|
||||
assert.compareArray([...s1.difference(s2)], [1, 4]);
|
||||
}
|
||||
|
||||
{
|
||||
const s1 = new Set([6, 5, 3, 2]);
|
||||
const s2 = new Set([1, 2, 3, 4]);
|
||||
|
||||
assert.compareArray([...s1.difference(s2)], [6, 5]);
|
||||
}
|
||||
|
||||
{
|
||||
const s1 = new Set([1, 2, 3, 4]);
|
||||
const s2 = new Set([7, 6, 5, 3, 2]);
|
||||
|
||||
assert.compareArray([...s1.difference(s2)], [1, 4]);
|
||||
}
|
||||
|
||||
{
|
||||
const s1 = new Set([7, 6, 5, 3, 2]);
|
||||
const s2 = new Set([1, 2, 3, 4]);
|
||||
|
||||
assert.compareArray([...s1.difference(s2)], [7, 6, 5]);
|
||||
}
|
||||
|
26
test/built-ins/Set/prototype/difference/set-like-array.js
vendored
Normal file
26
test/built-ins/Set/prototype/difference/set-like-array.js
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.difference
|
||||
description: Set.prototype.difference consumes a set-like array as a set-like, not an array
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = [5, 6];
|
||||
s2.size = 3;
|
||||
s2.has = function (v) {
|
||||
if (v === 1) return false;
|
||||
if (v === 2) return true;
|
||||
throw new Test262Error("Set.prototype.difference should only call its argument's has method with contents of this");
|
||||
};
|
||||
s2.keys = function () {
|
||||
throw new Test262Error("Set.prototype.difference should not call its argument's keys iterator when this.size ≤ arg.size");
|
||||
};
|
||||
|
||||
const expected = [1];
|
||||
const combined = s1.difference(s2);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
49
test/built-ins/Set/prototype/difference/set-like-class-mutation.js
vendored
Normal file
49
test/built-ins/Set/prototype/difference/set-like-class-mutation.js
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.difference
|
||||
description: Set.prototype.difference maintains values even when a custom Set-like class mutates the receiver
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
const baseSet = new Set(["a", "b", "c", "d", "e"]);
|
||||
|
||||
function mutatingIterator() {
|
||||
let index = 0;
|
||||
let values = ["x", "b", "b"];
|
||||
return {
|
||||
next() {
|
||||
if (index === 0) {
|
||||
baseSet.delete("b");
|
||||
baseSet.delete("c");
|
||||
baseSet.add("b");
|
||||
baseSet.add("d");
|
||||
}
|
||||
return {
|
||||
done: index >= values.length,
|
||||
value: values[index++],
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const evilSetLike = {
|
||||
size: 3,
|
||||
get has() {
|
||||
baseSet.add("q");
|
||||
return function () {
|
||||
throw new Test262Error("Set.prototype.difference should not invoke .has on its argument when this.size > other.size");
|
||||
};
|
||||
},
|
||||
keys() {
|
||||
return mutatingIterator();
|
||||
},
|
||||
};
|
||||
|
||||
const combined = baseSet.difference(evilSetLike);
|
||||
const expectedCombined = ["a", "c", "d", "e", "q"];
|
||||
assert.compareArray([...combined], expectedCombined);
|
||||
|
||||
const expectedNewBase = ["a", "d", "e", "q", "b"];
|
||||
assert.compareArray([...baseSet], expectedNewBase);
|
140
test/built-ins/Set/prototype/difference/set-like-class-order.js
vendored
Normal file
140
test/built-ins/Set/prototype/difference/set-like-class-order.js
vendored
Normal file
@ -0,0 +1,140 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.difference
|
||||
description: Set.prototype.difference calls a Set-like class's methods in order
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
let observedOrder = [];
|
||||
|
||||
function observableIterator() {
|
||||
let values = ["a", "b", "c"];
|
||||
let index = 0;
|
||||
return {
|
||||
get next() {
|
||||
observedOrder.push("getting next");
|
||||
return function () {
|
||||
observedOrder.push("calling next");
|
||||
return {
|
||||
get done() {
|
||||
observedOrder.push("getting done");
|
||||
return index >= values.length;
|
||||
},
|
||||
get value() {
|
||||
observedOrder.push("getting value");
|
||||
return values[index++];
|
||||
},
|
||||
};
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
class MySetLike {
|
||||
get size() {
|
||||
observedOrder.push("getting size");
|
||||
return {
|
||||
valueOf: function () {
|
||||
observedOrder.push("ToNumber(size)");
|
||||
return 3;
|
||||
},
|
||||
};
|
||||
}
|
||||
get has() {
|
||||
observedOrder.push("getting has");
|
||||
return function (v) {
|
||||
observedOrder.push("calling has");
|
||||
return ["a", "b", "c"].indexOf(v) !== -1;
|
||||
};
|
||||
}
|
||||
get keys() {
|
||||
observedOrder.push("getting keys");
|
||||
return function () {
|
||||
observedOrder.push("calling keys");
|
||||
return observableIterator();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// this is smaller than argument
|
||||
{
|
||||
observedOrder = [];
|
||||
|
||||
const s1 = new Set(["a", "d"]);
|
||||
const s2 = new MySetLike();
|
||||
const combined = s1.difference(s2);
|
||||
|
||||
const expectedOrder = [
|
||||
"getting size",
|
||||
"ToNumber(size)",
|
||||
"getting has",
|
||||
"getting keys",
|
||||
// two calls to has
|
||||
"calling has",
|
||||
"calling has",
|
||||
];
|
||||
|
||||
assert.compareArray([...combined], ["d"]);
|
||||
assert.compareArray(observedOrder, expectedOrder);
|
||||
}
|
||||
|
||||
// this is same size as argument
|
||||
{
|
||||
observedOrder = [];
|
||||
|
||||
const s1 = new Set(["a", "b", "d"]);
|
||||
const s2 = new MySetLike();
|
||||
const combined = s1.difference(s2);
|
||||
|
||||
const expectedOrder = [
|
||||
"getting size",
|
||||
"ToNumber(size)",
|
||||
"getting has",
|
||||
"getting keys",
|
||||
// three calls to has
|
||||
"calling has",
|
||||
"calling has",
|
||||
"calling has",
|
||||
];
|
||||
|
||||
assert.compareArray([...combined], ["d"]);
|
||||
assert.compareArray(observedOrder, expectedOrder);
|
||||
}
|
||||
|
||||
// this is larger than argument
|
||||
{
|
||||
observedOrder = [];
|
||||
|
||||
const s1 = new Set(["a", "b", "c", "d"]);
|
||||
const s2 = new MySetLike();
|
||||
const combined = s1.difference(s2);
|
||||
|
||||
const expectedOrder = [
|
||||
"getting size",
|
||||
"ToNumber(size)",
|
||||
"getting has",
|
||||
"getting keys",
|
||||
"calling keys",
|
||||
"getting next",
|
||||
// first iteration, has value
|
||||
"calling next",
|
||||
"getting done",
|
||||
"getting value",
|
||||
// second iteration, has value
|
||||
"calling next",
|
||||
"getting done",
|
||||
"getting value",
|
||||
// third iteration, has value
|
||||
"calling next",
|
||||
"getting done",
|
||||
"getting value",
|
||||
// fourth iteration, no value; ends
|
||||
"calling next",
|
||||
"getting done",
|
||||
];
|
||||
|
||||
assert.compareArray([...combined], ["d"]);
|
||||
assert.compareArray(observedOrder, expectedOrder);
|
||||
}
|
72
test/built-ins/Set/prototype/difference/size-is-a-number.js
vendored
Normal file
72
test/built-ins/Set/prototype/difference/size-is-a-number.js
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-getsetrecord
|
||||
description: GetSetRecord throws an exception if the Set-like object has a size that is coerced to NaN
|
||||
info: |
|
||||
2. Let rawSize be ? Get(obj, "size").
|
||||
3. Let numSize be ? ToNumber(rawSize).
|
||||
4. NOTE: If rawSize is undefined, then numSize will be NaN.
|
||||
5. If numSize is NaN, throw a TypeError exception.
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = {
|
||||
size: undefined,
|
||||
has: () => {},
|
||||
keys: function* keys() {
|
||||
yield 2;
|
||||
yield 3;
|
||||
},
|
||||
};
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.difference(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when size is undefined"
|
||||
);
|
||||
|
||||
s2.size = NaN;
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.difference(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when size is NaN"
|
||||
);
|
||||
|
||||
let coercionCalls = 0;
|
||||
s2.size = {
|
||||
valueOf: function() {
|
||||
++coercionCalls;
|
||||
return NaN;
|
||||
},
|
||||
};
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.difference(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when size coerces to NaN"
|
||||
);
|
||||
assert.sameValue(coercionCalls, 1, "GetSetRecord coerces size");
|
||||
|
||||
s2.size = 0n;
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.difference(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when size is a BigInt"
|
||||
);
|
||||
|
||||
s2.size = "string";
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.difference(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when size is a non-numeric string"
|
||||
);
|
45
test/built-ins/Set/prototype/difference/subclass-receiver-methods.js
vendored
Normal file
45
test/built-ins/Set/prototype/difference/subclass-receiver-methods.js
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.difference
|
||||
description: Set.prototype.difference works on subclasses of Set, but never calls the receiver's size/has/keys methods
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
let sizeCount = 0;
|
||||
let hasCount = 0;
|
||||
let keysCount = 0;
|
||||
|
||||
class MySet extends Set {
|
||||
size(...rest) {
|
||||
sizeCount++;
|
||||
return super.size(...rest);
|
||||
}
|
||||
|
||||
has(...rest) {
|
||||
hasCount++;
|
||||
return super.has(...rest);
|
||||
}
|
||||
|
||||
keys(...rest) {
|
||||
keysCount++;
|
||||
return super.keys(...rest);
|
||||
}
|
||||
}
|
||||
|
||||
const s1 = new MySet([1, 2]);
|
||||
const s2 = new Set([2, 3]);
|
||||
const expected = [2];
|
||||
const combined = s1.difference(s2);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
||||
assert.sameValue(
|
||||
combined instanceof MySet,
|
||||
false,
|
||||
"The returned object is a Set, not a subclass"
|
||||
);
|
||||
assert.sameValue(sizeCount, 0, "size should not be called on the receiver");
|
||||
assert.sameValue(hasCount, 0, "has should not be called on the receiver");
|
||||
assert.sameValue(keysCount, 0, "keys should not be called on the receiver");
|
29
test/built-ins/Set/prototype/difference/subclass-symbol-species.js
vendored
Normal file
29
test/built-ins/Set/prototype/difference/subclass-symbol-species.js
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.difference
|
||||
description: Set.prototype.difference works on subclasses of Set, but returns an instance of Set even when Symbol.species is overridden.
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
var count = 0;
|
||||
class MySet extends Set {
|
||||
static get [Symbol.species]() {
|
||||
count++;
|
||||
return Set;
|
||||
}
|
||||
}
|
||||
|
||||
const s1 = new MySet([1, 2]);
|
||||
const s2 = new Set([2, 3]);
|
||||
const expected = [1];
|
||||
const combined = s1.difference(s2);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(count, 0, "Symbol.species is never called");
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
||||
assert.sameValue(
|
||||
combined instanceof MySet,
|
||||
false,
|
||||
"The returned object is a Set, not a subclass"
|
||||
);
|
23
test/built-ins/Set/prototype/difference/subclass.js
vendored
Normal file
23
test/built-ins/Set/prototype/difference/subclass.js
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.difference
|
||||
description: Set.prototype.difference works on subclasses of Set, but returns an instance of Set
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
class MySet extends Set {}
|
||||
|
||||
const s1 = new MySet([1, 2]);
|
||||
const s2 = new Set([2, 3]);
|
||||
const expected = [1];
|
||||
const combined = s1.difference(s2);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
||||
assert.sameValue(
|
||||
combined instanceof MySet,
|
||||
false,
|
||||
"The returned object is a Set, not a subclass"
|
||||
);
|
27
test/built-ins/Set/prototype/intersection/add-not-called.js
vendored
Normal file
27
test/built-ins/Set/prototype/intersection/add-not-called.js
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.intersection
|
||||
description: Set.prototype.intersection should not call Set.prototype.add
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = new Set([2, 3]);
|
||||
const expected = [2];
|
||||
|
||||
const originalAdd = Set.prototype.add;
|
||||
let count = 0;
|
||||
Set.prototype.add = function (...rest) {
|
||||
count++;
|
||||
return originalAdd.apply(this, rest);
|
||||
};
|
||||
|
||||
const combined = s1.intersection(s2);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
||||
assert.sameValue(count, 0, "Add is never called");
|
||||
|
||||
Set.prototype.add = originalAdd;
|
35
test/built-ins/Set/prototype/intersection/allows-set-like-class.js
vendored
Normal file
35
test/built-ins/Set/prototype/intersection/allows-set-like-class.js
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.intersection
|
||||
description: GetSetRecord allows instances of Set-like classes
|
||||
info: |
|
||||
1. If obj is not an Object, throw a TypeError exception.
|
||||
2. Let rawSize be ? Get(obj, "size").
|
||||
...
|
||||
7. Let has be ? Get(obj, "has").
|
||||
...
|
||||
9. Let keys be ? Get(obj, "keys").
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = new class {
|
||||
get size() {
|
||||
return 2;
|
||||
}
|
||||
has(v) {
|
||||
if (v === 1) return false;
|
||||
if (v === 2) return true;
|
||||
throw new Test262Error("Set.prototype.intersection should only call its argument's has method with contents of this");
|
||||
}
|
||||
* keys() {
|
||||
throw new Test262Error("Set.prototype.intersection should not call its argument's keys iterator when this.size ≤ arg.size");
|
||||
}
|
||||
};
|
||||
const expected = [2];
|
||||
const combined = s1.intersection(s2);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
33
test/built-ins/Set/prototype/intersection/allows-set-like-object.js
vendored
Normal file
33
test/built-ins/Set/prototype/intersection/allows-set-like-object.js
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.intersection
|
||||
description: GetSetRecord allows Set-like objects
|
||||
info: |
|
||||
1. If obj is not an Object, throw a TypeError exception.
|
||||
2. Let rawSize be ? Get(obj, "size").
|
||||
...
|
||||
7. Let has be ? Get(obj, "has").
|
||||
...
|
||||
9. Let keys be ? Get(obj, "keys").
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = {
|
||||
size: 2,
|
||||
has: (v) => {
|
||||
if (v === 1) return false;
|
||||
if (v === 2) return true;
|
||||
throw new Test262Error("Set.prototype.intersection should only call its argument's has method with contents of this");
|
||||
},
|
||||
keys: function* keys() {
|
||||
throw new Test262Error("Set.prototype.intersection should not call its argument's keys iterator when this.size ≤ arg.size");
|
||||
},
|
||||
};
|
||||
const expected = [2];
|
||||
const combined = s1.intersection(s2);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
17
test/built-ins/Set/prototype/intersection/array-throws.js
vendored
Normal file
17
test/built-ins/Set/prototype/intersection/array-throws.js
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.intersection
|
||||
description: Set.prototype.intersection doesn't work with arrays
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = [3];
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.intersection(s2);
|
||||
},
|
||||
"Throws an error when an array is used"
|
||||
);
|
25
test/built-ins/Set/prototype/intersection/builtins.js
vendored
Normal file
25
test/built-ins/Set/prototype/intersection/builtins.js
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.intersection
|
||||
description: Tests that Set.prototype.intersection meets the requirements for built-in objects
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
assert.sameValue(
|
||||
Object.isExtensible(Set.prototype.intersection),
|
||||
true,
|
||||
"Built-in objects must be extensible."
|
||||
);
|
||||
|
||||
assert.sameValue(
|
||||
Object.prototype.toString.call(Set.prototype.intersection),
|
||||
"[object Function]",
|
||||
"Object.prototype.toString"
|
||||
);
|
||||
|
||||
assert.sameValue(
|
||||
Object.getPrototypeOf(Set.prototype.intersection),
|
||||
Function.prototype,
|
||||
"prototype"
|
||||
);
|
66
test/built-ins/Set/prototype/intersection/called-with-object.js
vendored
Normal file
66
test/built-ins/Set/prototype/intersection/called-with-object.js
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-getsetrecord
|
||||
description: GetSetRecord throws if obj is not an object
|
||||
info: |
|
||||
1. If obj is not an Object, throw a TypeError exception.
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
let s1 = new Set([1]);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.intersection(1);
|
||||
},
|
||||
"number"
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.intersection("");
|
||||
},
|
||||
"string"
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.intersection(1n);
|
||||
},
|
||||
"bigint"
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.intersection(false);
|
||||
},
|
||||
"boolean"
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.intersection(undefined);
|
||||
},
|
||||
"undefined"
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.intersection(null);
|
||||
},
|
||||
"null"
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.intersection(Symbol("test"));
|
||||
},
|
||||
"symbol"
|
||||
);
|
19
test/built-ins/Set/prototype/intersection/combines-Map.js
vendored
Normal file
19
test/built-ins/Set/prototype/intersection/combines-Map.js
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.intersection
|
||||
description: Set.prototype.intersection combines with Map
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const m1 = new Map([
|
||||
[2, "two"],
|
||||
[3, "three"],
|
||||
]);
|
||||
const expected = [2];
|
||||
const combined = s1.intersection(m1);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
32
test/built-ins/Set/prototype/intersection/combines-empty-sets.js
vendored
Normal file
32
test/built-ins/Set/prototype/intersection/combines-empty-sets.js
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.intersection
|
||||
description: Set.prototype.intersection can combine empty Sets
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([]);
|
||||
const s2 = new Set([1, 2]);
|
||||
let expected = [];
|
||||
let combined = s1.intersection(s2);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
||||
|
||||
const s3 = new Set([1, 2]);
|
||||
const s4 = new Set([]);
|
||||
expected = [];
|
||||
combined = s3.intersection(s4);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
||||
|
||||
const s5 = new Set([]);
|
||||
const s6 = new Set([]);
|
||||
expected = [];
|
||||
combined = s5.intersection(s6);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
16
test/built-ins/Set/prototype/intersection/combines-itself.js
vendored
Normal file
16
test/built-ins/Set/prototype/intersection/combines-itself.js
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.intersection
|
||||
description: Set.prototype.intersection is successful when called on itself
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const expected = [1, 2];
|
||||
const combined = s1.intersection(s1);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
||||
assert.sameValue(combined === s1, false, "The returned object is a new object");
|
18
test/built-ins/Set/prototype/intersection/combines-same-sets.js
vendored
Normal file
18
test/built-ins/Set/prototype/intersection/combines-same-sets.js
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.intersection
|
||||
description: Set.prototype.intersection can combine Sets that have the same content
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = new Set([1, 2]);
|
||||
const expected = [1, 2];
|
||||
const combined = s1.intersection(s2);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
||||
assert.sameValue(combined === s1, false, "The returned object is a new object");
|
||||
assert.sameValue(combined === s2, false, "The returned object is a new object");
|
16
test/built-ins/Set/prototype/intersection/combines-sets.js
vendored
Normal file
16
test/built-ins/Set/prototype/intersection/combines-sets.js
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.intersection
|
||||
description: Set.prototype.intersection combines Sets
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = new Set([2, 3]);
|
||||
const expected = [2];
|
||||
const combined = s1.intersection(s2);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
28
test/built-ins/Set/prototype/intersection/converts-negative-zero.js
vendored
Normal file
28
test/built-ins/Set/prototype/intersection/converts-negative-zero.js
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.intersection
|
||||
description: Set.prototype.intersection converts -0𝔽 to +0𝔽
|
||||
info: |
|
||||
7.c.ii.2 If nextValue is -0𝔽, set nextValue to +0𝔽.
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
const setlikeWithMinusZero = {
|
||||
size: 1,
|
||||
has: function () {
|
||||
throw new Test262Error("Set.prototype.intersection should not invoke .has on its argument when this.size > arg.size");
|
||||
},
|
||||
keys: function () {
|
||||
// we use an array here because the Set constructor would normalize away -0
|
||||
return [-0].values();
|
||||
},
|
||||
};
|
||||
|
||||
const s1 = new Set([0, 1, 2]);
|
||||
let expected = [+0];
|
||||
let combined = s1.intersection(setlikeWithMinusZero);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
36
test/built-ins/Set/prototype/intersection/has-is-callable.js
vendored
Normal file
36
test/built-ins/Set/prototype/intersection/has-is-callable.js
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-getsetrecord
|
||||
description: GetSetRecord throws an exception if the Set-like object's 'has' property is not callable
|
||||
info: |
|
||||
7. Let has be ? Get(obj, "has").
|
||||
8. If IsCallable(has) is false, throw a TypeError exception.
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = {
|
||||
size: 2,
|
||||
has: undefined,
|
||||
keys: function* keys() {
|
||||
yield 2;
|
||||
yield 3;
|
||||
},
|
||||
};
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.intersection(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when has is undefined"
|
||||
);
|
||||
|
||||
s2.has = {};
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.intersection(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when has is not callable"
|
||||
);
|
20
test/built-ins/Set/prototype/intersection/intersection.js
vendored
Normal file
20
test/built-ins/Set/prototype/intersection/intersection.js
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.intersection
|
||||
description: Set.prototype.intersection properties
|
||||
includes: [propertyHelper.js]
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
assert.sameValue(
|
||||
typeof Set.prototype.intersection,
|
||||
"function",
|
||||
"`typeof Set.prototype.intersection` is `'function'`"
|
||||
);
|
||||
|
||||
verifyProperty(Set.prototype, "intersection", {
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
configurable: true,
|
||||
});
|
33
test/built-ins/Set/prototype/intersection/keys-is-callable.js
vendored
Normal file
33
test/built-ins/Set/prototype/intersection/keys-is-callable.js
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-getsetrecord
|
||||
description: GetSetRecord throws an exception if the Set-like object's 'keys' property is not callable
|
||||
info: |
|
||||
9. Let keys be ? Get(obj, "keys").
|
||||
10. If IsCallable(keys) is false, throw a TypeError exception.
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = {
|
||||
size: 2,
|
||||
has: () => {},
|
||||
keys: undefined,
|
||||
};
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.intersection(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when keys is undefined"
|
||||
);
|
||||
|
||||
s2.keys = {};
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.intersection(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when keys is not callable"
|
||||
);
|
18
test/built-ins/Set/prototype/intersection/length.js
vendored
Normal file
18
test/built-ins/Set/prototype/intersection/length.js
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.intersection
|
||||
description: Set.prototype.intersection length property
|
||||
info: |
|
||||
Set.prototype.intersection ( other )
|
||||
includes: [propertyHelper.js]
|
||||
features: [set-methods]
|
||||
---*/
|
||||
assert.sameValue(typeof Set.prototype.intersection, "function");
|
||||
|
||||
verifyProperty(Set.prototype.intersection, "length", {
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
configurable: true,
|
||||
value: 1,
|
||||
});
|
18
test/built-ins/Set/prototype/intersection/name.js
vendored
Normal file
18
test/built-ins/Set/prototype/intersection/name.js
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.intersection
|
||||
description: Set.prototype.intersection name property
|
||||
info: |
|
||||
Set.prototype.intersection ( other )
|
||||
includes: [propertyHelper.js]
|
||||
features: [set-methods]
|
||||
---*/
|
||||
assert.sameValue(typeof Set.prototype.intersection, "function");
|
||||
|
||||
verifyProperty(Set.prototype.intersection, "name", {
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
configurable: true,
|
||||
value: "intersection",
|
||||
});
|
22
test/built-ins/Set/prototype/intersection/not-a-constructor.js
vendored
Normal file
22
test/built-ins/Set/prototype/intersection/not-a-constructor.js
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.intersection
|
||||
description: Set.prototype.intersection does not implement [[Construct]], is not new-able
|
||||
includes: [isConstructor.js]
|
||||
features: [Reflect.construct, set-methods]
|
||||
---*/
|
||||
|
||||
assert.sameValue(
|
||||
isConstructor(Set.prototype.intersection),
|
||||
false,
|
||||
"isConstructor(Set.prototype.intersection) must return false"
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
() => {
|
||||
new Set.prototype.intersection();
|
||||
},
|
||||
"`new Set.prototype.intersection()` throws TypeError"
|
||||
);
|
44
test/built-ins/Set/prototype/intersection/receiver-not-set.js
vendored
Normal file
44
test/built-ins/Set/prototype/intersection/receiver-not-set.js
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.intersection
|
||||
description: Set.prototype.intersection throws when receiver is not a Set
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
class MySetLike {
|
||||
constructor() {
|
||||
this.size = 2;
|
||||
this.has = () => {};
|
||||
this.keys = function* keys() {
|
||||
yield 2;
|
||||
yield 3;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const s1 = new MySetLike();
|
||||
const s2 = new Set();
|
||||
assert.throws(
|
||||
TypeError,
|
||||
() => {
|
||||
Set.prototype.intersection.call(s1, s2);
|
||||
},
|
||||
"Set-like class"
|
||||
);
|
||||
|
||||
const s3 = {
|
||||
size: 2,
|
||||
has: () => {},
|
||||
keys: function* keys() {
|
||||
yield 2;
|
||||
yield 3;
|
||||
},
|
||||
};
|
||||
assert.throws(
|
||||
TypeError,
|
||||
() => {
|
||||
Set.prototype.intersection.call(s3, s2);
|
||||
},
|
||||
"Set-like object"
|
||||
);
|
27
test/built-ins/Set/prototype/intersection/require-internal-slot.js
vendored
Normal file
27
test/built-ins/Set/prototype/intersection/require-internal-slot.js
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.intersection
|
||||
description: Set.prototype.intersection RequireInternalSlot
|
||||
info: |
|
||||
2. Perform ? RequireInternalSlot(O, [[SetData]])
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const intersection = Set.prototype.intersection;
|
||||
|
||||
assert.sameValue(typeof intersection, "function");
|
||||
|
||||
const realSet = new Set([]);
|
||||
|
||||
assert.throws(TypeError, () => intersection.call(undefined, realSet), "undefined");
|
||||
assert.throws(TypeError, () => intersection.call(null, realSet), "null");
|
||||
assert.throws(TypeError, () => intersection.call(true, realSet), "true");
|
||||
assert.throws(TypeError, () => intersection.call("", realSet), "empty string");
|
||||
assert.throws(TypeError, () => intersection.call(Symbol(), realSet), "symbol");
|
||||
assert.throws(TypeError, () => intersection.call(1, realSet), "1");
|
||||
assert.throws(TypeError, () => intersection.call(1n, realSet), "1n");
|
||||
assert.throws(TypeError, () => intersection.call({}, realSet), "plain object");
|
||||
assert.throws(TypeError, () => intersection.call([], realSet), "array");
|
||||
assert.throws(TypeError, () => intersection.call(new Map(), realSet), "map");
|
||||
assert.throws(TypeError, () => intersection.call(Set.prototype, realSet), "Set.prototype");
|
53
test/built-ins/Set/prototype/intersection/result-order.js
vendored
Normal file
53
test/built-ins/Set/prototype/intersection/result-order.js
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
// Copyright (C) 2023 Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.intersection
|
||||
description: Set.prototype.intersection result ordering
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
// when this.size ≤ other.size, results are ordered as in this
|
||||
{
|
||||
const s1 = new Set([1, 3, 5]);
|
||||
const s2 = new Set([3, 2, 1]);
|
||||
|
||||
assert.compareArray([...s1.intersection(s2)], [1, 3]);
|
||||
}
|
||||
|
||||
{
|
||||
const s1 = new Set([3, 2, 1]);
|
||||
const s2 = new Set([1, 3, 5]);
|
||||
|
||||
assert.compareArray([...s1.intersection(s2)], [3, 1]);
|
||||
}
|
||||
|
||||
{
|
||||
const s1 = new Set([1, 3, 5]);
|
||||
const s2 = new Set([3, 2, 1, 0]);
|
||||
|
||||
assert.compareArray([...s1.intersection(s2)], [1, 3]);
|
||||
}
|
||||
|
||||
{
|
||||
const s1 = new Set([3, 2, 1]);
|
||||
const s2 = new Set([1, 3, 5, 7]);
|
||||
|
||||
assert.compareArray([...s1.intersection(s2)], [3, 1]);
|
||||
}
|
||||
|
||||
|
||||
// when this.size > other.size, results are ordered as in other
|
||||
{
|
||||
const s1 = new Set([3, 2, 1, 0]);
|
||||
const s2 = new Set([1, 3, 5]);
|
||||
|
||||
assert.compareArray([...s1.intersection(s2)], [1, 3]);
|
||||
}
|
||||
|
||||
{
|
||||
const s1 = new Set([1, 3, 5, 7]);
|
||||
const s2 = new Set([3, 2, 1]);
|
||||
|
||||
assert.compareArray([...s1.intersection(s2)], [3, 1]);
|
||||
}
|
26
test/built-ins/Set/prototype/intersection/set-like-array.js
vendored
Normal file
26
test/built-ins/Set/prototype/intersection/set-like-array.js
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.intersection
|
||||
description: Set.prototype.intersection consumes a set-like array as a set-like, not an array
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = [5, 6];
|
||||
s2.size = 3;
|
||||
s2.has = function (v) {
|
||||
if (v === 1) return false;
|
||||
if (v === 2) return true;
|
||||
throw new Test262Error("Set.prototype.intersection should only call its argument's has method with contents of this");
|
||||
};
|
||||
s2.keys = function () {
|
||||
throw new Test262Error("Set.prototype.intersection should not call its argument's keys iterator when this.size ≤ arg.size");
|
||||
};
|
||||
|
||||
const expected = [2];
|
||||
const combined = s1.intersection(s2);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
49
test/built-ins/Set/prototype/intersection/set-like-class-mutation.js
vendored
Normal file
49
test/built-ins/Set/prototype/intersection/set-like-class-mutation.js
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.intersection
|
||||
description: Set.prototype.intersection maintains values even when a custom Set-like class mutates the receiver
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
const baseSet = new Set(["a", "b", "c", "d", "e"]);
|
||||
|
||||
function mutatingIterator() {
|
||||
let index = 0;
|
||||
let values = ["x", "b", "b"];
|
||||
return {
|
||||
next() {
|
||||
if (index === 0) {
|
||||
baseSet.delete("b");
|
||||
baseSet.delete("c");
|
||||
baseSet.add("b");
|
||||
baseSet.add("d");
|
||||
}
|
||||
return {
|
||||
done: index >= values.length,
|
||||
value: values[index++],
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const evilSetLike = {
|
||||
size: 3,
|
||||
get has() {
|
||||
baseSet.add("q");
|
||||
return function () {
|
||||
throw new Test262Error("Set.prototype.intersection should not invoke .has on its argument when this.size > other.size");
|
||||
};
|
||||
},
|
||||
keys() {
|
||||
return mutatingIterator();
|
||||
},
|
||||
};
|
||||
|
||||
const combined = baseSet.intersection(evilSetLike);
|
||||
const expectedCombined = ["b"];
|
||||
assert.compareArray([...combined], expectedCombined);
|
||||
|
||||
const expectedNewBase = ["a", "d", "e", "q", "b"];
|
||||
assert.compareArray([...baseSet], expectedNewBase);
|
140
test/built-ins/Set/prototype/intersection/set-like-class-order.js
vendored
Normal file
140
test/built-ins/Set/prototype/intersection/set-like-class-order.js
vendored
Normal file
@ -0,0 +1,140 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.intersection
|
||||
description: Set.prototype.intersection calls a Set-like class's methods in order
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
let observedOrder = [];
|
||||
|
||||
function observableIterator() {
|
||||
let values = ["a", "b", "c"];
|
||||
let index = 0;
|
||||
return {
|
||||
get next() {
|
||||
observedOrder.push("getting next");
|
||||
return function () {
|
||||
observedOrder.push("calling next");
|
||||
return {
|
||||
get done() {
|
||||
observedOrder.push("getting done");
|
||||
return index >= values.length;
|
||||
},
|
||||
get value() {
|
||||
observedOrder.push("getting value");
|
||||
return values[index++];
|
||||
},
|
||||
};
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
class MySetLike {
|
||||
get size() {
|
||||
observedOrder.push("getting size");
|
||||
return {
|
||||
valueOf: function () {
|
||||
observedOrder.push("ToNumber(size)");
|
||||
return 3;
|
||||
},
|
||||
};
|
||||
}
|
||||
get has() {
|
||||
observedOrder.push("getting has");
|
||||
return function (v) {
|
||||
observedOrder.push("calling has");
|
||||
return ["a", "b", "c"].indexOf(v) !== -1;
|
||||
};
|
||||
}
|
||||
get keys() {
|
||||
observedOrder.push("getting keys");
|
||||
return function () {
|
||||
observedOrder.push("calling keys");
|
||||
return observableIterator();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// this is smaller than argument
|
||||
{
|
||||
observedOrder = [];
|
||||
|
||||
const s1 = new Set(["a", "d"]);
|
||||
const s2 = new MySetLike();
|
||||
const combined = s1.intersection(s2);
|
||||
|
||||
const expectedOrder = [
|
||||
"getting size",
|
||||
"ToNumber(size)",
|
||||
"getting has",
|
||||
"getting keys",
|
||||
// two calls to has
|
||||
"calling has",
|
||||
"calling has",
|
||||
];
|
||||
|
||||
assert.compareArray([...combined], ["a"]);
|
||||
assert.compareArray(observedOrder, expectedOrder);
|
||||
}
|
||||
|
||||
// this is same size as argument
|
||||
{
|
||||
observedOrder = [];
|
||||
|
||||
const s1 = new Set(["a", "b", "d"]);
|
||||
const s2 = new MySetLike();
|
||||
const combined = s1.intersection(s2);
|
||||
|
||||
const expectedOrder = [
|
||||
"getting size",
|
||||
"ToNumber(size)",
|
||||
"getting has",
|
||||
"getting keys",
|
||||
// three calls to has
|
||||
"calling has",
|
||||
"calling has",
|
||||
"calling has",
|
||||
];
|
||||
|
||||
assert.compareArray([...combined], ["a", "b"]);
|
||||
assert.compareArray(observedOrder, expectedOrder);
|
||||
}
|
||||
|
||||
// this is larger than argument
|
||||
{
|
||||
observedOrder = [];
|
||||
|
||||
const s1 = new Set(["a", "b", "c", "d"]);
|
||||
const s2 = new MySetLike();
|
||||
const combined = s1.intersection(s2);
|
||||
|
||||
const expectedOrder = [
|
||||
"getting size",
|
||||
"ToNumber(size)",
|
||||
"getting has",
|
||||
"getting keys",
|
||||
"calling keys",
|
||||
"getting next",
|
||||
// first iteration, has value
|
||||
"calling next",
|
||||
"getting done",
|
||||
"getting value",
|
||||
// second iteration, has value
|
||||
"calling next",
|
||||
"getting done",
|
||||
"getting value",
|
||||
// third iteration, has value
|
||||
"calling next",
|
||||
"getting done",
|
||||
"getting value",
|
||||
// fourth iteration, no value; ends
|
||||
"calling next",
|
||||
"getting done",
|
||||
];
|
||||
|
||||
assert.compareArray([...combined], ["a", "b", "c"]);
|
||||
assert.compareArray(observedOrder, expectedOrder);
|
||||
}
|
72
test/built-ins/Set/prototype/intersection/size-is-a-number.js
vendored
Normal file
72
test/built-ins/Set/prototype/intersection/size-is-a-number.js
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-getsetrecord
|
||||
description: GetSetRecord throws an exception if the Set-like object has a size that is coerced to NaN
|
||||
info: |
|
||||
2. Let rawSize be ? Get(obj, "size").
|
||||
3. Let numSize be ? ToNumber(rawSize).
|
||||
4. NOTE: If rawSize is undefined, then numSize will be NaN.
|
||||
5. If numSize is NaN, throw a TypeError exception.
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = {
|
||||
size: undefined,
|
||||
has: () => {},
|
||||
keys: function* keys() {
|
||||
yield 2;
|
||||
yield 3;
|
||||
},
|
||||
};
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.intersection(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when size is undefined"
|
||||
);
|
||||
|
||||
s2.size = NaN;
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.intersection(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when size is NaN"
|
||||
);
|
||||
|
||||
let coercionCalls = 0;
|
||||
s2.size = {
|
||||
valueOf: function() {
|
||||
++coercionCalls;
|
||||
return NaN;
|
||||
},
|
||||
};
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.intersection(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when size coerces to NaN"
|
||||
);
|
||||
assert.sameValue(coercionCalls, 1, "GetSetRecord coerces size");
|
||||
|
||||
s2.size = 0n;
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.intersection(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when size is a BigInt"
|
||||
);
|
||||
|
||||
s2.size = "string";
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.intersection(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when size is a non-numeric string"
|
||||
);
|
45
test/built-ins/Set/prototype/intersection/subclass-receiver-methods.js
vendored
Normal file
45
test/built-ins/Set/prototype/intersection/subclass-receiver-methods.js
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.intersection
|
||||
description: Set.prototype.intersection works on subclasses of Set, but never calls the receiver's size/has/keys methods
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
let sizeCount = 0;
|
||||
let hasCount = 0;
|
||||
let keysCount = 0;
|
||||
|
||||
class MySet extends Set {
|
||||
size(...rest) {
|
||||
sizeCount++;
|
||||
return super.size(...rest);
|
||||
}
|
||||
|
||||
has(...rest) {
|
||||
hasCount++;
|
||||
return super.has(...rest);
|
||||
}
|
||||
|
||||
keys(...rest) {
|
||||
keysCount++;
|
||||
return super.keys(...rest);
|
||||
}
|
||||
}
|
||||
|
||||
const s1 = new MySet([1, 2]);
|
||||
const s2 = new Set([2, 3]);
|
||||
const expected = [2];
|
||||
const combined = s1.intersection(s2);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
||||
assert.sameValue(
|
||||
combined instanceof MySet,
|
||||
false,
|
||||
"The returned object is a Set, not a subclass"
|
||||
);
|
||||
assert.sameValue(sizeCount, 0, "size should not be called on the receiver");
|
||||
assert.sameValue(hasCount, 0, "has should not be called on the receiver");
|
||||
assert.sameValue(keysCount, 0, "keys should not be called on the receiver");
|
29
test/built-ins/Set/prototype/intersection/subclass-symbol-species.js
vendored
Normal file
29
test/built-ins/Set/prototype/intersection/subclass-symbol-species.js
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.intersection
|
||||
description: Set.prototype.intersection works on subclasses of Set, but returns an instance of Set even when Symbol.species is overridden.
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
var count = 0;
|
||||
class MySet extends Set {
|
||||
static get [Symbol.species]() {
|
||||
count++;
|
||||
return Set;
|
||||
}
|
||||
}
|
||||
|
||||
const s1 = new MySet([1, 2]);
|
||||
const s2 = new Set([2, 3]);
|
||||
const expected = [2];
|
||||
const combined = s1.intersection(s2);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(count, 0, "Symbol.species is never called");
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
||||
assert.sameValue(
|
||||
combined instanceof MySet,
|
||||
false,
|
||||
"The returned object is a Set, not a subclass"
|
||||
);
|
23
test/built-ins/Set/prototype/intersection/subclass.js
vendored
Normal file
23
test/built-ins/Set/prototype/intersection/subclass.js
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.intersection
|
||||
description: Set.prototype.intersection works on subclasses of Set, but returns an instance of Set
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
class MySet extends Set {}
|
||||
|
||||
const s1 = new MySet([1, 2]);
|
||||
const s2 = new Set([2, 3]);
|
||||
const expected = [2];
|
||||
const combined = s1.intersection(s2);
|
||||
|
||||
assert.compareArray([...combined], expected);
|
||||
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
|
||||
assert.sameValue(
|
||||
combined instanceof MySet,
|
||||
false,
|
||||
"The returned object is a Set, not a subclass"
|
||||
);
|
30
test/built-ins/Set/prototype/isDisjointFrom/allows-set-like-class.js
vendored
Normal file
30
test/built-ins/Set/prototype/isDisjointFrom/allows-set-like-class.js
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.isdisjointfrom
|
||||
description: GetSetRecord allows instances of Set-like classes
|
||||
info: |
|
||||
1. If obj is not an Object, throw a TypeError exception.
|
||||
2. Let rawSize be ? Get(obj, "size").
|
||||
...
|
||||
7. Let has be ? Get(obj, "has").
|
||||
...
|
||||
9. Let keys be ? Get(obj, "keys").
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = new class {
|
||||
get size() {
|
||||
return 2;
|
||||
}
|
||||
has(v) {
|
||||
if (v === 1 || v === 2) return false;
|
||||
throw new Test262Error("Set.prototype.isDisjointFrom should only call its argument's has method with contents of this");
|
||||
}
|
||||
* keys() {
|
||||
throw new Test262Error("Set.prototype.isDisjointFrom should not call its argument's keys iterator when this.size ≤ arg.size");
|
||||
}
|
||||
};
|
||||
|
||||
assert.sameValue(s1.isDisjointFrom(s2), true);
|
28
test/built-ins/Set/prototype/isDisjointFrom/allows-set-like-object.js
vendored
Normal file
28
test/built-ins/Set/prototype/isDisjointFrom/allows-set-like-object.js
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.isdisjointfrom
|
||||
description: GetSetRecord allows Set-like objects
|
||||
info: |
|
||||
1. If obj is not an Object, throw a TypeError exception.
|
||||
2. Let rawSize be ? Get(obj, "size").
|
||||
...
|
||||
7. Let has be ? Get(obj, "has").
|
||||
...
|
||||
9. Let keys be ? Get(obj, "keys").
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = {
|
||||
size: 2,
|
||||
has: (v) => {
|
||||
if (v === 1 || v === 2) return false;
|
||||
throw new Test262Error("Set.prototype.isDisjointFrom should only call its argument's has method with contents of this");
|
||||
},
|
||||
keys: function* keys() {
|
||||
throw new Test262Error("Set.prototype.isDisjointFrom should not call its argument's keys iterator when this.size ≤ arg.size");
|
||||
},
|
||||
};
|
||||
|
||||
assert.sameValue(s1.isDisjointFrom(s2), true);
|
17
test/built-ins/Set/prototype/isDisjointFrom/array-throws.js
vendored
Normal file
17
test/built-ins/Set/prototype/isDisjointFrom/array-throws.js
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.isdisjointfrom
|
||||
description: Set.prototype.isDisjointFrom doesn't work with arrays
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = [3];
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isDisjointFrom(s2);
|
||||
},
|
||||
"Throws an error when an array is used"
|
||||
);
|
25
test/built-ins/Set/prototype/isDisjointFrom/builtins.js
vendored
Normal file
25
test/built-ins/Set/prototype/isDisjointFrom/builtins.js
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.isdisjointfrom
|
||||
description: Tests that Set.prototype.isDisjointFrom meets the requirements for built-in objects
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
assert.sameValue(
|
||||
Object.isExtensible(Set.prototype.isDisjointFrom),
|
||||
true,
|
||||
"Built-in objects must be extensible."
|
||||
);
|
||||
|
||||
assert.sameValue(
|
||||
Object.prototype.toString.call(Set.prototype.isDisjointFrom),
|
||||
"[object Function]",
|
||||
"Object.prototype.toString"
|
||||
);
|
||||
|
||||
assert.sameValue(
|
||||
Object.getPrototypeOf(Set.prototype.isDisjointFrom),
|
||||
Function.prototype,
|
||||
"prototype"
|
||||
);
|
66
test/built-ins/Set/prototype/isDisjointFrom/called-with-object.js
vendored
Normal file
66
test/built-ins/Set/prototype/isDisjointFrom/called-with-object.js
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-getsetrecord
|
||||
description: GetSetRecord throws if obj is not an object
|
||||
info: |
|
||||
1. If obj is not an Object, throw a TypeError exception.
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
let s1 = new Set([1]);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isDisjointFrom(1);
|
||||
},
|
||||
"number"
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isDisjointFrom("");
|
||||
},
|
||||
"string"
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isDisjointFrom(1n);
|
||||
},
|
||||
"bigint"
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isDisjointFrom(false);
|
||||
},
|
||||
"boolean"
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isDisjointFrom(undefined);
|
||||
},
|
||||
"undefined"
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isDisjointFrom(null);
|
||||
},
|
||||
"null"
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isDisjointFrom(Symbol("test"));
|
||||
},
|
||||
"symbol"
|
||||
);
|
15
test/built-ins/Set/prototype/isDisjointFrom/compares-Map.js
vendored
Normal file
15
test/built-ins/Set/prototype/isDisjointFrom/compares-Map.js
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.isdisjointfrom
|
||||
description: Set.prototype.isDisjointFrom compares with Map
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const m1 = new Map([
|
||||
[2, "two"],
|
||||
[3, "three"],
|
||||
]);
|
||||
|
||||
assert.sameValue(s1.isDisjointFrom(m1), false);
|
22
test/built-ins/Set/prototype/isDisjointFrom/compares-empty-sets.js
vendored
Normal file
22
test/built-ins/Set/prototype/isDisjointFrom/compares-empty-sets.js
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.isdisjointfrom
|
||||
description: Set.prototype.isDisjointFrom can compare empty Sets
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([]);
|
||||
const s2 = new Set([1, 2]);
|
||||
|
||||
assert.sameValue(s1.isDisjointFrom(s2), true);
|
||||
|
||||
const s3 = new Set([1, 2]);
|
||||
const s4 = new Set([]);
|
||||
|
||||
assert.sameValue(s3.isDisjointFrom(s4), true);
|
||||
|
||||
const s5 = new Set([]);
|
||||
const s6 = new Set([]);
|
||||
|
||||
assert.sameValue(s5.isDisjointFrom(s6), true);
|
11
test/built-ins/Set/prototype/isDisjointFrom/compares-itself.js
vendored
Normal file
11
test/built-ins/Set/prototype/isDisjointFrom/compares-itself.js
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.isdisjointfrom
|
||||
description: Set.prototype.isDisjointFrom is successful when called on itself
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
|
||||
assert.sameValue(s1.isDisjointFrom(s1), false);
|
12
test/built-ins/Set/prototype/isDisjointFrom/compares-same-sets.js
vendored
Normal file
12
test/built-ins/Set/prototype/isDisjointFrom/compares-same-sets.js
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.isdisjointfrom
|
||||
description: Set.prototype.isDisjointFrom can compare Sets that have the same content
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = new Set([1, 2]);
|
||||
|
||||
assert.sameValue(s1.isDisjointFrom(s2), false);
|
16
test/built-ins/Set/prototype/isDisjointFrom/compares-sets.js
vendored
Normal file
16
test/built-ins/Set/prototype/isDisjointFrom/compares-sets.js
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.isdisjointfrom
|
||||
description: Set.prototype.isDisjointFrom compares Sets
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = new Set([2, 3]);
|
||||
|
||||
assert.sameValue(s1.isDisjointFrom(s2), false);
|
||||
|
||||
const s3 = new Set([3]);
|
||||
|
||||
assert.sameValue(s1.isDisjointFrom(s3), true);
|
22
test/built-ins/Set/prototype/isDisjointFrom/converts-negative-zero.js
vendored
Normal file
22
test/built-ins/Set/prototype/isDisjointFrom/converts-negative-zero.js
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.isdisjointfrom
|
||||
description: Set.prototype.isDisjointFrom converts -0𝔽 to +0𝔽
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const setlikeWithMinusZero = {
|
||||
size: 1,
|
||||
has: function () {
|
||||
throw new Test262Error("Set.prototype.isDisjointFrom should not call its argument's has method when this.size > arg.size");
|
||||
},
|
||||
keys: function () {
|
||||
// we use an array here because the Set constructor would normalize away -0
|
||||
return [-0].values();
|
||||
},
|
||||
};
|
||||
|
||||
const s1 = new Set([+0, 1]);
|
||||
|
||||
assert.sameValue(s1.isDisjointFrom(setlikeWithMinusZero), false);
|
36
test/built-ins/Set/prototype/isDisjointFrom/has-is-callable.js
vendored
Normal file
36
test/built-ins/Set/prototype/isDisjointFrom/has-is-callable.js
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-getsetrecord
|
||||
description: GetSetRecord throws an exception if the Set-like object's 'has' property is not callable
|
||||
info: |
|
||||
7. Let has be ? Get(obj, "has").
|
||||
8. If IsCallable(has) is false, throw a TypeError exception.
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = {
|
||||
size: 2,
|
||||
has: undefined,
|
||||
keys: function* keys() {
|
||||
yield 2;
|
||||
yield 3;
|
||||
},
|
||||
};
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isDisjointFrom(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when has is undefined"
|
||||
);
|
||||
|
||||
s2.has = {};
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isDisjointFrom(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when has is not callable"
|
||||
);
|
20
test/built-ins/Set/prototype/isDisjointFrom/isDisjointFrom.js
vendored
Normal file
20
test/built-ins/Set/prototype/isDisjointFrom/isDisjointFrom.js
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.isdisjointfrom
|
||||
description: Set.prototype.isDisjointFrom properties
|
||||
includes: [propertyHelper.js]
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
assert.sameValue(
|
||||
typeof Set.prototype.isDisjointFrom,
|
||||
"function",
|
||||
"`typeof Set.prototype.isDisjointFrom` is `'function'`"
|
||||
);
|
||||
|
||||
verifyProperty(Set.prototype, "isDisjointFrom", {
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
configurable: true,
|
||||
});
|
33
test/built-ins/Set/prototype/isDisjointFrom/keys-is-callable.js
vendored
Normal file
33
test/built-ins/Set/prototype/isDisjointFrom/keys-is-callable.js
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-getsetrecord
|
||||
description: GetSetRecord throws an exception if the Set-like object's 'keys' property is not callable
|
||||
info: |
|
||||
9. Let keys be ? Get(obj, "keys").
|
||||
10. If IsCallable(keys) is false, throw a TypeError exception.
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = {
|
||||
size: 2,
|
||||
has: () => {},
|
||||
keys: undefined,
|
||||
};
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isDisjointFrom(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when keys is undefined"
|
||||
);
|
||||
|
||||
s2.keys = {};
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isDisjointFrom(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when keys is not callable"
|
||||
);
|
18
test/built-ins/Set/prototype/isDisjointFrom/length.js
vendored
Normal file
18
test/built-ins/Set/prototype/isDisjointFrom/length.js
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.isdisjointfrom
|
||||
description: Set.prototype.isDisjointFrom length property
|
||||
info: |
|
||||
Set.prototype.isDisjointFrom ( other )
|
||||
includes: [propertyHelper.js]
|
||||
features: [set-methods]
|
||||
---*/
|
||||
assert.sameValue(typeof Set.prototype.isDisjointFrom, "function");
|
||||
|
||||
verifyProperty(Set.prototype.isDisjointFrom, "length", {
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
configurable: true,
|
||||
value: 1,
|
||||
});
|
18
test/built-ins/Set/prototype/isDisjointFrom/name.js
vendored
Normal file
18
test/built-ins/Set/prototype/isDisjointFrom/name.js
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.isdisjointfrom
|
||||
description: Set.prototype.isDisjointFrom name property
|
||||
info: |
|
||||
Set.prototype.isDisjointFrom ( other )
|
||||
includes: [propertyHelper.js]
|
||||
features: [set-methods]
|
||||
---*/
|
||||
assert.sameValue(typeof Set.prototype.isDisjointFrom, "function");
|
||||
|
||||
verifyProperty(Set.prototype.isDisjointFrom, "name", {
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
configurable: true,
|
||||
value: "isDisjointFrom",
|
||||
});
|
22
test/built-ins/Set/prototype/isDisjointFrom/not-a-constructor.js
vendored
Normal file
22
test/built-ins/Set/prototype/isDisjointFrom/not-a-constructor.js
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.isdisjointfrom
|
||||
description: Set.prototype.isDisjointFrom does not implement [[Construct]], is not new-able
|
||||
includes: [isConstructor.js]
|
||||
features: [Reflect.construct, set-methods]
|
||||
---*/
|
||||
|
||||
assert.sameValue(
|
||||
isConstructor(Set.prototype.isDisjointFrom),
|
||||
false,
|
||||
"isConstructor(Set.prototype.isDisjointFrom) must return false"
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
() => {
|
||||
new Set.prototype.isDisjointFrom();
|
||||
},
|
||||
"`new Set.prototype.isDisjointFrom()` throws TypeError"
|
||||
);
|
44
test/built-ins/Set/prototype/isDisjointFrom/receiver-not-set.js
vendored
Normal file
44
test/built-ins/Set/prototype/isDisjointFrom/receiver-not-set.js
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.isdisjointfrom
|
||||
description: Set.prototype.isDisjointFrom throws when receiver is not a Set
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
class MySetLike {
|
||||
constructor() {
|
||||
this.size = 2;
|
||||
this.has = () => {};
|
||||
this.keys = function* keys() {
|
||||
yield 2;
|
||||
yield 3;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const s1 = new MySetLike();
|
||||
const s2 = new Set();
|
||||
assert.throws(
|
||||
TypeError,
|
||||
() => {
|
||||
Set.prototype.isDisjointFrom.call(s1, s2);
|
||||
},
|
||||
"Set-like class"
|
||||
);
|
||||
|
||||
const s3 = {
|
||||
size: 2,
|
||||
has: () => {},
|
||||
keys: function* keys() {
|
||||
yield 2;
|
||||
yield 3;
|
||||
},
|
||||
};
|
||||
assert.throws(
|
||||
TypeError,
|
||||
() => {
|
||||
Set.prototype.isDisjointFrom.call(s3, s2);
|
||||
},
|
||||
"Set-like object"
|
||||
);
|
27
test/built-ins/Set/prototype/isDisjointFrom/require-internal-slot.js
vendored
Normal file
27
test/built-ins/Set/prototype/isDisjointFrom/require-internal-slot.js
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.isdisjointfrom
|
||||
description: Set.prototype.isDisjointFrom RequireInternalSlot
|
||||
info: |
|
||||
2. Perform ? RequireInternalSlot(O, [[SetData]])
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const isDisjointFrom = Set.prototype.isDisjointFrom;
|
||||
|
||||
assert.sameValue(typeof isDisjointFrom, "function");
|
||||
|
||||
const realSet = new Set([]);
|
||||
|
||||
assert.throws(TypeError, () => isDisjointFrom.call(undefined, realSet), "undefined");
|
||||
assert.throws(TypeError, () => isDisjointFrom.call(null, realSet), "null");
|
||||
assert.throws(TypeError, () => isDisjointFrom.call(true, realSet), "true");
|
||||
assert.throws(TypeError, () => isDisjointFrom.call("", realSet), "empty string");
|
||||
assert.throws(TypeError, () => isDisjointFrom.call(Symbol(), realSet), "symbol");
|
||||
assert.throws(TypeError, () => isDisjointFrom.call(1, realSet), "1");
|
||||
assert.throws(TypeError, () => isDisjointFrom.call(1n, realSet), "1n");
|
||||
assert.throws(TypeError, () => isDisjointFrom.call({}, realSet), "plain object");
|
||||
assert.throws(TypeError, () => isDisjointFrom.call([], realSet), "array");
|
||||
assert.throws(TypeError, () => isDisjointFrom.call(new Map(), realSet), "map");
|
||||
assert.throws(TypeError, () => isDisjointFrom.call(Set.prototype, realSet), "Set.prototype");
|
20
test/built-ins/Set/prototype/isDisjointFrom/set-like-array.js
vendored
Normal file
20
test/built-ins/Set/prototype/isDisjointFrom/set-like-array.js
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.isdisjointfrom
|
||||
description: Set.prototype.isDisjointFrom consumes a set-like array as a set-like, not an array
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = [5, 6];
|
||||
s2.size = 3;
|
||||
s2.has = function (v) {
|
||||
if (v === 1 || v === 2) return true;
|
||||
throw new Test262Error("Set.prototype.isDisjointFrom should only call its argument's has method with contents of this");
|
||||
};
|
||||
s2.keys = function () {
|
||||
throw new Test262Error("Set.prototype.isDisjointFrom should not call its argument's keys iterator when this.size ≤ arg.size");
|
||||
};
|
||||
|
||||
assert.sameValue(s1.isDisjointFrom(s2), false);
|
38
test/built-ins/Set/prototype/isDisjointFrom/set-like-class-mutation.js
vendored
Normal file
38
test/built-ins/Set/prototype/isDisjointFrom/set-like-class-mutation.js
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.isdisjointfrom
|
||||
description: Set.prototype.isDisjointFrom behavior when a custom Set-like class mutates the receiver
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
const baseSet = new Set(["a", "b", "c"]);
|
||||
|
||||
const evilSetLike = {
|
||||
size: 3,
|
||||
has(v) {
|
||||
if (v === "a") {
|
||||
baseSet.delete("b");
|
||||
baseSet.delete("c");
|
||||
baseSet.add("b");
|
||||
return false;
|
||||
}
|
||||
if (v === "b") {
|
||||
return false;
|
||||
}
|
||||
if (v === "c") {
|
||||
throw new Test262Error("Set.prototype.isDisjointFrom should not call its argument's has method with values from this which have been deleted before visiting");
|
||||
}
|
||||
throw new Test262Error("Set.prototype.isDisjointFrom should only call its argument's has method with contents of this");
|
||||
},
|
||||
* keys() {
|
||||
throw new Test262Error("Set.prototype.isDisjointFrom should not call its argument's keys iterator when this.size ≤ arg.size");
|
||||
},
|
||||
};
|
||||
|
||||
const result = baseSet.isDisjointFrom(evilSetLike);
|
||||
assert.sameValue(result, true);
|
||||
|
||||
const expectedNewBase = ["a", "b"];
|
||||
assert.compareArray([...baseSet], expectedNewBase);
|
191
test/built-ins/Set/prototype/isDisjointFrom/set-like-class-order.js
vendored
Normal file
191
test/built-ins/Set/prototype/isDisjointFrom/set-like-class-order.js
vendored
Normal file
@ -0,0 +1,191 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.isdisjointfrom
|
||||
description: Set.prototype.isDisjointFrom calls a Set-like class's methods in order
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
let observedOrder = [];
|
||||
|
||||
function observableIterator() {
|
||||
let values = ["a", "b", "c"];
|
||||
let index = 0;
|
||||
return {
|
||||
get next() {
|
||||
observedOrder.push("getting next");
|
||||
return function () {
|
||||
observedOrder.push("calling next");
|
||||
return {
|
||||
get done() {
|
||||
observedOrder.push("getting done");
|
||||
return index >= values.length;
|
||||
},
|
||||
get value() {
|
||||
observedOrder.push("getting value");
|
||||
return values[index++];
|
||||
},
|
||||
};
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
class MySetLike {
|
||||
get size() {
|
||||
observedOrder.push("getting size");
|
||||
return {
|
||||
valueOf: function () {
|
||||
observedOrder.push("ToNumber(size)");
|
||||
return 3;
|
||||
},
|
||||
};
|
||||
}
|
||||
get has() {
|
||||
observedOrder.push("getting has");
|
||||
return function (v) {
|
||||
observedOrder.push("calling has");
|
||||
return ["a", "b", "c"].indexOf(v) !== -1;
|
||||
};
|
||||
}
|
||||
get keys() {
|
||||
observedOrder.push("getting keys");
|
||||
return function () {
|
||||
observedOrder.push("calling keys");
|
||||
return observableIterator();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// this is smaller than argument
|
||||
{
|
||||
observedOrder = [];
|
||||
|
||||
const s1 = new Set(["x", "b"]);
|
||||
const s2 = new MySetLike();
|
||||
const result = s1.isDisjointFrom(s2);
|
||||
|
||||
const expectedOrder = [
|
||||
"getting size",
|
||||
"ToNumber(size)",
|
||||
"getting has",
|
||||
"getting keys",
|
||||
// two calls to has
|
||||
"calling has",
|
||||
"calling has",
|
||||
];
|
||||
|
||||
assert.sameValue(result, false);
|
||||
assert.compareArray(observedOrder, expectedOrder);
|
||||
}
|
||||
|
||||
// this is same size as argument - stops eagerly
|
||||
{
|
||||
observedOrder = [];
|
||||
|
||||
const s1 = new Set(["x", "b", "y"]);
|
||||
const s2 = new MySetLike();
|
||||
const result = s1.isDisjointFrom(s2);
|
||||
|
||||
const expectedOrder = [
|
||||
"getting size",
|
||||
"ToNumber(size)",
|
||||
"getting has",
|
||||
"getting keys",
|
||||
// two calls to has
|
||||
"calling has",
|
||||
"calling has",
|
||||
];
|
||||
|
||||
assert.sameValue(result, false);
|
||||
assert.compareArray(observedOrder, expectedOrder);
|
||||
}
|
||||
|
||||
// this is same size as argument - full run
|
||||
{
|
||||
observedOrder = [];
|
||||
|
||||
const s1 = new Set(["x", "y", "z"]);
|
||||
const s2 = new MySetLike();
|
||||
const result = s1.isDisjointFrom(s2);
|
||||
|
||||
const expectedOrder = [
|
||||
"getting size",
|
||||
"ToNumber(size)",
|
||||
"getting has",
|
||||
"getting keys",
|
||||
// three calls to has
|
||||
"calling has",
|
||||
"calling has",
|
||||
"calling has",
|
||||
];
|
||||
|
||||
assert.sameValue(result, true);
|
||||
assert.compareArray(observedOrder, expectedOrder);
|
||||
}
|
||||
|
||||
// this is larger than argument - stops eagerly
|
||||
{
|
||||
observedOrder = [];
|
||||
|
||||
const s1 = new Set(["x", "b", "y", "z"]);
|
||||
const s2 = new MySetLike();
|
||||
const result = s1.isDisjointFrom(s2);
|
||||
|
||||
const expectedOrder = [
|
||||
"getting size",
|
||||
"ToNumber(size)",
|
||||
"getting has",
|
||||
"getting keys",
|
||||
"calling keys",
|
||||
"getting next",
|
||||
// first iteration, has value
|
||||
"calling next",
|
||||
"getting done",
|
||||
"getting value",
|
||||
// second iteration, has value
|
||||
"calling next",
|
||||
"getting done",
|
||||
"getting value",
|
||||
];
|
||||
|
||||
assert.sameValue(result, false);
|
||||
assert.compareArray(observedOrder, expectedOrder);
|
||||
}
|
||||
|
||||
// this is larger than argument - full run
|
||||
{
|
||||
observedOrder = [];
|
||||
|
||||
const s1 = new Set(["x", "y", "z", "w"]);
|
||||
const s2 = new MySetLike();
|
||||
const result = s1.isDisjointFrom(s2);
|
||||
|
||||
const expectedOrder = [
|
||||
"getting size",
|
||||
"ToNumber(size)",
|
||||
"getting has",
|
||||
"getting keys",
|
||||
"calling keys",
|
||||
"getting next",
|
||||
// first iteration, has value
|
||||
"calling next",
|
||||
"getting done",
|
||||
"getting value",
|
||||
// second iteration, has value
|
||||
"calling next",
|
||||
"getting done",
|
||||
"getting value",
|
||||
// third iteration, has value
|
||||
"calling next",
|
||||
"getting done",
|
||||
"getting value",
|
||||
// fourth iteration, done
|
||||
"calling next",
|
||||
"getting done",
|
||||
];
|
||||
|
||||
assert.sameValue(result, true);
|
||||
assert.compareArray(observedOrder, expectedOrder);
|
||||
}
|
72
test/built-ins/Set/prototype/isDisjointFrom/size-is-a-number.js
vendored
Normal file
72
test/built-ins/Set/prototype/isDisjointFrom/size-is-a-number.js
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-getsetrecord
|
||||
description: GetSetRecord throws an exception if the Set-like object has a size that is coerced to NaN
|
||||
info: |
|
||||
2. Let rawSize be ? Get(obj, "size").
|
||||
3. Let numSize be ? ToNumber(rawSize).
|
||||
4. NOTE: If rawSize is undefined, then numSize will be NaN.
|
||||
5. If numSize is NaN, throw a TypeError exception.
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = {
|
||||
size: undefined,
|
||||
has: () => {},
|
||||
keys: function* keys() {
|
||||
yield 2;
|
||||
yield 3;
|
||||
},
|
||||
};
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isDisjointFrom(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when size is undefined"
|
||||
);
|
||||
|
||||
s2.size = NaN;
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isDisjointFrom(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when size is NaN"
|
||||
);
|
||||
|
||||
let coercionCalls = 0;
|
||||
s2.size = {
|
||||
valueOf: function() {
|
||||
++coercionCalls;
|
||||
return NaN;
|
||||
},
|
||||
};
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isDisjointFrom(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when size coerces to NaN"
|
||||
);
|
||||
assert.sameValue(coercionCalls, 1, "GetSetRecord coerces size");
|
||||
|
||||
s2.size = 0n;
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isDisjointFrom(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when size is a BigInt"
|
||||
);
|
||||
|
||||
s2.size = "string";
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isDisjointFrom(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when size is a non-numeric string"
|
||||
);
|
37
test/built-ins/Set/prototype/isDisjointFrom/subclass-receiver-methods.js
vendored
Normal file
37
test/built-ins/Set/prototype/isDisjointFrom/subclass-receiver-methods.js
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.isdisjointfrom
|
||||
description: Set.prototype.isDisjointFrom works on subclasses of Set, but never calls the receiver's size/has/keys methods
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
let sizeCount = 0;
|
||||
let hasCount = 0;
|
||||
let keysCount = 0;
|
||||
|
||||
class MySet extends Set {
|
||||
size(...rest) {
|
||||
sizeCount++;
|
||||
return super.size(...rest);
|
||||
}
|
||||
|
||||
has(...rest) {
|
||||
hasCount++;
|
||||
return super.has(...rest);
|
||||
}
|
||||
|
||||
keys(...rest) {
|
||||
keysCount++;
|
||||
return super.keys(...rest);
|
||||
}
|
||||
}
|
||||
|
||||
const s1 = new MySet([1, 2]);
|
||||
const s2 = new Set([2, 3]);
|
||||
const result = s1.isDisjointFrom(s2);
|
||||
assert.sameValue(result, false);
|
||||
|
||||
assert.sameValue(sizeCount, 0, "size should not be called on the receiver");
|
||||
assert.sameValue(hasCount, 0, "has should not be called on the receiver");
|
||||
assert.sameValue(keysCount, 0, "keys should not be called on the receiver");
|
31
test/built-ins/Set/prototype/isSubsetOf/allows-set-like-class.js
vendored
Normal file
31
test/built-ins/Set/prototype/isSubsetOf/allows-set-like-class.js
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.issubsetof
|
||||
description: GetSetRecord allows instances of Set-like classes
|
||||
info: |
|
||||
1. If obj is not an Object, throw a TypeError exception.
|
||||
2. Let rawSize be ? Get(obj, "size").
|
||||
...
|
||||
7. Let has be ? Get(obj, "has").
|
||||
...
|
||||
9. Let keys be ? Get(obj, "keys").
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = new class {
|
||||
get size() {
|
||||
return 3;
|
||||
}
|
||||
has(v) {
|
||||
if (v === 1) return false;
|
||||
if (v === 2) return true;
|
||||
throw new Test262Error("Set.prototype.isSubsetOf should only call its argument's has method with contents of this");
|
||||
}
|
||||
* keys() {
|
||||
throw new Test262Error("Set.prototype.isSubsetOf should not call its argument's keys iterator");
|
||||
}
|
||||
};
|
||||
|
||||
assert.sameValue(s1.isSubsetOf(s2), false);
|
29
test/built-ins/Set/prototype/isSubsetOf/allows-set-like-object.js
vendored
Normal file
29
test/built-ins/Set/prototype/isSubsetOf/allows-set-like-object.js
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.issubsetof
|
||||
description: GetSetRecord allows Set-like objects
|
||||
info: |
|
||||
1. If obj is not an Object, throw a TypeError exception.
|
||||
2. Let rawSize be ? Get(obj, "size").
|
||||
...
|
||||
7. Let has be ? Get(obj, "has").
|
||||
...
|
||||
9. Let keys be ? Get(obj, "keys").
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = {
|
||||
size: 2,
|
||||
has: (v) => {
|
||||
if (v === 1) return false;
|
||||
if (v === 2) return true;
|
||||
throw new Test262Error("Set.prototype.isSubsetOf should only call its argument's has method with contents of this");
|
||||
},
|
||||
keys: function* keys() {
|
||||
throw new Test262Error("Set.prototype.isSubsetOf should not call its argument's keys iterator");
|
||||
},
|
||||
};
|
||||
|
||||
assert.sameValue(s1.isSubsetOf(s2), false);
|
17
test/built-ins/Set/prototype/isSubsetOf/array-throws.js
vendored
Normal file
17
test/built-ins/Set/prototype/isSubsetOf/array-throws.js
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.issubsetof
|
||||
description: Set.prototype.isSubsetOf doesn't work with arrays
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = [3];
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isSubsetOf(s2);
|
||||
},
|
||||
"Throws an error when an array is used"
|
||||
);
|
25
test/built-ins/Set/prototype/isSubsetOf/builtins.js
vendored
Normal file
25
test/built-ins/Set/prototype/isSubsetOf/builtins.js
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.issubsetof
|
||||
description: Tests that Set.prototype.isSubsetOf meets the requirements for built-in objects
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
assert.sameValue(
|
||||
Object.isExtensible(Set.prototype.isSubsetOf),
|
||||
true,
|
||||
"Built-in objects must be extensible."
|
||||
);
|
||||
|
||||
assert.sameValue(
|
||||
Object.prototype.toString.call(Set.prototype.isSubsetOf),
|
||||
"[object Function]",
|
||||
"Object.prototype.toString"
|
||||
);
|
||||
|
||||
assert.sameValue(
|
||||
Object.getPrototypeOf(Set.prototype.isSubsetOf),
|
||||
Function.prototype,
|
||||
"prototype"
|
||||
);
|
66
test/built-ins/Set/prototype/isSubsetOf/called-with-object.js
vendored
Normal file
66
test/built-ins/Set/prototype/isSubsetOf/called-with-object.js
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-getsetrecord
|
||||
description: GetSetRecord throws if obj is not an object
|
||||
info: |
|
||||
1. If obj is not an Object, throw a TypeError exception.
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
let s1 = new Set([1]);
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isSubsetOf(1);
|
||||
},
|
||||
"number"
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isSubsetOf("");
|
||||
},
|
||||
"string"
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isSubsetOf(1n);
|
||||
},
|
||||
"bigint"
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isSubsetOf(false);
|
||||
},
|
||||
"boolean"
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isSubsetOf(undefined);
|
||||
},
|
||||
"undefined"
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isSubsetOf(null);
|
||||
},
|
||||
"null"
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isSubsetOf(Symbol("test"));
|
||||
},
|
||||
"symbol"
|
||||
);
|
15
test/built-ins/Set/prototype/isSubsetOf/compares-Map.js
vendored
Normal file
15
test/built-ins/Set/prototype/isSubsetOf/compares-Map.js
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.issubsetof
|
||||
description: Set.prototype.isSubsetOf compares with Map
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const m1 = new Map([
|
||||
[2, "two"],
|
||||
[3, "three"],
|
||||
]);
|
||||
|
||||
assert.sameValue(s1.isSubsetOf(m1), false);
|
22
test/built-ins/Set/prototype/isSubsetOf/compares-empty-sets.js
vendored
Normal file
22
test/built-ins/Set/prototype/isSubsetOf/compares-empty-sets.js
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.issubsetof
|
||||
description: Set.prototype.isSubsetOf can compare empty Sets
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([]);
|
||||
const s2 = new Set([1, 2]);
|
||||
|
||||
assert.sameValue(s1.isSubsetOf(s2), true);
|
||||
|
||||
const s3 = new Set([1, 2]);
|
||||
const s4 = new Set([]);
|
||||
|
||||
assert.sameValue(s3.isSubsetOf(s4), false);
|
||||
|
||||
const s5 = new Set([]);
|
||||
const s6 = new Set([]);
|
||||
|
||||
assert.sameValue(s5.isSubsetOf(s6), true);
|
11
test/built-ins/Set/prototype/isSubsetOf/compares-itself.js
vendored
Normal file
11
test/built-ins/Set/prototype/isSubsetOf/compares-itself.js
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.issubsetof
|
||||
description: Set.prototype.isSubsetOf is successful when called on itself
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
|
||||
assert.sameValue(s1.isSubsetOf(s1), true);
|
12
test/built-ins/Set/prototype/isSubsetOf/compares-same-sets.js
vendored
Normal file
12
test/built-ins/Set/prototype/isSubsetOf/compares-same-sets.js
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.issubsetof
|
||||
description: Set.prototype.isSubsetOf can compare Sets that have the same content
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = new Set([1, 2]);
|
||||
|
||||
assert.sameValue(s1.isSubsetOf(s2), true);
|
16
test/built-ins/Set/prototype/isSubsetOf/compares-sets.js
vendored
Normal file
16
test/built-ins/Set/prototype/isSubsetOf/compares-sets.js
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.issubsetof
|
||||
description: Set.prototype.isSubsetOf compares Sets
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = new Set([2, 3]);
|
||||
|
||||
assert.sameValue(s1.isSubsetOf(s2), false);
|
||||
|
||||
const s3 = new Set([1, 2, 3]);
|
||||
|
||||
assert.sameValue(s1.isSubsetOf(s3), true);
|
36
test/built-ins/Set/prototype/isSubsetOf/has-is-callable.js
vendored
Normal file
36
test/built-ins/Set/prototype/isSubsetOf/has-is-callable.js
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-getsetrecord
|
||||
description: GetSetRecord throws an exception if the Set-like object's 'has' property is not callable
|
||||
info: |
|
||||
7. Let has be ? Get(obj, "has").
|
||||
8. If IsCallable(has) is false, throw a TypeError exception.
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = {
|
||||
size: 2,
|
||||
has: undefined,
|
||||
keys: function* keys() {
|
||||
yield 2;
|
||||
yield 3;
|
||||
},
|
||||
};
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isSubsetOf(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when has is undefined"
|
||||
);
|
||||
|
||||
s2.has = {};
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isSubsetOf(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when has is not callable"
|
||||
);
|
20
test/built-ins/Set/prototype/isSubsetOf/isSubsetOf.js
vendored
Normal file
20
test/built-ins/Set/prototype/isSubsetOf/isSubsetOf.js
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.issubsetof
|
||||
description: Set.prototype.isSubsetOf properties
|
||||
includes: [propertyHelper.js]
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
assert.sameValue(
|
||||
typeof Set.prototype.isSubsetOf,
|
||||
"function",
|
||||
"`typeof Set.prototype.isSubsetOf` is `'function'`"
|
||||
);
|
||||
|
||||
verifyProperty(Set.prototype, "isSubsetOf", {
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
configurable: true,
|
||||
});
|
33
test/built-ins/Set/prototype/isSubsetOf/keys-is-callable.js
vendored
Normal file
33
test/built-ins/Set/prototype/isSubsetOf/keys-is-callable.js
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-getsetrecord
|
||||
description: GetSetRecord throws an exception if the Set-like object's 'keys' property is not callable
|
||||
info: |
|
||||
9. Let keys be ? Get(obj, "keys").
|
||||
10. If IsCallable(keys) is false, throw a TypeError exception.
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = {
|
||||
size: 2,
|
||||
has: () => {},
|
||||
keys: undefined,
|
||||
};
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isSubsetOf(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when keys is undefined"
|
||||
);
|
||||
|
||||
s2.keys = {};
|
||||
assert.throws(
|
||||
TypeError,
|
||||
function () {
|
||||
s1.isSubsetOf(s2);
|
||||
},
|
||||
"GetSetRecord throws an error when keys is not callable"
|
||||
);
|
18
test/built-ins/Set/prototype/isSubsetOf/length.js
vendored
Normal file
18
test/built-ins/Set/prototype/isSubsetOf/length.js
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.issubsetof
|
||||
description: Set.prototype.isSubsetOf length property
|
||||
info: |
|
||||
Set.prototype.isSubsetOf ( other )
|
||||
includes: [propertyHelper.js]
|
||||
features: [set-methods]
|
||||
---*/
|
||||
assert.sameValue(typeof Set.prototype.isSubsetOf, "function");
|
||||
|
||||
verifyProperty(Set.prototype.isSubsetOf, "length", {
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
configurable: true,
|
||||
value: 1,
|
||||
});
|
18
test/built-ins/Set/prototype/isSubsetOf/name.js
vendored
Normal file
18
test/built-ins/Set/prototype/isSubsetOf/name.js
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.issubsetof
|
||||
description: Set.prototype.isSubsetOf name property
|
||||
info: |
|
||||
Set.prototype.isSubsetOf ( other )
|
||||
includes: [propertyHelper.js]
|
||||
features: [set-methods]
|
||||
---*/
|
||||
assert.sameValue(typeof Set.prototype.isSubsetOf, "function");
|
||||
|
||||
verifyProperty(Set.prototype.isSubsetOf, "name", {
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
configurable: true,
|
||||
value: "isSubsetOf",
|
||||
});
|
22
test/built-ins/Set/prototype/isSubsetOf/not-a-constructor.js
vendored
Normal file
22
test/built-ins/Set/prototype/isSubsetOf/not-a-constructor.js
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.issubsetof
|
||||
description: Set.prototype.isSubsetOf does not implement [[Construct]], is not new-able
|
||||
includes: [isConstructor.js]
|
||||
features: [Reflect.construct, set-methods]
|
||||
---*/
|
||||
|
||||
assert.sameValue(
|
||||
isConstructor(Set.prototype.isSubsetOf),
|
||||
false,
|
||||
"isConstructor(Set.prototype.isSubsetOf) must return false"
|
||||
);
|
||||
|
||||
assert.throws(
|
||||
TypeError,
|
||||
() => {
|
||||
new Set.prototype.isSubsetOf();
|
||||
},
|
||||
"`new Set.prototype.isSubsetOf()` throws TypeError"
|
||||
);
|
44
test/built-ins/Set/prototype/isSubsetOf/receiver-not-set.js
vendored
Normal file
44
test/built-ins/Set/prototype/isSubsetOf/receiver-not-set.js
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.issubsetof
|
||||
description: Set.prototype.isSubsetOf throws when receiver is not a Set
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
class MySetLike {
|
||||
constructor() {
|
||||
this.size = 2;
|
||||
this.has = () => {};
|
||||
this.keys = function* keys() {
|
||||
yield 2;
|
||||
yield 3;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const s1 = new MySetLike();
|
||||
const s2 = new Set();
|
||||
assert.throws(
|
||||
TypeError,
|
||||
() => {
|
||||
Set.prototype.isSubsetOf.call(s1, s2);
|
||||
},
|
||||
"Set-like class"
|
||||
);
|
||||
|
||||
const s3 = {
|
||||
size: 2,
|
||||
has: () => {},
|
||||
keys: function* keys() {
|
||||
yield 2;
|
||||
yield 3;
|
||||
},
|
||||
};
|
||||
assert.throws(
|
||||
TypeError,
|
||||
() => {
|
||||
Set.prototype.isSubsetOf.call(s3, s2);
|
||||
},
|
||||
"Set-like object"
|
||||
);
|
27
test/built-ins/Set/prototype/isSubsetOf/require-internal-slot.js
vendored
Normal file
27
test/built-ins/Set/prototype/isSubsetOf/require-internal-slot.js
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.issubsetof
|
||||
description: Set.prototype.isSubsetOf RequireInternalSlot
|
||||
info: |
|
||||
2. Perform ? RequireInternalSlot(O, [[SetData]])
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const isSubsetOf = Set.prototype.isSubsetOf;
|
||||
|
||||
assert.sameValue(typeof isSubsetOf, "function");
|
||||
|
||||
const realSet = new Set([]);
|
||||
|
||||
assert.throws(TypeError, () => isSubsetOf.call(undefined, realSet), "undefined");
|
||||
assert.throws(TypeError, () => isSubsetOf.call(null, realSet), "null");
|
||||
assert.throws(TypeError, () => isSubsetOf.call(true, realSet), "true");
|
||||
assert.throws(TypeError, () => isSubsetOf.call("", realSet), "empty string");
|
||||
assert.throws(TypeError, () => isSubsetOf.call(Symbol(), realSet), "symbol");
|
||||
assert.throws(TypeError, () => isSubsetOf.call(1, realSet), "1");
|
||||
assert.throws(TypeError, () => isSubsetOf.call(1n, realSet), "1n");
|
||||
assert.throws(TypeError, () => isSubsetOf.call({}, realSet), "plain object");
|
||||
assert.throws(TypeError, () => isSubsetOf.call([], realSet), "array");
|
||||
assert.throws(TypeError, () => isSubsetOf.call(new Map(), realSet), "map");
|
||||
assert.throws(TypeError, () => isSubsetOf.call(Set.prototype, realSet), "Set.prototype");
|
21
test/built-ins/Set/prototype/isSubsetOf/set-like-array.js
vendored
Normal file
21
test/built-ins/Set/prototype/isSubsetOf/set-like-array.js
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.issubsetof
|
||||
description: Set.prototype.isSubsetOf consumes a set-like array as a set-like, not an array
|
||||
features: [set-methods]
|
||||
---*/
|
||||
|
||||
const s1 = new Set([1, 2]);
|
||||
const s2 = [5, 6];
|
||||
s2.size = 3;
|
||||
s2.has = function (v) {
|
||||
if (v === 1) return true;
|
||||
if (v === 2) return true;
|
||||
throw new Test262Error("Set.prototype.isSubsetOf should only call its argument's has method with contents of this");
|
||||
};
|
||||
s2.keys = function () {
|
||||
throw new Test262Error("Set.prototype.isSubsetOf should not call its argument's keys iterator when this.size ≤ arg.size");
|
||||
};
|
||||
|
||||
assert.sameValue(s1.isSubsetOf(s2), true);
|
29
test/built-ins/Set/prototype/isSubsetOf/set-like-class-mutation.js
vendored
Normal file
29
test/built-ins/Set/prototype/isSubsetOf/set-like-class-mutation.js
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright (C) 2023 Anthony Frehner and Kevin Gibbons. All rights reserved.
|
||||
// This code is governed by the BSD license found in the LICENSE file.
|
||||
/*---
|
||||
esid: sec-set.prototype.issubsetof
|
||||
description: Set.prototype.isSubsetOf behavior when a custom Set-like class mutates the receiver
|
||||
features: [set-methods]
|
||||
includes: [compareArray.js]
|
||||
---*/
|
||||
|
||||
const baseSet = new Set(["a", "b", "c"]);
|
||||
|
||||
const evilSetLike = {
|
||||
size: 3,
|
||||
has(v) {
|
||||
if (v === "a") {
|
||||
baseSet.delete("c");
|
||||
}
|
||||
return ["x", "a", "b"].includes(v);
|
||||
},
|
||||
* keys() {
|
||||
throw new Test262Error("Set.prototype.isSubsetOf should not call its argument's keys iterator");
|
||||
},
|
||||
};
|
||||
|
||||
const result = baseSet.isSubsetOf(evilSetLike);
|
||||
assert.sameValue(result, true);
|
||||
|
||||
const expectedNewBase = ["a", "b"];
|
||||
assert.compareArray([...baseSet], expectedNewBase);
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user