Add upsert tests (#4454)

These tests are currently being executed in SpiderMonkey as `non262` tests,
and were exported using the `test262-export.py` script. Linting errors
were then corrected.
This commit is contained in:
Daniel Minor 2025-05-05 15:20:47 -04:00 committed by GitHub
parent 27622d7647
commit 93d63969bc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
72 changed files with 2355 additions and 0 deletions

View File

@ -96,6 +96,10 @@ iterator-sequencing
# https://github.com/tc39/proposal-canonical-tz
canonical-tz
# Upsert
# https://github.com/tc39/proposal-upsert
upsert
## Standard language features
#
# Language features that have been included in a published version of the

View File

@ -0,0 +1,28 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2024 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Append a new value in the map normalizing +0 and -0.
info: |
Map.prototype.getOrInsert ( key , value )
...
3. Set key to CanonicalizeKeyedCollectionKey(key).
4. 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]].
5. Let p be the Record { [[Key]]: key, [[Value]]: value }.
6. Append p to M.[[MapData]].
...
features: [Symbol, upsert]
flags: [noStrict]
---*/
var map = new Map();
map.getOrInsert(-0, 42);
assert.sameValue(map.get(0), 42);
map = new Map();
map.getOrInsert(+0, 43);
assert.sameValue(map.get(0), 43);

View File

@ -0,0 +1,50 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2024 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Append a new value as the last element of entries.
info: |
Map.prototype.getOrInsert ( key , value )
...
3. Set key to CanonicalizeKeyedCollectionKey(key).
4. 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]].
5. Let p be the Record { [[Key]]: key, [[Value]]: value }.
6. Append p to M.[[MapData]].
...
features: [Symbol, upsert]
flags: [noStrict]
---*/
var s = Symbol(2);
var map = new Map([[4, 4], ['foo3', 3], [s, 2]]);
map.getOrInsert(null, 42);
map.getOrInsert(1, 'valid');
assert.sameValue(map.size, 5);
assert.sameValue(map.get(1), 'valid');
var results = [];
map.forEach(function(value, key) {
results.push({
value: value,
key: key
});
});
var result = results.pop();
assert.sameValue(result.value, 'valid');
assert.sameValue(result.key, 1);
result = results.pop();
assert.sameValue(result.value, 42);
assert.sameValue(result.key, null);
result = results.pop();
assert.sameValue(result.value, 2);
assert.sameValue(result.key, s);

View File

@ -0,0 +1,48 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2024 Sune Eriksson Lianes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Inserts the value for the specified key on different types, when key not present.
info: |
Map.prototype.getOrInsert ( key , value )
...
5. Let p be the Record { [[Key]]: key, [[Value]]: value }.
6. Append p to M.[[MapData]].
...
features: [Symbol, upsert]
flags: [noStrict]
---*/
var map = new Map();
map.getOrInsert('bar', 0);
assert.sameValue(map.get('bar'), 0);
map.getOrInsert(1, 42);
assert.sameValue(map.get(1), 42);
map.getOrInsert(NaN, 1);
assert.sameValue(map.get(NaN), 1);
var item = {};
map.getOrInsert(item, 2);
assert.sameValue(map.get(item), 2);
item = [];
map.getOrInsert(item, 3);
assert.sameValue(map.get(item), 3);
item = Symbol('item');
map.getOrInsert(item, 4);
assert.sameValue(map.get(item), 4);
item = null;
map.getOrInsert(item, 5);
assert.sameValue(map.get(item), 5);
item = undefined;
map.getOrInsert(item, 6);
assert.sameValue(map.get(item), 6);

View File

@ -0,0 +1,26 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2024 Sune Eriksson Lianes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Throws a TypeError if `this` is a Set Object
info: |
Map.prototype.getOrInsert ( key , value )
...
1. Let M be the this value.
2. Perform ? RequireInternalSlot(M, [[MapData]])
...
features: [Set, upsert]
flags: [noStrict]
---*/
assert.throws(TypeError, function () {
Map.prototype.getOrInsert.call(new Set(), 1, 1);
});
assert.throws(TypeError, function () {
var map = new Map();
map.getOrInsert.call(new Set(), 1, 1);
});

View File

@ -0,0 +1,26 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2024 Sune Eriksson Lianes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Throws a TypeError if `this` is a WeakMap object.
info: |
Map.prototype.getOrInsert ( key , value )
...
1. Let M be the this value.
2. Perform ? RequireInternalSlot(M, [[MapData]]).
...
features: [WeakMap, upsert]
flags: [noStrict]
---*/
assert.throws(TypeError, function() {
Map.prototype.getOrInsert.call(new WeakMap(), 1, 1);
});
assert.throws(TypeError, function() {
var map = new Map();
map.getOrInsert.call(new WeakMap(), 1, 1);
});

View File

@ -0,0 +1,35 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2024 Sune Eriksson Lianes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Throws a TypeError if `this` object does not have a [[MapData]] internal slot.
info: |
Map.getOrInsert ( key , value )
...
1. Let M be the this value.
2. Perform ? RequireInternalSLot(M, [[MapData]])
...
features: [upsert]
flags: [noStrict]
---*/
var map = new Map();
assert.throws(TypeError, function () {
Map.prototype.getOrInsert.call([], 1, 1);
});
assert.throws(TypeError, function () {
map.getOrInsert.call([], 1, 1);
});
assert.throws(TypeError, function () {
Map.prototype.getOrInsert.call({}, 1, 1);
});
assert.throws(TypeError, function () {
map.getOrInsert.call({}, 1, 1);
});

View File

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

View File

@ -0,0 +1,22 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2024 Jonas Haukenes. 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.getOrInsert ( key , value )
17 ECMAScript Standard Built-in Objects
includes: [propertyHelper.js]
features: [upsert]
flags: [noStrict]
---*/
verifyProperty(Map.prototype.getOrInsert, "length", {
value: 2,
writable: false,
enumerable: false,
configurable: true
});

View File

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

View File

