summaryrefslogtreecommitdiffstats
path: root/dom/promise/tests/file_promise_argument_tests.js
diff options
context:
space:
mode:
Diffstat (limited to 'dom/promise/tests/file_promise_argument_tests.js')
-rw-r--r--dom/promise/tests/file_promise_argument_tests.js175
1 files changed, 175 insertions, 0 deletions
diff --git a/dom/promise/tests/file_promise_argument_tests.js b/dom/promise/tests/file_promise_argument_tests.js
new file mode 100644
index 0000000000..2a3b4e78c9
--- /dev/null
+++ b/dom/promise/tests/file_promise_argument_tests.js
@@ -0,0 +1,175 @@
+/*
+ * 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.
+ */
+
+/* global verifyPromiseGlobal, getPromise, isXrayArgumentTest */
+
+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(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();
+ });
+}