Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions test/built-ins/Promise/allKeyed/arg-is-function.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright (C) 2026 Danial Asaria (Bloomberg LP). All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-promise.allkeyed
description: >
Promise.allKeyed accepts a function argument with enumerable own properties
info: |
Promise.allKeyed ( promises )

...
5. If promises is not an Object, then
a. ...Reject...
...

Functions are objects, so they pass the type check. Only own enumerable
properties are traversed; built-in function properties (name, length,
prototype) are non-enumerable by default and should be excluded.
includes: [asyncHelpers.js]
flags: [async]
features: [await-dictionary]
---*/

function fn() {}
fn.key = Promise.resolve('val');

asyncTest(function() {
return Promise.allKeyed(fn).then(function(result) {
assert.sameValue(Object.getPrototypeOf(result), null);

var keys = Reflect.ownKeys(result);
assert.sameValue(keys.length, 1);
assert.sameValue(keys[0], 'key');
assert.sameValue(result.key, 'val');

assert.sameValue(Object.prototype.hasOwnProperty.call(result, 'name'), false);
assert.sameValue(Object.prototype.hasOwnProperty.call(result, 'length'), false);
assert.sameValue(Object.prototype.hasOwnProperty.call(result, 'prototype'), false);
});
});
25 changes: 25 additions & 0 deletions test/built-ins/Promise/allKeyed/arg-not-object-reject-bigint.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (C) 2026 Danial Asaria (Bloomberg LP). All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-promise.allkeyed
description: >
Promise.allKeyed rejects when the promises argument is a BigInt
info: |
Promise.allKeyed ( promises )

...
5. If promises is not an Object, then
a. Let error be a newly created TypeError object.
b. Perform ? Call(promiseCapability.[[Reject]], undefined, « error »).
c. Return promiseCapability.[[Promise]].
includes: [asyncHelpers.js]
flags: [async]
features: [await-dictionary, BigInt]
---*/

asyncTest(function() {
return assert.throwsAsync(TypeError, function() {
return Promise.allKeyed(0n);
}, 'BigInt');
});
34 changes: 34 additions & 0 deletions test/built-ins/Promise/allKeyed/arg-not-object-reject.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (C) 2026 Danial Asaria (Bloomberg LP). All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-promise.allkeyed
description: >
Promise.allKeyed rejects when the promises argument is not an Object
info: |
Promise.allKeyed ( promises )

...
5. If promises is not an Object, then
a. Let error be a newly created TypeError object.
b. Perform ? Call(promiseCapability.[[Reject]], undefined, « error »).
c. Return promiseCapability.[[Promise]].
includes: [asyncHelpers.js]
flags: [async]
features: [await-dictionary, Symbol]
---*/

asyncTest(function() {
function check(value, msg) {
return assert.throwsAsync(TypeError, function() {
return Promise.allKeyed(value);
}, msg);
}

return check(undefined, 'undefined')
.then(function() { return check(null, 'null'); })
.then(function() { return check(86, 'number'); })
.then(function() { return check('string', 'string'); })
.then(function() { return check(true, 'boolean'); })
.then(function() { return check(Symbol(), 'symbol'); });
});
22 changes: 22 additions & 0 deletions test/built-ins/Promise/allKeyed/ctx-non-ctor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (C) 2026 Danial Asaria (Bloomberg LP). All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-promise.allkeyed
description: >
Promise.allKeyed invoked on a non-constructor value
info: |
Promise.allKeyed ( promises )

1. Let C be the this value.
2. Let promiseCapability be ? NewPromiseCapability(C).

NewPromiseCapability ( C )

1. If IsConstructor(C) is false, throw a TypeError exception.
features: [await-dictionary]
---*/

assert.throws(TypeError, function() {
Promise.allKeyed.call(eval);
});
60 changes: 60 additions & 0 deletions test/built-ins/Promise/allKeyed/key-order-preserved.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (C) 2026 Danial Asaria (Bloomberg LP). All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-performpromiseallkeyed
description: >
Promise.allKeyed result key order matches property key order, not settlement order
info: |
PerformPromiseAllKeyed ( variant, promises, constructor, resultCapability, promiseResolve )