@ -0,0 +1,30 @@
// Copyright (C) 2020 Rick Waldron. All rights reserved.
// Copyright (C) 2024 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Map.prototype.getOrInsert does not implement [[Construct]], is not new-able
info: |
ECMAScript Function Objects
Built-in function objects that are not identified as constructors do not
implement the [[Construct]] internal method unless otherwise specified in
the description of a particular function.
sec-evaluatenew
...
7. If IsConstructor(constructor) is false, throw a TypeError exception.
...
includes: [isConstructor.js]
features: [Map, Reflect.construct, arrow-function, upsert]
flags: [noStrict]
---*/
assert.sameValue(isConstructor(Map.prototype.getOrInsert), false, 'isConstructor(Map.prototype.getOrInsert) must return false');
assert.throws(TypeError, () => {
let m = new Map(); new m.getOrInsert();
});

View File

@ -0,0 +1,41 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2024 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Returns the value from the specified key on different types, when key not present.
info: |
Map.prototype.getOrInsert ( key , value )
...
5. Let p be the Record { [[Key]]: key, [[Value]]: value }.
6. Append p to M.[[MapData]].
7. Return p.[[Value]].
...
features: [Symbol, upsert]
flags: [noStrict]
---*/
var map = new Map();
assert.sameValue(map.getOrInsert('bar', 0), 0);
assert.sameValue(map.getOrInsert(1, 42), 42);
assert.sameValue(map.getOrInsert(NaN, 1), 1);
var item = {};
assert.sameValue(map.getOrInsert(item, 2), 2);
item = [];
assert.sameValue(map.getOrInsert(item, 3), 3);
item = Symbol('item');
assert.sameValue(map.getOrInsert(item, 4), 4);
item = null;
assert.sameValue(map.getOrInsert(item, 5), 5);
item = undefined;
assert.sameValue(map.getOrInsert(item, 6), 6);

View File

@ -0,0 +1,56 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2024 Sune Eriksson Lianes. 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 getOrInsert from the specified key on different types.
info: |
Map.prototype.getOrInsert ( key , value )
...
4. 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, upsert]
flags: [noStrict]
---*/
var map = new Map();
map.set('bar', 0);
assert.sameValue(map.get('bar'), map.getOrInsert('bar', 1));
assert.sameValue(0, map.getOrInsert('bar', 1));
map.set(1, 42);
assert.sameValue(map.get(1), map.getOrInsert(1, 43));
assert.sameValue(42, map.getOrInsert(1, 43));
map.set(NaN, 1);
assert.sameValue(map.get(NaN), map.getOrInsert(NaN, 2));
assert.sameValue(1, map.getOrInsert(NaN, 2));
var item = {};
map.set(item, 2);
assert.sameValue(map.get(item), map.getOrInsert(item, 3));
assert.sameValue(2, map.getOrInsert(item, 3));
item = [];
map.set(item, 3);
assert.sameValue(map.get(item), map.getOrInsert(item, 4));
assert.sameValue(3, map.getOrInsert(item, 4));
item = Symbol('item');
map.set(item, 4);
assert.sameValue(map.get(item), map.getOrInsert(item, 5));
assert.sameValue(4, map.getOrInsert(item, 5));
item = null;
map.set(item, 5);
assert.sameValue(map.get(item), map.getOrInsert(item, 6));
assert.sameValue(5, map.getOrInsert(item, 6));
item = undefined;
map.set(item, 6);
assert.sameValue(map.get(item), map.getOrInsert(item, 7));
assert.sameValue(6, map.getOrInsert(item, 7));

View File

@ -0,0 +1,26 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2024 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Returns the value from the specified key normalizing +0 and -0.
info: |
Map.prototype.getOrInsert ( key , value )
5. Set key to CanonicalizeKeyedCollectionKey(key).
4. 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: [upsert]
flags: [noStrict]
---*/
var map = new Map();
map.set(+0, 42);
assert.sameValue(map.getOrInsert(-0, 1), 42);
map = new Map();
map.set(-0, 43);
assert.sameValue(map.getOrInsert(+0, 1), 43);

View File

@ -0,0 +1,42 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2024 Sune Eriksson Lianes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Throws a TypeError if `this` is not an Object.
info: |
Map.prototype.getOrInsert ( key , value )
1. Let M be the this value
2. Perform ? RequireInternalSlot(M, [[MapData]])
...
features: [Symbol, upsert]
flags: [noStrict]
---*/
var m = new Map();
assert.throws(TypeError, function () {
m.getOrInsert.call(false, 1, 1);
});
assert.throws(TypeError, function () {
m.getOrInsert.call(1, 1, 1);
});
assert.throws(TypeError, function () {
m.getOrInsert.call("", 1, 1);
});
assert.throws(TypeError, function () {
m.getOrInsert.call(undefined, 1, 1);
});
assert.throws(TypeError, function () {
m.getOrInsert.call(null, 1, 1);
});
assert.throws(TypeError, function () {
m.getOrInsert.call(Symbol(), 1, 1);
});

View File

@ -0,0 +1,29 @@
// 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: |
Append a new value in the map normalizing +0 and -0.
info: |
Map.prototype.getOrInsertComputed ( key , callbackfn )
...
4. Set key to CanonicalizeKeyedCollectionKey(key).
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]].
6. Let value be ? Call(callbackfn, key).
7. Let p be the Record { [[Key]]: key, [[Value]]: value }.
8. Append p to M.[[MapData]].
...
features: [Symbol, arrow-function, upsert]
flags: [noStrict]
---*/
var map = new Map();
map.getOrInsertComputed(-0, () => 42);
assert.sameValue(map.get(0), 42);
map = new Map();
map.getOrInsertComputed(+0, () => 43);
assert.sameValue(map.get(0), 43);

View File

@ -0,0 +1,51 @@
// 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: |
Append a new value as the last element of entries.
info: |
Map.prototype.getOrInsertComputed ( key , callbackfn )
...
4. Set key to CanonicalizeKeyedCollectionKey(key).
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]].
6. Let value be ? Call(callbackfn, key).
7. Let p be the Record { [[Key]]: key, [[Value]]: value }.
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]]);
map.getOrInsertComputed(null, () => 42);
map.getOrInsertComputed(1, () => 'valid');
assert.sameValue(map.size, 5);
assert.sameValue(map.get(1), 'valid');
var results = [];
map.forEach(function(value, key) {
results.push({
value: value,
key: key
});
});
var result = results.pop();
assert.sameValue(result.value, 'valid');
assert.sameValue(result.key, 1);
result = results.pop();
assert.sameValue(result.value, 42);
assert.sameValue(result.key, null);
result = results.pop();
assert.sameValue(result.value, 2);
assert.sameValue(result.key, s);

