Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  test_monitor_uncaught.js   Sprache: JAVA

 
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


"use strict";

const { setTimeout } = ChromeUtils.importESModule(
  "resource://gre/modules/Timer.sys.mjs"
);
const { PromiseTestUtils } = ChromeUtils.importESModule(
  "resource://testing-common/PromiseTestUtils.sys.mjs"
);

// Prevent test failures due to the unhandled rejections in this test file.
PromiseTestUtils.disableUncaughtRejectionObserverForSelfTest();

add_task(async function test_globals() {
  Assert.notEqual(
    PromiseDebugging,
    undefined,
    "PromiseDebugging is available."
  );
});

add_task(async function test_promiseID() {
  let p1 = new Promise(() => {});
  let p2 = new Promise(() => {});
  let p3 = p2.catch(null);
  let promise = [p1, p2, p3];

  let identifiers = promise.map(PromiseDebugging.getPromiseID);
  info("Identifiers: " + JSON.stringify(identifiers));
  let idSet = new Set(identifiers);
  Assert.equal(
    idSet.size,
    identifiers.length,
    "PromiseDebugging.getPromiseID returns a distinct id per promise"
  );

  let identifiers2 = promise.map(PromiseDebugging.getPromiseID);
  Assert.equal(
    JSON.stringify(identifiers),
    JSON.stringify(identifiers2),
    "Successive calls to PromiseDebugging.getPromiseID return the same id for the same promise"
  );
});

