Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/toolkit/components/places/tests/queries/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 11 kB image not shown  

Quelle  test_async.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/. */


var tests = [
  {
    desc:
      "nsNavHistoryFolderResultNode: Basic test, asynchronously open and " +
      "close container with a single child",

    loading(node, newState, oldState) {
      this.checkStateChanged("loading", 1);
      this.checkArgs("loading", node, oldState, node.STATE_CLOSED);
    },

    opened(node, newState, oldState) {
      this.checkStateChanged("opened", 1);
      this.checkState("loading", 1);
      this.checkArgs("opened", node, oldState, node.STATE_LOADING);

      print("Checking node children");
      compareArrayToResult(this.data, node);

      print("Closing container");
      node.containerOpen = false;
    },

    closed(node, newState, oldState) {
      this.checkStateChanged("closed", 1);
      this.checkState("opened", 1);
      this.checkArgs("closed", node, oldState, node.STATE_OPENED);
      this.success();
    },
  },

  {
    desc:
      "nsNavHistoryFolderResultNode: After async open and no changes, " +
      "second open should be synchronous",

    loading(node, newState, oldState) {
      this.checkStateChanged("loading", 1);
      this.checkState("closed", 0);
      this.checkArgs("loading", node, oldState, node.STATE_CLOSED);
    },

    opened(node, newState, oldState) {
      let cnt = this.checkStateChanged("opened", 1, 2);
      let expectOldState = cnt === 1 ? node.STATE_LOADING : node.STATE_CLOSED;
      this.checkArgs("opened", node, oldState, expectOldState);

      print("Checking node children");
      compareArrayToResult(this.data, node);

      print("Closing container");
      node.containerOpen = false;
    },

    closed(node, newState, oldState) {
      let cnt = this.checkStateChanged("closed", 1, 2);
      this.checkArgs("closed", node, oldState, node.STATE_OPENED);

      switch (cnt) {
        case 1:
          node.containerOpen = true;
          break;
        case 2:
          this.success();
          break;
      }
    },
  },

  {
    desc:
      "nsNavHistoryFolderResultNode: After closing container in " +
      "loading(), opened() should not be called",

    loading(node, newState, oldState) {
      this.checkStateChanged("loading", 1);
      this.checkArgs("loading", node, oldState, node.STATE_CLOSED);
      print("Closing container");
      node.containerOpen = false;
    },

    opened() {
      do_throw("opened should not be called");
    },

    closed(node, newState, oldState) {
      this.checkStateChanged("closed", 1);
      this.checkState("loading", 1);
      this.checkArgs("closed", node, oldState, node.STATE_LOADING);
      this.success();
    },
  },
];

/**
 * Instances of this class become the prototypes of the test objects above.
 * Each test can therefore use the methods of this class, or they can override
 * them if they want.  To run a test, call setup() and then run().
 */

function Test() {
  // This maps a state name to the number of times it's been observed.
  this.stateCounts = {};
  // Promise object resolved when the next test can be run.
  this.deferNextTest = Promise.withResolvers();
}