View File

@ -0,0 +1,48 @@
// 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: |
Inserts the value for the specified key on different types, when key not present.
info: |
Map.prototype.getOrInsertComputed ( key , callbackfn )
...
7. Let p be the Record { [[Key]]: key, [[Value]]: value }.
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);
map.getOrInsertComputed(1, () => 42);
assert.sameValue(map.get(1), 42);
map.getOrInsertComputed(NaN, () => 1);
assert.sameValue(map.get(NaN), 1);
var item = {};
map.getOrInsertComputed(item, () => 2);
assert.sameValue(map.get(item), 2);
item = [];
map.getOrInsertComputed(item, () => 3);
assert.sameValue(map.get(item), 3);
item = Symbol('item');
map.getOrInsertComputed(item, () => 4);
assert.sameValue(map.get(item), 4);
item = null;
map.getOrInsertComputed(item, () => 5);
assert.sameValue(map.get(item), 5);
item = undefined;
map.getOrInsertComputed(item, () => 6);
assert.sameValue(map.get(item), 6);

View File

@ -0,0 +1,25 @@
// 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.getOrInsertComputed throws when callbackfn throws return if abrubt completion Call(callbackfn, key)
info: |
Map.prototype.getOrInsertComputed ( key , callbackfn )
...
6. Let value be ? Call(callbackfn, key).
...
features: [upsert]
flags: [noStrict]
---*/
var map = new Map();
assert.throws(Error, function() {
map.getOrInsertComputed(1, function() {
throw new Error('throw in callback');
})
}, Error);

View File

@ -0,0 +1,51 @@
// Copyright (C) 2024 Mathias Ness. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Does not throw if `callbackfn` is callable.
info: |
Map.prototype.getOrInsertComputed ( key , callbackfn )
...
3. If IsCallable(callbackfn) is false, throw a TypeError exception.
...
features: [arrow-function, upsert]
flags: [noStrict]
---*/
var m = new Map();
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.get(2), 2);
function three() {return 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.get(4), undefined);
assert.sameValue(
m.getOrInsertComputed(5, (function() {return 5;}).bind(m))
, 5);
assert.sameValue(m.get(5), 5);

View File

@ -0,0 +1,37 @@
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Does not evaluate the callback function if the key is already in the map.
info: |
WeakMap.prototype.getOrInsertComputed ( key, callbackfn )
...
5. For each Record { [[Key]], [[Value]] } p of M.[[WeakMapData]], do
a. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, return p.[[Value]].
6. Let value be ? Call(callbackfn, undefined, « key »).
...
features: [WeakMap, upsert]
flags: [noStrict]
---*/
var map = new Map([
[1, 0]
]);
function callback() {
throw new Error('Callbackfn should not be evaluated if key is present');
}
assert.sameValue(map.getOrInsertComputed(1, callback), 0);
map.set(2, 1);
assert.sameValue(map.getOrInsertComputed(2, callback), 1);
map.set(3, 2);
assert.sameValue(map.getOrInsertComputed(3, callback), 2);
assert.throws(Error, function() {
map.getOrInsertComputed(4, callback)}
, Error);

View File

@ -0,0 +1,26 @@
// 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: |
Throws a TypeError if `this` is a Set Object
info: |
Map.prototype.getOrInsertComputed ( key , callbackfn )
...
1. Let M be the this value.
2. Perform ? RequireInternalSlot(M, [[MapData]])
...
features: [Set, arrow-function, upsert]
flags: [noStrict]
---*/
assert.throws(TypeError, function () {
Map.prototype.getOrInsertComputed.call(new Set(), 1, () => 1);
});
assert.throws(TypeError, function () {
var map = new Map();
map.getOrInsertComputed.call(new Set(), 1, () => 1);
});

View File

@ -0,0 +1,26 @@
// 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: |
Throws a TypeError if `this` is a WeakMap object.
info: |
Map.prototype.getOrInsertComputed ( key , callbackfn )
...
1. Let M be the this value.
2. Perform ? RequireInternalSlot(M, [[MapData]]).
...
features: [WeakMap, arrow-function, upsert]
flags: [noStrict]
---*/
assert.throws(TypeError, function() {
Map.prototype.getOrInsertComputed.call(new WeakMap(), 1, () => 1);
});
assert.throws(TypeError, function() {
var map = new Map();
map.getOrInsertComputed.call(new WeakMap(), 1, () => 1);
});

View File

@ -0,0 +1,28 @@
// 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: |
Property type and descriptor.
info: |
Map.prototype.getOrInsertComputed ( key , callbackfn )
17 ECMAScript Standard Built-in Objects
includes: [propertyHelper.js]
features: [arrow-function, upsert]
flags: [noStrict]
---*/
assert.sameValue(
typeof Map.prototype.getOrInsertComputed,
'function',
'`typeof Map.prototype.getOrInsertComputed` is `function`'
);
verifyProperty(Map.prototype, "getOrInsertComputed", {
value: Map.prototype.getOrInsertComputed,
writable: true,
enumerable: false,
configurable: true
});

View File

@ -0,0 +1,22 @@
// 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

@ -0,0 +1,22 @@
// 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

@ -0,0 +1,30 @@
// Copyright (C) 2020 Rick Waldron. 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 does not implement [[Construct]], is not new-able
info: |
ECMAScript Function Objects
Built-in function objects that are not identified as constructors do not
implement the [[Construct]] internal method unless otherwise specified in
the description of a particular function.
sec-evaluatenew
...
7. If IsConstructor(constructor) is false, throw a TypeError exception.
...
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');
assert.throws(TypeError, () => {
let m = new Map(); new m.getOrInsertComputed();
});

View File

@ -0,0 +1,50 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2024 Mathias Ness. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Throws a TypeError if `callbackfn` is not callable.
info: |
Map.prototype.getOrInsertComputed ( key , callbackfn )
...
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);
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(m, 1, "");
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(m, 1, true);
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(m, 1, undefined);
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(m, 1, null);
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(m, 1, {});
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(m, 1, []);
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(m, 1, Symbol());
});

View File

