Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/toolkit/components/places/tests/unit/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 23 kB image not shown  

Quelle  test_keywords.js   Sprache: JAVA

 
"use strict";

ChromeUtils.defineESModuleGetters(this, {
  Preferences: "resource://gre/modules/Preferences.sys.mjs",
});

async function check_keyword(aExpectExists, aHref, aKeyword, aPostData = null) {
  // Check case-insensitivity.
  aKeyword = aKeyword.toUpperCase();

  let entry = await PlacesUtils.keywords.fetch(aKeyword);

  Assert.deepEqual(
    entry,
    await PlacesUtils.keywords.fetch({ keyword: aKeyword })
  );

  if (aExpectExists) {
    Assert.ok(!!entry, "A keyword should exist");
    Assert.equal(entry.url.href, aHref);
    Assert.equal(entry.postData, aPostData);
    Assert.deepEqual(
      entry,
      await PlacesUtils.keywords.fetch({ keyword: aKeyword, url: aHref })
    );
    let entries = [];
    await PlacesUtils.keywords.fetch({ url: aHref }, e => entries.push(e));
    Assert.ok(
      entries.some(
        e => e.url.href == aHref && e.keyword == aKeyword.toLowerCase()
      )
    );
  } else {
    Assert.ok(
      !entry || entry.url.href != aHref,
      "The given keyword entry should not exist"
    );
    if (aHref) {
      Assert.equal(
        null,
        await PlacesUtils.keywords.fetch({ keyword: aKeyword, url: aHref })
      );
    } else {
      Assert.equal(
        null,
        await PlacesUtils.keywords.fetch({ keyword: aKeyword })
      );
    }
  }
}

/**
 * Polls the keywords cache waiting for the given keyword entry.
 */

async function promiseKeyword(keyword, expectedHref) {
  let href = null;
  do {
    await new Promise(resolve => do_timeout(100, resolve));
    let entry = await PlacesUtils.keywords.fetch(keyword);
    if (entry) {
      href = entry.url.href;
    }
  } while (href != expectedHref);
}

async function check_no_orphans() {
  let db = await PlacesUtils.promiseDBConnection();
  let rows = await db.executeCached(
    `SELECT id FROM moz_keywords k
     WHERE NOT EXISTS (SELECT 1 FROM moz_places WHERE id = k.place_id)
    `
  );
  Assert.equal(rows.length, 0);
}

function expectBookmarkNotifications() {
  const observer = {
    notifications: [],
    _start() {
      this._handle = this._handle.bind(this);
      PlacesUtils.observers.addListener(
        ["bookmark-keyword-changed"],
        this._handle
      );
    },
    _handle(events) {
      for (const event of events) {
        this.notifications.push({
          type: event.type,
          id: event.id,
          itemType: event.itemType,
          url: event.url,
          guid: event.guid,
          parentGuid: event.parentGuid,
          keyword: event.keyword,
          lastModified: new Date(event.lastModified),
          source: event.source,
          isTagging: event.isTagging,
        });
      }
    },
    check(expected) {
      PlacesUtils.observers.removeListener(
        ["bookmark-keyword-changed"],
        this._handle
      );
      Assert.deepEqual(this.notifications, expected);
    },
  };
  observer._start();
  return observer;
}

