Skip to content

Commit

Permalink
Add Set.prototype.union tests (#3816)
Browse files Browse the repository at this point in the history
* Beginning of adding Set.prototype.union tests

* Fix description

* Add tests for GetSetRecord

Which also allows Set-like objects

* Add title to test descriptions

* Add test for ensuring values are appended

* Add tests for properties of union

Also: tests for RequireInternalSlot, Constructor, BuiltIns.

Added a test to ensure that -0F is converted to +0F

* Ensure Set.prototype.add is not called as part of .union

* fix lint issues

* Set subclassing and Symbol.species tests

* Set.prototype.union tests for arrays and subclass methods

* Add the Set-methods frontmatter feature flag

* Add additional Set.prototype.union test for edge cases

* Update test/built-ins/Set/GetSetRecord/keys-is-callable.js

Co-authored-by: Kevin Gibbons <bakkot@gmail.com>

* Use compareArray() for assertions

* Remove class field syntax

* Remove unused args

* Update test/built-ins/Set/prototype/union/subclass-receiver-methods.js

Co-authored-by: Jordan Harband <ljharb@gmail.com>

* Return original 'add'

* address comments

* add one more mutation in the evil mutating iterator test

* address further comments

---------

Co-authored-by: Kevin Gibbons <bakkot@gmail.com>
Co-authored-by: Jordan Harband <ljharb@gmail.com>
Co-authored-by: Ms2ger <Ms2ger@igalia.com>
  • Loading branch information
4 people authored Nov 15, 2023
1 parent 5962be6 commit 60310b7
Show file tree
Hide file tree
Showing 29 changed files with 902 additions and 0 deletions.
1 change: 1 addition & 0 deletions features.txt
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ regexp-named-groups
regexp-unicode-property-escapes
rest-parameters
Set
Set-methods
SharedArrayBuffer
string-trimming
String.fromCodePoint
Expand Down
27 changes: 27 additions & 0 deletions test/built-ins/Set/prototype/union/add-not-called.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (C) 2023 Anthony Frehner. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-set.prototype.union
description: Set.prototype.union 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, 2, 3];

const originalAdd = Set.prototype.add;
let count = 0;
Set.prototype.add = function (...rest) {
count++;
return originalAdd.apply(this, rest);
};

const combined = s1.union(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;
34 changes: 34 additions & 0 deletions test/built-ins/Set/prototype/union/allows-set-like-class.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (C) 2023 Anthony Frehner. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-set.prototype.union
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() {
throw new Test262Error("Set.prototype.union should not invoke .has on its argument");
}
* keys() {
yield 2;
yield 3;
}
};
const expected = [1, 2, 3];
const combined = s1.union(s2);

assert.compareArray([...combined], expected);
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
30 changes: 30 additions & 0 deletions test/built-ins/Set/prototype/union/allows-set-like-object.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (C) 2023 Anthony Frehner. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-set.prototype.union
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: () => {},
keys: function* keys() {
yield 2;
yield 3;
},
};
const expected = [1, 2, 3];
const combined = s1.union(s2);

assert.compareArray([...combined], expected);
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
30 changes: 30 additions & 0 deletions test/built-ins/Set/prototype/union/appends-new-values.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright (C) 2023 Anthony Frehner. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-set.prototype.union
description: Set.prototype.union appends new values to a copy of the original Set
info: |
7.b.iii.1 Append nextValue to resultSetData.
features: [Set-methods]
includes: [compareArray.js]
---*/

const s1 = new Set([1, 2]);
const s2 = new Set([-1, 0, 3]);
const expected = [1, 2, -1, 0, 3];
const combined = s1.union(s2);

assert.compareArray([...combined], expected);
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");

const s3 = new Set([1, 2, -3]);
const s4 = new Set([-1, 0]);
const expected2 = [1, 2, -3, -1, 0];
const combined2 = s3.union(s4);