@ -0,0 +1,34 @@
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
If the callbackfn inserts a value on the given key, the value is overwritten.
info: |
WeakMap.prototype.set ( key, value )
...
6. Let value be ? Call(callbackfn, undefined, « key »).
7. For each Record { [[Key]], [[Value]] } p of M.[[WeakMapData]], do
a. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, then
i. Set p.[[Value]] to value.
ii. Return value.
8. Let p be the Record { [[Key]]: key, [[Value]]: value }.
9. Append p to M.[[WeakMapData]].
...
flags: [noStrict]
features: [upsert]
---*/
var map = new Map();
var foo = 1;
var bar = 2;
var baz = 3;
map.getOrInsertComputed(foo, () => {map.set(foo, 0); return 3;});
map.getOrInsertComputed(bar, () => {map.set(bar, 1)});
map.getOrInsertComputed(baz, () => {map.set(baz, 2); return 'string';});
assert.sameValue(map.get(foo), 3);
assert.sameValue(map.get(bar), undefined);
assert.sameValue(map.get(baz), 'string');

View File

@ -0,0 +1,41 @@
// 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: |
Returns the value from the specified key on different types, when key not present.
info: |
Map.prototype.getOrInsertComputed ( key , callbackfn )
...
7. Let p be the Record { [[Key]]: key, [[Value]]: value }.
8. Append p to M.[[MapData]].
9. Return p.[[Value]].
...
features: [Symbol, arrow-function, upsert]
flags: [noStrict]
---*/
var map = new Map();
assert.sameValue(map.getOrInsertComputed('bar', () => 0), 0);
assert.sameValue(map.getOrInsertComputed(1, () => 42), 42);
assert.sameValue(map.getOrInsertComputed(NaN, () => 1), 1);
var item = {};
assert.sameValue(map.getOrInsertComputed(item, () => 2), 2);
item = [];
assert.sameValue(map.getOrInsertComputed(item, () => 3), 3);
item = Symbol('item');
assert.sameValue(map.getOrInsertComputed(item, () => 4), 4);
item = null;
assert.sameValue(map.getOrInsertComputed(item, () => 5), 5);
item = undefined;
assert.sameValue(map.getOrInsertComputed(item, () => 6), 6);

View File

@ -0,0 +1,56 @@
// 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));

View File

@ -0,0 +1,27 @@
// 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: |
Returns the value from the specified key normalizing +0 and -0.
info: |
Map.prototype.getOrInsertComputed ( key , Callbackfn )
4. Set key to CanonicalizeKeyedCollectionKey(key).
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: [arrow-function, upsert]
flags: [noStrict]
---*/
var map = new Map();
map.set(+0, 42);
assert.sameValue(map.getOrInsertComputed(-0, () => 1), 42);
map = new Map();
map.set(-0, 43);
assert.sameValue(map.getOrInsertComputed(+0, () => 1), 43);

View File

@ -0,0 +1,42 @@
// 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: |
Throws a TypeError if `this` is not an Object.
info: |
Map.prototype.getOrInsertComputed ( key , callbackfn )
1. Let M be the this value
2. Perform ? RequireInternalSlot(M, [[MapData]])
...
features: [Symbol, arrow-function, upsert]
flags: [noStrict]
---*/
var m = new Map();
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(false, 1, () => 1);
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(1, 1, () => 1);
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call("", 1, () => 1);
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(undefined, 1, () => 1);
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(null, 1, () => 1);
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(Symbol(), 1, () => 1);
});

View File

@ -0,0 +1,34 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Adds a value with an Object key if key is not already in the map.
info: |
WeakMap.prototype.getOrInsert ( key, value )
...
5. Let p be the Record {[[Key]]: key, [[Value]]: value}.
6. Append p to M.[[WeakMapData]].
...
features: [WeakMap, upsert]
flags: [noStrict]
---*/
var map = new WeakMap();
var foo = {};
var bar = {};
var baz = {};
map.getOrInsert(foo, 1);
map.getOrInsert(bar, 2);
map.getOrInsert(baz, 3);
assert.sameValue(map.has(foo), true);
assert.sameValue(map.has(bar), true);
assert.sameValue(map.has(baz), true);
assert.sameValue(map.get(foo), 1);
assert.sameValue(map.get(bar), 2);
assert.sameValue(map.get(baz), 3);

View File

@ -0,0 +1,32 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Adds a value with a Symbol key if key is not already in the map.
info: |
WeakMap.prototype.getOrInsert ( key, value )
...
5. Let p be the Record {[[Key]]: key, [[Value]]: value}.
6. Append p to M.[[WeakMapData]].
...
features: [Symbol, WeakMap, symbols-as-weakmap-keys, upsert]
flags: [noStrict]
---*/
var map = new WeakMap();
var foo = Symbol('a description');
var bar = Symbol('a description');
map.getOrInsert(foo, 1);
map.getOrInsert(bar, 2);
map.getOrInsert(Symbol.hasInstance, 3);
assert.sameValue(map.has(bar), true, 'Regular symbol as key');
assert.sameValue(map.get(foo), 1, "Symbols with the same description don't overwrite each other");
assert.sameValue(map.has(Symbol.hasInstance), true, 'Well-known symbol as key');
assert.sameValue(map.get(bar), 2);
assert.sameValue(map.get(Symbol.hasInstance), 3);

View File

@ -0,0 +1,26 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Throws TypeError if `this` doesn't have a [[WeakMapData]] internal slot.
info: |
WeakMap.prototype.getOrInsert ( key, value )
...
1. Let M be the this value.
2. Perform ? RequireInternalSlot(M, [[WeakMapData]]).
...
features: [upsert]
flags: [noStrict]
---*/
assert.throws(TypeError, function() {
WeakMap.prototype.getOrInsert.call([], {}, 1);
});
assert.throws(TypeError, function() {
var map = new WeakMap();
map.getOrInsert.call([], {}, 1);
});

View File

@ -0,0 +1,26 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Throws TypeError if `this` doesn't have a [[WeakMapData]] internal slot.
info: |
WeakMap.prototype.getOrInsert ( key, value )
...
1. Let M be the this value.
2. Perform ? RequireInternalSlot(M, [[WeakMapData]]).
...
features: [Map, upsert]
flags: [noStrict]
---*/
assert.throws(TypeError, function() {
WeakMap.prototype.getOrInsert.call(new Map(), {}, 1);
});
assert.throws(TypeError, function() {
var map = new WeakMap();
map.getOrInsert.call(new Map(), {}, 1);
});