add_task(async function test_invalid_input() {
  Assert.throws(() => PlacesUtils.keywords.fetch(null), /Invalid keyword/);
  Assert.throws(() => PlacesUtils.keywords.fetch(5), /Invalid keyword/);
  Assert.throws(() => PlacesUtils.keywords.fetch(undefined), /Invalid keyword/);
  Assert.throws(
    () => PlacesUtils.keywords.fetch({ keyword: null }),
    /Invalid keyword/
  );
  Assert.throws(
    () => PlacesUtils.keywords.fetch({ keyword: {} }),
    /Invalid keyword/
  );
  Assert.throws(
    () => PlacesUtils.keywords.fetch({ keyword: 5 }),
    /Invalid keyword/
  );
  Assert.throws(
    () => PlacesUtils.keywords.fetch({}),
    /At least keyword or url must be provided/
  );
  Assert.throws(
    () => PlacesUtils.keywords.fetch({ keyword: "test" }, "test"),
    /onResult callback must be a valid function/
  );
  Assert.throws(
    () => PlacesUtils.keywords.fetch({ url: "test" }),
    /is not a valid URL/
  );
  Assert.throws(
    () => PlacesUtils.keywords.fetch({ url: {} }),
    /is not a valid URL/
  );
  Assert.throws(
    () => PlacesUtils.keywords.fetch({ url: null }),
    /is not a valid URL/
  );
  Assert.throws(
    () => PlacesUtils.keywords.fetch({ url: "" }),
    /is not a valid URL/
  );

  Assert.throws(
    () => PlacesUtils.keywords.insert(null),
    /Input should be a valid object/
  );
  Assert.throws(
    () => PlacesUtils.keywords.insert("test"),
    /Input should be a valid object/
  );
  Assert.throws(
    () => PlacesUtils.keywords.insert(undefined),
    /Input should be a valid object/
  );
  Assert.throws(() => PlacesUtils.keywords.insert({}), /Invalid keyword/);
  Assert.throws(
    () => PlacesUtils.keywords.insert({ keyword: null }),
    /Invalid keyword/
  );
  Assert.throws(
    () => PlacesUtils.keywords.insert({ keyword: 5 }),
    /Invalid keyword/
  );
  Assert.throws(
    () => PlacesUtils.keywords.insert({ keyword: "" }),
    /Invalid keyword/
  );
  Assert.throws(
    () => PlacesUtils.keywords.insert({ keyword: "test", postData: 5 }),
    /Invalid POST data/
  );
  Assert.throws(
    () => PlacesUtils.keywords.insert({ keyword: "test", postData: {} }),
    /Invalid POST data/
  );
  Assert.throws(
    () => PlacesUtils.keywords.insert({ keyword: "test" }),
    /is not a valid URL/
  );
  Assert.throws(
    () => PlacesUtils.keywords.insert({ keyword: "test", url: 5 }),
    /is not a valid URL/
  );
  Assert.throws(
    () => PlacesUtils.keywords.insert({ keyword: "test", url: "" }),
    /is not a valid URL/
  );
  Assert.throws(
    () => PlacesUtils.keywords.insert({ keyword: "test", url: null }),
    /is not a valid URL/
  );
  Assert.throws(
    () => PlacesUtils.keywords.insert({ keyword: "test", url: "mozilla" }),
    /is not a valid URL/
  );

  Assert.throws(() => PlacesUtils.keywords.remove(null), /Invalid keyword/);
  Assert.throws(() => PlacesUtils.keywords.remove(""), /Invalid keyword/);
  Assert.throws(() => PlacesUtils.keywords.remove(5), /Invalid keyword/);
});

add_task(async function test_addKeyword() {
  await check_keyword(false"http://example.com/", "keyword");
  let fc = await foreign_count("http://example.com/");
  let observer = expectBookmarkNotifications();

  await PlacesUtils.keywords.insert({
    keyword: "keyword",
    url: "http://example.com/",
  });
  observer.check([]);

  await check_keyword(true"http://example.com/", "keyword");
  Assert.equal(await foreign_count("http://example.com/"), fc + 1); // +1 keyword

  // Now remove the keyword.
  observer = expectBookmarkNotifications();
  await PlacesUtils.keywords.remove("keyword");
  observer.check([]);

  await check_keyword(false"http://example.com/", "keyword");
  Assert.equal(await foreign_count("http://example.com/"), fc); // -1 keyword

  // Check using URL.
  await PlacesUtils.keywords.insert({
    keyword: "keyword",
    url: new URL("http://example.com/"),
  });
  await check_keyword(true"http://example.com/", "keyword");
  await PlacesUtils.keywords.remove("keyword");
  await check_keyword(false"http://example.com/", "keyword");

  await check_no_orphans();
});