Test.prototype = {
  /**
   * Call this when an observer observes a container state change to sanity
   * check the arguments.
   *
   * @param {string} aNewState
   *   The name of the new state. Used only for printing out helpful info.
   * @param {nsINavHistoryContainerResultNode} aNode
   *   The node argument passed to containerStateChanged.
   * @param {string} aOldState
   *   The old state argument passed to containerStateChanged.
   * @param {string} aExpectOldState
   *   The expected old state.
   */

  checkArgs(aNewState, aNode, aOldState, aExpectOldState) {
    print("Node passed on " + aNewState + " should be result.root");
    Assert.equal(this.result.root, aNode);
    print("Old state passed on " + aNewState + " should be " + aExpectOldState);

    // aOldState comes from xpconnect and will therefore be defined.  It may be
    // zero, though, so use strict equality just to make sure aExpectOldState is
    // also defined.
    Assert.strictEqual(aOldState, aExpectOldState);
  },

  /**
   * Call this when an observer observes a container state change.  It registers
   * the state change and ensures that it has been observed the given number
   * of times.  See checkState for parameter explanations.
   *
   * @param {string} aState
   * @param {number} aExpectedMin
   * @param {number} aExpectedMax
   * @returns {number}
   *   The number of times aState has been observed, including the new observation.
   */

  checkStateChanged(aState, aExpectedMin, aExpectedMax) {
    print(aState + " state change observed");
    if (!this.stateCounts.hasOwnProperty(aState)) {
      this.stateCounts[aState] = 0;
    }
    this.stateCounts[aState]++;
    return this.checkState(aState, aExpectedMin, aExpectedMax);
  },

  /**
   * Ensures that the state has been observed the given number of times.
   *
   * @param {string} aState
   *   The name of the state.
   * @param {number} aExpectedMin
   *   The state must have been observed at least this number of times.
   * @param {number} [aExpectedMax]
   *   The state must have been observed at most this number of times.
   *   This parameter is optional. If undefined, it's set to aExpectedMin.
   * @returns {number}
   *   The number of times aState has been observed, including the new observation.
   */

  checkState(aState, aExpectedMin, aExpectedMax) {
    let cnt = this.stateCounts[aState] || 0;
    if (aExpectedMax === undefined) {
      aExpectedMax = aExpectedMin;
    }
    if (aExpectedMin === aExpectedMax) {
      print(
        aState +
          " should be observed only " +
          aExpectedMin +
          " times (actual = " +
          cnt +
          ")"
      );
    } else {
      print(
        aState +
          " should be observed at least " +
          aExpectedMin +
          " times and at most " +
          aExpectedMax +
          " times (actual = " +
          cnt +
          ")"
      );
    }
    Assert.ok(cnt >= aExpectedMin && cnt <= aExpectedMax);
    return cnt;
  },

  /**
   * Asynchronously opens the root of the test's result.
   */

  openContainer() {
    // Set up the result observer.  It delegates to this object's callbacks and
    // wraps them in a try-catch so that errors don't get eaten.
    let self = this;
    this.observer = {
      containerStateChanged(container, oldState, newState) {
        print(
          "New state passed to containerStateChanged() should equal the " +
            "container's current state"
        );
        Assert.equal(newState, container.state);

        try {
          switch (newState) {
            case Ci.nsINavHistoryContainerResultNode.STATE_LOADING:
              self.loading(container, newState, oldState);
              break;
            case Ci.nsINavHistoryContainerResultNode.STATE_OPENED:
              self.opened(container, newState, oldState);
              break;
            case Ci.nsINavHistoryContainerResultNode.STATE_CLOSED:
              self.closed(container, newState, oldState);
              break;
            default:
              do_throw("Unexpected new state! " + newState);
          }
        } catch (err) {
          do_throw(err);
        }
      },
    };
    this.result.addObserver(this.observer);

    print("Opening container");
    this.result.root.containerOpen = true;
  },

  /**
   * Starts the test and returns a promise resolved when the test completes.
   */

  run() {
    this.openContainer();
    return this.deferNextTest.promise;
  },

  /**
   * This must be called before run().  It adds a bookmark and sets up the
   * test's result.  Override if need be.
   */

  async setup() {
    // Populate the database with different types of bookmark items.
    this.data = DataHelper.makeDataArray([
      { type: "bookmark" },
      { type: "separator" },
      { type: "folder" },
      { type: "bookmark", uri: "place:terms=foo" },
    ]);
    await task_populateDB(this.data);

    // Make a query.
    this.query = PlacesUtils.history.getNewQuery();
    this.query.setParents([DataHelper.defaults.bookmark.parentGuid]);
    this.opts = PlacesUtils.history.getNewQueryOptions();
    this.opts.asyncEnabled = true;
    this.result = PlacesUtils.history.executeQuery(this.query, this.opts);
  },

  /**
   * Call this when the test has succeeded.  It cleans up resources and starts
   * the next test.
   */

  success() {
    this.result.removeObserver(this.observer);

    // Resolve the promise object that indicates that the next test can be run.
    this.deferNextTest.resolve();
  },
};