assert.compareArray([...combined2], expected2);
assert.sameValue(
combined2 instanceof Set,
true,
"The returned object is a Set"
);
17 changes: 17 additions & 0 deletions test/built-ins/Set/prototype/union/array-throws.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (C) 2023 Anthony Frehner. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-set.prototype.union
description: Set.prototype.union doesn't work with arrays
features: [Set-methods]
---*/

const s1 = new Set([1, 2]);
const s2 = [3];
assert.throws(
TypeError,
function () {
s1.union(s2);
},
"Throws an error when an array is used"
);
25 changes: 25 additions & 0 deletions test/built-ins/Set/prototype/union/builtins.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (C) 2023 Anthony Frehner. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-set.prototype.union
description: Tests that Set.prototype.union meets the requirements for built-in objects
features: [Set-methods]
---*/

assert.sameValue(
Object.isExtensible(Set.prototype.union),
true,
"Built-in objects must be extensible."
);

assert.sameValue(
Object.prototype.toString.call(Set.prototype.union),
"[object Function]",
"Object.prototype.toString"
);

assert.sameValue(
Object.getPrototypeOf(Set.prototype.union),
Function.prototype,
"prototype"
);
66 changes: 66 additions & 0 deletions test/built-ins/Set/prototype/union/called-with-object.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright (C) 2023 Anthony Frehner. 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.union(1);
},
"number"
);

assert.throws(
TypeError,
function () {
s1.union("");
},
"string"
);

assert.throws(
TypeError,
function () {
s1.union(1n);
},
"bigint"
);

assert.throws(
TypeError,
function () {
s1.union(false);
},
"boolean"
);

assert.throws(
TypeError,
function () {
s1.union(undefined);
},
"undefined"
);

assert.throws(
TypeError,
function () {
s1.union(null);
},
"null"
);

assert.throws(
TypeError,
function () {
s1.union(Symbol("test"));
},
"symbol"
);
19 changes: 19 additions & 0 deletions test/built-ins/Set/prototype/union/combines-Map.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (C) 2023 Anthony Frehner. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-set.prototype.union
description: Set.prototype.union 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, 2, 3];
const combined = s1.union(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/union/combines-empty-sets.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (C) 2023 Anthony Frehner. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-set.prototype.union
description: Set.prototype.union can combine empty Sets
features: [Set-methods]
includes: [compareArray.js]
---*/

const s1 = new Set([]);
const s2 = new Set([1, 2]);
let expected = [1, 2];
let combined = s1.union(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.union(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.union(s6);

assert.compareArray([...combined], expected);
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
15 changes: 15 additions & 0 deletions test/built-ins/Set/prototype/union/combines-itself.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (C) 2023 Anthony Frehner. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-set.prototype.union
description: Set.prototype.union 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.union(s1);

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/union/combines-same-sets.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (C) 2023 Anthony Frehner. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-set.prototype.union
description: Set.prototype.union 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.union(s2);

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/union/combines-sets.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (C) 2023 Anthony Frehner. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-set.prototype.union
description: Set.prototype.union combines Sets
features: [Set-methods]
includes: [compareArray.js]
---*/

const s1 = new Set([1, 2]);
const s2 = new Set([2, 3]);
const expected = [1, 2, 3];
const combined = s1.union(s2);

assert.compareArray([...combined], expected);
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
35 changes: 35 additions & 0 deletions test/built-ins/Set/prototype/union/converts-negative-zero.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (C) 2023 Anthony Frehner. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-set.prototype.union
description: Set.prototype.union 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.union should not invoke .has on its argument");
},
keys: function () {
// we use an array here because the Set constructor would normalize away -0
return [-0].values();
},
};

const s1 = new Set([1]);
let expected = [1, +0];
let combined = s1.union(setlikeWithMinusZero);

assert.compareArray([...combined], expected);
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");

const s2 = new Set([+0]);
expected = [+0];
combined = s2.union(setlikeWithMinusZero);

assert.compareArray([...combined], expected);
assert.sameValue(combined instanceof Set, true, "The returned object is a Set");
Loading

0 comments on commit 60310b7

Please sign in to comment.