mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-08 08:48:39 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
229
toolkit/components/places/tests/cpp/mock_Link.h
Normal file
229
toolkit/components/places/tests/cpp/mock_Link.h
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
/**
|
||||
* This is a mock Link object which can be used in tests.
|
||||
*/
|
||||
|
||||
#ifndef mock_Link_h__
|
||||
#define mock_Link_h__
|
||||
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/dom/Link.h"
|
||||
#include "mozilla/dom/URLSearchParams.h"
|
||||
|
||||
class mock_Link : public mozilla::dom::Link
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
explicit mock_Link(void (*aHandlerFunction)(nsLinkState),
|
||||
bool aRunNextTest = true)
|
||||
: mozilla::dom::Link(nullptr)
|
||||
, mHandler(aHandlerFunction)
|
||||
, mRunNextTest(aRunNextTest)
|
||||
{
|
||||
// Create a cyclic ownership, so that the link will be released only
|
||||
// after its status has been updated. This will ensure that, when it should
|
||||
// run the next test, it will happen at the end of the test function, if
|
||||
// the link status has already been set before. Indeed the link status is
|
||||
// updated on a separate connection, thus may happen at any time.
|
||||
mDeathGrip = this;
|
||||
}
|
||||
|
||||
virtual void SetLinkState(nsLinkState aState) override
|
||||
{
|
||||
// Notify our callback function.
|
||||
mHandler(aState);
|
||||
|
||||
// Break the cycle so the object can be destroyed.
|
||||
mDeathGrip = nullptr;
|
||||
}
|
||||
|
||||
virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override
|
||||
{
|
||||
return 0; // the value shouldn't matter
|
||||
}
|
||||
|
||||
protected:
|
||||
~mock_Link() {
|
||||
// Run the next test if we are supposed to.
|
||||
if (mRunNextTest) {
|
||||
run_next_test();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void (*mHandler)(nsLinkState);
|
||||
bool mRunNextTest;
|
||||
RefPtr<Link> mDeathGrip;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(
|
||||
mock_Link,
|
||||
mozilla::dom::Link
|
||||
)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Needed Link Methods
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
Link::Link(Element* aElement)
|
||||
: mElement(aElement)
|
||||
, mLinkState(eLinkState_NotLink)
|
||||
, mRegistered(false)
|
||||
{
|
||||
}
|
||||
|
||||
Link::~Link()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
Link::ElementHasHref() const
|
||||
{
|
||||
NS_NOTREACHED("Unexpected call to Link::ElementHasHref");
|
||||
return false; // suppress compiler warning
|
||||
}
|
||||
|
||||
void
|
||||
Link::SetLinkState(nsLinkState aState)
|
||||
{
|
||||
NS_NOTREACHED("Unexpected call to Link::SetLinkState");
|
||||
}
|
||||
|
||||
void
|
||||
Link::ResetLinkState(bool aNotify, bool aHasHref)
|
||||
{
|
||||
NS_NOTREACHED("Unexpected call to Link::ResetLinkState");
|
||||
}
|
||||
|
||||
nsIURI*
|
||||
Link::GetURI() const
|
||||
{
|
||||
NS_NOTREACHED("Unexpected call to Link::GetURI");
|
||||
return nullptr; // suppress compiler warning
|
||||
}
|
||||
|
||||
size_t
|
||||
Link::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
NS_NOTREACHED("Unexpected call to Link::SizeOfExcludingThis");
|
||||
return 0;
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(URLSearchParams)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(URLSearchParams)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(URLSearchParams)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(URLSearchParams)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(URLSearchParams)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(URLSearchParams)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(URLSearchParams)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
|
||||
URLSearchParams::URLSearchParams(nsISupports* aParent,
|
||||
URLSearchParamsObserver* aObserver)
|
||||
{
|
||||
}
|
||||
|
||||
URLSearchParams::~URLSearchParams()
|
||||
{
|
||||
}
|
||||
|
||||
JSObject*
|
||||
URLSearchParams::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
URLSearchParams::ParseInput(const nsACString& aInput)
|
||||
{
|
||||
NS_NOTREACHED("Unexpected call to URLSearchParams::ParseInput");
|
||||
}
|
||||
|
||||
void
|
||||
URLSearchParams::Serialize(nsAString& aValue) const
|
||||
{
|
||||
NS_NOTREACHED("Unexpected call to URLSearchParams::Serialize");
|
||||
}
|
||||
|
||||
void
|
||||
URLSearchParams::Get(const nsAString& aName, nsString& aRetval)
|
||||
{
|
||||
NS_NOTREACHED("Unexpected call to URLSearchParams::Get");
|
||||
}
|
||||
|
||||
void
|
||||
URLSearchParams::GetAll(const nsAString& aName, nsTArray<nsString >& aRetval)
|
||||
{
|
||||
NS_NOTREACHED("Unexpected call to URLSearchParams::GetAll");
|
||||
}
|
||||
|
||||
void
|
||||
URLSearchParams::Set(const nsAString& aName, const nsAString& aValue)
|
||||
{
|
||||
NS_NOTREACHED("Unexpected call to URLSearchParams::Set");
|
||||
}
|
||||
|
||||
void
|
||||
URLSearchParams::Append(const nsAString& aName, const nsAString& aValue)
|
||||
{
|
||||
NS_NOTREACHED("Unexpected call to URLSearchParams::Append");
|
||||
}
|
||||
|
||||
void
|
||||
URLSearchParams::AppendInternal(const nsAString& aName, const nsAString& aValue)
|
||||
{
|
||||
NS_NOTREACHED("Unexpected call to URLSearchParams::AppendInternal");
|
||||
}
|
||||
|
||||
bool
|
||||
URLSearchParams::Has(const nsAString& aName)
|
||||
{
|
||||
NS_NOTREACHED("Unexpected call to URLSearchParams::Has");
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
URLSearchParams::Delete(const nsAString& aName)
|
||||
{
|
||||
NS_NOTREACHED("Unexpected call to URLSearchParams::Delete");
|
||||
}
|
||||
|
||||
void
|
||||
URLSearchParams::DeleteAll()
|
||||
{
|
||||
NS_NOTREACHED("Unexpected call to URLSearchParams::DeleteAll");
|
||||
}
|
||||
|
||||
void
|
||||
URLSearchParams::NotifyObserver()
|
||||
{
|
||||
NS_NOTREACHED("Unexpected call to URLSearchParams::NotifyObserver");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
URLSearchParams::GetSendInfo(nsIInputStream** aBody, uint64_t* aContentLength,
|
||||
nsACString& aContentType, nsACString& aCharset)
|
||||
{
|
||||
NS_NOTREACHED("Unexpected call to URLSearchParams::GetSendInfo");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mock_Link_h__
|
||||
14
toolkit/components/places/tests/cpp/moz.build
Normal file
14
toolkit/components/places/tests/cpp/moz.build
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
GeckoCppUnitTests([
|
||||
'test_IHistory',
|
||||
])
|
||||
|
||||
if CONFIG['JS_SHARED_LIBRARY']:
|
||||
USE_LIBS += [
|
||||
'js',
|
||||
]
|
||||
413
toolkit/components/places/tests/cpp/places_test_harness.h
Normal file
413
toolkit/components/places/tests/cpp/places_test_harness.h
Normal file
|
|
@ -0,0 +1,413 @@
|
|||
/* -*- 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 "TestHarness.h"
|
||||
#include "nsMemory.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsDocShellCID.h"
|
||||
|
||||
#include "nsToolkitCompsCID.h"
|
||||
#include "nsINavHistoryService.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIURI.h"
|
||||
#include "mozilla/IHistory.h"
|
||||
#include "mozIStorageConnection.h"
|
||||
#include "mozIStorageStatement.h"
|
||||
#include "mozIStorageAsyncStatement.h"
|
||||
#include "mozIStorageStatementCallback.h"
|
||||
#include "mozIStoragePendingStatement.h"
|
||||
#include "nsPIPlacesDatabase.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "prinrval.h"
|
||||
#include "prtime.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
#define WAITFORTOPIC_TIMEOUT_SECONDS 5
|
||||
|
||||
|
||||
static size_t gTotalTests = 0;
|
||||
static size_t gPassedTests = 0;
|
||||
|
||||
#define do_check_true(aCondition) \
|
||||
PR_BEGIN_MACRO \
|
||||
gTotalTests++; \
|
||||
if (aCondition) { \
|
||||
gPassedTests++; \
|
||||
} else { \
|
||||
fail("%s | Expected true, got false at line %d", __FILE__, __LINE__); \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
#define do_check_false(aCondition) \
|
||||
PR_BEGIN_MACRO \
|
||||
gTotalTests++; \
|
||||
if (!aCondition) { \
|
||||
gPassedTests++; \
|
||||
} else { \
|
||||
fail("%s | Expected false, got true at line %d", __FILE__, __LINE__); \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
#define do_check_success(aResult) \
|
||||
do_check_true(NS_SUCCEEDED(aResult))
|
||||
|
||||
#ifdef LINUX
|
||||
// XXX Linux opt builds on tinderbox are orange due to linking with stdlib.
|
||||
// This is sad and annoying, but it's a workaround that works.
|
||||
#define do_check_eq(aExpected, aActual) \
|
||||
do_check_true(aExpected == aActual)
|
||||
#else
|
||||
#include <sstream>
|
||||
|
||||
#define do_check_eq(aActual, aExpected) \
|
||||
PR_BEGIN_MACRO \
|
||||
gTotalTests++; \
|
||||
if (aExpected == aActual) { \
|
||||
gPassedTests++; \
|
||||
} else { \
|
||||
std::ostringstream temp; \
|
||||
temp << __FILE__ << " | Expected '" << aExpected << "', got '"; \
|
||||
temp << aActual <<"' at line " << __LINE__; \
|
||||
fail(temp.str().c_str()); \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
#endif
|
||||
|
||||
struct Test
|
||||
{
|
||||
void (*func)(void);
|
||||
const char* const name;
|
||||
};
|
||||
#define TEST(aName) \
|
||||
{aName, #aName}
|
||||
|
||||
/**
|
||||
* Runs the next text.
|
||||
*/
|
||||
void run_next_test();
|
||||
|
||||
/**
|
||||
* To be used around asynchronous work.
|
||||
*/
|
||||
void do_test_pending();
|
||||
void do_test_finished();
|
||||
|
||||
/**
|
||||
* Spins current thread until a topic is received.
|
||||
*/
|
||||
class WaitForTopicSpinner final : public nsIObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
explicit WaitForTopicSpinner(const char* const aTopic)
|
||||
: mTopicReceived(false)
|
||||
, mStartTime(PR_IntervalNow())
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
|
||||
do_check_true(observerService);
|
||||
(void)observerService->AddObserver(this, aTopic, false);
|
||||
}
|
||||
|
||||
void Spin() {
|
||||
while (!mTopicReceived) {
|
||||
if ((PR_IntervalNow() - mStartTime) > (WAITFORTOPIC_TIMEOUT_SECONDS * PR_USEC_PER_SEC)) {
|
||||
// Timed out waiting for the topic.
|
||||
do_check_true(false);
|
||||
break;
|
||||
}
|
||||
(void)NS_ProcessNextEvent();
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHOD Observe(nsISupports* aSubject,
|
||||
const char* aTopic,
|
||||
const char16_t* aData) override
|
||||
{
|
||||
mTopicReceived = true;
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
|
||||
do_check_true(observerService);
|
||||
(void)observerService->RemoveObserver(this, aTopic);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
~WaitForTopicSpinner() {}
|
||||
|
||||
bool mTopicReceived;
|
||||
PRIntervalTime mStartTime;
|
||||
};
|
||||
NS_IMPL_ISUPPORTS(
|
||||
WaitForTopicSpinner,
|
||||
nsIObserver
|
||||
)
|
||||
|
||||
/**
|
||||
* Spins current thread until an async statement is executed.
|
||||
*/
|
||||
class AsyncStatementSpinner final : public mozIStorageStatementCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_MOZISTORAGESTATEMENTCALLBACK
|
||||
|
||||
AsyncStatementSpinner();
|
||||
void SpinUntilCompleted();
|
||||
uint16_t completionReason;
|
||||
|
||||
protected:
|
||||
~AsyncStatementSpinner() {}
|
||||
|
||||
volatile bool mCompleted;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(AsyncStatementSpinner,
|
||||
mozIStorageStatementCallback)
|
||||
|
||||
AsyncStatementSpinner::AsyncStatementSpinner()
|
||||
: completionReason(0)
|
||||
, mCompleted(false)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
AsyncStatementSpinner::HandleResult(mozIStorageResultSet *aResultSet)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
AsyncStatementSpinner::HandleError(mozIStorageError *aError)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
AsyncStatementSpinner::HandleCompletion(uint16_t aReason)
|
||||
{
|
||||
completionReason = aReason;
|
||||
mCompleted = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void AsyncStatementSpinner::SpinUntilCompleted()
|
||||
{
|
||||
nsCOMPtr<nsIThread> thread(::do_GetCurrentThread());
|
||||
nsresult rv = NS_OK;
|
||||
bool processed = true;
|
||||
while (!mCompleted && NS_SUCCEEDED(rv)) {
|
||||
rv = thread->ProcessNextEvent(true, &processed);
|
||||
}
|
||||
}
|
||||
|
||||
struct PlaceRecord
|
||||
{
|
||||
int64_t id;
|
||||
int32_t hidden;
|
||||
int32_t typed;
|
||||
int32_t visitCount;
|
||||
nsCString guid;
|
||||
};
|
||||
|
||||
struct VisitRecord
|
||||
{
|
||||
int64_t id;
|
||||
int64_t lastVisitId;
|
||||
int32_t transitionType;
|
||||
};
|
||||
|
||||
already_AddRefed<mozilla::IHistory>
|
||||
do_get_IHistory()
|
||||
{
|
||||
nsCOMPtr<mozilla::IHistory> history = do_GetService(NS_IHISTORY_CONTRACTID);
|
||||
do_check_true(history);
|
||||
return history.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<nsINavHistoryService>
|
||||
do_get_NavHistory()
|
||||
{
|
||||
nsCOMPtr<nsINavHistoryService> serv =
|
||||
do_GetService(NS_NAVHISTORYSERVICE_CONTRACTID);
|
||||
do_check_true(serv);
|
||||
return serv.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<mozIStorageConnection>
|
||||
do_get_db()
|
||||
{
|
||||
nsCOMPtr<nsINavHistoryService> history = do_get_NavHistory();
|
||||
nsCOMPtr<nsPIPlacesDatabase> database = do_QueryInterface(history);
|
||||
do_check_true(database);
|
||||
|
||||
nsCOMPtr<mozIStorageConnection> dbConn;
|
||||
nsresult rv = database->GetDBConnection(getter_AddRefs(dbConn));
|
||||
do_check_success(rv);
|
||||
return dbConn.forget();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the place record from the database.
|
||||
*
|
||||
* @param aURI The unique URI of the place we are looking up
|
||||
* @param result Out parameter where the result is stored
|
||||
*/
|
||||
void
|
||||
do_get_place(nsIURI* aURI, PlaceRecord& result)
|
||||
{
|
||||
nsCOMPtr<mozIStorageConnection> dbConn = do_get_db();
|
||||
nsCOMPtr<mozIStorageStatement> stmt;
|
||||
|
||||
nsCString spec;
|
||||
nsresult rv = aURI->GetSpec(spec);
|
||||
do_check_success(rv);
|
||||
|
||||
rv = dbConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"SELECT id, hidden, typed, visit_count, guid FROM moz_places "
|
||||
"WHERE url_hash = hash(?1) AND url = ?1"
|
||||
), getter_AddRefs(stmt));
|
||||
do_check_success(rv);
|
||||
|
||||
rv = stmt->BindUTF8StringByIndex(0, spec);
|
||||
do_check_success(rv);
|
||||
|
||||
bool hasResults;
|
||||
rv = stmt->ExecuteStep(&hasResults);
|
||||
do_check_success(rv);
|
||||
if (!hasResults) {
|
||||
result.id = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
rv = stmt->GetInt64(0, &result.id);
|
||||
do_check_success(rv);
|
||||
rv = stmt->GetInt32(1, &result.hidden);
|
||||
do_check_success(rv);
|
||||
rv = stmt->GetInt32(2, &result.typed);
|
||||
do_check_success(rv);
|
||||
rv = stmt->GetInt32(3, &result.visitCount);
|
||||
do_check_success(rv);
|
||||
rv = stmt->GetUTF8String(4, result.guid);
|
||||
do_check_success(rv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the most recent visit to a place.
|
||||
*
|
||||
* @param placeID ID from the moz_places table
|
||||
* @param result Out parameter where visit is stored
|
||||
*/
|
||||
void
|
||||
do_get_lastVisit(int64_t placeId, VisitRecord& result)
|
||||
{
|
||||
nsCOMPtr<mozIStorageConnection> dbConn = do_get_db();
|
||||
nsCOMPtr<mozIStorageStatement> stmt;
|
||||
|
||||
nsresult rv = dbConn->CreateStatement(NS_LITERAL_CSTRING(
|
||||
"SELECT id, from_visit, visit_type FROM moz_historyvisits "
|
||||
"WHERE place_id=?1 "
|
||||
"LIMIT 1"
|
||||
), getter_AddRefs(stmt));
|
||||
do_check_success(rv);
|
||||
|
||||
rv = stmt->BindInt64ByIndex(0, placeId);
|
||||
do_check_success(rv);
|
||||
|
||||
bool hasResults;
|
||||
rv = stmt->ExecuteStep(&hasResults);
|
||||
do_check_success(rv);
|
||||
|
||||
if (!hasResults) {
|
||||
result.id = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
rv = stmt->GetInt64(0, &result.id);
|
||||
do_check_success(rv);
|
||||
rv = stmt->GetInt64(1, &result.lastVisitId);
|
||||
do_check_success(rv);
|
||||
rv = stmt->GetInt32(2, &result.transitionType);
|
||||
do_check_success(rv);
|
||||
}
|
||||
|
||||
void
|
||||
do_wait_async_updates() {
|
||||
nsCOMPtr<mozIStorageConnection> db = do_get_db();
|
||||
nsCOMPtr<mozIStorageAsyncStatement> stmt;
|
||||
|
||||
db->CreateAsyncStatement(NS_LITERAL_CSTRING("BEGIN EXCLUSIVE"),
|
||||
getter_AddRefs(stmt));
|
||||
nsCOMPtr<mozIStoragePendingStatement> pending;
|
||||
(void)stmt->ExecuteAsync(nullptr, getter_AddRefs(pending));
|
||||
|
||||
db->CreateAsyncStatement(NS_LITERAL_CSTRING("COMMIT"),
|
||||
getter_AddRefs(stmt));
|
||||
RefPtr<AsyncStatementSpinner> spinner = new AsyncStatementSpinner();
|
||||
(void)stmt->ExecuteAsync(spinner, getter_AddRefs(pending));
|
||||
|
||||
spinner->SpinUntilCompleted();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a URI to the database.
|
||||
*
|
||||
* @param aURI
|
||||
* The URI to add to the database.
|
||||
*/
|
||||
void
|
||||
addURI(nsIURI* aURI)
|
||||
{
|
||||
nsCOMPtr<mozilla::IHistory> history = do_GetService(NS_IHISTORY_CONTRACTID);
|
||||
do_check_true(history);
|
||||
nsresult rv = history->VisitURI(aURI, nullptr, mozilla::IHistory::TOP_LEVEL);
|
||||
do_check_success(rv);
|
||||
|
||||
do_wait_async_updates();
|
||||
}
|
||||
|
||||
static const char TOPIC_PROFILE_CHANGE[] = "profile-before-change";
|
||||
static const char TOPIC_PLACES_CONNECTION_CLOSED[] = "places-connection-closed";
|
||||
|
||||
class WaitForConnectionClosed final : public nsIObserver
|
||||
{
|
||||
RefPtr<WaitForTopicSpinner> mSpinner;
|
||||
|
||||
~WaitForConnectionClosed() {}
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
WaitForConnectionClosed()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> os =
|
||||
do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(os);
|
||||
if (os) {
|
||||
MOZ_ALWAYS_SUCCEEDS(os->AddObserver(this, TOPIC_PROFILE_CHANGE, false));
|
||||
}
|
||||
mSpinner = new WaitForTopicSpinner(TOPIC_PLACES_CONNECTION_CLOSED);
|
||||
}
|
||||
|
||||
NS_IMETHOD Observe(nsISupports* aSubject,
|
||||
const char* aTopic,
|
||||
const char16_t* aData) override
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> os =
|
||||
do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(os);
|
||||
if (os) {
|
||||
MOZ_ALWAYS_SUCCEEDS(os->RemoveObserver(this, aTopic));
|
||||
}
|
||||
|
||||
mSpinner->Spin();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(WaitForConnectionClosed, nsIObserver)
|
||||
149
toolkit/components/places/tests/cpp/places_test_harness_tail.h
Normal file
149
toolkit/components/places/tests/cpp/places_test_harness_tail.h
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
/* -*- 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 "nsWidgetsCID.h"
|
||||
#include "nsIComponentRegistrar.h"
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
#include "nsICrashReporter.h"
|
||||
#endif
|
||||
|
||||
#ifndef TEST_NAME
|
||||
#error "Must #define TEST_NAME before including places_test_harness_tail.h"
|
||||
#endif
|
||||
|
||||
#ifndef TEST_FILE
|
||||
#error "Must #define TEST_FILE before include places_test_harness_tail.h"
|
||||
#endif
|
||||
|
||||
int gTestsIndex = 0;
|
||||
|
||||
#define TEST_INFO_STR "TEST-INFO | (%s) | "
|
||||
|
||||
class RunNextTest : public mozilla::Runnable
|
||||
{
|
||||
public:
|
||||
NS_IMETHOD Run() override
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Not running on the main thread?");
|
||||
if (gTestsIndex < int(mozilla::ArrayLength(gTests))) {
|
||||
do_test_pending();
|
||||
Test &test = gTests[gTestsIndex++];
|
||||
(void)fprintf(stderr, TEST_INFO_STR "Running %s.\n", TEST_FILE,
|
||||
test.name);
|
||||
test.func();
|
||||
}
|
||||
|
||||
do_test_finished();
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
run_next_test()
|
||||
{
|
||||
nsCOMPtr<nsIRunnable> event = new RunNextTest();
|
||||
do_check_success(NS_DispatchToCurrentThread(event));
|
||||
}
|
||||
|
||||
int gPendingTests = 0;
|
||||
|
||||
void
|
||||
do_test_pending()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Not running on the main thread?");
|
||||
gPendingTests++;
|
||||
}
|
||||
|
||||
void
|
||||
do_test_finished()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Not running on the main thread?");
|
||||
NS_ASSERTION(gPendingTests > 0, "Invalid pending test count!");
|
||||
gPendingTests--;
|
||||
}
|
||||
|
||||
void
|
||||
disable_idle_service()
|
||||
{
|
||||
(void)fprintf(stderr, TEST_INFO_STR "Disabling Idle Service.\n", TEST_FILE);
|
||||
static NS_DEFINE_IID(kIdleCID, NS_IDLE_SERVICE_CID);
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIFactory> idleFactory = do_GetClassObject(kIdleCID, &rv);
|
||||
do_check_success(rv);
|
||||
nsCOMPtr<nsIComponentRegistrar> registrar;
|
||||
rv = NS_GetComponentRegistrar(getter_AddRefs(registrar));
|
||||
do_check_success(rv);
|
||||
rv = registrar->UnregisterFactory(kIdleCID, idleFactory);
|
||||
do_check_success(rv);
|
||||
}
|
||||
|
||||
int
|
||||
main(int aArgc,
|
||||
char** aArgv)
|
||||
{
|
||||
ScopedXPCOM xpcom(TEST_NAME);
|
||||
if (xpcom.failed())
|
||||
return -1;
|
||||
// Initialize a profile folder to ensure a clean shutdown.
|
||||
nsCOMPtr<nsIFile> profile = xpcom.GetProfileDirectory();
|
||||
if (!profile) {
|
||||
fail("Couldn't get the profile directory.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
char* enabled = PR_GetEnv("MOZ_CRASHREPORTER");
|
||||
if (enabled && !strcmp(enabled, "1")) {
|
||||
// bug 787458: move this to an even-more-common location to use in all
|
||||
// C++ unittests
|
||||
nsCOMPtr<nsICrashReporter> crashreporter =
|
||||
do_GetService("@mozilla.org/toolkit/crash-reporter;1");
|
||||
if (crashreporter) {
|
||||
fprintf(stderr, "Setting up crash reporting\n");
|
||||
|
||||
nsCOMPtr<nsIProperties> dirsvc =
|
||||
do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
|
||||
if (!dirsvc)
|
||||
NS_RUNTIMEABORT("Couldn't get directory service");
|
||||
nsCOMPtr<nsIFile> cwd;
|
||||
nsresult rv = dirsvc->Get(NS_OS_CURRENT_WORKING_DIR,
|
||||
NS_GET_IID(nsIFile),
|
||||
getter_AddRefs(cwd));
|
||||
if (NS_FAILED(rv))
|
||||
NS_RUNTIMEABORT("Couldn't get CWD");
|
||||
crashreporter->SetEnabled(true);
|
||||
crashreporter->SetMinidumpPath(cwd);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
RefPtr<WaitForConnectionClosed> spinClose = new WaitForConnectionClosed();
|
||||
|
||||
// Tinderboxes are constantly on idle. Since idle tasks can interact with
|
||||
// tests, causing random failures, disable the idle service.
|
||||
disable_idle_service();
|
||||
|
||||
do_test_pending();
|
||||
run_next_test();
|
||||
|
||||
// Spin the event loop until we've run out of tests to run.
|
||||
while (gPendingTests) {
|
||||
(void)NS_ProcessNextEvent();
|
||||
}
|
||||
|
||||
// And let any other events finish before we quit.
|
||||
(void)NS_ProcessPendingEvents(nullptr);
|
||||
|
||||
// Check that we have passed all of our tests, and output accordingly.
|
||||
if (gPassedTests == gTotalTests) {
|
||||
passed(TEST_FILE);
|
||||
}
|
||||
|
||||
(void)fprintf(stderr, TEST_INFO_STR "%u of %u tests passed\n",
|
||||
TEST_FILE, unsigned(gPassedTests), unsigned(gTotalTests));
|
||||
|
||||
return gPassedTests == gTotalTests ? 0 : -1;
|
||||
}
|
||||
639
toolkit/components/places/tests/cpp/test_IHistory.cpp
Normal file
639
toolkit/components/places/tests/cpp/test_IHistory.cpp
Normal file
|
|
@ -0,0 +1,639 @@
|
|||
/* -*- 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 "nsIPrefService.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "mozilla/Attributes.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(nsLinkState aState)
|
||||
{
|
||||
do_check_true(aState == eLinkState_Visited);
|
||||
}
|
||||
|
||||
void
|
||||
expect_no_visit(nsLinkState aState)
|
||||
{
|
||||
do_check_true(aState == eLinkState_Unvisited);
|
||||
}
|
||||
|
||||
already_AddRefed<nsIURI>
|
||||
new_test_uri()
|
||||
{
|
||||
// Create a unique spec.
|
||||
static int32_t specNumber = 0;
|
||||
nsAutoCString spec = NS_LITERAL_CSTRING("http://mozilla.org/");
|
||||
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() {}
|
||||
|
||||
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()
|
||||
{
|
||||
while (mVisits < mExpectedVisits) {
|
||||
(void)NS_ProcessNextEvent();
|
||||
}
|
||||
}
|
||||
|
||||
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(NS_LITERAL_CSTRING("SELECT 1"),
|
||||
getter_AddRefs(stmt));
|
||||
RefPtr<AsyncStatementSpinner> spinner = new AsyncStatementSpinner();
|
||||
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 {
|
||||
nsCOMPtr<nsIURI> testURI;
|
||||
RefPtr<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();
|
||||
nsresult rv = history->RegisterVisitedCallback(testURI, testLink);
|
||||
do_check_success(rv);
|
||||
|
||||
// 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();
|
||||
nsresult rv = history->RegisterVisitedCallback(testURI, link);
|
||||
do_check_success(rv);
|
||||
|
||||
// Note: test will continue upon notification.
|
||||
}
|
||||
|
||||
void
|
||||
test_unvisited_does_not_notify_part2()
|
||||
{
|
||||
using namespace test_unvisited_does_not_notify;
|
||||
|
||||
// We would have had a failure at this point had the content node been told it
|
||||
// was visited. Therefore, it is safe to unregister our content node.
|
||||
nsCOMPtr<IHistory> history = do_get_IHistory();
|
||||
nsresult rv = history->UnregisterVisitedCallback(testURI, testLink);
|
||||
do_check_success(rv);
|
||||
|
||||
// Clear the stored variables now.
|
||||
testURI = nullptr;
|
||||
testLink = nullptr;
|
||||
|
||||
// Run the next test.
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
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();
|
||||
nsresult rv = history->RegisterVisitedCallback(testURI, link1);
|
||||
do_check_success(rv);
|
||||
rv = history->RegisterVisitedCallback(testURI, link2);
|
||||
do_check_success(rv);
|
||||
|
||||
// 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);
|
||||
|
||||
// Now, register our Link to be notified.
|
||||
nsCOMPtr<IHistory> history(do_get_IHistory());
|
||||
nsresult rv = history->RegisterVisitedCallback(testURI, link);
|
||||
do_check_success(rv);
|
||||
|
||||
// Unregister the Link.
|
||||
rv = history->UnregisterVisitedCallback(testURI, link);
|
||||
do_check_success(rv);
|
||||
|
||||
// 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.
|
||||
RefPtr<Link> link = new mock_Link(expect_visit);
|
||||
|
||||
// Now, register our content node to be notified.
|
||||
nsCOMPtr<nsIURI> testURI = new_test_uri();
|
||||
nsCOMPtr<IHistory> history = do_get_IHistory();
|
||||
nsresult rv = history->RegisterVisitedCallback(testURI, link);
|
||||
do_check_success(rv);
|
||||
|
||||
// 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);
|
||||
|
||||
// Now, register our content node to be notified. It should not be notified.
|
||||
nsCOMPtr<IHistory> history = do_get_IHistory();
|
||||
nsresult rv = history->RegisterVisitedCallback(testURI, link);
|
||||
do_check_success(rv);
|
||||
|
||||
// Remove ourselves as an observer. We would have failed if we had been
|
||||
// notified.
|
||||
rv = history->UnregisterVisitedCallback(testURI, link);
|
||||
do_check_success(rv);
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
namespace test_observer_topic_dispatched_helpers {
|
||||
#define URI_VISITED "visited"
|
||||
#define URI_NOT_VISITED "not visited"
|
||||
#define URI_VISITED_RESOLUTION_TOPIC "visited-status-resolution"
|
||||
class statusObserver final : public nsIObserver
|
||||
{
|
||||
~statusObserver() {}
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
statusObserver(nsIURI* aURI,
|
||||
const bool aExpectVisit,
|
||||
bool& _notified)
|
||||
: mURI(aURI)
|
||||
, mExpectVisit(aExpectVisit)
|
||||
, mNotified(_notified)
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
|
||||
do_check_true(observerService);
|
||||
(void)observerService->AddObserver(this,
|
||||
URI_VISITED_RESOLUTION_TOPIC,
|
||||
false);
|
||||
}
|
||||
|
||||
NS_IMETHOD Observe(nsISupports* aSubject,
|
||||
const char* aTopic,
|
||||
const char16_t* aData) override
|
||||
{
|
||||
// Make sure we got notified of the right topic.
|
||||
do_check_false(strcmp(aTopic, URI_VISITED_RESOLUTION_TOPIC));
|
||||
|
||||
// If this isn't for our URI, do not do anything.
|
||||
nsCOMPtr<nsIURI> notifiedURI = do_QueryInterface(aSubject);
|
||||
do_check_true(notifiedURI);
|
||||
|
||||
bool isOurURI;
|
||||
nsresult rv = notifiedURI->Equals(mURI, &isOurURI);
|
||||
do_check_success(rv);
|
||||
if (!isOurURI) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Check that we have either the visited or not visited string.
|
||||
bool visited = !!NS_LITERAL_STRING(URI_VISITED).Equals(aData);
|
||||
bool notVisited = !!NS_LITERAL_STRING(URI_NOT_VISITED).Equals(aData);
|
||||
do_check_true(visited || notVisited);
|
||||
|
||||
// Check to make sure we got the state we expected.
|
||||
do_check_eq(visited, mExpectVisit);
|
||||
|
||||
// Indicate that we've been notified.
|
||||
mNotified = true;
|
||||
|
||||
// Remove ourselves as an observer.
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
|
||||
(void)observerService->RemoveObserver(this,
|
||||
URI_VISITED_RESOLUTION_TOPIC);
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
const bool mExpectVisit;
|
||||
bool& mNotified;
|
||||
};
|
||||
NS_IMPL_ISUPPORTS(
|
||||
statusObserver,
|
||||
nsIObserver
|
||||
)
|
||||
} // namespace test_observer_topic_dispatched_helpers
|
||||
void
|
||||
test_observer_topic_dispatched()
|
||||
{
|
||||
using namespace test_observer_topic_dispatched_helpers;
|
||||
|
||||
// Create two URIs, making sure only one is in history.
|
||||
nsCOMPtr<nsIURI> visitedURI = new_test_uri();
|
||||
nsCOMPtr<nsIURI> notVisitedURI = new_test_uri();
|
||||
bool urisEqual;
|
||||
nsresult rv = visitedURI->Equals(notVisitedURI, &urisEqual);
|
||||
do_check_success(rv);
|
||||
do_check_false(urisEqual);
|
||||
addURI(visitedURI);
|
||||
|
||||
// Need two Link objects as well - one for each URI.
|
||||
RefPtr<Link> visitedLink = new mock_Link(expect_visit, false);
|
||||
RefPtr<Link> visitedLinkCopy = visitedLink;
|
||||
RefPtr<Link> notVisitedLink = new mock_Link(expect_no_visit);
|
||||
|
||||
// Add the right observers for the URIs to check results.
|
||||
bool visitedNotified = false;
|
||||
nsCOMPtr<nsIObserver> visitedObs =
|
||||
new statusObserver(visitedURI, true, visitedNotified);
|
||||
bool notVisitedNotified = false;
|
||||
nsCOMPtr<nsIObserver> unvisitedObs =
|
||||
new statusObserver(notVisitedURI, false, notVisitedNotified);
|
||||
|
||||
// Register our Links to be notified.
|
||||
nsCOMPtr<IHistory> history = do_get_IHistory();
|
||||
rv = history->RegisterVisitedCallback(visitedURI, visitedLink);
|
||||
do_check_success(rv);
|
||||
rv = history->RegisterVisitedCallback(notVisitedURI, notVisitedLink);
|
||||
do_check_success(rv);
|
||||
|
||||
// Spin the event loop as long as we have not been properly notified.
|
||||
while (!visitedNotified || !notVisitedNotified) {
|
||||
(void)NS_ProcessNextEvent();
|
||||
}
|
||||
|
||||
// Unregister our observer that would not have been released.
|
||||
rv = history->UnregisterVisitedCallback(notVisitedURI, notVisitedLink);
|
||||
do_check_success(rv);
|
||||
|
||||
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(visitedURI, lastURI, mozilla::IHistory::TOP_LEVEL);
|
||||
|
||||
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(visitedURI, lastURI, mozilla::IHistory::TOP_LEVEL);
|
||||
finisher = new VisitURIObserver();
|
||||
finisher->WaitForNotification();
|
||||
|
||||
history->VisitURI(visitedURI, lastURI, mozilla::IHistory::TOP_LEVEL);
|
||||
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(visitedURI, lastURI, mozilla::IHistory::TOP_LEVEL);
|
||||
// this simulates the uri visit happening in a frame. Normally frame
|
||||
// transitions would be hidden unless it was previously loaded top-level
|
||||
history->VisitURI(visitedURI, lastURI, 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(visitedURI, lastURI, mozilla::IHistory::TOP_LEVEL);
|
||||
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_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(visitedURI, lastURI, mozilla::IHistory::TOP_LEVEL);
|
||||
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(visitedURI, lastURI, 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(visitedURI, nullptr,
|
||||
mozilla::IHistory::TOP_LEVEL);
|
||||
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(), 12);
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// IPC-only Tests
|
||||
|
||||
void
|
||||
test_two_null_links_same_uri()
|
||||
{
|
||||
// Tests that we do not crash when we have had two nullptr Links passed to
|
||||
// RegisterVisitedCallback and then the visit occurs (bug 607469). This only
|
||||
// happens in IPC builds.
|
||||
nsCOMPtr<nsIURI> testURI = new_test_uri();
|
||||
|
||||
nsCOMPtr<IHistory> history = do_get_IHistory();
|
||||
nsresult rv = history->RegisterVisitedCallback(testURI, nullptr);
|
||||
do_check_success(rv);
|
||||
rv = history->RegisterVisitedCallback(testURI, nullptr);
|
||||
do_check_success(rv);
|
||||
|
||||
rv = history->VisitURI(testURI, nullptr, mozilla::IHistory::TOP_LEVEL);
|
||||
do_check_success(rv);
|
||||
|
||||
RefPtr<VisitURIObserver> finisher = new VisitURIObserver();
|
||||
finisher->WaitForNotification();
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Test Harness
|
||||
|
||||
/**
|
||||
* Note: for tests marked "Order Important!", please see the test for details.
|
||||
*/
|
||||
Test gTests[] = {
|
||||
TEST(test_set_places_enabled), // Must come first!
|
||||
TEST(test_wait_checkpoint), // Must come second!
|
||||
TEST(test_unvisited_does_not_notify_part1), // Order Important!
|
||||
TEST(test_visited_notifies),
|
||||
TEST(test_unvisited_does_not_notify_part2), // Order Important!
|
||||
TEST(test_same_uri_notifies_both),
|
||||
TEST(test_unregistered_visited_does_not_notify), // Order Important!
|
||||
TEST(test_new_visit_notifies_waiting_Link),
|
||||
TEST(test_RegisterVisitedCallback_returns_before_notifying),
|
||||
TEST(test_observer_topic_dispatched),
|
||||
TEST(test_visituri_inserts),
|
||||
TEST(test_visituri_updates),
|
||||
TEST(test_visituri_preserves_shown_and_typed),
|
||||
TEST(test_visituri_creates_visit),
|
||||
TEST(test_visituri_transition_typed),
|
||||
TEST(test_visituri_transition_embed),
|
||||
TEST(test_new_visit_adds_place_guid),
|
||||
|
||||
// The rest of these tests are tests that are only run in IPC builds.
|
||||
TEST(test_two_null_links_same_uri),
|
||||
};
|
||||
|
||||
const char* file = __FILE__;
|
||||
#define TEST_NAME "IHistory"
|
||||
#define TEST_FILE file
|
||||
#include "places_test_harness_tail.h"
|
||||
Loading…
Add table
Add a link
Reference in a new issue