...
1. Let allKeys be ? promises.[[OwnPropertyKeys]]().
...
6. For each element key of allKeys, do
...
b. If desc is not undefined and desc.[[Enumerable]] is true, then
...
ii. Append key to keys.
...
...
...
8. If remainingElementsCount.[[Value]] = 0, then
...
b. Let result be CreateKeyedPromiseCombinatorResultObject(keys, values).
includes: [asyncHelpers.js, compareArray.js]
flags: [async]
features: [await-dictionary]
---*/

var resolveFirst;
var resolveSecond;
var resolveThird;

var input = {
first: new Promise(function(resolve) {
resolveFirst = resolve;
}),
second: new Promise(function(resolve) {
resolveSecond = resolve;
}),
third: new Promise(function(resolve) {
resolveThird = resolve;
})
};

var combined = Promise.allKeyed(input);

resolveSecond('second');
resolveThird('third');
resolveFirst('first');

asyncTest(function() {
return combined.then(function(result) {
assert.sameValue(Object.getPrototypeOf(result), null);
assert.compareArray(Object.keys(result), ['first', 'second', 'third']);
assert.sameValue(result.first, 'first');
assert.sameValue(result.second, 'second');
assert.sameValue(result.third, 'third');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (C) 2026 Danial Asaria (Bloomberg LP). All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-performpromiseallkeyed
description: >
Promise.allKeyed ignores non-enumerable own properties
info: |
PerformPromiseAllKeyed ( variant, promises, constructor, resultCapability, promiseResolve )

...
6. For each element key of allKeys, do
a. Let desc be ? promises.[[GetOwnProperty]](key).
b. If desc is not undefined and desc.[[Enumerable]] is true, then
...
includes: [asyncHelpers.js, compareArray.js]
flags: [async]
features: [await-dictionary]
---*/

var input = {
visible: Promise.resolve(2)
};

Object.defineProperty(input, 'hidden', {
enumerable: false,
value: Promise.resolve(1)
});

asyncTest(function() {
return Promise.allKeyed(input).then(function(result) {
assert.sameValue(Object.getPrototypeOf(result), null);
assert.compareArray(Object.keys(result), ['visible']);
assert.sameValue(result.visible, 2);
assert.sameValue(Object.prototype.hasOwnProperty.call(result, 'hidden'), false);
});
});
34 changes: 34 additions & 0 deletions test/built-ins/Promise/allKeyed/prototype-keys-ignored.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (C) 2026 Danial Asaria (Bloomberg LP). All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-performpromiseallkeyed
description: >
Promise.allKeyed ignores inherited prototype properties
info: |
PerformPromiseAllKeyed ( variant, promises, constructor, resultCapability, promiseResolve )

...
1. Let allKeys be ? promises.[[OwnPropertyKeys]]().
...
6. For each element key of allKeys, do
a. Let desc be ? promises.[[GetOwnProperty]](key).
b. If desc is not undefined and desc.[[Enumerable]] is true, then
...
includes: [asyncHelpers.js, compareArray.js]
flags: [async]
features: [await-dictionary]
---*/

var proto = { inherited: Promise.resolve('nope') };
var input = Object.create(proto);
input.own = Promise.resolve('yes');

asyncTest(function() {
return Promise.allKeyed(input).then(function(result) {
assert.sameValue(Object.getPrototypeOf(result), null);
assert.compareArray(Object.keys(result), ['own']);
assert.sameValue(result.own, 'yes');
assert.sameValue(Object.prototype.hasOwnProperty.call(result, 'inherited'), false);
});
});
38 changes: 38 additions & 0 deletions test/built-ins/Promise/allKeyed/reject-deferred.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (C) 2026 Danial Asaria (Bloomberg LP). All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-performpromiseallkeyed
description: Rejecting from an asynchronously rejected input promise
info: |
PerformPromiseAllKeyed ( variant, promises, constructor, resultCapability, promiseResolve )

...
6. For each element key of allKeys, do
...
b. If desc is not undefined and desc.[[Enumerable]] is true, then
...
8. If variant is all, then
a. Let onRejected be resultCapability.[[Reject]].
...
11. Perform ? Invoke(nextPromise, "then", « onFulfilled, onRejected »).
includes: [asyncHelpers.js]
flags: [async]
features: [await-dictionary]
---*/

var error = new Test262Error();

var p = new Promise(function(_, reject) {
Promise.resolve().then(function() {
reject(error);
});
});

asyncTest(function() {
return Promise.allKeyed({ key: p }).then(function() {
throw new Test262Error('The promise should not be fulfilled.');
}, function(reason) {
assert.sameValue(reason, error);
});
});
36 changes: 36 additions & 0 deletions test/built-ins/Promise/allKeyed/reject-immed.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (C) 2026 Danial Asaria (Bloomberg LP). All rights reserved.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was this file supposed to be named reject-immediately?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either one works for me, we usually don't sweat the filenames too much as long as they are descriptive (and not spec references like "13.1.9.step5.js" or "fail-RequireInternalSlot-step2.js")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Im happy either way too. Mostly just checking it wasn't a typo.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a typo! Went with the shorter form, but happy to rename if there's a preference.

// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-performpromiseallkeyed
description: Rejecting from a synchronously rejected input promise
info: |
PerformPromiseAllKeyed ( variant, promises, constructor, resultCapability, promiseResolve )

...
6. For each element key of allKeys, do
...
b. If desc is not undefined and desc.[[Enumerable]] is true, then
...
8. If variant is all, then
a. Let onRejected be resultCapability.[[Reject]].
...
11. Perform ? Invoke(nextPromise, "then", « onFulfilled, onRejected »).
includes: [asyncHelpers.js]
flags: [async]
features: [await-dictionary]
---*/

var error = new Test262Error();

var p = new Promise(function(_, reject) {
reject(error);
});

asyncTest(function() {
return Promise.allKeyed({ key: p }).then(function() {
throw new Test262Error('The promise should not be fulfilled.');
}, function(reason) {
assert.sameValue(reason, error);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (C) 2026 Danial Asaria (Bloomberg LP). All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-promise.allkeyed
description: >
If the constructor's `resolve` method is not callable, reject with a TypeError.
info: |
Promise.allKeyed ( promises )

...
3. Let promiseResolve be Completion(GetPromiseResolve(C)).
4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
...

GetPromiseResolve ( promiseConstructor )

...
3. If IsCallable(promiseResolve) is false, throw a TypeError exception.
includes: [asyncHelpers.js]
flags: [async]
features: [await-dictionary]
---*/

Promise.resolve = null;

asyncTest(function() {
return assert.throwsAsync(TypeError, function() {
return Promise.allKeyed({ key: 1 });
});
});
29 changes: 29 additions & 0 deletions test/built-ins/Promise/allKeyed/resolves-empty-object.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (C) 2026 Danial Asaria (Bloomberg LP). All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-performpromiseallkeyed
description: >
Promise.allKeyed resolves an empty object to an empty null-prototype object
info: |
PerformPromiseAllKeyed ( variant, promises, constructor, resultCapability, promiseResolve )

...
1. Let allKeys be ? promises.[[OwnPropertyKeys]]().
...
7. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
8. If remainingElementsCount.[[Value]] = 0, then
a. Let result be CreateKeyedPromiseCombinatorResultObject(keys, values).
b. Perform ? Call(resultCapability.[[Resolve]], undefined, « result »).
includes: [asyncHelpers.js, compareArray.js]
flags: [async]
features: [await-dictionary]
---*/

asyncTest(function() {
return Promise.allKeyed({}).then(function(result) {
assert.sameValue(Object.getPrototypeOf(result), null);
assert.sameValue(result.hasOwnProperty, undefined);
assert.compareArray(Reflect.ownKeys(result), []);
});
});
Loading
Loading