Bug 762579 - Implement SocialAPI service provider registry. r=gavin

This commit is contained in:
Drew Willcoxon 2012-06-20 18:01:27 -07:00
parent 7d0e71644b
commit 530c9d7e3b
8 changed files with 207 additions and 0 deletions

View File

@ -44,6 +44,7 @@ skip-if = os == "android"
[include:toolkit/components/downloads/test/schema_migration/xpcshell.ini]
[include:toolkit/components/startup/tests/unit/xpcshell.ini]
[include:toolkit/components/telemetry/tests/unit/xpcshell.ini]
[include:toolkit/components/social/test/xpcshell/xpcshell.ini]
[include:toolkit/content/tests/unit/xpcshell.ini]
[include:toolkit/mozapps/downloads/tests/unit/xpcshell.ini]
[include:toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini]

View File

@ -35,6 +35,7 @@ PARALLEL_DIRS += \
places \
prompts \
reflect \
social \
startup \
statusfilter \
telemetry \

View File

@ -0,0 +1,20 @@
# 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/.
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
EXTRA_JS_MODULES = \
SocialService.jsm \
$(NULL)
TEST_DIRS += \
test \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,39 @@
/* 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 EXPORTED_SYMBOLS = ["SocialService"];
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/Services.jsm");
const MANIFEST_PREFS = Services.prefs.getBranch("social.manifest.");
const SocialService = {
_init: function _init() {
let origins = MANIFEST_PREFS.getChildList("", {});
this._providers = origins.reduce(function (memo, origin) {
try {
var manifest = JSON.parse(MANIFEST_PREFS.getCharPref(origin));
}
catch (err) {}
if (manifest && typeof(manifest) == "object") {
memo[manifest.origin] = Object.create(manifest);
}
return memo;
}, {}, this);
},
getProvider: function getProvider(origin, onDone) {
schedule((function () {
onDone(this._providers[origin] || null);
}).bind(this));
},
};
SocialService._init();
function schedule(callback) {
Services.tm.mainThread.dispatch(callback, Ci.nsIThread.DISPATCH_NORMAL);
}

View File

@ -0,0 +1,17 @@
# 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/.
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
relativesrcdir = toolkit/components/social/test
include $(DEPTH)/config/autoconf.mk
XPCSHELL_TESTS = \
xpcshell \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,91 @@
/* 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");
const MANIFEST_PREFS = Services.prefs.getBranch("social.manifest.");
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)
this._callbacks.consoleError(msg);
},
};

View File

@ -0,0 +1,33 @@
/* 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/. */
function run_test() {
let manifests = [0, 1, 2].map(function (i) {
return {
origin: "http://example" + i + ".com",
name: "provider " + i,
};
});
manifests.forEach(function (manifest) {
MANIFEST_PREFS.setCharPref(manifest.origin, JSON.stringify(manifest));
});
do_register_cleanup(function () MANIFEST_PREFS.deleteBranch(""));
Cu.import("resource://gre/modules/SocialService.jsm");
let runner = new AsyncRunner();
runner.appendIterator(test(manifests, runner.next.bind(runner)));
runner.next();
}
function test(manifests, next) {
for (let i = 0; i < manifests.length; i++) {
let manifest = manifests[i];
let provider = yield SocialService.getProvider(manifest.origin, next);
do_check_neq(provider, null);
do_check_eq(provider.origin, manifest.origin);
do_check_eq(provider.name, manifest.name);
}
do_check_eq((yield SocialService.getProvider("bogus", next)), null);
}

View File

@ -0,0 +1,5 @@
[DEFAULT]
head = head.js
tail =
[test_getProvider.js]