View File

@ -0,0 +1,26 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Throws TypeError if `this` doesn't have a [[WeakMapData]] internal slot.
info: |
WeakMap.prototype.getOrInsert ( key, value )
...
1. Let M be the this value.
2. Perform ? RequireInternalSlot(M, [[WeakMapData]]).
...
features: [upsert]
flags: [noStrict]
---*/
assert.throws(TypeError, function() {
WeakMap.prototype.getOrInsert.call({}, {}, 1);
});
assert.throws(TypeError, function() {
var map = new WeakMap();
map.getOrInsert.call({}, {}, 1);
});

View File

@ -0,0 +1,26 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Throws TypeError if `this` doesn't have a [[WeakMapData]] internal slot.
info: |
WeakMap.prototype.getOrInsert ( key, value )
...
1. Let M be the this value.
2. Perform ? RequireInternalSlot(M, [[WeakMapData]]).
...
features: [Set, upsert]
flags: [noStrict]
---*/
assert.throws(TypeError, function() {
WeakMap.prototype.getOrInsert.call(new Set(), {}, 1);
});
assert.throws(TypeError, function() {
var map = new WeakMap();
map.getOrInsert.call(new Set(), {}, 1);
});

View File

@ -0,0 +1,26 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Throws TypeError if `this` doesn't have a [[WeakMapData]] internal slot.
info: |
WeakMap.prototype.getOrInsert ( key, value )
...
1. Let M be the this value.
2. Perform ? RequireInternalSlot(M, [[WeakMapData]]).
...
features: [upsert]
flags: [noStrict]
---*/
assert.throws(TypeError, function() {
WeakMap.prototype.getOrInsert.call(WeakMap.prototype, {}, 1);
});
assert.throws(TypeError, function() {
var map = new WeakMap();
map.getOrInsert.call(WeakMap.prototype, {}, 1);
});

View File

@ -0,0 +1,28 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
WeakMap.prototype.getOrInsert property descriptor
info: |
WeakMap.prototype.getOrInsert ( key, value )
17 ECMAScript Standard Built-in Objects
includes: [propertyHelper.js]
features: [upsert]
flags: [noStrict]
---*/
assert.sameValue(
typeof WeakMap.prototype.getOrInsert,
'function',
'typeof WeakMap.prototype.getOrInsert is "function"'
);
verifyProperty(WeakMap.prototype, "getOrInsert", {
value: WeakMap.prototype.getOrInsert,
writable: true,
enumerable: false,
configurable: true
});

View File

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

View File

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

View File

@ -0,0 +1,33 @@
// Copyright (C) 2020 Rick Waldron. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
WeakMap.prototype.getOrInsert does not implement [[Construct]], is not new-able
info: |
ECMAScript Function Objects
Built-in function objects that are not identified as constructors do not
implement the [[Construct]] internal method unless otherwise specified in
the description of a particular function.
sec-evaluatenew
...
7. If IsConstructor(constructor) is false, throw a TypeError exception.
...
includes: [isConstructor.js]
features: [Reflect.construct, WeakMap, arrow-function, upsert]
flags: [noStrict]
---*/
assert.sameValue(
isConstructor(WeakMap.prototype.getOrInsert),
false,
'isConstructor(WeakMap.prototype.getOrInsert) must return false'
);
assert.throws(TypeError, () => {
let wm = new WeakMap(); new wm.getOrInsert({}, 1);
});

View File

@ -0,0 +1,30 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Returns the value given as parameter when key is not present.
info: |
WeakMap.prototype.getOrInsert ( key, value )
...
4. For each Record { [[Key]], [[Value]] } p of M.[[WeakMapData]], do
a. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, return p.[[Value]].
5. Let p be the Record { [[Key]]: key, [[Value]]: value }.
6. Append p to M.[[WeakMapData]].
7. Return value.
features: [WeakMap, upsert]
flags: [noStrict]
---*/
var foo = {};
var bar = {};
var baz = [];
var map = new WeakMap();
assert.sameValue(map.getOrInsert(foo, 0), 0);
assert.sameValue(map.getOrInsert(bar, 1), 1);
assert.sameValue(map.getOrInsert(baz, 2), 2);

View File

@ -0,0 +1,31 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Returns the value given as parameter when key is not present.
info: |
WeakMap.prototype.getOrInsert ( key, value )
...
4. For each Record { [[Key]], [[Value]] } p of M.[[WeakMapData]], do
a. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, return p.[[Value]].
5. Let p be the Record { [[Key]]: key, [[Value]]: value }.
6. Append p to M.[[WeakMapData]].
7. Return value.
features: [Symbol, WeakMap, symbols-as-weakmap-keys, upsert]
flags: [noStrict]
---*/
var foo = Symbol('a description');
var bar = Symbol('a description');
var baz = Symbol('different description');
var map = new WeakMap();
assert.sameValue(map.getOrInsert(foo, 0), 0, 'Regular symbol as key, added in constructor');
assert.sameValue(map.getOrInsert(baz, 2), 2, 'Regular symbol as key, added with set()');
assert.sameValue(map.getOrInsert(bar, 1), 1, "Symbols with the same description don't overwrite each other");
assert.sameValue(map.getOrInsert(Symbol.hasInstance, 3), 3, 'Well-known symbol as key');

View File

@ -0,0 +1,32 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Returns the value from the specified Object key
info: |
WeakMap.prototype.getOrInsert ( key, value)
...
4. For each Record { [[Key]], [[Value]] } p of M.[[WeakMapData]], do
a. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, return p.[[Value]].
...
features: [WeakMap, upsert]
flags: [noStrict]
---*/
var foo = {};
var bar = {};
var baz = [];
var map = new WeakMap([
[foo, 0]
]);
assert.sameValue(map.getOrInsert(foo, 3), 0);
map.set(bar, 1);
assert.sameValue(map.getOrInsert(bar, 4), 1);
map.set(baz, 2);
assert.sameValue(map.getOrInsert(baz, 5), 2);

View File

