gecko-dev/dom/promise/tests/file_promise_argument_tests.js

135 строки
5.0 KiB
JavaScript

/*
* This file is meant to provide common infrastructure for several consumers.
* The consumer is expected to define the following things:
*
* 1) An verifyPromiseGlobal function which does whatever test the consumer
* wants.
* 2) An isXrayArgumentTest global boolean, because some of these tests act
* differenly based on that boolean.
* 3) A function named getPromise. This function is given a global object and a
* single argument to use for getting the promise. The getPromise function
* is expected to trigger the canonical Promise.resolve for the given global
* with the given argument in some way that depends on the test, and return
* the result.
* 4) A subframe (frames[0]) which can be used as a second global for creating
* promises.
*/
var label = parent;
function passBasicPromise() {
var p1 = Promise.resolve();
verifyPromiseGlobal(p1, window, "Promise.resolve return value 1");
var p2 = getPromise(window, p1);
is(p1, p2, "Basic promise should just pass on through");
return p2;
}
function passPrimitive(global) {
var p = getPromise(global, 5);
verifyPromiseGlobal(p, global, "Promise wrapping primitive");
return p.then(function(arg) {
is(arg, 5, "Should have the arg we passed in");
});
}
function passThenable(global) {
var called = false;
var thenable = {
then: function(f) {
called = true;
f(7);
}
};
var p = getPromise(global, thenable);
verifyPromiseGlobal(p, global, "Promise wrapping thenable");
return p.then(function(arg) {
ok(called, "Thenable should have been called");
is(arg, 7, "Should have the arg our thenable passed in");
});
}
function passWrongPromiseWithMatchingConstructor() {
var p1 = Promise.resolve();
verifyPromiseGlobal(p1, window, "Promise.resolve() return value 2");
p1.constructor = frames[0].Promise;
var p2 = getPromise(frames[0], p1);
// The behavior here will depend on whether we're touching frames[0] via Xrays
// or not. If we are not, the current compartment while getting our promise
// will be that of frames[0]. If we are, it will be our window's compartment.
if (isXrayArgumentTest) {
isnot(p1, p2, "Should have wrapped the Promise in a new promise, because its constructor is not matching the current-compartment Promise constructor");
verifyPromiseGlobal(p2, window, "Promise wrapping xrayed promise with therefore non-matching constructor");
} else {
is(p1, p2, "Should have left the Promise alone because its constructor matched");
}
return p2;
}
function passCorrectPromiseWithMismatchedConstructor() {
var p1 = Promise.resolve(9);
verifyPromiseGlobal(p1, window, "Promise.resolve() return value 3");
p1.constructor = frames[0].Promise;
var p2 = getPromise(window, p1);
isnot(p1, p2,
"Should have wrapped promise in a new promise, since its .constructor was wrong");
verifyPromiseGlobal(p2, window,
"Promise wrapping passed-in promise with mismatched constructor");
return p2.then(function(arg) {
is(arg, 9, "Should have propagated along our resolution value");
});
}
function passPromiseToOtherGlobal() {
var p1 = Promise.resolve();
verifyPromiseGlobal(p1, window, "Promise.resolve() return value 4");
var p2 = getPromise(frames[0], p1);
// The behavior here will depend on whether we're touching frames[0] via Xrays
// or not. If we are not, the current compartment while getting our promise
// will be that of frames[0]. If we are, it will be our window's compartment.
if (isXrayArgumentTest) {
is(p1, p2, "Should have left the Promise alone, because its constructor matches the current compartment's constructor");
} else {
isnot(p1, p2, "Should have wrapped promise in a promise from the other global");
verifyPromiseGlobal(p2, frames[0],
"Promise wrapping passed-in basic promise");
}
return p2;
}
function passPromiseSubclass() {
class PromiseSubclass extends Promise {
constructor(func) {
super(func);
}
}
var p1 = PromiseSubclass.resolve(11);
verifyPromiseGlobal(p1, window, "PromiseSubclass.resolve() return value");
var p2 = getPromise(window, p1);
isnot(p1, p2,
"Should have wrapped promise subclass in a new promise");
verifyPromiseGlobal(p2, window,
"Promise wrapping passed-in promise subclass");
return p2.then(function(arg) {
is(arg, 11, "Should have propagated along our resolution value from subclass");
});
}
function runPromiseArgumentTests(finishFunc) {
Promise.resolve()
.then(passBasicPromise)
.then(passPrimitive.bind(undefined, window))
.then(passPrimitive.bind(undefined, frames[0]))
.then(passThenable.bind(undefined, window))
.then(passThenable.bind(undefined, frames[0]))
.then(passWrongPromiseWithMatchingConstructor)
.then(passCorrectPromiseWithMismatchedConstructor)
.then(passPromiseToOtherGlobal)
.then(passPromiseSubclass)
.then(finishFunc)
.catch(function(e) {
ok(false, `Exception thrown: ${e}@${location.pathname}:${e.lineNumber}:${e.columnNumber}`);
finishFunc();
});
}