add_task(async function test_addBookmarkAndKeyword() {
  let timerPrecision = Preferences.get("privacy.reduceTimerPrecision");
  Preferences.set("privacy.reduceTimerPrecision"false);

  registerCleanupFunction(function () {
    Preferences.set("privacy.reduceTimerPrecision", timerPrecision);
  });

  await check_keyword(false"http://example.com/", "keyword");
  let fc = await foreign_count("http://example.com/");
  let bookmark = await PlacesUtils.bookmarks.insert({
    url: "http://example.com/",
    parentGuid: PlacesUtils.bookmarks.unfiledGuid,
  });

  let observer = expectBookmarkNotifications();
  await PlacesUtils.keywords.insert({
    keyword: "keyword",
    url: "http://example.com/",
  });

  observer.check([
    {
      type: "bookmark-keyword-changed",
      id: await PlacesTestUtils.promiseItemId(bookmark.guid),
      itemType: bookmark.type,
      url: bookmark.url,
      guid: bookmark.guid,
      parentGuid: bookmark.parentGuid,
      keyword: "keyword",
      lastModified: new Date(bookmark.lastModified),
      source: Ci.nsINavBookmarksService.SOURCE_DEFAULT,
      isTagging: false,
    },
  ]);

  await check_keyword(true"http://example.com/", "keyword");
  Assert.equal(await foreign_count("http://example.com/"), fc + 2); // +1 bookmark +1 keyword

  // Now remove the keyword.
  observer = expectBookmarkNotifications();
  await PlacesUtils.keywords.remove("keyword");

  observer.check([
    {
      type: "bookmark-keyword-changed",
      id: await PlacesTestUtils.promiseItemId(bookmark.guid),
      itemType: bookmark.type,
      url: bookmark.url,
      guid: bookmark.guid,
      parentGuid: bookmark.parentGuid,
      keyword: "",
      lastModified: new Date(bookmark.lastModified),
      source: Ci.nsINavBookmarksService.SOURCE_DEFAULT,
      isTagging: false,
    },
  ]);

  await check_keyword(false"http://example.com/", "keyword");
  Assert.equal(await foreign_count("http://example.com/"), fc + 1); // -1 keyword

  // Add again the keyword, then remove the bookmark.
  await PlacesUtils.keywords.insert({
    keyword: "keyword",
    url: "http://example.com/",
  });

  observer = expectBookmarkNotifications();
  await PlacesUtils.bookmarks.remove(bookmark.guid);
  // the notification is synchronous but the removal process is async.
  // Unfortunately there's nothing explicit we can wait for.
  // eslint-disable-next-line no-empty
  while (await foreign_count("http://example.com/")) {}
  // We don't get any itemChanged notification since the bookmark has been
  // removed already.
  observer.check([]);

  await check_keyword(false"http://example.com/", "keyword");

  await check_no_orphans();
});

add_task(async function test_addKeywordToURIHavingKeyword() {
  await check_keyword(false"http://example.com/", "keyword");
  let fc = await foreign_count("http://example.com/");

  let observer = expectBookmarkNotifications();
  await PlacesUtils.keywords.insert({
    keyword: "keyword",
    url: "http://example.com/",
  });
  observer.check([]);

  await check_keyword(true"http://example.com/", "keyword");
  Assert.equal(await foreign_count("http://example.com/"), fc + 1); // +1 keyword

  await PlacesUtils.keywords.insert({
    keyword: "keyword2",
    url: "http://example.com/",
    postData: "test=1",
  });

  await check_keyword(true"http://example.com/", "keyword");
  await check_keyword(true"http://example.com/", "keyword2", "test=1");
  Assert.equal(await foreign_count("http://example.com/"), fc + 2); // +1 keyword
  let entries = [];
  let entry = await PlacesUtils.keywords.fetch(
    { url: "http://example.com/" },
    e => entries.push(e)
  );
  Assert.equal(entries.length, 2);
  Assert.deepEqual(entries[0], entry);

  // Now remove the keywords.
  observer = expectBookmarkNotifications();
  await PlacesUtils.keywords.remove("keyword");
  await PlacesUtils.keywords.remove("keyword2");
  observer.check([]);

  await check_keyword(false"http://example.com/", "keyword");
  await check_keyword(false"http://example.com/", "keyword2");
  Assert.equal(await foreign_count("http://example.com/"), fc); // -1 keyword

  await check_no_orphans();
});

add_task(async function test_addBookmarkToURIHavingKeyword() {
  await check_keyword(false"http://example.com/", "keyword");
  let fc = await foreign_count("http://example.com/");
  let observer = expectBookmarkNotifications();

  await PlacesUtils.keywords.insert({
    keyword: "keyword",
    url: "http://example.com/",
  });
  observer.check([]);

  await check_keyword(true"http://example.com/", "keyword");
  Assert.equal(await foreign_count("http://example.com/"), fc + 1); // +1 keyword

  observer = expectBookmarkNotifications();
  let bookmark = await PlacesUtils.bookmarks.insert({
    url: "http://example.com/",
    parentGuid: PlacesUtils.bookmarks.unfiledGuid,
  });
  Assert.equal(await foreign_count("http://example.com/"), fc + 2); // +1 bookmark
  observer.check([]);

  observer = expectBookmarkNotifications();
  await PlacesUtils.bookmarks.remove(bookmark.guid);
  // the notification is synchronous but the removal process is async.
  // Unfortunately there's nothing explicit we can wait for.
  // eslint-disable-next-line no-empty
  while (await foreign_count("http://example.com/")) {}
  // We don't get any itemChanged notification since the bookmark has been
  // removed already.
  observer.check([]);

  await check_keyword(false"http://example.com/", "keyword");

  await check_no_orphans();
});

