Move Map.prototype.getOrInsertComputed tests from staging to built-ins

This commit is contained in:
Daniel Minor 2025-06-08 23:14:26 +02:00 committed by GitHub
parent 3cd73c15f2
commit 81ba0de350
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 201 additions and 191 deletions

View File

@ -2,7 +2,7 @@
// Copyright (C) 2024 Jonas Haukenes, Mathias Ness. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
esid: sec-map.prototype.getorinsertcomputed
description: |
Append a new value in the map normalizing +0 and -0.
info: |
@ -17,7 +17,6 @@ info: |
8. Append p to M.[[MapData]].
...
features: [Symbol, arrow-function, upsert]
flags: [noStrict]
---*/
var map = new Map();
map.getOrInsertComputed(-0, () => 42);

View File

@ -2,7 +2,7 @@
// Copyright (C) 2024 Jonas Haukenes, Mathias Ness. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
esid: sec-map.prototype.getorinsertcomputed
description: |
Append a new value as the last element of entries.
info: |
@ -17,7 +17,6 @@ info: |
8. Append p to M.[[MapData]].
...
features: [Symbol, arrow-function, upsert]
flags: [noStrict]
---*/
var s = Symbol(2);
var map = new Map([[4, 4], ['foo3', 3], [s, 2]]);

View File

@ -2,7 +2,7 @@
// Copyright (C) 2024 Sune Eriksson Lianes, Mathias Ness. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
esid: sec-map.prototype.getorinsertcomputed
description: |
Inserts the value for the specified key on different types, when key not present.
info: |
@ -13,20 +13,22 @@ info: |
8. Append p to M.[[MapData]].
...
features: [Symbol, arrow-function, upsert]
flags: [noStrict]
---*/
var map = new Map();
map.getOrInsertComputed('bar', () => 0);
assert.sameValue(map.get('bar'), 0);
var item = 'bar';
map.getOrInsertComputed(item, () => 0);
assert.sameValue(map.get(item), 0);
map.getOrInsertComputed(1, () => 42);
assert.sameValue(map.get(1), 42);
item = 1;
map.getOrInsertComputed(item, () => 42);
assert.sameValue(map.get(item), 42);
map.getOrInsertComputed(NaN, () => 1);
assert.sameValue(map.get(NaN), 1);
item = NaN;
map.getOrInsertComputed(item, () => 1);
assert.sameValue(map.get(item), 1);
var item = {};
item = {};
map.getOrInsertComputed(item, () => 2);
assert.sameValue(map.get(item), 2);

View File

@ -2,7 +2,7 @@
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
esid: sec-map.prototype.getorinsertcomputed
description: |
Map.getOrInsertComputed throws when callbackfn throws return if abrubt completion Call(callbackfn, key)
info: |
@ -13,7 +13,6 @@ info: |
6. Let value be ? Call(callbackfn, key).
...
features: [upsert]
flags: [noStrict]
---*/
var map = new Map();
@ -21,5 +20,5 @@ assert.throws(Error, function() {
map.getOrInsertComputed(1, function() {
throw new Error('throw in callback');
})
}, Error);
});

View File

@ -0,0 +1,23 @@
// Copyright (C) 2025 Daniel Minor. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-map.prototype.getorinsertcomputed
description: |
Check that callbackfn receives undefined for this and exactly one argument.
info: |
Map.prototype.getOrInsertComputed ( key , callbackfn )
...
6. Let value be ? Call(callbackfn, key).
...
features: [upsert]
flags: [onlyStrict]
---*/
var map = new Map();
map.getOrInsertComputed(1, function(...args) {
assert.sameValue(this, undefined);
assert.sameValue(args.length, 1);
assert.sameValue(args[0], 1);
});

View File

