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

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/components/contentprefs/tests/unit_cps2/head.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,319 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     1.6 + * You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +const { interfaces: Ci, classes: Cc, results: Cr, utils: Cu } = Components;
     1.9 +
    1.10 +Cu.import("resource://gre/modules/Services.jsm");
    1.11 +
    1.12 +var cps;
    1.13 +var asyncRunner;
    1.14 +var next;
    1.15 +
    1.16 +(function init() {
    1.17 +  // There has to be a profile directory before the CPS service is gotten.
    1.18 +  do_get_profile();
    1.19 +})();
    1.20 +
    1.21 +function runAsyncTests(tests) {
    1.22 +  do_test_pending();
    1.23 +
    1.24 +  cps = Cc["@mozilla.org/content-pref/service;1"].
    1.25 +        getService(Ci.nsIContentPrefService2);
    1.26 +
    1.27 +  // Without this the private-browsing service tries to open a dialog when you
    1.28 +  // change its enabled state.
    1.29 +  Services.prefs.setBoolPref("browser.privatebrowsing.keep_current_session",
    1.30 +                             true);
    1.31 +
    1.32 +  let s = {};
    1.33 +  Cu.import("resource://test/AsyncRunner.jsm", s);
    1.34 +  asyncRunner = new s.AsyncRunner({
    1.35 +    done: do_test_finished,
    1.36 +    error: function (err) {
    1.37 +      // xpcshell test functions like do_check_eq throw NS_ERROR_ABORT on
    1.38 +      // failure.  Ignore those and catch only uncaught exceptions.
    1.39 +      if (err !== Cr.NS_ERROR_ABORT) {
    1.40 +        if (err.stack) {
    1.41 +          err = err + "\n\nTraceback (most recent call first):\n" + err.stack +
    1.42 +                      "\nUseless do_throw stack:";
    1.43 +        }
    1.44 +        do_throw(err);
    1.45 +      }
    1.46 +    },
    1.47 +    consoleError: function (scriptErr) {
    1.48 +      // As much as possible make sure the error is related to the test.  On the
    1.49 +      // other hand if this fails to catch a test-related error, we'll hang.
    1.50 +      let filename = scriptErr.sourceName || scriptErr.toString() || "";
    1.51 +      if (/contentpref/i.test(filename))
    1.52 +        do_throw(scriptErr);
    1.53 +    }
    1.54 +  });
    1.55 +
    1.56 +  next = asyncRunner.next.bind(asyncRunner);
    1.57 +
    1.58 +  do_register_cleanup(function () {
    1.59 +    asyncRunner.destroy();
    1.60 +    asyncRunner = null;
    1.61 +  });
    1.62 +
    1.63 +  tests.forEach(function (test) {
    1.64 +    function gen() {
    1.65 +      do_print("Running " + test.name);
    1.66 +      yield test();
    1.67 +      yield reset();
    1.68 +    }
    1.69 +    asyncRunner.appendIterator(gen());
    1.70 +  });
    1.71 +
    1.72 +  // reset() ends up calling asyncRunner.next(), starting the tests.
    1.73 +  reset();
    1.74 +}
    1.75 +
    1.76 +function makeCallback(callbacks) {
    1.77 +  callbacks = callbacks || {};
    1.78 +  ["handleResult", "handleError"].forEach(function (meth) {
    1.79 +    if (!callbacks[meth])
    1.80 +      callbacks[meth] = function () {
    1.81 +        do_throw(meth + " shouldn't be called.");
    1.82 +      };
    1.83 +  });
    1.84 +  if (!callbacks.handleCompletion)
    1.85 +    callbacks.handleCompletion = function (reason) {
    1.86 +      do_check_eq(reason, Ci.nsIContentPrefCallback2.COMPLETE_OK);
    1.87 +      next();
    1.88 +    };
    1.89 +  return callbacks;
    1.90 +}
    1.91 +
    1.92 +function do_check_throws(fn) {
    1.93 +  let threw = false;
    1.94 +  try {
    1.95 +    fn();
    1.96 +  }
    1.97 +  catch (err) {
    1.98 +    threw = true;
    1.99 +  }
   1.100 +  do_check_true(threw);
   1.101 +}
   1.102 +
   1.103 +function sendMessage(msg, callback) {
   1.104 +  let obj = callback || {};
   1.105 +  let ref = Cu.getWeakReference(obj);
   1.106 +  cps.QueryInterface(Ci.nsIObserver).observe(ref, "test:" + msg, null);
   1.107 +  return "value" in obj ? obj.value : undefined;
   1.108 +}
   1.109 +
   1.110 +function reset() {
   1.111 +  sendMessage("reset", next);
   1.112 +}
   1.113 +
   1.114 +function set(group, name, val, context) {
   1.115 +  cps.set(group, name, val, context, makeCallback());
   1.116 +}
   1.117 +
   1.118 +function setGlobal(name, val, context) {
   1.119 +  cps.setGlobal(name, val, context, makeCallback());
   1.120 +}
   1.121 +
   1.122 +function prefOK(actual, expected, strict) {
   1.123 +  do_check_true(actual instanceof Ci.nsIContentPref);
   1.124 +  do_check_eq(actual.domain, expected.domain);
   1.125 +  do_check_eq(actual.name, expected.name);
   1.126 +  if (strict)
   1.127 +    do_check_true(actual.value === expected.value);
   1.128 +  else
   1.129 +    do_check_eq(actual.value, expected.value);
   1.130 +}
   1.131 +
   1.132 +function getOK(args, expectedVal, expectedGroup, strict) {
   1.133 +  if (args.length == 2)
   1.134 +    args.push(undefined);
   1.135 +  let expectedPrefs = expectedVal === undefined ? [] :
   1.136 +                      [{ domain: expectedGroup || args[0],
   1.137 +                         name: args[1],
   1.138 +                         value: expectedVal }];
   1.139 +  yield getOKEx("getByDomainAndName", args, expectedPrefs, strict);
   1.140 +}
   1.141 +
   1.142 +function getSubdomainsOK(args, expectedGroupValPairs) {
   1.143 +  if (args.length == 2)
   1.144 +    args.push(undefined);
   1.145 +  let expectedPrefs = expectedGroupValPairs.map(function ([group, val]) {
   1.146 +    return { domain: group, name: args[1], value: val };
   1.147 +  });
   1.148 +  yield getOKEx("getBySubdomainAndName", args, expectedPrefs);
   1.149 +}
   1.150 +
   1.151 +function getGlobalOK(args, expectedVal) {
   1.152 +  if (args.length == 1)
   1.153 +    args.push(undefined);
   1.154 +  let expectedPrefs = expectedVal === undefined ? [] :
   1.155 +                      [{ domain: null, name: args[0], value: expectedVal }];
   1.156 +  yield getOKEx("getGlobal", args, expectedPrefs);
   1.157 +}
   1.158 +
   1.159 +function getOKEx(methodName, args, expectedPrefs, strict, context) {
   1.160 +  let actualPrefs = [];
   1.161 +  args.push(makeCallback({
   1.162 +    handleResult: function (pref) actualPrefs.push(pref)
   1.163 +  }));
   1.164 +  yield cps[methodName].apply(cps, args);
   1.165 +  arraysOfArraysOK([actualPrefs], [expectedPrefs], function (actual, expected) {
   1.166 +    prefOK(actual, expected, strict);
   1.167 +  });
   1.168 +}
   1.169 +
   1.170 +function getCachedOK(args, expectedIsCached, expectedVal, expectedGroup,
   1.171 +                     strict) {
   1.172 +  if (args.length == 2)
   1.173 +    args.push(undefined);
   1.174 +  let expectedPref = !expectedIsCached ? null : {
   1.175 +    domain: expectedGroup || args[0],
   1.176 +    name: args[1],
   1.177 +    value: expectedVal
   1.178 +  };
   1.179 +  getCachedOKEx("getCachedByDomainAndName", args, expectedPref, strict);
   1.180 +}
   1.181 +
   1.182 +function getCachedSubdomainsOK(args, expectedGroupValPairs) {
   1.183 +  if (args.length == 2)
   1.184 +    args.push(undefined);
   1.185 +  let len = {};
   1.186 +  args.push(len);
   1.187 +  let actualPrefs = cps.getCachedBySubdomainAndName.apply(cps, args);
   1.188 +  actualPrefs = actualPrefs.sort(function (a, b) {
   1.189 +    return a.domain.localeCompare(b.domain);
   1.190 +  });
   1.191 +  do_check_eq(actualPrefs.length, len.value);
   1.192 +  let expectedPrefs = expectedGroupValPairs.map(function ([group, val]) {
   1.193 +    return { domain: group, name: args[1], value: val };
   1.194 +  });
   1.195 +  arraysOfArraysOK([actualPrefs], [expectedPrefs], prefOK);
   1.196 +}
   1.197 +
   1.198 +function getCachedGlobalOK(args, expectedIsCached, expectedVal) {
   1.199 +  if (args.length == 1)
   1.200 +    args.push(undefined);
   1.201 +  let expectedPref = !expectedIsCached ? null : {
   1.202 +    domain: null,
   1.203 +    name: args[0],
   1.204 +    value: expectedVal
   1.205 +  };
   1.206 +  getCachedOKEx("getCachedGlobal", args, expectedPref);
   1.207 +}
   1.208 +
   1.209 +function getCachedOKEx(methodName, args, expectedPref, strict) {
   1.210 +  let actualPref = cps[methodName].apply(cps, args);
   1.211 +  if (expectedPref)
   1.212 +    prefOK(actualPref, expectedPref, strict);
   1.213 +  else
   1.214 +    do_check_true(actualPref === null);
   1.215 +}
   1.216 +
   1.217 +function arraysOfArraysOK(actual, expected, cmp) {
   1.218 +  cmp = cmp || function (a, b) do_check_eq(a, b);
   1.219 +  do_check_eq(actual.length, expected.length);
   1.220 +  actual.forEach(function (actualChildArr, i) {
   1.221 +    let expectedChildArr = expected[i];
   1.222 +    do_check_eq(actualChildArr.length, expectedChildArr.length);
   1.223 +    actualChildArr.forEach(function (actualElt, j) {
   1.224 +      let expectedElt = expectedChildArr[j];
   1.225 +      cmp(actualElt, expectedElt);
   1.226 +    });
   1.227 +  });
   1.228 +}
   1.229 +
   1.230 +function dbOK(expectedRows) {
   1.231 +  let db = sendMessage("db");
   1.232 +  let stmt = db.createAsyncStatement(
   1.233 +    "SELECT groups.name AS grp, settings.name AS name, prefs.value AS value " +
   1.234 +    "FROM prefs " +
   1.235 +    "LEFT JOIN groups ON groups.id = prefs.groupID " +
   1.236 +    "LEFT JOIN settings ON settings.id = prefs.settingID " +
   1.237 +    "UNION " +
   1.238 +
   1.239 +    // These second two SELECTs get the rows of the groups and settings tables
   1.240 +    // that aren't referenced by the prefs table.  Neither should return any
   1.241 +    // rows if the component is working properly.
   1.242 +    "SELECT groups.name AS grp, NULL AS name, NULL AS value " +
   1.243 +    "FROM groups " +
   1.244 +    "WHERE id NOT IN (" +
   1.245 +      "SELECT DISTINCT groupID " +
   1.246 +      "FROM prefs " +
   1.247 +      "WHERE groupID NOTNULL" +
   1.248 +    ") " +
   1.249 +    "UNION " +
   1.250 +    "SELECT NULL AS grp, settings.name AS name, NULL AS value " +
   1.251 +    "FROM settings " +
   1.252 +    "WHERE id NOT IN (" +
   1.253 +      "SELECT DISTINCT settingID " +
   1.254 +      "FROM prefs " +
   1.255 +      "WHERE settingID NOTNULL" +
   1.256 +    ") " +
   1.257 +
   1.258 +    "ORDER BY value ASC, grp ASC, name ASC"
   1.259 +  );
   1.260 +
   1.261 +  let actualRows = [];
   1.262 +  let cols = ["grp", "name", "value"];
   1.263 +
   1.264 +  db.executeAsync([stmt], 1, {
   1.265 +    handleCompletion: function (reason) {
   1.266 +      arraysOfArraysOK(actualRows, expectedRows);
   1.267 +      next();
   1.268 +    },
   1.269 +    handleResult: function (results) {
   1.270 +      let row = null;
   1.271 +      while (row = results.getNextRow()) {
   1.272 +        actualRows.push(cols.map(function (c) row.getResultByName(c)));
   1.273 +      }
   1.274 +    },
   1.275 +    handleError: function (err) {
   1.276 +      do_throw(err);
   1.277 +    }
   1.278 +  });
   1.279 +  stmt.finalize();
   1.280 +}
   1.281 +
   1.282 +function on(event, names, dontRemove) {
   1.283 +  let args = {
   1.284 +    reset: function () {
   1.285 +      for (let prop in this) {
   1.286 +        if (Array.isArray(this[prop]))
   1.287 +          this[prop].splice(0, this[prop].length);
   1.288 +      }
   1.289 +    },
   1.290 +  };
   1.291 +
   1.292 +  let observers = {};
   1.293 +
   1.294 +  names.forEach(function (name) {
   1.295 +    let obs = {};
   1.296 +    ["onContentPrefSet", "onContentPrefRemoved"].forEach(function (meth) {
   1.297 +      obs[meth] = function () do_throw(meth + " should not be called");
   1.298 +    });
   1.299 +    obs["onContentPref" + event] = function () {
   1.300 +      args[name].push(Array.slice(arguments));
   1.301 +    };
   1.302 +    observers[name] = obs;
   1.303 +    args[name] = [];
   1.304 +    args[name].observer = obs;
   1.305 +    cps.addObserverForName(name, obs);
   1.306 +  });
   1.307 +
   1.308 +  do_execute_soon(function () {
   1.309 +    if (!dontRemove)
   1.310 +      names.forEach(function (n) cps.removeObserverForName(n, observers[n]));
   1.311 +    next(args);
   1.312 +  });
   1.313 +}
   1.314 +
   1.315 +function wait() {
   1.316 +  do_execute_soon(next);
   1.317 +}
   1.318 +
   1.319 +function observerArgsOK(actualArgs, expectedArgs) {
   1.320 +  do_check_neq(actualArgs, undefined);
   1.321 +  arraysOfArraysOK(actualArgs, expectedArgs);
   1.322 +}

mercurial