tor-browser

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

test_sync.js (8516B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 const {
      6  DebounceCallback,
      7  PollPromise,
      8  Sleep,
      9  waitForMessage,
     10  waitForObserverTopic,
     11 } = ChromeUtils.importESModule(
     12  "chrome://remote/content/marionette/sync.sys.mjs"
     13 );
     14 
     15 /**
     16 * Mimic a message manager for sending messages.
     17 */
     18 class MessageManager {
     19  constructor() {
     20    this.func = null;
     21    this.message = null;
     22  }
     23 
     24  addMessageListener(message, func) {
     25    this.func = func;
     26    this.message = message;
     27  }
     28 
     29  removeMessageListener() {
     30    this.func = null;
     31    this.message = null;
     32  }
     33 
     34  send(message, data) {
     35    if (this.func) {
     36      this.func({
     37        data,
     38        message,
     39        target: this,
     40      });
     41    }
     42  }
     43 }
     44 
     45 /**
     46 * Mimics nsITimer, but instead of using a system clock you can
     47 * preprogram it to invoke the callback after a given number of ticks.
     48 */
     49 class MockTimer {
     50  constructor(ticksBeforeFiring) {
     51    this.goal = ticksBeforeFiring;
     52    this.ticks = 0;
     53    this.cancelled = false;
     54  }
     55 
     56  initWithCallback(cb) {
     57    this.ticks++;
     58    if (this.ticks >= this.goal) {
     59      cb();
     60    }
     61  }
     62 
     63  cancel() {
     64    this.cancelled = true;
     65  }
     66 }
     67 
     68 add_task(function test_PollPromise_funcTypes() {
     69  for (let type of ["foo", 42, null, undefined, true, [], {}]) {
     70    Assert.throws(() => new PollPromise(type), /TypeError/);
     71  }
     72  new PollPromise(() => {});
     73  new PollPromise(function () {});
     74 });
     75 
     76 add_task(function test_PollPromise_timeoutTypes() {
     77  for (let timeout of ["foo", true, [], {}]) {
     78    Assert.throws(() => new PollPromise(() => {}, { timeout }), /TypeError/);
     79  }
     80  for (let timeout of [1.2, -1]) {
     81    Assert.throws(() => new PollPromise(() => {}, { timeout }), /RangeError/);
     82  }
     83  for (let timeout of [null, undefined, 42]) {
     84    new PollPromise(resolve => resolve(1), { timeout });
     85  }
     86 });
     87 
     88 add_task(function test_PollPromise_intervalTypes() {
     89  for (let interval of ["foo", null, true, [], {}]) {
     90    Assert.throws(() => new PollPromise(() => {}, { interval }), /TypeError/);
     91  }
     92  for (let interval of [1.2, -1]) {
     93    Assert.throws(() => new PollPromise(() => {}, { interval }), /RangeError/);
     94  }
     95  new PollPromise(() => {}, { interval: 42 });
     96 });
     97 
     98 add_task(async function test_PollPromise_retvalTypes() {
     99  for (let typ of [true, false, "foo", 42, [], {}]) {
    100    strictEqual(typ, await new PollPromise(resolve => resolve(typ)));
    101  }
    102 });
    103 
    104 add_task(async function test_PollPromise_rethrowError() {
    105  let nevals = 0;
    106  let err;
    107  try {
    108    await PollPromise(() => {
    109      ++nevals;
    110      throw new Error();
    111    });
    112  } catch (e) {
    113    err = e;
    114  }
    115  equal(1, nevals);
    116  ok(err instanceof Error);
    117 });
    118 
    119 add_task(async function test_PollPromise_noTimeout() {
    120  let nevals = 0;
    121  await new PollPromise((resolve, reject) => {
    122    ++nevals;
    123    nevals < 100 ? reject() : resolve();
    124  });
    125  equal(100, nevals);
    126 });
    127 
    128 add_task(async function test_PollPromise_zeroTimeout() {
    129  // run at least once when timeout is 0
    130  let nevals = 0;
    131  let start = new Date().getTime();
    132  await new PollPromise(
    133    (resolve, reject) => {
    134      ++nevals;
    135      reject();
    136    },
    137    { timeout: 0 }
    138  );
    139  let end = new Date().getTime();
    140  equal(1, nevals);
    141  less(end - start, 500);
    142 });
    143 
    144 add_task(async function test_PollPromise_timeoutElapse() {
    145  let nevals = 0;
    146  let start = new Date().getTime();
    147  await new PollPromise(
    148    (resolve, reject) => {
    149      ++nevals;
    150      reject();
    151    },
    152    { timeout: 100 }
    153  );
    154  let end = new Date().getTime();
    155  lessOrEqual(nevals, 11);
    156  greaterOrEqual(end - start, 100);
    157 });
    158 
    159 add_task(async function test_PollPromise_interval() {
    160  let nevals = 0;
    161  await new PollPromise(
    162    (resolve, reject) => {
    163      ++nevals;
    164      reject();
    165    },
    166    { timeout: 100, interval: 100 }
    167  );
    168  equal(2, nevals);
    169 });
    170 
    171 add_task(async function test_Sleep() {
    172  await Sleep(0);
    173  for (let type of ["foo", true, null, undefined]) {
    174    Assert.throws(() => new Sleep(type), /TypeError/);
    175  }
    176  Assert.throws(() => new Sleep(1.2), /RangeError/);
    177  Assert.throws(() => new Sleep(-1), /RangeError/);
    178 });
    179 
    180 add_task(function test_DebounceCallback_constructor() {
    181  for (let cb of [42, "foo", true, null, undefined, [], {}]) {
    182    Assert.throws(() => new DebounceCallback(cb), /TypeError/);
    183  }
    184  for (let timeout of ["foo", true, [], {}, () => {}]) {
    185    Assert.throws(
    186      () => new DebounceCallback(() => {}, { timeout }),
    187      /TypeError/
    188    );
    189  }
    190  for (let timeout of [-1, 2.3, NaN]) {
    191    Assert.throws(
    192      () => new DebounceCallback(() => {}, { timeout }),
    193      /RangeError/
    194    );
    195  }
    196 });
    197 
    198 add_task(async function test_DebounceCallback_repeatedCallback() {
    199  let uniqueEvent = {};
    200  let ncalls = 0;
    201 
    202  let cb = ev => {
    203    ncalls++;
    204    equal(ev, uniqueEvent);
    205  };
    206  let debouncer = new DebounceCallback(cb);
    207  debouncer.timer = new MockTimer(3);
    208 
    209  // flood the debouncer with events,
    210  // we only expect the last one to fire
    211  debouncer.handleEvent(uniqueEvent);
    212  debouncer.handleEvent(uniqueEvent);
    213  debouncer.handleEvent(uniqueEvent);
    214 
    215  equal(ncalls, 1);
    216  ok(debouncer.timer.cancelled);
    217 });
    218 
    219 add_task(async function test_waitForMessage_messageManagerAndMessageTypes() {
    220  let messageManager = new MessageManager();
    221 
    222  for (let manager of ["foo", 42, null, undefined, true, [], {}]) {
    223    Assert.throws(() => waitForMessage(manager, "message"), /TypeError/);
    224  }
    225 
    226  for (let message of [42, null, undefined, true, [], {}]) {
    227    Assert.throws(() => waitForMessage(messageManager, message), /TypeError/);
    228  }
    229 
    230  let data = { foo: "bar" };
    231  let sent = waitForMessage(messageManager, "message");
    232  messageManager.send("message", data);
    233  equal(data, await sent);
    234 });
    235 
    236 add_task(async function test_waitForMessage_checkFnTypes() {
    237  let messageManager = new MessageManager();
    238 
    239  for (let checkFn of ["foo", 42, true, [], {}]) {
    240    Assert.throws(
    241      () => waitForMessage(messageManager, "message", { checkFn }),
    242      /TypeError/
    243    );
    244  }
    245 
    246  let data1 = { notFoo: "bar" };
    247  let data2 = { foo: "bar" };
    248 
    249  for (let checkFn of [null, undefined, msg => "foo" in msg.data]) {
    250    let expected_data = checkFn == null ? data1 : data2;
    251 
    252    messageManager = new MessageManager();
    253    let sent = waitForMessage(messageManager, "message", { checkFn });
    254    messageManager.send("message", data1);
    255    messageManager.send("message", data2);
    256    equal(expected_data, await sent);
    257  }
    258 });
    259 
    260 add_task(async function test_waitForObserverTopic_topicTypes() {
    261  for (let topic of [42, null, undefined, true, [], {}]) {
    262    Assert.throws(() => waitForObserverTopic(topic), /TypeError/);
    263  }
    264 
    265  let data = { foo: "bar" };
    266  let sent = waitForObserverTopic("message");
    267  Services.obs.notifyObservers(this, "message", data);
    268  let result = await sent;
    269  equal(this, result.subject);
    270  equal(data, result.data);
    271 });
    272 
    273 add_task(async function test_waitForObserverTopic_checkFnTypes() {
    274  for (let checkFn of ["foo", 42, true, [], {}]) {
    275    Assert.throws(
    276      () => waitForObserverTopic("message", { checkFn }),
    277      /TypeError/
    278    );
    279  }
    280 
    281  let data1 = { notFoo: "bar" };
    282  let data2 = { foo: "bar" };
    283 
    284  for (let checkFn of [null, undefined, (subject, data) => data == data2]) {
    285    let expected_data = checkFn == null ? data1 : data2;
    286 
    287    let sent = waitForObserverTopic("message");
    288    Services.obs.notifyObservers(this, "message", data1);
    289    Services.obs.notifyObservers(this, "message", data2);
    290    let result = await sent;
    291    equal(expected_data, result.data);
    292  }
    293 });
    294 
    295 add_task(async function test_waitForObserverTopic_timeoutTypes() {
    296  for (let timeout of ["foo", true, [], {}]) {
    297    Assert.throws(
    298      () => waitForObserverTopic("message", { timeout }),
    299      /TypeError/
    300    );
    301  }
    302  for (let timeout of [1.2, -1]) {
    303    Assert.throws(
    304      () => waitForObserverTopic("message", { timeout }),
    305      /RangeError/
    306    );
    307  }
    308  for (let timeout of [null, undefined, 42]) {
    309    let data = { foo: "bar" };
    310    let sent = waitForObserverTopic("message", { timeout });
    311    Services.obs.notifyObservers(this, "message", data);
    312    let result = await sent;
    313    equal(this, result.subject);
    314    equal(data, result.data);
    315  }
    316 });
    317 
    318 add_task(async function test_waitForObserverTopic_timeoutElapse() {
    319  try {
    320    await waitForObserverTopic("message", { timeout: 0 });
    321    ok(false, "Expected Timeout error not raised");
    322  } catch (e) {
    323    ok(
    324      e.message.includes("waitForObserverTopic timed out after"),
    325      "Expected error received"
    326    );
    327  }
    328 });