add_task(async function test_sameKeywordDifferentURL() {
  let fc1 = await foreign_count("http://example1.com/");
  let bookmark1 = await PlacesUtils.bookmarks.insert({
    url: "http://example1.com/",
    parentGuid: PlacesUtils.bookmarks.unfiledGuid,
  });
  let fc2 = await foreign_count("http://example2.com/");
  let bookmark2 = await PlacesUtils.bookmarks.insert({
    url: "http://example2.com/",
    parentGuid: PlacesUtils.bookmarks.unfiledGuid,
  });
  await PlacesUtils.keywords.insert({
    keyword: "keyword",
    url: "http://example1.com/",
  });

  await check_keyword(true"http://example1.com/", "keyword");
  Assert.equal(await foreign_count("http://example1.com/"), fc1 + 2); // +1 bookmark +1 keyword
  await check_keyword(false"http://example2.com/", "keyword");
  Assert.equal(await foreign_count("http://example2.com/"), fc2 + 1); // +1 bookmark

  // Assign the same keyword to another url.
  let observer = expectBookmarkNotifications();
  await PlacesUtils.keywords.insert({
    keyword: "keyword",
    url: "http://example2.com/",
  });

  observer.check([
    {
      type: "bookmark-keyword-changed",
      id: await PlacesTestUtils.promiseItemId(bookmark1.guid),
      itemType: bookmark1.type,
      url: bookmark1.url,
      guid: bookmark1.guid,
      parentGuid: bookmark1.parentGuid,
      keyword: "",
      lastModified: new Date(bookmark1.lastModified),
      source: Ci.nsINavBookmarksService.SOURCE_DEFAULT,
      isTagging: false,
    },
    {
      type: "bookmark-keyword-changed",
      id: await PlacesTestUtils.promiseItemId(bookmark2.guid),
      itemType: bookmark2.type,
      url: bookmark2.url,
      guid: bookmark2.guid,
      parentGuid: bookmark2.parentGuid,
      keyword: "keyword",
      lastModified: new Date(bookmark2.lastModified),
      source: Ci.nsINavBookmarksService.SOURCE_DEFAULT,
      isTagging: false,
    },
  ]);

  await check_keyword(false"http://example1.com/", "keyword");
  Assert.equal(await foreign_count("http://example1.com/"), fc1 + 1); // -1 keyword
  await check_keyword(true"http://example2.com/", "keyword");
  Assert.equal(await foreign_count("http://example2.com/"), fc2 + 2); // +1 keyword

  // Now remove the keyword.
  observer = expectBookmarkNotifications();
  await PlacesUtils.keywords.remove("keyword");
  observer.check([
    {
      type: "bookmark-keyword-changed",
      id: await PlacesTestUtils.promiseItemId(bookmark2.guid),
      itemType: bookmark2.type,
      url: bookmark2.url,
      guid: bookmark2.guid,
      parentGuid: bookmark2.parentGuid,
      keyword: "",
      lastModified: new Date(bookmark2.lastModified),
      source: Ci.nsINavBookmarksService.SOURCE_DEFAULT,
      isTagging: false,
    },
  ]);

  await check_keyword(false"http://example1.com/", "keyword");
  await check_keyword(false"http://example2.com/", "keyword");
  Assert.equal(await foreign_count("http://example1.com/"), fc1 + 1);
  Assert.equal(await foreign_count("http://example2.com/"), fc2 + 1); // -1 keyword

  await PlacesUtils.bookmarks.remove(bookmark1);
  await PlacesUtils.bookmarks.remove(bookmark2);
  Assert.equal(await foreign_count("http://example1.com/"), fc1); // -1 bookmark
  // eslint-disable-next-line no-empty
  while (await foreign_count("http://example2.com/")) {} // -1 keyword

  await check_no_orphans();
});