@ -0,0 +1,34 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Returns the value from the specified Symbol key
info: |
WeakMap.prototype.getOrInsert ( key, value)
...
4. For each Record { [[Key]], [[Value]] } p of M.[[WeakMapData]], do
a. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, return p.[[Value]].
...
features: [Symbol, WeakMap, symbols-as-weakmap-keys, upsert]
flags: [noStrict]
---*/
var foo = Symbol('a description');
var bar = Symbol('a description');
var baz = Symbol('different description');
var map = new WeakMap([
[foo, 0],
]);
assert.sameValue(map.getOrInsert(foo), 0, 'Regular symbol as key, added in constructor');
map.set(bar, 1);
map.set(baz, 2);
assert.sameValue(map.getOrInsert(baz), 2, 'Regular symbol as key, added with set()');
assert.sameValue(map.getOrInsert(bar), 1, "Symbols with the same description don't overwrite each other");
map.set(Symbol.hasInstance, 3);
assert.sameValue(map.getOrInsert(Symbol.hasInstance), 3, 'Well-known symbol as key');

View File

@ -0,0 +1,46 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes, Sune Eriksson Lianes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Throws a TypeError if `this` is not an Object.
info: |
WeakMap.prototype.getOrInsert ( key , value )
1. Let M be the this value
2. Perform ? RequireInternalSlot(M, [[WeakMapData]])
...
features: [Symbol, upsert]
flags: [noStrict]
---*/
var m = new WeakMap();
assert.throws(TypeError, function () {
m.getOrInsert.call(false, {}, 1);
});
assert.throws(TypeError, function () {
m.getOrInsert.call(1, {}, 1);
});
assert.throws(TypeError, function () {
m.getOrInsert.call("", {}, 1);
});
assert.throws(TypeError, function () {
m.getOrInsert.call(undefined, {}, 1);
});
assert.throws(TypeError, function () {
m.getOrInsert.call(null, {}, 1);
});
assert.throws(TypeError, function () {
m.getOrInsert.call(Symbol(), {}, 1);
});
assert.throws(TypeError, function () {
m.getOrInsert.call('', {}, 1);
});

View File

@ -0,0 +1,42 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Throws TypeError if key cannot be held weakly.
info: |
WeakMap.prototype.getOrInsert ( key, value )
...
3. If CanBeHeldWeakly(key) is false, throw a TypeError exception.
...
features: [Symbol, WeakMap, upsert]
flags: [noStrict]
---*/
var s = new WeakMap();
assert.throws(TypeError, function() {
s.getOrInsert(1, 1);
});
assert.throws(TypeError, function() {
s.getOrInsert(false, 1);
});
assert.throws(TypeError, function() {
s.getOrInsert(undefined, 1);
});
assert.throws(TypeError, function() {
s.getOrInsert('string', 1);
});
assert.throws(TypeError, function() {
s.getOrInsert(null, 1);
});
assert.throws(TypeError, function() {
s.getOrInsert(Symbol.for('registered symbol'), 1);
}, 'Registered symbol not allowed as WeakMap key');

View File

@ -0,0 +1,34 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Adds a value with an Object key if key is not already in the map.
info: |
WeakMap.prototype.getOrInsertComputed ( key, callbackfn )
...
8. Let p be the Record { [[Key]]: key, [[Value]]: value }.
9. Append p to M.[[WeakMapData]].
...
features: [WeakMap, upsert]
flags: [noStrict]
---*/
var map = new WeakMap();
var foo = {};
var bar = {};
var baz = {};
map.getOrInsertComputed(foo, () => 1);
map.getOrInsertComputed(bar, () => 2);
map.getOrInsertComputed(baz, () => 3);
assert.sameValue(map.has(foo), true);
assert.sameValue(map.has(bar), true);
assert.sameValue(map.has(baz), true);
assert.sameValue(map.get(foo), 1);
assert.sameValue(map.get(bar), 2);
assert.sameValue(map.get(baz), 3);

View File

@ -0,0 +1,32 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Adds a value with a Symbol key if key is not already in the map.
info: |
WeakMap.prototype.getOrInsertComputed ( _key_, callbackfn )
...
8. Let p be the Record { [[Key]]: key, [[Value]]: value }.
9. Append p to M.[[WeakMapData]].
...
features: [Symbol, WeakMap, symbols-as-weakmap-keys, upsert]
flags: [noStrict]
---*/
var map = new WeakMap();
var foo = Symbol('a description');
var bar = Symbol('a description');
map.getOrInsertComputed(foo, () => 1);
map.getOrInsertComputed(bar, () => 2);
map.getOrInsertComputed(Symbol.hasInstance, () => 3);
assert.sameValue(map.has(bar), true, 'Regular symbol as key');
assert.sameValue(map.get(foo), 1, "Symbols with the same description don't overwrite each other");
assert.sameValue(map.has(Symbol.hasInstance), true, 'Well-known symbol as key');
assert.sameValue(map.get(bar), 2);
assert.sameValue(map.get(Symbol.hasInstance), 3);

View File

@ -0,0 +1,55 @@
// Copyright (C) 2025 Jonas Haukenes, Mathias Ness. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Does not throw if `callbackfn` is callable.
info: |
WeakMap.prototype.getOrInsertComputed ( key , callbackfn )
...
3. If IsCallable(callbackfn) is false, throw a TypeError exception.
...
features: [arrow-function, upsert]
flags: [noStrict]
---*/
var bar = {};
var baz = {};
var foo = {};
var foobar = {};
var foobarbaz = {};
var m = new WeakMap();
assert.sameValue(
m.getOrInsertComputed(bar, function() {return 1;})
, 1);
assert.sameValue(m.get(bar), 1);
assert.sameValue(
m.getOrInsertComputed(baz, () => 2)
, 2);
assert.sameValue(m.get(baz), 2);
function three() {return 3;}
assert.sameValue(
m.getOrInsertComputed(foo, three)
, 3);
assert.sameValue(m.get(foo), 3);
assert.sameValue(
m.getOrInsertComputed(foobar, new Function())
, undefined);
assert.sameValue(m.get(foobar), undefined);
assert.sameValue(
m.getOrInsertComputed(foobarbaz, (function() {return 5;}).bind(m))
, 5);
assert.sameValue(m.get(foobarbaz), 5);

View File

@ -0,0 +1,25 @@
// 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: |
WeakMap.getOrInsertComputed throws when callbackfn throws return if abrubt completion Call(callbackfn, key)
info: |
WeakMap.prototype.getOrInsertComputed ( key , callbackfn )
...
6. Let value be ? Call(callbackfn, undefined, key).
...
features: [upsert]
flags: [noStrict]
---*/
var map = new WeakMap();
var bar = {};
assert.throws(Error, function() {
map.getOrInsertComputed(bar, function() {
throw new Error('throw in callback');
})
}, Error);