@ -0,0 +1,57 @@
// Copyright (C) 2025 Daniel Minor. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-map.prototype.getorinsertcomputed
description: |
Check state after callback function throws
info: |
Map.prototype.getOrInsertComputed ( key , callbackfn )
...
6. Let value be ? Call(callbackfn, key).
...
features: [upsert]
---*/
var map = new Map();
map.set(0, 'zero');
map.set(1, 'one');
map.set(2, 'two');
assert.throws(Error, function() {
map.getOrInsertComputed(3, function() {
throw new Error('throw in callback');
})
});
// Check the values after throwing in callbackfn.
assert.sameValue(map.get(0), 'zero');
assert.sameValue(map.get(1), 'one');
assert.sameValue(map.get(2), 'two');
assert.sameValue(map.has(3), false)
assert.throws(Error, function() {
map.getOrInsertComputed(3, function() {
map.set(1, 'mutated');
throw new Error('throw in callback');
})
});
// Check the values after throwing in callbackfn, with mutation.
assert.sameValue(map.get(0), 'zero');
assert.sameValue(map.get(1), 'mutated',);
assert.sameValue(map.get(2), 'two');
assert.sameValue(map.has(3), false)
assert.throws(Error, function() {
map.getOrInsertComputed(3, function() {
map.set(3, 'mutated');
throw new Error('throw in callback');
})
});
// Check the values after throwing in callbackfn, with mutation.
assert.sameValue(map.get(0), 'zero');
assert.sameValue(map.get(1), 'mutated',);
assert.sameValue(map.get(2), 'two');
assert.sameValue(map.get(3), 'mutated')

View File

@ -1,7 +1,7 @@
// Copyright (C) 2024 Mathias Ness. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
esid: sec-map.prototype.getorinsertcomputed
description: |
Does not throw if `callbackfn` is callable.
info: |
@ -12,40 +12,21 @@ info: |
...
features: [arrow-function, upsert]
flags: [noStrict]
---*/
var m = new Map();
assert.sameValue(
m.getOrInsertComputed(1, function() {return 1;})
, 1);
assert.sameValue(m.getOrInsertComputed(1, function () { return 1; }), 1);
assert.sameValue(m.get(1), 1);
assert.sameValue(
m.getOrInsertComputed(2, () => 2)
, 2);
assert.sameValue(m.getOrInsertComputed(2, () => 2), 2);
assert.sameValue(m.get(2), 2);
function three() { return 3; }
assert.sameValue(
m.getOrInsertComputed(3, three)
, 3);
assert.sameValue(m.getOrInsertComputed(3, three), 3);
assert.sameValue(m.get(3), 3);
assert.sameValue(
m.getOrInsertComputed(4, new Function())
, undefined);
assert.sameValue(m.getOrInsertComputed(4, new Function()), undefined);
assert.sameValue(m.get(4), undefined);
assert.sameValue(
m.getOrInsertComputed(5, (function() {return 5;}).bind(m))
, 5);
assert.sameValue(m.getOrInsertComputed(5, (function () { return 5; }).bind(m)), 5);
assert.sameValue(m.get(5), 5);

View File

@ -1,7 +1,7 @@
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
esid: sec-map.prototype.getorinsertcomputed
description: |
Does not evaluate the callback function if the key is already in the map.
info: |
@ -13,13 +13,14 @@ info: |
6. Let value be ? Call(callbackfn, undefined, « key »).
...
features: [WeakMap, upsert]
flags: [noStrict]
---*/
var map = new Map([
[1, 0]
]);
var callbackCalls = 0;
function callback() {
callbackCalls += 1;
throw new Error('Callbackfn should not be evaluated if key is present');
}
@ -35,3 +36,4 @@ assert.throws(Error, function() {
map.getOrInsertComputed(4, callback)}
, Error);
assert.sameValue(callbackCalls, 1);

View File

