Skip to content

Commit

Permalink
More set methods tests (#3966)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>

* 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 <[email protected]>
  • Loading branch information
bakkot and ljharb authored Jan 10, 2024
1 parent 80590ce commit c8cd136
Show file tree
Hide file tree
Showing 164 changed files with 5,455 additions and 39 deletions.
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;
35 changes: 35 additions & 0 deletions test/built-ins/Set/prototype/difference/allows-set-like-class.js
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");
33 changes: 33 additions & 0 deletions test/built-ins/Set/prototype/difference/allows-set-like-object.js
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");
28 changes: 28 additions & 0 deletions test/built-ins/Set/prototype/difference/converts-negative-zero.js
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");
},
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

0 comments on commit c8cd136

Please sign in to comment.