/**
 * This makes it a little bit easier to use the functions of head_queries.js.
 */

var DataHelper = {
  defaults: {
    bookmark: {
      parentGuid: PlacesUtils.bookmarks.unfiledGuid,
      uri: "http://example.com/",
      title: "test bookmark",
    },

    folder: {
      parentGuid: PlacesUtils.bookmarks.unfiledGuid,
      title: "test folder",
    },

    separator: {
      parentGuid: PlacesUtils.bookmarks.unfiledGuid,
    },
  },

  /**
   * Converts an array of simple bookmark item descriptions to the more verbose
   * format required by task_populateDB() in head_queries.js.
   *
   * @param {object[]} aData
   *   An array of objects, each of which describes a bookmark item.
   * @param {string} aData.type
   *   The type of item to create.
   * @param {string} [aData.uri]
   *   The URI to use for the item.
   * @returns {object[]}
   *   An array of objects suitable for passing to populateDB().
   */

  makeDataArray(aData) {
    let self = this;
    return aData.map(function (dat) {
      let type = dat.type;
      dat = self._makeDataWithDefaults(dat, self.defaults[type]);
      switch (type) {
        case "bookmark":
          return {
            isBookmark: true,
            uri: dat.uri,
            parentGuid: dat.parentGuid,
            index: PlacesUtils.bookmarks.DEFAULT_INDEX,
            title: dat.title,
            isInQuery: true,
          };
        case "separator":
          return {
            isSeparator: true,
            parentGuid: dat.parentGuid,
            index: PlacesUtils.bookmarks.DEFAULT_INDEX,
            isInQuery: true,
          };
        case "folder":
          return {
            isFolder: true,
            parentGuid: dat.parentGuid,
            index: PlacesUtils.bookmarks.DEFAULT_INDEX,
            title: dat.title,
            isInQuery: true,
          };
        default:
          do_throw("Unknown data type when populating DB: " + type);
          return undefined;
      }
    });
  },

  /**
   * Returns a copy of aData, except that any properties that are undefined but
   * defined in aDefaults are set to the corresponding values in aDefaults.
   *
   * @param {object} aData
   *   An array of objects, each of which describes a bookmark item.
   * @param {string} aData.type
   *   The type of item to create.
   * @param {string} [aData.uri]
   *   The URI to use for the item.
   * @param {object} aDefaults
   *   An object describing the default bookmark item.
   * @param {string} aDefaults.parentGuid
   *   The parent folder to create the bookmark item in by default.
   * @param {string} [aDefaults.uri]
   *   The URI to use as the default.
   * @param {string} [aDefaults.title]
   *   The title to use as the default
   * @returns {object}
   *   A copy of aData with defaults values set.
   */

  _makeDataWithDefaults(aData, aDefaults) {
    let dat = {};
    for (let [prop, val] of Object.entries(aDefaults)) {
      dat[prop] = aData.hasOwnProperty(prop) ? aData[prop] : val;
    }
    return dat;
  },
};

add_task(async function test_async() {
  for (let test of tests) {
    await PlacesUtils.bookmarks.eraseEverything();

    Object.setPrototypeOf(test, new Test());
    await test.setup();

    print("------ Running test: " + test.desc);
    await test.run();
  }

  await PlacesUtils.bookmarks.eraseEverything();
  print("All tests done, exiting");
});

Messung V0.5 in Prozent
C=95 H=88 G=91

¤ Dauer der Verarbeitung: 0.16 Sekunden  (vorverarbeitet am  2026-10-04) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

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.