mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-10 02:08:38 +09:00
Issue #2089 - Implement the Promise.any combinator
Based-on: m-c 1568903/9,1560300
This commit is contained in:
parent
9fc50a9920
commit
f75e9d9441
9 changed files with 577 additions and 50 deletions
69
js/src/tests/non262/Promise/any-stack.js
Normal file
69
js/src/tests/non262/Promise/any-stack.js
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
// |reftest| skip-if(!Promise.any)
|
||||
|
||||
function toMessage(stack) {
|
||||
// Provide the stack string in the error message for debugging.
|
||||
return `[stack: ${stack.replace(/\n/g, "\\n")}]`;
|
||||
}
|
||||
|
||||
// Test when AggregateError isn't created from a Promise Job.
|
||||
{
|
||||
let p = Promise.any([]); // line 10
|
||||
|
||||
p.then(v => {
|
||||
reportCompare(0, 1, "expected error");
|
||||
}, e => {
|
||||
assertEq(e.name, "AggregateError");
|
||||
var {stack} = e;
|
||||
|
||||
assertEq(/^@.+any-stack.js:10/m.test(stack), true, toMessage(stack));
|
||||
});
|
||||
}
|
||||
|
||||
// Same as above, but now with surrounding function context.
|
||||
function testNoJobQueue() {
|
||||
let p = Promise.any([]); // line 24
|
||||
|
||||
p.then(v => {
|
||||
reportCompare(0, 1, "expected error");
|
||||
}, e => {
|
||||
assertEq(e.name, "AggregateError");
|
||||
var {stack} = e;
|
||||
|
||||
assertEq(/^testNoJobQueue@.+any-stack.js:24/m.test(stack), true, toMessage(stack));
|
||||
});
|
||||
}
|
||||
testNoJobQueue();
|
||||
|
||||
// Test when AggregateError is created from a Promise Job.
|
||||
{
|
||||
let rejected = Promise.reject(0);
|
||||
let p = Promise.any([rejected]); // line 40
|
||||
|
||||
p.then(v => {
|
||||
reportCompare(0, 1, "expected error");
|
||||
}, e => {
|
||||
assertEq(e.name, "AggregateError");
|
||||
var {stack} = e;
|
||||
|
||||
assertEq(/^Promise.any\*@.+any-stack.js:40/m.test(stack), true, toMessage(stack));
|
||||
});
|
||||
}
|
||||
|
||||
// Same as above, but now with surrounding function context.
|
||||
function testFromJobQueue() {
|
||||
let rejected = Promise.reject(0);
|
||||
let p = Promise.any([rejected]); // line 55
|
||||
|
||||
p.then(v => {
|
||||
reportCompare(0, 1, "expected error");
|
||||
}, e => {
|
||||
assertEq(e.name, "AggregateError");
|
||||
var {stack} = e;
|
||||
|
||||
assertEq(/^Promise.any\*testFromJobQueue@.+any-stack.js:55/m.test(stack), true, toMessage(stack));
|
||||
});
|
||||
}
|
||||
testFromJobQueue();
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(0, 0);
|
||||
78
js/src/tests/non262/Promise/any.js
Normal file
78
js/src/tests/non262/Promise/any.js
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
// |reftest| skip-if(!Promise.any)
|
||||
|
||||
// Smoke test for `Promise.any`, test262 should cover the function in
|
||||
// more detail.
|
||||
|
||||
function expectedError() {
|
||||
reportCompare(true, false, "expected error");
|
||||
}
|
||||
|
||||
// Empty elements.
|
||||
Promise.any([]).then(expectedError, e => {
|
||||
assertEq(e instanceof AggregateError, true);
|
||||
assertEq(e.errors.length, 0);
|
||||
});
|
||||
|
||||
// Single element.
|
||||
Promise.any([Promise.resolve(0)]).then(v => {
|
||||
assertEq(v, 0);
|
||||
});
|
||||
Promise.any([Promise.reject(1)]).then(expectedError, e => {
|
||||
assertEq(e instanceof AggregateError, true);
|
||||
assertEq(e.errors.length, 1);
|
||||
assertEq(e.errors[0], 1);
|
||||
});
|
||||
|
||||
// Multiple elements.
|
||||
Promise.any([Promise.resolve(1), Promise.resolve(2)]).then(v => {
|
||||
assertEq(v, 1);
|
||||
});
|
||||
Promise.any([Promise.resolve(3), Promise.reject(4)]).then(v => {
|
||||
assertEq(v, 3);
|
||||
});
|
||||
Promise.any([Promise.reject(5), Promise.resolve(6)]).then(v => {
|
||||
assertEq(v, 6);
|
||||
});
|
||||
Promise.any([Promise.reject(7), Promise.reject(8)]).then(expectedError, e => {
|
||||
assertEq(e instanceof AggregateError, true);
|
||||
assertEq(e.errors.length, 2);
|
||||
assertEq(e.errors[0], 7);
|
||||
assertEq(e.errors[1], 8);
|
||||
});
|
||||
|
||||
// Cross-Realm tests.
|
||||
//
|
||||
// Note: When |g| is a cross-compartment global, Promise.any creates the errors
|
||||
// array and the AggregateError in |g|'s Realm. This doesn't follow the spec, but
|
||||
// the code in js/src/builtin/Promise.cpp claims this is useful when the Promise
|
||||
// compartment is less-privileged. This means for this test we can't use
|
||||
// assertDeepEq below, because the result array/error may have the wrong prototype.
|
||||
let g = newGlobal();
|
||||
|
||||
if (typeof isSameCompartment !== "function") {
|
||||
var isSameCompartment = SpecialPowers.Cu.getJSTestingFunctions().isSameCompartment;
|
||||
}
|
||||
|
||||
// Test wrapping when no `Promise.any Reject Element Function` is called.
|
||||
Promise.any.call(g.Promise, []).then(expectedError, e => {
|
||||
assertEq(e.name, "AggregateError");
|
||||
|
||||
assertEq(isSameCompartment(e, g), true);
|
||||
assertEq(isSameCompartment(e.errors, g), true);
|
||||
|
||||
assertEq(e.errors.length, 0);
|
||||
});
|
||||
|
||||
// Test wrapping in `Promise.any Reject Element Function`.
|
||||
Promise.any.call(g.Promise, [Promise.reject("err")]).then(expectedError, e => {
|
||||
assertEq(e.name, "AggregateError");
|
||||
|
||||
assertEq(isSameCompartment(e, g), true);
|
||||
assertEq(isSameCompartment(e.errors, g), true);
|
||||
|
||||
assertEq(e.errors.length, 1);
|
||||
assertEq(e.errors[0], "err");
|
||||
});
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(0, 0);
|
||||
Loading…
Add table
Add a link
Reference in a new issue