@ -2,7 +2,7 @@
// Copyright (C) 2024 Sune Eriksson Lianes, Mathias Ness. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
esid: sec-map.prototype.getorinsertcomputed
description: |
Throws a TypeError if `this` is a Set Object
info: |
@ -13,14 +13,14 @@ info: |
2. Perform ? RequireInternalSlot(M, [[MapData]])
...
features: [Set, arrow-function, upsert]
flags: [noStrict]
---*/
var set = new Set();
assert.throws(TypeError, function () {
Map.prototype.getOrInsertComputed.call(new Set(), 1, () => 1);
Map.prototype.getOrInsertComputed.call(set, 1, () => 1);
});
assert.throws(TypeError, function () {
var map = new Map();
map.getOrInsertComputed.call(new Set(), 1, () => 1);
assert.throws(TypeError, function () {
map.getOrInsertComputed.call(set, 1, () => 1);
});

View File

@ -2,7 +2,7 @@
// Copyright (C) 2024 Sune Eriksson Lianes, Mathias Ness. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
esid: sec-map.prototype.getorinsertcomputed
description: |
Throws a TypeError if `this` is a WeakMap object.
info: |
@ -13,14 +13,14 @@ info: |
2. Perform ? RequireInternalSlot(M, [[MapData]]).
...
features: [WeakMap, arrow-function, upsert]
flags: [noStrict]
---*/
var weakmap = new WeakMap();
assert.throws(TypeError, function() {
Map.prototype.getOrInsertComputed.call(new WeakMap(), 1, () => 1);
Map.prototype.getOrInsertComputed.call(weakmap, 1, () => 1);
});
assert.throws(TypeError, function() {
var map = new Map();
map.getOrInsertComputed.call(new WeakMap(), 1, () => 1);
assert.throws(TypeError, function() {
map.getOrInsertComputed.call(weakmap, 1, () => 1);
});

View File

@ -2,7 +2,7 @@
// Copyright (C) 2024 Jonas Haukenes, Mathias Ness. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
esid: sec-map.prototype.getorinsertcomputed
description: |
Property type and descriptor.
info: |
@ -10,16 +10,9 @@ info: |
17 ECMAScript Standard Built-in Objects
includes: [propertyHelper.js]
features: [arrow-function, upsert]
flags: [noStrict]
features: [upsert]
---*/
assert.sameValue(
typeof Map.prototype.getOrInsertComputed,
'function',
'`typeof Map.prototype.getOrInsertComputed` is `function`'
);
verifyProperty(Map.prototype, "getOrInsertComputed", {
verifyPrimordialCallableProperty(Map.prototype, "getOrInsertComputed", "getOrInsertComputed", 2, {
value: Map.prototype.getOrInsertComputed,
writable: true,
enumerable: false,

View File

@ -3,7 +3,7 @@
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
esid: sec-map.prototype.getorinsertcomputed
description: |
Map.prototype.getOrInsertComputed does not implement [[Construct]], is not new-able
info: |
@ -20,11 +20,11 @@ info: |
...
includes: [isConstructor.js]
features: [Map, Reflect.construct, arrow-function, upsert]
flags: [noStrict]
---*/
assert.sameValue(isConstructor(Map.prototype.getOrInsertComputed), false, 'isConstructor(Map.prototype.getOrInsertComputed) must return false');
var m = new Map();
assert.throws(TypeError, () => {
let m = new Map(); new m.getOrInsertComputed();
new m.getOrInsertComputed();
});

View File

@ -2,7 +2,7 @@
// Copyright (C) 2024 Mathias Ness. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
esid: sec-map.prototype.getorinsertcomputed
description: |
Throws a TypeError if `callbackfn` is not callable.
info: |
@ -12,39 +12,43 @@ info: |
3. If IsCallable(callbackfn) is false, throw a TypeError exception.
...
features: [Symbol, upsert]
flags: [noStrict]
---*/
var m = new Map();
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(m, 1, 1);
m.getOrInsertComputed(1, 1);
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(m, 1, "");
m.getOrInsertComputed(1, "");
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(m, 1, true);
m.getOrInsertComputed(1, true);
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(m, 1, undefined);
m.getOrInsertComputed(1, undefined);
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(m, 1, null);
m.getOrInsertComputed(1, null);
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(m, 1, {});
m.getOrInsertComputed(1, {});
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(m, 1, []);
m.getOrInsertComputed(1, []);
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(m, 1, Symbol());
m.getOrInsertComputed(1, Symbol());
});
// Check that it also throws if the key is already present (thus it does not try to call the callback)
m.set(1, "foo");
assert.throws(TypeError, function () {
m.getOrInsertComputed(1, 1);
});

View File

@ -1,7 +1,7 @@
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
esid: sec-map.prototype.getorinsertcomputed
description: |
If the callbackfn inserts a value on the given key, the value is overwritten.
info: |
@ -16,7 +16,6 @@ info: |
8. Let p be the Record { [[Key]]: key, [[Value]]: value }.
9. Append p to M.[[WeakMapData]].
...
flags: [noStrict]
features: [upsert]
---*/
var map = new Map();

View File

@ -2,9 +2,9 @@
// Copyright (C) 2024 Jonas Haukenes, Mathias Ness. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
esid: sec-map.prototype.getorinsertcomputed
description: |
Returns the value from the specified key on different types, when key not present.
Test insertion of value returned from callback with different key types.
info: |
Map.prototype.getOrInsertComputed ( key , callbackfn )
@ -14,17 +14,18 @@ info: |
9. Return p.[[Value]].
...
features: [Symbol, arrow-function, upsert]
flags: [noStrict]
---*/
var map = new Map();
var item = 'bar';
assert.sameValue(map.getOrInsertComputed(item, () => 0), 0);
assert.sameValue(map.getOrInsertComputed('bar', () => 0), 0);
item = 1;
assert.sameValue(map.getOrInsertComputed(item, () => 42), 42);
assert.sameValue(map.getOrInsertComputed(1, () => 42), 42);
item = NaN;
assert.sameValue(map.getOrInsertComputed(item, () => 1), 1);
assert.sameValue(map.getOrInsertComputed(NaN, () => 1), 1);
var item = {};
item = {};
assert.sameValue(map.getOrInsertComputed(item, () => 2), 2);
item = [];

View File

@ -0,0 +1,50 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2024 Sune Eriksson Lianes, Mathias Ness. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: sec-map.prototype.getorinsertcomputed
description: |
Returns the value set before getOrInsertComputed from the specified key on different types.
info: |
Map.prototype.getOrInsertComputed ( key , callbackfn )
...
5. For each Record { [[Key]], [[Value]] } p of M.[[MapData]], do
a. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, return p.[[Value]].
...
features: [Symbol, arrow-function, upsert]
---*/
var map = new Map();
var item = 'bar';
map.set(item, 0);
assert.sameValue(map.getOrInsertComputed(item, () => 1), 0);
item = 1;
map.set(item, 42);
assert.sameValue(map.getOrInsertComputed(item, () => 43), 42);
item = NaN;
map.set(item, 1);
assert.sameValue(map.getOrInsertComputed(item, () => 2), 1);
item = {};
map.set(item, 2);
assert.sameValue(map.getOrInsertComputed(item, () => 3), 2);
item = [];
map.set(item, 3);
assert.sameValue(map.getOrInsertComputed(item, () => 4), 3);
item = Symbol('item');
map.set(item, 4);
assert.sameValue(map.getOrInsertComputed(item, () => 5), 4);
item = null;
map.set(item, 5);
assert.sameValue(map.getOrInsertComputed(item, () => 6), 5);
item = undefined;
map.set(item, 6);
assert.sameValue(map.getOrInsertComputed(item, () => 7), 6);

View File

@ -2,7 +2,7 @@
// Copyright (C) 2024 Jonas Haukenes, Mathias Ness. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
esid: sec-map.prototype.getorinsertcomputed
description: |
Returns the value from the specified key normalizing +0 and -0.
info: |
@ -14,7 +14,6 @@ info: |
...
features: [arrow-function, upsert]
flags: [noStrict]
---*/
var map = new Map();

View File

@ -2,7 +2,7 @@
// Copyright (C) 2024 Sune Eriksson Lianes, Mathias Ness. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
esid: sec-map.prototype.getorinsertcomputed
description: |
Throws a TypeError if `this` is not an Object.
info: |
@ -12,7 +12,6 @@ info: |
2. Perform ? RequireInternalSlot(M, [[MapData]])
...
features: [Symbol, arrow-function, upsert]
flags: [noStrict]
---*/
var m = new Map();
@ -40,3 +39,6 @@ assert.throws(TypeError, function () {
m.getOrInsertComputed.call(Symbol(), 1, () => 1);
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(1n, 1, () => 1);
});

View File

@ -1,22 +0,0 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2024 Jonas Haukenes, Mathias Ness. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Map.prototype.getOrInsert.length value and descriptor.
info: |
Map.prototype.getOrInsertComputed ( key , callbackfn )
17 ECMAScript Standard Built-in Objects
includes: [propertyHelper.js]
features: [upsert]
flags: [noStrict]
---*/
verifyProperty(Map.prototype.getOrInsertComputed, "length", {
value: 2,
writable: false,
enumerable: false,
configurable: true
});

View File

@ -1,22 +0,0 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2024 Jonas Haukenes, Mathias Ness. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Map.prototype.getOrInsertComputed.name value and descriptor.
info: |
Map.prototype.getOrInsertComputed ( key , callbackfn )
17 ECMAScript Standard Built-in Objects
includes: [propertyHelper.js]
features: [upsert]
flags: [noStrict]
---*/
verifyProperty(Map.prototype.getOrInsertComputed, "name", {
value: "getOrInsertComputed",
writable: false,
enumerable: false,
configurable: true
});

View File

@ -1,56 +0,0 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2024 Sune Eriksson Lianes, Mathias Ness. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Returns the value set before getOrInsertComputed from the specified key on different types.
info: |
Map.prototype.getOrInsertComputed ( key , callbackfn )
...
5. For each Record { [[Key]], [[Value]] } p of M.[[MapData]], do
a. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, return p.[[Value]].
...
features: [Symbol, arrow-function, upsert]
flags: [noStrict]
---*/
var map = new Map();
map.set('bar', 0);
assert.sameValue(map.get('bar'), map.getOrInsertComputed('bar', () => 1));
assert.sameValue(0, map.getOrInsertComputed('bar', () => 1));
map.set(1, 42);
assert.sameValue(map.get(1), map.getOrInsertComputed(1, () => 43));
assert.sameValue(42, map.getOrInsertComputed(1, () => 43));
map.set(NaN, 1);
assert.sameValue(map.get(NaN), map.getOrInsertComputed(NaN, () => 2));
assert.sameValue(1, map.getOrInsertComputed(NaN, () => 2));
var item = {};
map.set(item, 2);
assert.sameValue(map.get(item), map.getOrInsertComputed(item, () => 3));
assert.sameValue(2, map.getOrInsertComputed(item, () => 3));
item = [];
map.set(item, 3);
assert.sameValue(map.get(item), map.getOrInsertComputed(item, () => 4));
assert.sameValue(3, map.getOrInsertComputed(item, () => 4));
item = Symbol('item');
map.set(item, 4);
assert.sameValue(map.get(item), map.getOrInsertComputed(item, () => 5));
assert.sameValue(4, map.getOrInsertComputed(item, () => 5));
item = null;
map.set(item, 5);
assert.sameValue(map.get(item), map.getOrInsertComputed(item, () => 6));
assert.sameValue(5, map.getOrInsertComputed(item, () => 6));
item = undefined;
map.set(item, 6);
assert.sameValue(map.get(item), map.getOrInsertComputed(item, () => 7));
assert.sameValue(6, map.getOrInsertComputed(item, () => 7));