View File

@ -0,0 +1,37 @@
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Does not evaluate the callback function if the key is already in the map.
info: |
WeakMap.prototype.getOrInsertComputed ( key, callbackfn )
...
5. For each Record { [[Key]], [[Value]] } p of M.[[WeakMapData]], do
a. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, return p.[[Value]].
6. Let value be ? Call(callbackfn, undefined, « key »).
...
features: [WeakMap, upsert]
flags: [noStrict]
---*/
var map = new Map([
[1, 0]
]);
function callback() {
throw new Error('Callbackfn should not be evaluated if key is present');
}
assert.sameValue(map.getOrInsertComputed(1, callback), 0);
map.set(2, 1);
assert.sameValue(map.getOrInsertComputed(2, callback), 1);
map.set(3, 2);
assert.sameValue(map.getOrInsertComputed(3, callback), 2);
assert.throws(Error, function() {
map.getOrInsertComputed(4, callback)
}, Error);

View File

@ -0,0 +1,25 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Throws TypeError if `this` doesn't have a [[WeakMapData]] internal slot.
info: |
WeakMap.prototype.getOrInsertComputed ( key, callbackfn )
...
2. Perform ? RequireInternalSlot(M, [[WeakMapData]]).
...
features: [upsert]
flags: [noStrict]
---*/
assert.throws(TypeError, function() {
WeakMap.prototype.getOrInsertComputed.call([], {}, () => 1);
});
assert.throws(TypeError, function() {
var map = new WeakMap();
map.getOrInsertComputed.call([], {}, () => 1);
});

View File

@ -0,0 +1,25 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Throws TypeError if `this` doesn't have a [[WeakMapData]] internal slot.
info: |
WeakMap.prototype.getOrInsertComputed ( key, callbackfn )
...
2. Perform ? RequireInternalSlot(M, [[WeakMapData]]).
...
features: [Map, upsert]
flags: [noStrict]
---*/
assert.throws(TypeError, function() {
WeakMap.prototype.getOrInsertComputed.call(new Map(), {}, () => 1);
});
assert.throws(TypeError, function() {
var map = new WeakMap();
map.getOrInsertComputed.call(new Map(), {}, () => 1);
});

View File

@ -0,0 +1,25 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Throws TypeError if `this` doesn't have a [[WeakMapData]] internal slot.
info: |
WeakMap.prototype.getOrInsertComputed ( key, callbackfn )
...
2. Perform ? RequireInternalSlot(M, [[WeakMapData]]).
...
features: [upsert]
flags: [noStrict]
---*/
assert.throws(TypeError, function() {
WeakMap.prototype.getOrInsertComputed.call({}, {}, () => 1);
});
assert.throws(TypeError, function() {
var map = new WeakMap();
map.getOrInsertComputed.call({}, {}, () => 1);
});

View File

@ -0,0 +1,25 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Throws TypeError if `this` doesn't have a [[WeakMapData]] internal slot.
info: |
WeakMap.prototype.getOrInsertComputed ( key, callbackfn )
...
2. Perform ? RequireInternalSlot(M, [[WeakMapData]]).
...
features: [Set, upsert]
flags: [noStrict]
---*/
assert.throws(TypeError, function() {
WeakMap.prototype.getOrInsertComputed.call(new Set(), {}, () => 1);
});
assert.throws(TypeError, function() {
var map = new WeakMap();
map.getOrInsertComputed.call(new Set(), {}, () => 1);
});

View File

@ -0,0 +1,25 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Throws TypeError if `this` doesn't have a [[WeakMapData]] internal slot.
info: |
WeakMap.prototype.getOrInsertComputed ( key, callbackfn )
...
2. Perform ? RequireInternalSlot(M, [[WeakMapData]]).
...
features: [upsert]
flags: [noStrict]
---*/
assert.throws(TypeError, function() {
WeakMap.prototype.getOrInsertComputed.call(WeakMap.prototype, {}, () => 1);
});
assert.throws(TypeError, function() {
var map = new WeakMap();
map.getOrInsertComputed.call(WeakMap.prototype, {}, () => 1);
});

View File

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

View File

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

View File

@ -0,0 +1,22 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
WeakMap.prototype.getOrInsertComputed.name descriptor
info: |
WeakMap.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

@ -0,0 +1,33 @@
// Copyright (C) 2020 Rick Waldron. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
WeakMap.prototype.getOrInsertComputed does not implement [[Construct]], is not new-able
info: |
ECMAScript Function Objects
Built-in function objects that are not identified as constructors do not
implement the [[Construct]] internal method unless otherwise specified in
the description of a particular function.
sec-evaluatenew
...
7. If IsConstructor(constructor) is false, throw a TypeError exception.
...
includes: [isConstructor.js]
features: [Reflect.construct, WeakMap, arrow-function, upsert]
flags: [noStrict]
---*/
assert.sameValue(
isConstructor(WeakMap.prototype.getOrInsertComputed),
false,
'isConstructor(WeakMap.prototype.getOrInsertComputed) must return false'
);
assert.throws(TypeError, () => {
let wm = new WeakMap(); new wm.getOrInsertComputed({}, () => 1);
});

View File

@ -0,0 +1,51 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes, Mathias Ness. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Throws a TypeError if `callbackfn` is not callable.
info: |
WeakMap.prototype.getOrInsertComputed ( key , callbackfn )
...
3. If IsCallable(callbackfn) is false, throw a TypeError exception.
...
features: [Symbol, upsert]
flags: [noStrict]
---*/
var bar = {};
var m = new WeakMap();
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(m, bar, 1);
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(m, bar, "");
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(m, bar, true);
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(m, bar, undefined);
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(m, bar, null);
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(m, bar, {});
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(m, bar, []);
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(m, bar, Symbol());
});

View File

