toolkit/components/contentprefs/tests/unit_cps2/head.js

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

Integrate suggestion from review to improve consistency with existing code.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 const { interfaces: Ci, classes: Cc, results: Cr, utils: Cu } = Components;
michael@0 6
michael@0 7 Cu.import("resource://gre/modules/Services.jsm");
michael@0 8
michael@0 9 var cps;
michael@0 10 var asyncRunner;
michael@0 11 var next;
michael@0 12
michael@0 13 (function init() {
michael@0 14 // There has to be a profile directory before the CPS service is gotten.
michael@0 15 do_get_profile();
michael@0 16 })();
michael@0 17
michael@0 18 function runAsyncTests(tests) {
michael@0 19 do_test_pending();
michael@0 20
michael@0 21 cps = Cc["@mozilla.org/content-pref/service;1"].
michael@0 22 getService(Ci.nsIContentPrefService2);
michael@0 23
michael@0 24 // Without this the private-browsing service tries to open a dialog when you
michael@0 25 // change its enabled state.
michael@0 26 Services.prefs.setBoolPref("browser.privatebrowsing.keep_current_session",
michael@0 27 true);
michael@0 28
michael@0 29 let s = {};
michael@0 30 Cu.import("resource://test/AsyncRunner.jsm", s);
michael@0 31 asyncRunner = new s.AsyncRunner({
michael@0 32 done: do_test_finished,
michael@0 33 error: function (err) {
michael@0 34 // xpcshell test functions like do_check_eq throw NS_ERROR_ABORT on
michael@0 35 // failure. Ignore those and catch only uncaught exceptions.
michael@0 36 if (err !== Cr.NS_ERROR_ABORT) {
michael@0 37 if (err.stack) {
michael@0 38 err = err + "\n\nTraceback (most recent call first):\n" + err.stack +
michael@0 39 "\nUseless do_throw stack:";
michael@0 40 }
michael@0 41 do_throw(err);
michael@0 42 }
michael@0 43 },
michael@0 44 consoleError: function (scriptErr) {
michael@0 45 // As much as possible make sure the error is related to the test. On the
michael@0 46 // other hand if this fails to catch a test-related error, we'll hang.
michael@0 47 let filename = scriptErr.sourceName || scriptErr.toString() || "";
michael@0 48 if (/contentpref/i.test(filename))
michael@0 49 do_throw(scriptErr);
michael@0 50 }
michael@0 51 });
michael@0 52
michael@0 53 next = asyncRunner.next.bind(asyncRunner);
michael@0 54
michael@0 55 do_register_cleanup(function () {
michael@0 56 asyncRunner.destroy();
michael@0 57 asyncRunner = null;
michael@0 58 });
michael@0 59
michael@0 60 tests.forEach(function (test) {
michael@0 61 function gen() {
michael@0 62 do_print("Running " + test.name);
michael@0 63 yield test();
michael@0 64 yield reset();
michael@0 65 }
michael@0 66 asyncRunner.appendIterator(gen());
michael@0 67 });
michael@0 68
michael@0 69 // reset() ends up calling asyncRunner.next(), starting the tests.
michael@0 70 reset();
michael@0 71 }
michael@0 72
michael@0 73 function makeCallback(callbacks) {
michael@0 74 callbacks = callbacks || {};
michael@0 75 ["handleResult", "handleError"].forEach(function (meth) {
michael@0 76 if (!callbacks[meth])
michael@0 77 callbacks[meth] = function () {
michael@0 78 do_throw(meth + " shouldn't be called.");
michael@0 79 };
michael@0 80 });
michael@0 81 if (!callbacks.handleCompletion)
michael@0 82 callbacks.handleCompletion = function (reason) {
michael@0 83 do_check_eq(reason, Ci.nsIContentPrefCallback2.COMPLETE_OK);
michael@0 84 next();
michael@0 85 };
michael@0 86 return callbacks;
michael@0 87 }
michael@0 88
michael@0 89 function do_check_throws(fn) {
michael@0 90 let threw = false;
michael@0 91 try {
michael@0 92 fn();
michael@0 93 }
michael@0 94 catch (err) {
michael@0 95 threw = true;
michael@0 96 }
michael@0 97 do_check_true(threw);
michael@0 98 }
michael@0 99
michael@0 100 function sendMessage(msg, callback) {
michael@0 101 let obj = callback || {};
michael@0 102 let ref = Cu.getWeakReference(obj);
michael@0 103 cps.QueryInterface(Ci.nsIObserver).observe(ref, "test:" + msg, null);
michael@0 104 return "value" in obj ? obj.value : undefined;
michael@0 105 }
michael@0 106
michael@0 107 function reset() {
michael@0 108 sendMessage("reset", next);
michael@0 109 }
michael@0 110
michael@0 111 function set(group, name, val, context) {
michael@0 112 cps.set(group, name, val, context, makeCallback());
michael@0 113 }
michael@0 114
michael@0 115 function setGlobal(name, val, context) {
michael@0 116 cps.setGlobal(name, val, context, makeCallback());
michael@0 117 }
michael@0 118
michael@0 119 function prefOK(actual, expected, strict) {
michael@0 120 do_check_true(actual instanceof Ci.nsIContentPref);
michael@0 121 do_check_eq(actual.domain, expected.domain);
michael@0 122 do_check_eq(actual.name, expected.name);
michael@0 123 if (strict)
michael@0 124 do_check_true(actual.value === expected.value);
michael@0 125 else
michael@0 126 do_check_eq(actual.value, expected.value);
michael@0 127 }
michael@0 128
michael@0 129 function getOK(args, expectedVal, expectedGroup, strict) {
michael@0 130 if (args.length == 2)
michael@0 131 args.push(undefined);
michael@0 132 let expectedPrefs = expectedVal === undefined ? [] :
michael@0 133 [{ domain: expectedGroup || args[0],
michael@0 134 name: args[1],
michael@0 135 value: expectedVal }];
michael@0 136 yield getOKEx("getByDomainAndName", args, expectedPrefs, strict);
michael@0 137 }
michael@0 138
michael@0 139 function getSubdomainsOK(args, expectedGroupValPairs) {
michael@0 140 if (args.length == 2)
michael@0 141 args.push(undefined);
michael@0 142 let expectedPrefs = expectedGroupValPairs.map(function ([group, val]) {
michael@0 143 return { domain: group, name: args[1], value: val };
michael@0 144 });
michael@0 145 yield getOKEx("getBySubdomainAndName", args, expectedPrefs);
michael@0 146 }
michael@0 147
michael@0 148 function getGlobalOK(args, expectedVal) {
michael@0 149 if (args.length == 1)
michael@0 150 args.push(undefined);
michael@0 151 let expectedPrefs = expectedVal === undefined ? [] :
michael@0 152 [{ domain: null, name: args[0], value: expectedVal }];
michael@0 153 yield getOKEx("getGlobal", args, expectedPrefs);
michael@0 154 }
michael@0 155
michael@0 156 function getOKEx(methodName, args, expectedPrefs, strict, context) {
michael@0 157 let actualPrefs = [];
michael@0 158 args.push(makeCallback({
michael@0 159 handleResult: function (pref) actualPrefs.push(pref)
michael@0 160 }));
michael@0 161 yield cps[methodName].apply(cps, args);
michael@0 162 arraysOfArraysOK([actualPrefs], [expectedPrefs], function (actual, expected) {
michael@0 163 prefOK(actual, expected, strict);
michael@0 164 });
michael@0 165 }
michael@0 166
michael@0 167 function getCachedOK(args, expectedIsCached, expectedVal, expectedGroup,
michael@0 168 strict) {
michael@0 169 if (args.length == 2)
michael@0 170 args.push(undefined);
michael@0 171 let expectedPref = !expectedIsCached ? null : {
michael@0 172 domain: expectedGroup || args[0],
michael@0 173 name: args[1],
michael@0 174 value: expectedVal
michael@0 175 };
michael@0 176 getCachedOKEx("getCachedByDomainAndName", args, expectedPref, strict);
michael@0 177 }
michael@0 178
michael@0 179 function getCachedSubdomainsOK(args, expectedGroupValPairs) {
michael@0 180 if (args.length == 2)
michael@0 181 args.push(undefined);
michael@0 182 let len = {};
michael@0 183 args.push(len);
michael@0 184 let actualPrefs = cps.getCachedBySubdomainAndName.apply(cps, args);
michael@0 185 actualPrefs = actualPrefs.sort(function (a, b) {
michael@0 186 return a.domain.localeCompare(b.domain);
michael@0 187 });
michael@0 188 do_check_eq(actualPrefs.length, len.value);
michael@0 189 let expectedPrefs = expectedGroupValPairs.map(function ([group, val]) {
michael@0 190 return { domain: group, name: args[1], value: val };
michael@0 191 });
michael@0 192 arraysOfArraysOK([actualPrefs], [expectedPrefs], prefOK);
michael@0 193 }
michael@0 194
michael@0 195 function getCachedGlobalOK(args, expectedIsCached, expectedVal) {
michael@0 196 if (args.length == 1)
michael@0 197 args.push(undefined);
michael@0 198 let expectedPref = !expectedIsCached ? null : {
michael@0 199 domain: null,
michael@0 200 name: args[0],
michael@0 201 value: expectedVal
michael@0 202 };
michael@0 203 getCachedOKEx("getCachedGlobal", args, expectedPref);
michael@0 204 }
michael@0 205
michael@0 206 function getCachedOKEx(methodName, args, expectedPref, strict) {
michael@0 207 let actualPref = cps[methodName].apply(cps, args);
michael@0 208 if (expectedPref)
michael@0 209 prefOK(actualPref, expectedPref, strict);
michael@0 210 else
michael@0 211 do_check_true(actualPref === null);
michael@0 212 }
michael@0 213
michael@0 214 function arraysOfArraysOK(actual, expected, cmp) {
michael@0 215 cmp = cmp || function (a, b) do_check_eq(a, b);
michael@0 216 do_check_eq(actual.length, expected.length);
michael@0 217 actual.forEach(function (actualChildArr, i) {
michael@0 218 let expectedChildArr = expected[i];
michael@0 219 do_check_eq(actualChildArr.length, expectedChildArr.length);
michael@0 220 actualChildArr.forEach(function (actualElt, j) {
michael@0 221 let expectedElt = expectedChildArr[j];
michael@0 222 cmp(actualElt, expectedElt);
michael@0 223 });
michael@0 224 });
michael@0 225 }
michael@0 226
michael@0 227 function dbOK(expectedRows) {
michael@0 228 let db = sendMessage("db");
michael@0 229 let stmt = db.createAsyncStatement(
michael@0 230 "SELECT groups.name AS grp, settings.name AS name, prefs.value AS value " +
michael@0 231 "FROM prefs " +
michael@0 232 "LEFT JOIN groups ON groups.id = prefs.groupID " +
michael@0 233 "LEFT JOIN settings ON settings.id = prefs.settingID " +
michael@0 234 "UNION " +
michael@0 235
michael@0 236 // These second two SELECTs get the rows of the groups and settings tables
michael@0 237 // that aren't referenced by the prefs table. Neither should return any
michael@0 238 // rows if the component is working properly.
michael@0 239 "SELECT groups.name AS grp, NULL AS name, NULL AS value " +
michael@0 240 "FROM groups " +
michael@0 241 "WHERE id NOT IN (" +
michael@0 242 "SELECT DISTINCT groupID " +
michael@0 243 "FROM prefs " +
michael@0 244 "WHERE groupID NOTNULL" +
michael@0 245 ") " +
michael@0 246 "UNION " +
michael@0 247 "SELECT NULL AS grp, settings.name AS name, NULL AS value " +
michael@0 248 "FROM settings " +
michael@0 249 "WHERE id NOT IN (" +
michael@0 250 "SELECT DISTINCT settingID " +
michael@0 251 "FROM prefs " +
michael@0 252 "WHERE settingID NOTNULL" +
michael@0 253 ") " +
michael@0 254
michael@0 255 "ORDER BY value ASC, grp ASC, name ASC"
michael@0 256 );
michael@0 257
michael@0 258 let actualRows = [];
michael@0 259 let cols = ["grp", "name", "value"];
michael@0 260
michael@0 261 db.executeAsync([stmt], 1, {
michael@0 262 handleCompletion: function (reason) {
michael@0 263 arraysOfArraysOK(actualRows, expectedRows);
michael@0 264 next();
michael@0 265 },
michael@0 266 handleResult: function (results) {
michael@0 267 let row = null;
michael@0 268 while (row = results.getNextRow()) {
michael@0 269 actualRows.push(cols.map(function (c) row.getResultByName(c)));
michael@0 270 }
michael@0 271 },
michael@0 272 handleError: function (err) {
michael@0 273 do_throw(err);
michael@0 274 }
michael@0 275 });
michael@0 276 stmt.finalize();
michael@0 277 }
michael@0 278
michael@0 279 function on(event, names, dontRemove) {
michael@0 280 let args = {
michael@0 281 reset: function () {
michael@0 282 for (let prop in this) {
michael@0 283 if (Array.isArray(this[prop]))
michael@0 284 this[prop].splice(0, this[prop].length);
michael@0 285 }
michael@0 286 },
michael@0 287 };
michael@0 288
michael@0 289 let observers = {};
michael@0 290
michael@0 291 names.forEach(function (name) {
michael@0 292 let obs = {};
michael@0 293 ["onContentPrefSet", "onContentPrefRemoved"].forEach(function (meth) {
michael@0 294 obs[meth] = function () do_throw(meth + " should not be called");
michael@0 295 });
michael@0 296 obs["onContentPref" + event] = function () {
michael@0 297 args[name].push(Array.slice(arguments));
michael@0 298 };
michael@0 299 observers[name] = obs;
michael@0 300 args[name] = [];
michael@0 301 args[name].observer = obs;
michael@0 302 cps.addObserverForName(name, obs);
michael@0 303 });
michael@0 304
michael@0 305 do_execute_soon(function () {
michael@0 306 if (!dontRemove)
michael@0 307 names.forEach(function (n) cps.removeObserverForName(n, observers[n]));
michael@0 308 next(args);
michael@0 309 });
michael@0 310 }
michael@0 311
michael@0 312 function wait() {
michael@0 313 do_execute_soon(next);
michael@0 314 }
michael@0 315
michael@0 316 function observerArgsOK(actualArgs, expectedArgs) {
michael@0 317 do_check_neq(actualArgs, undefined);
michael@0 318 arraysOfArraysOK(actualArgs, expectedArgs);
michael@0 319 }

mercurial