add_task(async function test_sameURIDifferentKeyword() {
  let fc = await foreign_count("http://example.com/");

  let observer = expectBookmarkNotifications();
  let bookmark = await PlacesUtils.bookmarks.insert({
    url: "http://example.com/",
    parentGuid: PlacesUtils.bookmarks.unfiledGuid,
  });
  await PlacesUtils.keywords.insert({
    keyword: "keyword",
    url: "http://example.com/",
  });

  await check_keyword(true"http://example.com/", "keyword");
  Assert.equal(await foreign_count("http://example.com/"), fc + 2); // +1 bookmark +1 keyword

  observer.check([
    {
      type: "bookmark-keyword-changed",
      id: await PlacesTestUtils.promiseItemId(bookmark.guid),
      itemType: bookmark.type,
      url: bookmark.url,
      guid: bookmark.guid,
      parentGuid: bookmark.parentGuid,
      keyword: "keyword",
      lastModified: new Date(bookmark.lastModified),
      source: Ci.nsINavBookmarksService.SOURCE_DEFAULT,
      isTagging: false,
    },
  ]);

  observer = expectBookmarkNotifications();
  await PlacesUtils.keywords.insert({
    keyword: "keyword2",
    url: "http://example.com/",
  });
  await check_keyword(false"http://example.com/", "keyword");
  await check_keyword(true"http://example.com/", "keyword2");
  Assert.equal(await foreign_count("http://example.com/"), fc + 2); // -1 keyword +1 keyword
  observer.check([
    {
      type: "bookmark-keyword-changed",
      id: await PlacesTestUtils.promiseItemId(bookmark.guid),
      itemType: bookmark.type,
      url: bookmark.url,
      guid: bookmark.guid,
      parentGuid: bookmark.parentGuid,
      keyword: "keyword2",
      lastModified: new Date(bookmark.lastModified),
      source: Ci.nsINavBookmarksService.SOURCE_DEFAULT,
      isTagging: false,
    },
  ]);

  // Now remove the bookmark.
  await PlacesUtils.bookmarks.remove(bookmark);
  // eslint-disable-next-line no-empty
  while (await foreign_count("http://example.com/")) {}
  await check_keyword(false"http://example.com/", "keyword");
  await check_keyword(false"http://example.com/", "keyword2");

  await check_no_orphans();
});

add_task(async function test_deleteKeywordMultipleBookmarks() {
  let fc = await foreign_count("http://example.com/");

  let observer = expectBookmarkNotifications();
  let bookmark1 = await PlacesUtils.bookmarks.insert({
    url: "http://example.com/",
    parentGuid: PlacesUtils.bookmarks.unfiledGuid,
  });
  let bookmark2 = await PlacesUtils.bookmarks.insert({
    url: "http://example.com/",
    parentGuid: PlacesUtils.bookmarks.unfiledGuid,
  });
  await PlacesUtils.keywords.insert({
    keyword: "keyword",
    url: "http://example.com/",
  });

  await check_keyword(true"http://example.com/", "keyword");
  Assert.equal(await foreign_count("http://example.com/"), fc + 3); // +2 bookmark +1 keyword
  observer.check([
    {
      type: "bookmark-keyword-changed",
      id: await PlacesTestUtils.promiseItemId(bookmark2.guid),
      itemType: bookmark2.type,
      url: bookmark2.url,
      guid: bookmark2.guid,
      parentGuid: bookmark2.parentGuid,
      keyword: "keyword",
      lastModified: new Date(bookmark2.lastModified),
      source: Ci.nsINavBookmarksService.SOURCE_DEFAULT,
      isTagging: false,
    },
    {
      type: "bookmark-keyword-changed",
      id: await PlacesTestUtils.promiseItemId(bookmark1.guid),
      itemType: bookmark1.type,
      url: bookmark1.url,
      guid: bookmark1.guid,
      parentGuid: bookmark1.parentGuid,
      keyword: "keyword",
      lastModified: new Date(bookmark1.lastModified),
      source: Ci.nsINavBookmarksService.SOURCE_DEFAULT,
      isTagging: false,
    },
  ]);

  observer = expectBookmarkNotifications();
  await PlacesUtils.keywords.remove("keyword");
  await check_keyword(false"http://example.com/", "keyword");
  Assert.equal(await foreign_count("http://example.com/"), fc + 2); // -1 keyword
  observer.check([
    {
      type: "bookmark-keyword-changed",
      id: await PlacesTestUtils.promiseItemId(bookmark2.guid),
      itemType: bookmark2.type,
      url: bookmark2.url,
      guid: bookmark2.guid,
      parentGuid: bookmark2.parentGuid,
      keyword: "",
      lastModified: new Date(bookmark2.lastModified),
      source: Ci.nsINavBookmarksService.SOURCE_DEFAULT,
      isTagging: false,
    },
    {
      type: "bookmark-keyword-changed",
      id: await PlacesTestUtils.promiseItemId(bookmark1.guid),
      itemType: bookmark1.type,
      url: bookmark1.url,
      guid: bookmark1.guid,
      parentGuid: bookmark1.parentGuid,
      keyword: "",
      lastModified: new Date(bookmark1.lastModified),
      source: Ci.nsINavBookmarksService.SOURCE_DEFAULT,
      isTagging: false,
    },
  ]);

  // Now remove the bookmarks.
  await PlacesUtils.bookmarks.remove(bookmark1);
  await PlacesUtils.bookmarks.remove(bookmark2);
  Assert.equal(await foreign_count("http://example.com/"), fc); // -2 bookmarks

  await check_no_orphans();
});

add_task(async function test_multipleKeywordsSamePostData() {
  await PlacesUtils.keywords.insert({
    keyword: "keyword",
    url: "http://example.com/",
    postData: "postData1",
  });
  await check_keyword(true"http://example.com/", "keyword", "postData1");
  // Add another keyword with same postData, should fail.
  await PlacesUtils.keywords.insert({
    keyword: "keyword2",
    url: "http://example.com/",
    postData: "postData1",
  });
  await check_keyword(false"http://example.com/", "keyword", "postData1");
  await check_keyword(true"http://example.com/", "keyword2", "postData1");

  await PlacesUtils.keywords.remove("keyword2");

  await check_no_orphans();
});

add_task(async function test_bookmarkURLChange() {
  let fc1 = await foreign_count("http://example1.com/");
  let fc2 = await foreign_count("http://example2.com/");
  let bookmark = await PlacesUtils.bookmarks.insert({
    url: "http://example1.com/",
    parentGuid: PlacesUtils.bookmarks.unfiledGuid,
  });
  await PlacesUtils.keywords.insert({
    keyword: "keyword",
    url: "http://example1.com/",
  });

  await check_keyword(true"http://example1.com/", "keyword");
  Assert.equal(await foreign_count("http://example1.com/"), fc1 + 2); // +1 bookmark +1 keyword

  await PlacesUtils.bookmarks.update({
    guid: bookmark.guid,
    url: "http://example2.com/",
  });
  await promiseKeyword("keyword""http://example2.com/");

  await check_keyword(false"http://example1.com/", "keyword");
  await check_keyword(true"http://example2.com/", "keyword");
  Assert.equal(await foreign_count("http://example1.com/"), fc1); // -1 bookmark -1 keyword
  Assert.equal(await foreign_count("http://example2.com/"), fc2 + 2); // +1 bookmark +1 keyword
});

add_task(async function test_tagDoesntPreventKeywordRemoval() {
  await check_keyword(false"http://example.com/", "example");
  let fc = await foreign_count("http://example.com/");

  let httpBookmark = await PlacesUtils.bookmarks.insert({
    url: "http://example.com/",
    parentGuid: PlacesUtils.bookmarks.unfiledGuid,
  });
  Assert.equal(await foreign_count("http://example.com/"), fc + 1); // +1 bookmark

  PlacesUtils.tagging.tagURI(uri("http://example.com/"), ["example_tag"]);
  Assert.equal(await foreign_count("http://example.com/"), fc + 2); // +1 bookmark +1 tag

  await PlacesUtils.keywords.insert({
    keyword: "example",
    url: "http://example.com/",
  });
  Assert.equal(await foreign_count("http://example.com/"), fc + 3); // +1 bookmark +1 tag +1 keyword

  await check_keyword(true"http://example.com/", "example");

  await PlacesUtils.bookmarks.remove(httpBookmark);

  await TestUtils.waitForCondition(
    async () =>
      !(await PlacesUtils.bookmarks.fetch({ url: "http://example.com/" })),
    "Wait for bookmark to be removed"
  );

  await check_keyword(false"http://example.com/", "example");
  Assert.equal(await foreign_count("http://example.com/"), fc); // bookmark, keyword, and tag should all have been removed

  await check_no_orphans();
});

Messung V0.5
C=82 H=67 G=74

¤ Dauer der Verarbeitung: 0.8 Sekunden  ¤

*© 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.