tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

file_promise_argument_tests.js (5376B)


      1 /*
      2 * This file is meant to provide common infrastructure for several consumers.
      3 * The consumer is expected to define the following things:
      4 *
      5 * 1) An verifyPromiseGlobal function which does whatever test the consumer
      6 *    wants.
      7 * 2) An isXrayArgumentTest global boolean, because some of these tests act
      8 *    differenly based on that boolean.
      9 * 3) A function named getPromise.  This function is given a global object and a
     10 *    single argument to use for getting the promise.  The getPromise function
     11 *    is expected to trigger the canonical Promise.resolve for the given global
     12 *    with the given argument in some way that depends on the test, and return
     13 *    the result.
     14 * 4) A subframe (frames[0]) which can be used as a second global for creating
     15 *    promises.
     16 */
     17 
     18 /* global verifyPromiseGlobal, getPromise, isXrayArgumentTest */
     19 
     20 var label = "parent";
     21 
     22 function passBasicPromise() {
     23  var p1 = Promise.resolve();
     24  verifyPromiseGlobal(p1, window, "Promise.resolve return value 1");
     25  var p2 = getPromise(window, p1);
     26  is(p1, p2, "Basic promise should just pass on through");
     27  return p2;
     28 }
     29 
     30 function passPrimitive(global) {
     31  var p = getPromise(global, 5);
     32  verifyPromiseGlobal(p, global, "Promise wrapping primitive");
     33  return p.then(function (arg) {
     34    is(arg, 5, "Should have the arg we passed in");
     35  });
     36 }
     37 
     38 function passThenable(global) {
     39  var called = false;
     40  var thenable = {
     41    then(f) {
     42      called = true;
     43      f(7);
     44    },
     45  };
     46  var p = getPromise(global, thenable);
     47  verifyPromiseGlobal(p, global, "Promise wrapping thenable");
     48  return p.then(function (arg) {
     49    ok(called, "Thenable should have been called");
     50    is(arg, 7, "Should have the arg our thenable passed in");
     51  });
     52 }
     53 
     54 function passWrongPromiseWithMatchingConstructor() {
     55  var p1 = Promise.resolve();
     56  verifyPromiseGlobal(p1, window, "Promise.resolve() return value 2");
     57  p1.constructor = frames[0].Promise;
     58  var p2 = getPromise(frames[0], p1);
     59  // The behavior here will depend on whether we're touching frames[0] via Xrays
     60  // or not.  If we are not, the current compartment while getting our promise
     61  // will be that of frames[0].  If we are, it will be our window's compartment.
     62  if (isXrayArgumentTest) {
     63    isnot(
     64      p1,
     65      p2,
     66      "Should have wrapped the Promise in a new promise, because its constructor is not matching the current-compartment Promise constructor"
     67    );
     68    verifyPromiseGlobal(
     69      p2,
     70      window,
     71      "Promise wrapping xrayed promise with therefore non-matching constructor"
     72    );
     73  } else {
     74    is(
     75      p1,
     76      p2,
     77      "Should have left the Promise alone because its constructor matched"
     78    );
     79  }
     80  return p2;
     81 }
     82 
     83 function passCorrectPromiseWithMismatchedConstructor() {
     84  var p1 = Promise.resolve(9);
     85  verifyPromiseGlobal(p1, window, "Promise.resolve() return value 3");
     86  p1.constructor = frames[0].Promise;
     87  var p2 = getPromise(window, p1);
     88  isnot(
     89    p1,
     90    p2,
     91    "Should have wrapped promise in a new promise, since its .constructor was wrong"
     92  );
     93  verifyPromiseGlobal(
     94    p2,
     95    window,
     96    "Promise wrapping passed-in promise with mismatched constructor"
     97  );
     98  return p2.then(function (arg) {
     99    is(arg, 9, "Should have propagated along our resolution value");
    100  });
    101 }
    102 
    103 function passPromiseToOtherGlobal() {
    104  var p1 = Promise.resolve();
    105  verifyPromiseGlobal(p1, window, "Promise.resolve() return value 4");
    106  var p2 = getPromise(frames[0], p1);
    107  // The behavior here will depend on whether we're touching frames[0] via Xrays
    108  // or not.  If we are not, the current compartment while getting our promise
    109  // will be that of frames[0].  If we are, it will be our window's compartment.
    110  if (isXrayArgumentTest) {
    111    is(
    112      p1,
    113      p2,
    114      "Should have left the Promise alone, because its constructor matches the current compartment's constructor"
    115    );
    116  } else {
    117    isnot(
    118      p1,
    119      p2,
    120      "Should have wrapped promise in a promise from the other global"
    121    );
    122    verifyPromiseGlobal(
    123      p2,
    124      frames[0],
    125      "Promise wrapping passed-in basic promise"
    126    );
    127  }
    128  return p2;
    129 }
    130 
    131 function passPromiseSubclass() {
    132  class PromiseSubclass extends Promise {
    133    constructor(func) {
    134      super(func);
    135    }
    136  }
    137 
    138  var p1 = PromiseSubclass.resolve(11);
    139  verifyPromiseGlobal(p1, window, "PromiseSubclass.resolve() return value");
    140  var p2 = getPromise(window, p1);
    141  isnot(p1, p2, "Should have wrapped promise subclass in a new promise");
    142  verifyPromiseGlobal(
    143    p2,
    144    window,
    145    "Promise wrapping passed-in promise subclass"
    146  );
    147  return p2.then(function (arg) {
    148    is(
    149      arg,
    150      11,
    151      "Should have propagated along our resolution value from subclass"
    152    );
    153  });
    154 }
    155 
    156 function runPromiseArgumentTests(finishFunc) {
    157  Promise.resolve()
    158    .then(passBasicPromise)
    159    .then(passPrimitive.bind(undefined, window))
    160    .then(passPrimitive.bind(undefined, frames[0]))
    161    .then(passThenable.bind(undefined, window))
    162    .then(passThenable.bind(undefined, frames[0]))
    163    .then(passWrongPromiseWithMatchingConstructor)
    164    .then(passCorrectPromiseWithMismatchedConstructor)
    165    .then(passPromiseToOtherGlobal)
    166    .then(passPromiseSubclass)
    167    .then(finishFunc)
    168    .catch(function (e) {
    169      ok(
    170        false,
    171        `Exception thrown: ${e}@${location.pathname}:${e.lineNumber}:${e.columnNumber}`
    172      );
    173      finishFunc();
    174    });
    175 }