@ -0,0 +1,34 @@
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
If the callbackfn inserts a value on the given key, the value is overwritten.
info: |
WeakMap.prototype.set ( key, value )
...
6. Let value be ? Call(callbackfn, undefined, « key »).
7. For each Record { [[Key]], [[Value]] } p of M.[[WeakMapData]], do
a. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, then
i. Set p.[[Value]] to value.
ii. Return value.
8. Let p be the Record { [[Key]]: key, [[Value]]: value }.
9. Append p to M.[[WeakMapData]].
...
features: [upsert]
flags: [noStrict]
---*/
var map = new WeakMap();
var foo = {};
var bar = {};
var baz = {};
map.getOrInsertComputed(foo, () => {map.set(foo, 0); return 3;});
map.getOrInsertComputed(bar, () => {map.set(bar, 1)});
map.getOrInsertComputed(baz, () => {map.set(baz, 2); return 'string';});
assert.sameValue(map.get(foo), 3);
assert.sameValue(map.get(bar), undefined);
assert.sameValue(map.get(baz), 'string');

View File

@ -0,0 +1,28 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Returns the value from the specified Object key
info: |
WeakMap.prototype.getOrInsertComputed ( key, callbackfn )
...
8. Let p be the Record { [[Key]]: key, [[Value]]: value }.
9. Append p to M.[[WeakMapData]].
10. Return value.
features: [WeakMap, upsert]
flags: [noStrict]
---*/
var foo = {};
var bar = {};
var baz = [];
var map = new WeakMap();
assert.sameValue(map.getOrInsertComputed(foo, () => 0), 0);
assert.sameValue(map.getOrInsertComputed(bar, () => 1), 1);
assert.sameValue(map.getOrInsertComputed(baz, () => 2), 2);

View File

@ -0,0 +1,27 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Returns the value from the specified Symbol key
info: |
WeakMap.prototype.getOrInsertComputed ( key, callbackfn )
...
8. Let p be the Record { [[Key]]: key, [[Value]]: value }.
9. Append p to M.[[WeakMapData]].
10. Return value.
features: [Symbol, WeakMap, symbols-as-weakmap-keys, upsert]
flags: [noStrict]
---*/
var foo = Symbol('a description');
var bar = Symbol('a description');
var baz = Symbol('different description');
var map = new WeakMap();
assert.sameValue(map.getOrInsertComputed(foo, () => 0), 0, 'Regular symbol as key, added in constructor');
assert.sameValue(map.getOrInsertComputed(baz, () => 2), 2, 'Regular symbol as key, added with set()');
assert.sameValue(map.getOrInsertComputed(bar, () => 1), 1, "Symbols with the same description don't overwrite each other");
assert.sameValue(map.getOrInsertComputed(Symbol.hasInstance, () => 3), 3, 'Well-known symbol as key');

View File

@ -0,0 +1,32 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Returns the value from the specified Object key
info: |
WeakMap.prototype.getOrInsertComputed ( key, callbackfn )
...
5. For each Record { [[Key]], [[Value]] } p of M.[[WeakMapData]], do
a. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, return p.[[Value]].
...
features: [WeakMap, upsert]
flags: [noStrict]
---*/
var foo = {};
var bar = {};
var baz = [];
var map = new WeakMap([
[foo, 0]
]);
assert.sameValue(map.getOrInsertComputed(foo, () => 3), 0);
map.set(bar, 1);
assert.sameValue(map.getOrInsertComputed(bar, () => 4), 1);
map.set(baz, 2);
assert.sameValue(map.getOrInsertComputed(baz, () => 5), 2);

View File

@ -0,0 +1,35 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Returns the value from the specified Symbol key
info: |
WeakMap.prototype.getOrInsertComputed ( key, callbackfn )
...
8. Let p be the Record { [[Key]]: key, [[Value]]: value }.
9. Append p to M.[[WeakMapData]].
10. Return value.
features: [Symbol, WeakMap, symbols-as-weakmap-keys, upsert]
flags: [noStrict]
---*/
var foo = Symbol('a description');
var bar = Symbol('a description');
var baz = Symbol('different description');
var map = new WeakMap([
[foo, 0],
]);
assert.sameValue(map.getOrInsertComputed(foo, () => 3), 0, 'Regular symbol as key, added in constructor');
map.set(bar, 1);
map.set(baz, 2);
assert.sameValue(map.getOrInsertComputed(baz, () => 4), 2, 'Regular symbol as key, added with set()');
assert.sameValue(map.getOrInsertComputed(bar, () => 5), 1, "Symbols with the same description don't overwrite each other");
map.set(Symbol.hasInstance, 3);
assert.sameValue(map.getOrInsertComputed(Symbol.hasInstance, () => 6), 3, 'Well-known symbol as key');

View File

@ -0,0 +1,46 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes, Sune Eriksson Lianes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Throws a TypeError if `this` is not an Object.
info: |
WeakMap.prototype.getOrInsertComputed ( key , callbackfn )
1. Let M be the this value
2. Perform ? RequireInternalSlot(M, [[WeakMapData]])
...
features: [Symbol, upsert]
flags: [noStrict]
---*/
var m = new WeakMap();
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(false, {}, () => 1);
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(1, {}, () => 1);
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call("", {}, () => 1);
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(undefined, {}, () => 1);
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(null, {}, () => 1);
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call(Symbol(), {}, () => 1);
});
assert.throws(TypeError, function () {
m.getOrInsertComputed.call('', {}, () => 1);
});

View File

@ -0,0 +1,42 @@
// Copyright (C) 2015 the V8 project authors. All rights reserved.
// Copyright (C) 2025 Jonas Haukenes. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
esid: proposal-upsert
description: |
Throws TypeError if key cannot be held weakly.
info: |
WeakMap.prototype.getOrInsertComputed ( key, callbackfn )
...
4. If CanBeHeldWeakly(_key_) is *false*, throw a *TypeError* exception.
...
features: [Symbol, WeakMap, upsert]
flags: [noStrict]
---*/
var s = new WeakMap();
assert.throws(TypeError, function() {
s.getOrInsertComputed(1, () => 1);
});
assert.throws(TypeError, function() {
s.getOrInsertComputed(false, () => 1);
});
assert.throws(TypeError, function() {
s.getOrInsertComputed(undefined, () => 1);
});
assert.throws(TypeError, function() {
s.getOrInsertComputed('string', () => 1);
});
assert.throws(TypeError, function() {
s.getOrInsertComputed(null, () => 1);
});
assert.throws(TypeError, function() {
s.getOrInsertComputed(Symbol.for('registered symbol'), () => 1);
}, 'Registered symbol not allowed as WeakMap key');