add_task(async function test_observe_uncaught() {
  // The names of Promise instances
  let names = new Map();

  // The results for UncaughtPromiseObserver callbacks.
  let CallbackResults = function (name) {
    this.name = name;
    this.expected = new Set();
    this.observed = new Set();
    this.blocker = new Promise(resolve => (this.resolve = resolve));
  };
  CallbackResults.prototype = {
    observe(promise) {
      info(this.name + " observing Promise " + names.get(promise));
      Assert.equal(
        PromiseDebugging.getState(promise).state,
        "rejected",
        this.name + " observed a rejected Promise"
      );
      if (!this.expected.has(promise)) {
        Assert.ok(
          false,
          this.name +
            " observed a Promise that it expected to observe, " +
            names.get(promise) +
            " (" +
            PromiseDebugging.getPromiseID(promise) +
            ", " +
            PromiseDebugging.getAllocationStack(promise) +
            ")"
        );
      }
      Assert.ok(
        this.expected.delete(promise),
        this.name +
          " observed a Promise that it expected to observe, " +
          names.get(promise) +
          " (" +
          PromiseDebugging.getPromiseID(promise) +
          ")"
      );
      Assert.ok(
        !this.observed.has(promise),
        this.name + " observed a Promise that it has not observed yet"
      );
      this.observed.add(promise);
      if (this.expected.size == 0) {
        this.resolve();
      } else {
        info(
          this.name +
            " is still waiting for " +
            this.expected.size +
            " observations:"
        );
        info(
          JSON.stringify(Array.from(this.expected.values(), x => names.get(x)))
        );
      }
    },
  };

  let onLeftUncaught = new CallbackResults("onLeftUncaught");
  let onConsumed = new CallbackResults("onConsumed");

  let observer = {
    onLeftUncaught(promise) {
      onLeftUncaught.observe(promise);
    },
    onConsumed(promise) {
      onConsumed.observe(promise);
    },
  };

  let resolveLater = function (delay = 20) {
    // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
    return new Promise(resolve => setTimeout(resolve, delay));
  };
  let rejectLater = function (delay = 20) {
    // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
    return new Promise((resolve, reject) => setTimeout(reject, delay));
  };
  let makeSamples = function* () {
    yield {
      promise: Promise.resolve(0),
      name: "Promise.resolve",
    };
    yield {
      promise: Promise.resolve(resolve => resolve(0)),
      name: "Resolution callback",
    };
    yield {
      promise: Promise.resolve(0).catch(null),
      name: "`catch(null)`",
    };
    yield {
      promise: Promise.reject(0).catch(() => {}),
      name: "Reject and catch immediately",
    };
    yield {
      promise: resolveLater(),
      name: "Resolve later",
    };
    yield {
      promise: Promise.reject("Simple rejection"),
      leftUncaught: true,
      consumed: false,
      name: "Promise.reject",
    };

    // Reject a promise now, consume it later.
    let p = Promise.reject("Reject now, consume later");

    // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
    setTimeout(
      () =>
        p.catch(() => {
          info("Consumed promise");
        }),
      200
    );
    yield {
      promise: p,
      leftUncaught: true,
      consumed: true,
      name: "Reject now, consume later",
    };

    yield {
      promise: Promise.all([Promise.resolve("Promise.all"), rejectLater()]),
      leftUncaught: true,
      name: "Rejecting through Promise.all",
    };
    yield {
      promise: Promise.race([resolveLater(500), Promise.reject()]),
      leftUncaught: true// The rejection wins the race.
      name: "Rejecting through Promise.race",
    };
    yield {
      promise: Promise.race([Promise.resolve(), rejectLater(500)]),
      leftUncaught: false// The resolution wins the race.
      name: "Resolving through Promise.race",
    };

    let boom = new Error("`throw` in the constructor");
    yield {
      promise: new Promise(() => {
        throw boom;
      }),
      leftUncaught: true,
      name: "Throwing in the constructor",
    };

    let rejection = Promise.reject("`reject` during resolution");
    yield {
      promise: rejection,
      leftUncaught: false,
      consumed: false// `rejection` is consumed immediately (see below)
      name: "Promise.reject, again",
    };

    yield {
      promise: new Promise(resolve => resolve(rejection)),
      leftUncaught: true,
      consumed: false,
      name: "Resolving with a rejected promise",
    };

    yield {
      promise: Promise.resolve(0).then(() => rejection),
      leftUncaught: true,
      consumed: false,
      name: "Returning a rejected promise from success handler",
    };

    yield {
      promise: Promise.resolve(0).then(() => {
        throw new Error();
      }),
      leftUncaught: true,
      consumed: false,
      name: "Throwing during the call to the success callback",
    };
  };
  let samples = [];
  for (let s of makeSamples()) {
    samples.push(s);
    info(
      "Promise '" +
        s.name +
        "' has id " +
        PromiseDebugging.getPromiseID(s.promise)
    );
  }

  PromiseDebugging.addUncaughtRejectionObserver(observer);

  for (let s of samples) {
    names.set(s.promise, s.name);
    if (s.leftUncaught || false) {
      onLeftUncaught.expected.add(s.promise);
    }
    if (s.consumed || false) {
      onConsumed.expected.add(s.promise);
    }
  }

  info("Test setup, waiting for callbacks.");
  await onLeftUncaught.blocker;

  info("All calls to onLeftUncaught are complete.");
  if (onConsumed.expected.size != 0) {
    info("onConsumed is still waiting for the following Promise:");
    info(
      JSON.stringify(
        Array.from(onConsumed.expected.values(), x => names.get(x))
      )
    );
    await onConsumed.blocker;
  }

  info("All calls to onConsumed are complete.");
  let removed = PromiseDebugging.removeUncaughtRejectionObserver(observer);
  Assert.ok(removed, "removeUncaughtRejectionObserver succeeded");
  removed = PromiseDebugging.removeUncaughtRejectionObserver(observer);
  Assert.ok(
    !removed,
    "second call to removeUncaughtRejectionObserver didn't remove anything"
  );
});

add_task(async function test_uninstall_observer() {
  let Observer = function () {
    this.blocker = new Promise(resolve => (this.resolve = resolve));
    this.active = true;
  };
  Observer.prototype = {
    set active(x) {
      this._active = x;
      if (x) {
        PromiseDebugging.addUncaughtRejectionObserver(this);
      } else {
        PromiseDebugging.removeUncaughtRejectionObserver(this);
      }
    },
    onLeftUncaught() {
      Assert.ok(this._active, "This observer is active.");
      this.resolve();
    },
    onConsumed() {
      Assert.ok(false"We should not consume any Promise.");
    },
  };

  info("Adding an observer.");
  let deactivate = new Observer();
  Promise.reject("I am an uncaught rejection.");
  await deactivate.blocker;
  Assert.ok(true"The observer has observed an uncaught Promise.");
  deactivate.active = false;
  info(
    "Removing the observer, it should not observe any further uncaught Promise."
  );

  info(
    "Rejecting a Promise and waiting a little to give a chance to observers."
  );
  let wait = new Observer();
  Promise.reject("I am another uncaught rejection.");
  await wait.blocker;
  // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
  await new Promise(resolve => setTimeout(resolve, 100));
  // Normally, `deactivate` should not be notified of the uncaught rejection.
  wait.active = false;
});

Messung V0.5
C=93 H=93 G=92

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge