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

Quelle  test_IHistory.cpp   Sprache: C

 
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
 * 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/. */


#include "places_test_harness.h"
#include "nsIPrefBranch.h"
#include "nsIPrefService.h"
#include "nsString.h"
#include "mozilla/Attributes.h"
#include "mozilla/SpinEventLoopUntil.h"
#include "mozilla/StaticPrefs_layout.h"
#include "nsNetUtil.h"

#include "mock_Link.h"
using namespace mozilla;
using namespace mozilla::dom;

/**
 * This file tests the IHistory interface.
 */


////////////////////////////////////////////////////////////////////////////////
//// Helper Methods

void expect_visit(Link::State aState) {
  do_check_true(aState == Link::State::Visited);
}

void expect_no_visit(Link::State aState) {
  do_check_true(aState == Link::State::Unvisited);
}

already_AddRefed<nsIURI> new_test_uri() {
  // Create a unique spec.
  static int32_t specNumber = 0;
  nsCString spec = "http://mozilla.org/"_ns;
  spec.AppendInt(specNumber++);

  // Create the URI for the spec.
  nsCOMPtr<nsIURI> testURI;
  nsresult rv = NS_NewURI(getter_AddRefs(testURI), spec);
  do_check_success(rv);
  return testURI.forget();
}

class VisitURIObserver final : public nsIObserver {
  ~VisitURIObserver() = default;

 public:
  NS_DECL_ISUPPORTS

  explicit VisitURIObserver(int aExpectedVisits = 1)
      : mVisits(0), mExpectedVisits(aExpectedVisits) {
    nsCOMPtr<nsIObserverService> observerService =
        do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
    do_check_true(observerService);
    (void)observerService->AddObserver(this"uri-visit-saved"false);
  }

  void WaitForNotification() {
    SpinEventLoopUntil("places:VisitURIObserver::WaitForNotification"_ns,
                       [&]() { return mVisits >= mExpectedVisits; });
  }

  NS_IMETHOD Observe(nsISupports* aSubject, const char* aTopic,
                     const char16_t* aData) override {
    mVisits++;

    if (mVisits == mExpectedVisits) {
      nsCOMPtr<nsIObserverService> observerService =
          do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
      (void)observerService->RemoveObserver(this"uri-visit-saved");
    }

    return NS_OK;
  }

 private:
  int mVisits;
  int mExpectedVisits;
};
NS_IMPL_ISUPPORTS(VisitURIObserver, nsIObserver)

////////////////////////////////////////////////////////////////////////////////
//// Test Functions

void test_set_places_enabled() {
  // Ensure places is enabled for everyone.
  nsresult rv;
  nsCOMPtr<nsIPrefBranch> prefBranch =
      do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
  do_check_success(rv);

  rv = prefBranch->SetBoolPref("places.history.enabled"true);
  do_check_success(rv);

  // Run the next test.
  run_next_test();
}

void test_wait_checkpoint() {
  // This "fake" test is here to wait for the initial WAL checkpoint we force
  // after creating the database schema, since that may happen at any time,
  // and cause concurrent readers to access an older checkpoint.
  nsCOMPtr<mozIStorageConnection> db = do_get_db();
  nsCOMPtr<mozIStorageAsyncStatement> stmt;
  db->CreateAsyncStatement("SELECT 1"_ns, getter_AddRefs(stmt));
  RefPtr<PlacesAsyncStatementSpinner> spinner =
      new PlacesAsyncStatementSpinner();
  nsCOMPtr<mozIStoragePendingStatement> pending;
  (void)stmt->ExecuteAsync(spinner, getter_AddRefs(pending));
  spinner->SpinUntilCompleted();

  // Run the next test.
  run_next_test();
}

// These variables are shared between part 1 and part 2 of the test.  Part 2
// sets the nsCOMPtr's to nullptr, freeing the reference.
namespace test_unvisited_does_not_notify {
MOZ_RUNINIT nsCOMPtr<nsIURI> testURI;
MOZ_RUNINIT RefPtr<mock_Link> testLink;
}  // namespace test_unvisited_does_not_notify
void test_unvisited_does_not_notify_part1() {
  using namespace test_unvisited_does_not_notify;

  // This test is done in two parts.  The first part registers for a URI that
  // should not be visited.  We then run another test that will also do a
  // lookup and will be notified.  Since requests are answered in the order they
  // are requested (at least as long as the same URI isn't asked for later), we
  // will know that the Link was not notified.

  // First, we need a test URI.
  testURI = new_test_uri();

  // Create our test Link.
  testLink = new mock_Link(expect_no_visit);

  // Now, register our Link to be notified.
  nsCOMPtr<IHistory> history = do_get_IHistory();
  history->RegisterVisitedCallback(testURI, testLink);

  // Run the next test.
  run_next_test();
}

void test_visited_notifies() {
  // First, we add our test URI to history.
  nsCOMPtr<nsIURI> testURI = new_test_uri();
  addURI(testURI);

  // Create our test Link.  The callback function will release the reference we
  // have on the Link.
  RefPtr<Link> link = new mock_Link(expect_visit);

  // Now, register our Link to be notified.
  nsCOMPtr<IHistory> history = do_get_IHistory();
  history->RegisterVisitedCallback(testURI, link);

  // Note: test will continue upon notification.
}

void test_unvisited_does_not_notify_part2() {
  using namespace test_unvisited_does_not_notify;

  SpinEventLoopUntil("places:test_unvisited_does_not_notify_part2"_ns,
                     [&]() { return testLink->GotNotified(); });

  // We would have had a failure at this point had the content node been told it
  // was visited. Therefore, now we change it so that it expects a visited
  // notification, and unregisters itself after addURI.
  testLink->AwaitNewNotification(expect_visit);
  addURI(testURI);

  // Clear the stored variables now.
  testURI = nullptr;
  testLink = nullptr;
}

void test_same_uri_notifies_both() {
  // First, we add our test URI to history.
  nsCOMPtr<nsIURI> testURI = new_test_uri();
  addURI(testURI);

  // Create our two test Links.  The callback function will release the
  // reference we have on the Links.  Only the second Link should run the next
  // test!
  RefPtr<Link> link1 = new mock_Link(expect_visit, false);
  RefPtr<Link> link2 = new mock_Link(expect_visit);

  // Now, register our Link to be notified.
  nsCOMPtr<IHistory> history = do_get_IHistory();
  history->RegisterVisitedCallback(testURI, link1);
  history->RegisterVisitedCallback(testURI, link2);

  // Note: test will continue upon notification.
}

void test_unregistered_visited_does_not_notify() {
  // This test must have a test that has a successful notification after it.
  // The Link would have been notified by now if we were buggy and notified
  // unregistered Links (due to request serialization).

  nsCOMPtr<nsIURI> testURI = new_test_uri();
  RefPtr<Link> link = new mock_Link(expect_no_visit, false);
  nsCOMPtr<IHistory> history(do_get_IHistory());
  history->RegisterVisitedCallback(testURI, link);

  // Unregister the Link.
  history->UnregisterVisitedCallback(testURI, link);

  // And finally add a visit for the URI.
  addURI(testURI);

  // If history tries to notify us, we'll either crash because the Link will
  // have been deleted (we are the only thing holding a reference to it), or our
  // expect_no_visit call back will produce a failure.  Either way, the test
  // will be reported as a failure.

  // Run the next test.
  run_next_test();
}

void test_new_visit_notifies_waiting_Link() {
  // Create our test Link.  The callback function will release the reference we
  // have on the link.
  //
  // Note that this will query the database and we'll get an _unvisited_
  // notification, then (after we addURI) a _visited_ one.
  RefPtr<mock_Link> link = new mock_Link(expect_no_visit);

  // Now, register our content node to be notified.
  nsCOMPtr<nsIURI> testURI = new_test_uri();
  nsCOMPtr<IHistory> history = do_get_IHistory();
  history->RegisterVisitedCallback(testURI, link);

  SpinEventLoopUntil("places:test_new_visit_notifies_waiting_Link"_ns,
                     [&]() { return link->GotNotified(); });

  link->AwaitNewNotification(expect_visit);

  // Add ourselves to history.
  addURI(testURI);

  // Note: test will continue upon notification.
}

void test_RegisterVisitedCallback_returns_before_notifying() {
  // Add a URI so that it's already in history.
  nsCOMPtr<nsIURI> testURI = new_test_uri();
  addURI(testURI);

  // Create our test Link.
  RefPtr<Link> link = new mock_Link(expect_no_visit, false);

  // Now, register our content node to be notified.  It should not be notified.
  nsCOMPtr<IHistory> history = do_get_IHistory();
  history->RegisterVisitedCallback(testURI, link);

  // Remove ourselves as an observer.  We would have failed if we had been
  // notified.
  history->UnregisterVisitedCallback(testURI, link);

  run_next_test();
}

void test_visituri_inserts() {
  nsCOMPtr<IHistory> history = do_get_IHistory();
  nsCOMPtr<nsIURI> lastURI = new_test_uri();
  nsCOMPtr<nsIURI> visitedURI = new_test_uri();

  history->VisitURI(nullptr, visitedURI, lastURI, mozilla::IHistory::TOP_LEVEL,
                    0);

  RefPtr<VisitURIObserver> finisher = new VisitURIObserver();
  finisher->WaitForNotification();

  PlaceRecord place;
  do_get_place(visitedURI, place);

  do_check_true(place.id > 0);
  do_check_false(place.hidden);
  do_check_false(place.typed);
  do_check_eq(place.visitCount, 1);

  run_next_test();
}

void test_visituri_updates() {
  nsCOMPtr<IHistory> history = do_get_IHistory();
  nsCOMPtr<nsIURI> lastURI = new_test_uri();
  nsCOMPtr<nsIURI> visitedURI = new_test_uri();
  RefPtr<VisitURIObserver> finisher;

  history->VisitURI(nullptr, visitedURI, lastURI, mozilla::IHistory::TOP_LEVEL,
                    0);
  finisher = new VisitURIObserver();
  finisher->WaitForNotification();

  history->VisitURI(nullptr, visitedURI, lastURI, mozilla::IHistory::TOP_LEVEL,
                    0);
  finisher = new VisitURIObserver();
  finisher->WaitForNotification();

  PlaceRecord place;
  do_get_place(visitedURI, place);

  do_check_eq(place.visitCount, 2);

  run_next_test();
}

void test_visituri_preserves_shown_and_typed() {
  nsCOMPtr<IHistory> history = do_get_IHistory();
  nsCOMPtr<nsIURI> lastURI = new_test_uri();
  nsCOMPtr<nsIURI> visitedURI = new_test_uri();

  history->VisitURI(nullptr, visitedURI, lastURI, mozilla::IHistory::TOP_LEVEL,
                    0);
  // this simulates the uri visit happening in a frame.  Normally frame
  // transitions would be hidden unless it was previously loaded top-level
  history->VisitURI(nullptr, visitedURI, lastURI, 0, 0);

  RefPtr<VisitURIObserver> finisher = new VisitURIObserver(2);
  finisher->WaitForNotification();

  PlaceRecord place;
  do_get_place(visitedURI, place);
  do_check_false(place.hidden);

  run_next_test();
}

void test_visituri_creates_visit() {
  nsCOMPtr<IHistory> history = do_get_IHistory();
  nsCOMPtr<nsIURI> lastURI = new_test_uri();
  nsCOMPtr<nsIURI> visitedURI = new_test_uri();

  history->VisitURI(nullptr, visitedURI, lastURI, mozilla::IHistory::TOP_LEVEL,
                    0);
  RefPtr<VisitURIObserver> finisher = new VisitURIObserver();
  finisher->WaitForNotification();

  PlaceRecord place;
  VisitRecord visit;
  do_get_place(visitedURI, place);
  do_get_lastVisit(place.id, visit);

  do_check_true(visit.id > 0);
  do_check_eq(visit.lastVisitId, 0);
  do_check_eq(visit.transitionType, nsINavHistoryService::TRANSITION_LINK);

  run_next_test();
}

void test_visituri_frecency() {
  // Adding a visit calculates frecency immediately.
  nsCOMPtr<IHistory> history = do_get_IHistory();
  nsCOMPtr<nsIURI> visitedURI = new_test_uri();
  RefPtr<WaitForNotificationSpinner> spinner =
      new WaitForNotificationSpinner(PlacesEventType::Pages_rank_changed);
  history->VisitURI(nullptr, visitedURI, nullptr, mozilla::IHistory::TOP_LEVEL,
                    0);
  RefPtr<VisitURIObserver> finisher = new VisitURIObserver();
  finisher->WaitForNotification();
  spinner->SpinUntilCompleted();
  PlaceRecord place;
  do_get_place(visitedURI, place);
  do_check_true(place.frecency > 0);
  run_next_test();
}

void test_visituri_hidden() {
  nsCOMPtr<IHistory> history = do_get_IHistory();
  {
    // Insert a framed link visit.
    nsCOMPtr<nsIURI> visitedURI = new_test_uri();
    nsCOMPtr<nsINavHistoryService> navHistory = do_get_NavHistory();
    navHistory->MarkPageAsFollowedLink(visitedURI);
    history->VisitURI(nullptr, visitedURI, nullptr, 0, 0);
    RefPtr<VisitURIObserver> finisher = new VisitURIObserver();
    finisher->WaitForNotification();
    PlaceRecord place;
    do_get_place(visitedURI, place);
    do_check_true(place.hidden);
  }

  // Insert a redirect.
  nsCOMPtr<nsIURI> visitedURI = new_test_uri();
  history->VisitURI(nullptr, visitedURI, nullptr,
                    mozilla::IHistory::TOP_LEVEL | IHistory::REDIRECT_SOURCE,
                    0);
  {
    RefPtr<VisitURIObserver> finisher = new VisitURIObserver();
    finisher->WaitForNotification();
    PlaceRecord place;
    do_get_place(visitedURI, place);
    do_check_true(place.hidden);
  }

  // Now add a non-hidden visit to the hidden page, check it gets unhidden.
  history->VisitURI(nullptr, visitedURI, nullptr, mozilla::IHistory::TOP_LEVEL,
                    0);
  {
    RefPtr<VisitURIObserver> finisher = new VisitURIObserver();
    finisher->WaitForNotification();
    PlaceRecord place;
    do_get_place(visitedURI, place);
    do_check_false(place.hidden);
  }

  // Add another hidden visit, it should stay unhidden.
  history->VisitURI(nullptr, visitedURI, nullptr,
                    mozilla::IHistory::TOP_LEVEL | IHistory::REDIRECT_SOURCE,
                    0);
  {
    RefPtr<VisitURIObserver> finisher = new VisitURIObserver();
    finisher->WaitForNotification();
    PlaceRecord place;
    do_get_place(visitedURI, place);
    do_check_false(place.hidden);
  }

  run_next_test();
}

void test_visituri_transition_typed() {
  nsCOMPtr<nsINavHistoryService> navHistory = do_get_NavHistory();
  nsCOMPtr<IHistory> history = do_get_IHistory();
  nsCOMPtr<nsIURI> lastURI = new_test_uri();
  nsCOMPtr<nsIURI> visitedURI = new_test_uri();

  navHistory->MarkPageAsTyped(visitedURI);
  history->VisitURI(nullptr, visitedURI, lastURI, mozilla::IHistory::TOP_LEVEL,
                    0);
  RefPtr<VisitURIObserver> finisher = new VisitURIObserver();
  finisher->WaitForNotification();

  PlaceRecord place;
  VisitRecord visit;
  do_get_place(visitedURI, place);
  do_get_lastVisit(place.id, visit);

  do_check_true(visit.transitionType == nsINavHistoryService::TRANSITION_TYPED);

  run_next_test();
}

void test_visituri_transition_embed() {
  nsCOMPtr<IHistory> history = do_get_IHistory();
  nsCOMPtr<nsIURI> lastURI = new_test_uri();
  nsCOMPtr<nsIURI> visitedURI = new_test_uri();

  history->VisitURI(nullptr, visitedURI, lastURI, 0, 0);
  RefPtr<VisitURIObserver> finisher = new VisitURIObserver();
  finisher->WaitForNotification();

  PlaceRecord place;
  VisitRecord visit;
  do_get_place(visitedURI, place);
  do_get_lastVisit(place.id, visit);

  do_check_eq(place.id, 0);
  do_check_eq(visit.id, 0);

  run_next_test();
}

void test_new_visit_adds_place_guid() {
  // First, add a visit and wait.  This will also add a place.
  nsCOMPtr<nsIURI> visitedURI = new_test_uri();
  nsCOMPtr<IHistory> history = do_get_IHistory();
  nsresult rv = history->VisitURI(nullptr, visitedURI, nullptr,
                                  mozilla::IHistory::TOP_LEVEL, 0);
  do_check_success(rv);
  RefPtr<VisitURIObserver> finisher = new VisitURIObserver();
  finisher->WaitForNotification();

  // Check that we have a guid for our visit.
  PlaceRecord place;
  do_get_place(visitedURI, place);
  do_check_eq(place.visitCount, 1);
  do_check_eq(place.guid.Length(), 12u);

  run_next_test();
}

////////////////////////////////////////////////////////////////////////////////
//// Test Harness

/**
 * Note: for tests marked "Order Important!", please see the test for details.
 */

Test gTests[] = {
    PTEST(test_set_places_enabled),               // Must come first!
    PTEST(test_wait_checkpoint),                  // Must come second!
    PTEST(test_unvisited_does_not_notify_part1),  // Order Important!
    PTEST(test_visited_notifies),
    PTEST(test_unvisited_does_not_notify_part2),  // Order Important!
    PTEST(test_same_uri_notifies_both),
    PTEST(test_unregistered_visited_does_not_notify),  // Order Important!
    PTEST(test_new_visit_adds_place_guid),
    PTEST(test_new_visit_notifies_waiting_Link),
    PTEST(test_RegisterVisitedCallback_returns_before_notifying),
    PTEST(test_visituri_inserts),
    PTEST(test_visituri_updates),
    PTEST(test_visituri_preserves_shown_and_typed),
    PTEST(test_visituri_creates_visit),
    PTEST(test_visituri_frecency),
    PTEST(test_visituri_hidden),
    PTEST(test_visituri_transition_typed),
    PTEST(test_visituri_transition_embed),

};

#define TEST_NAME "IHistory"
#include "places_test_harness_tail.h"

Messung V0.5
C=88 H=100 G=94

¤ Dauer der Verarbeitung: 0.11 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.