diff -r 000000000000 -r 6474c204b198 toolkit/components/social/test/xpcshell/head.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toolkit/components/social/test/xpcshell/head.js Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,226 @@ +/* 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/. */ + +const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; +Cu.import("resource://gre/modules/Services.jsm"); +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); + +XPCOMUtils.defineLazyModuleGetter(this, "Promise", + "resource://gre/modules/Promise.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils", + "resource://gre/modules/PlacesUtils.jsm"); + +const MANIFEST_PREFS = Services.prefs.getBranch("social.manifest."); +const gProfD = do_get_profile(); + +const XULAPPINFO_CONTRACTID = "@mozilla.org/xre/app-info;1"; +const XULAPPINFO_CID = Components.ID("{c763b610-9d49-455a-bbd2-ede71682a1ac}"); + +function createAppInfo(id, name, version, platformVersion) { + gAppInfo = { + // nsIXULAppInfo + vendor: "Mozilla", + name: name, + ID: id, + version: version, + appBuildID: "2007010101", + platformVersion: platformVersion ? platformVersion : "1.0", + platformBuildID: "2007010101", + + // nsIXULRuntime + inSafeMode: false, + logConsoleErrors: true, + OS: "XPCShell", + XPCOMABI: "noarch-spidermonkey", + invalidateCachesOnRestart: function invalidateCachesOnRestart() { + // Do nothing + }, + + // nsICrashReporter + annotations: {}, + + annotateCrashReport: function(key, data) { + this.annotations[key] = data; + }, + + QueryInterface: XPCOMUtils.generateQI([Ci.nsIXULAppInfo, + Ci.nsIXULRuntime, + Ci.nsICrashReporter, + Ci.nsISupports]) + }; + + var XULAppInfoFactory = { + createInstance: function (outer, iid) { + if (outer != null) + throw Components.results.NS_ERROR_NO_AGGREGATION; + return gAppInfo.QueryInterface(iid); + } + }; + var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); + registrar.registerFactory(XULAPPINFO_CID, "XULAppInfo", + XULAPPINFO_CONTRACTID, XULAppInfoFactory); +} + +function initApp() { + createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9"); + // prepare a blocklist file for the blocklist service + var blocklistFile = gProfD.clone(); + blocklistFile.append("blocklist.xml"); + if (blocklistFile.exists()) + blocklistFile.remove(false); + var source = do_get_file("blocklist.xml"); + source.copyTo(gProfD, "blocklist.xml"); + blocklistFile.lastModifiedTime = Date.now(); +} + +function AsyncRunner() { + do_test_pending(); + do_register_cleanup((function () this.destroy()).bind(this)); + + this._callbacks = { + done: do_test_finished, + error: function (err) { + // xpcshell test functions like do_check_eq throw NS_ERROR_ABORT on + // failure. Ignore those so they aren't rethrown here. + if (err !== Cr.NS_ERROR_ABORT) { + if (err.stack) { + err = err + " - See following stack:\n" + err.stack + + "\nUseless do_throw stack"; + } + do_throw(err); + } + }, + consoleError: function (scriptErr) { + // Try to ensure the error is related to the test. + let filename = scriptErr.sourceName || scriptErr.toString() || ""; + if (filename.indexOf("/toolkit/components/social/") >= 0) + do_throw(scriptErr); + }, + }; + this._iteratorQueue = []; + + // This catches errors reported to the console, e.g., via Cu.reportError, but + // not on the runner's stack. + Cc["@mozilla.org/consoleservice;1"]. + getService(Ci.nsIConsoleService). + registerListener(this); +} + +AsyncRunner.prototype = { + + appendIterator: function appendIterator(iter) { + this._iteratorQueue.push(iter); + }, + + next: function next(/* ... */) { + if (!this._iteratorQueue.length) { + this.destroy(); + this._callbacks.done(); + return; + } + + // send() discards all arguments after the first, so there's no choice here + // but to send only one argument to the yielder. + let args = [arguments.length <= 1 ? arguments[0] : Array.slice(arguments)]; + try { + var val = this._iteratorQueue[0].send.apply(this._iteratorQueue[0], args); + } + catch (err if err instanceof StopIteration) { + this._iteratorQueue.shift(); + this.next(); + return; + } + catch (err) { + this._callbacks.error(err); + } + + // val is an iterator => prepend it to the queue and start on it + // val is otherwise truthy => call next + if (val) { + if (typeof(val) != "boolean") + this._iteratorQueue.unshift(val); + this.next(); + } + }, + + destroy: function destroy() { + Cc["@mozilla.org/consoleservice;1"]. + getService(Ci.nsIConsoleService). + unregisterListener(this); + this.destroy = function alreadyDestroyed() {}; + }, + + observe: function observe(msg) { + if (msg instanceof Ci.nsIScriptError && + !(msg.flags & Ci.nsIScriptError.warningFlag)) + { + this._callbacks.consoleError(msg); + } + }, +}; + + +function promiseAddVisits(aPlaceInfo) +{ + let deferred = Promise.defer(); + let places = []; + if (aPlaceInfo instanceof Ci.nsIURI) { + places.push({ uri: aPlaceInfo }); + } + else if (Array.isArray(aPlaceInfo)) { + places = places.concat(aPlaceInfo); + } else { + places.push(aPlaceInfo) + } + + // Create mozIVisitInfo for each entry. + let now = Date.now(); + for (let i = 0; i < places.length; i++) { + if (!places[i].title) { + places[i].title = "test visit for " + places[i].uri.spec; + } + places[i].visits = [{ + transitionType: places[i].transition === undefined ? Ci.nsINavHistoryService.TRANSITION_LINK + : places[i].transition, + visitDate: places[i].visitDate || (now++) * 1000, + referrerURI: places[i].referrer + }]; + } + + PlacesUtils.asyncHistory.updatePlaces( + places, + { + handleError: function handleError(aResultCode, aPlaceInfo) { + let ex = new Components.Exception("Unexpected error in adding visits.", + aResultCode); + deferred.reject(ex); + }, + handleResult: function () {}, + handleCompletion: function handleCompletion() { + deferred.resolve(); + } + } + ); + + return deferred.promise; +} + +function promiseTopicObserved(aTopic) +{ + let deferred = Promise.defer(); + + Services.obs.addObserver( + function PTO_observe(aSubject, aTopic, aData) { + Services.obs.removeObserver(PTO_observe, aTopic); + deferred.resolve([aSubject, aData]); + }, aTopic, false); + + return deferred.promise; +} + +function promiseClearHistory() { + let promise = promiseTopicObserved(PlacesUtils.TOPIC_EXPIRATION_FINISHED); + do_execute_soon(function() PlacesUtils.bhistory.removeAllPages()); + return promise; +}