Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More set methods tests #3966

Merged
merged 14 commits into from
Jan 10, 2024
27 changes: 27 additions & 0 deletions test/built-ins/Set/prototype/difference/add-not-called.js
Original file line number Diff line number Diff line change
@@ -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;
Original file line number Diff line number Diff line change
@@ -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");
Original file line number Diff line number Diff line change
@@ -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 changes: 17 additions & 0 deletions test/built-ins/Set/prototype/difference/array-throws.js
Original file line number Diff line number Diff line change
@@ -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 changes: 25 additions & 0 deletions test/built-ins/Set/prototype/difference/builtins.js
Original file line number Diff line number Diff line change
@@ -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 changes: 66 additions & 0 deletions test/built-ins/Set/prototype/difference/called-with-object.js
Original file line number Diff line number Diff line change
@@ -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 changes: 19 additions & 0 deletions test/built-ins/Set/prototype/difference/combines-Map.js
Original file line number Diff line number Diff line change
@@ -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 changes: 32 additions & 0 deletions test/built-ins/Set/prototype/difference/combines-empty-sets.js
Original file line number Diff line number Diff line change
@@ -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 changes: 16 additions & 0 deletions test/built-ins/Set/prototype/difference/combines-itself.js
Original file line number Diff line number Diff line change
@@ -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 changes: 18 additions & 0 deletions test/built-ins/Set/prototype/difference/combines-same-sets.js
Original file line number Diff line number Diff line change
@@ -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 changes: 16 additions & 0 deletions test/built-ins/Set/prototype/difference/combines-sets.js
Original file line number Diff line number Diff line change
@@ -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");
Original file line number Diff line number Diff line change
@@ -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");
ljharb marked this conversation as resolved.
Show resolved Hide resolved
},
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 changes: 20 additions & 0 deletions test/built-ins/Set/prototype/difference/difference.js
Original file line number Diff line number Diff line change
@@ -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,
});
Loading