Bug 681843 - Part 1: Clean up async.js. r=rnewman
authorPhilipp von Weitershausen <philipp@weitershausen.de>
Fri, 26 Aug 2011 10:25:19 -0700
changeset 77609 2c1cda171930c25d53a784dfa24b6c6cab7a5ff8
parent 77608 ae08860bf0a305dab9fd71e5e3b99caee7047db1
child 77610 725bf4c716978a0fdcd9702fa1132408acb0aaa4
push id78
push userclegnitto@mozilla.com
push dateFri, 16 Dec 2011 17:32:24 +0000
treeherdermozilla-release@79d24e644fdd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrnewman
bugs681843
milestone9.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 681843 - Part 1: Clean up async.js. r=rnewman
services/sync/modules/async.js
services/sync/modules/util.js
services/sync/tests/unit/test_async_helpers.js
services/sync/tests/unit/test_utils_slices.js
services/sync/tests/unit/xpcshell.ini
--- a/services/sync/modules/async.js
+++ b/services/sync/modules/async.js
@@ -124,167 +124,16 @@ let Async = {
       if (error)
         cb.throw(error);
       cb(ret);
     }
     callback.wait = function() Async.waitForSyncCallback(cb);
     return callback;
   },
 
-  /**
-   * Synchronously invoke a method that takes only a `callback` argument.
-   */
-  callSpinningly: function callSpinningly(self, method) {
-    let callback = this.makeSpinningCallback();
-    method.call(self, callback);
-    return callback.wait();
-  },
-
-  /*
-   * Produce a sequence of callbacks which -- when all have been executed
-   * successfully *or* any have failed -- invoke the output callback.
-   *
-   * Returns a generator.
-   *
-   * Each input callback should have the signature (error, result), and should
-   * return a truthy value if the computation should be considered to have
-   * failed.
-   *
-   * The contents of ".data" on each input callback are copied to the
-   * resultant callback items. This can save some effort on the caller's side.
-   *
-   * These callbacks are assumed to be single- or double-valued (a "result" and
-   * a "context", say), which covers the common cases without the expense of
-   * `arguments`.
-   */
-  barrieredCallbacks: function (callbacks, output) {
-    if (!output) {
-      throw "No output callback provided to barrieredCallbacks.";
-    }
-
-    let counter = callbacks.length;
-    function makeCb(input) {
-      let cb = function(error, result, context) {
-        if (!output) {
-          return;
-        }
-
-        let err;
-        try {
-          err = input(error, result, context);
-        } catch (ex) {
-          output(ex);
-          output = undefined;
-          return;
-        }
-        if ((0 == --counter) || err) {
-          output(err);
-          output = undefined;
-        }
-      };
-      cb.data = input.data;
-      return cb;
-    }
-    return (makeCb(i) for each (i in callbacks));
-  },
-
-  /*
-   * Similar to barrieredCallbacks, but with the same callback each time.
-   */
-  countedCallback: function (componentCb, count, output) {
-    if (!output) {
-      throw "No output callback provided to countedCallback.";
-    }
-
-    if (!count || (count <= 0)) {
-      throw "Invalid count provided to countedCallback.";
-    }
-
-    let counter = count;
-    return function (error, result, context) {
-      if (!output) {
-        return;
-      }
-
-      let err;
-      try {
-        err = componentCb(error, result, context);
-      } catch (ex) {
-        output(ex);
-        // We're done; make sure output callback is only called once.
-        output = undefined;
-        return;
-      }
-      if ((0 == --counter) || err) {
-        output(err);             // If this throws, then... oh well.
-        output = undefined;
-        return;
-      }
-    };
-  },
-
-  /*
-   * Invoke `f` with each item and a wrapped version of `componentCb`.
-   * When each component callback is invoked, the next invocation of `f` is
-   * begun, unless the return value is truthy. (See barrieredCallbacks.)
-   *
-   * Finally, invoke the output callback.
-   *
-   * If there are no items, the output callback is invoked immediately.
-   */
-  serially: function serially(items, f, componentCb, output) {
-    if (!output) {
-      throw "No output callback provided to serially.";
-    }
-
-    if (!items || !items.length) {
-      output();
-      return;
-    }
-
-    let count = items.length;
-    let i = 0;
-    function cb(error, result, context) {
-      let err = error;
-      if (!err) {
-        try {
-          err = componentCb(error, result, context);
-        } catch (ex) {
-          err = ex;
-        }
-      }
-      if ((++i == count) || err) {
-        output(err);
-        return;
-      }
-      Utils.nextTick(function () { f(items[i], cb); });
-    }
-    f(items[i], cb);
-  },
-
-  /*
-   * Return a callback which executes `f` then `callback`, regardless of
-   * whether it was invoked with an error. If an exception is thrown during the
-   * evaluation of `f`, it takes precedence over an error provided to the
-   * callback.
-   *
-   * When used to wrap a callback, this offers similar behavior to try..finally
-   * in plain JavaScript.
-   */
-  finallyCallback: function (callback, f) {
-    return function(err) {
-      try {
-        f();
-        callback(err);
-      } catch (ex) {
-        callback(ex);
-      }
-    };
-  },
-
   // Prototype for mozIStorageCallback, used in querySpinningly.
   // This allows us to define the handle* functions just once rather
   // than on every querySpinningly invocation.
   _storageCallbackPrototype: {
     results: null,
 
     // These are set by queryAsync.
     names: null,
--- a/services/sync/modules/util.js
+++ b/services/sync/modules/util.js
@@ -197,35 +197,16 @@ let Utils = {
       return callback.call(thisObj);
     } finally {
       if (hasTransaction) {
         db.commitTransaction();
       }
     }
   },
 
-
-  /*
-   * Partition the input array into an array of arrays. Return a generator.
-   */
-  slices: function slices(arr, sliceSize) {
-    if (!sliceSize || sliceSize <= 0)
-      throw "Invalid slice size.";
-
-    if (sliceSize > arr.length) {
-      yield arr;
-    } else {
-      let offset = 0;
-      while (arr.length > offset) {
-        yield arr.slice(offset, offset + sliceSize);
-        offset += sliceSize;
-      }
-    }
-  },
-
   byteArrayToString: function byteArrayToString(bytes) {
     return [String.fromCharCode(byte) for each (byte in bytes)].join("");
   },
 
   /**
    * Generate a string of random bytes.
    */
   generateRandomBytes: function generateRandomBytes(length) {
deleted file mode 100644
--- a/services/sync/tests/unit/test_async_helpers.js
+++ /dev/null
@@ -1,297 +0,0 @@
-Cu.import("resource://services-sync/async.js");
-
-function chain(fs) {
-  fs.reduce(function (prev, next) next.bind(this, prev),
-            run_next_test)();
-}
-
-// barrieredCallbacks.
-add_test(function test_barrieredCallbacks() {
-  let s1called = false;
-  let s2called = false;
-
-  function reset() {
-    _(" > reset.");
-    s1called = s2called = false;
-  }
-  function succeed1(err, result) {
-    _(" > succeed1.");
-    s1called = true;
-  }
-  function succeed2(err, result) {
-    _(" > succeed2.");
-    s2called = true;
-  }
-  function fail1(err, result) {
-    _(" > fail1.");
-    return "failed";
-  }
-  function throw1(err, result) {
-    _(" > throw1.");
-    throw "Aieeee!";
-  }
-
-  function doneSequential(next, err) {
-    _(" > doneSequential.");
-    do_check_eq(err, "failed");
-    do_check_true(s1called);
-    do_check_true(s2called);
-    next();
-  }
-  function doneFailFirst(next, err) {
-    _(" > doneFailFirst.");
-    do_check_eq(err, "failed");
-    do_check_false(s1called);
-    do_check_false(s2called);
-    next();
-  }
-  function doneOnlySucceed(next, err) {
-    _(" > doneOnlySucceed.");
-    do_check_true(!err);
-    do_check_true(s1called);
-    do_check_true(s2called);
-    next();
-  }
-  function doneThrow(next, err) {
-    _(" > doneThrow.");
-    do_check_eq(err, "Aieeee!");
-    do_check_true(s1called);
-    do_check_false(s2called);
-    next();
-  }
-
-  function sequence_test(label, parts, end) {
-    return function (next) {
-      _("Sequence test '" + label + "':");
-      reset();
-      for (let cb in Async.barrieredCallbacks(parts, end.bind(this, next)))
-        cb();
-    };
-  }
-
-  chain(
-    [sequence_test("failFirst",
-                   [fail1, succeed1, succeed2],
-                   doneFailFirst),
-
-     sequence_test("sequentially",
-                   [succeed1, succeed2, fail1],
-                   doneSequential),
-
-     sequence_test("onlySucceed",
-                   [succeed1, succeed2],
-                   doneOnlySucceed),
-
-     sequence_test("throw",
-                   [succeed1, throw1, succeed2],
-                   doneThrow)]);
-
-});
-
-add_test(function test_empty_barrieredCallbacks() {
-  let err;
-  try {
-    Async.barrieredCallbacks([], function (err) { }).next();
-  } catch (ex) {
-    err = ex;
-  }
-  _("err is " + err);
-  do_check_true(err instanceof StopIteration);
-  run_next_test();
-});
-
-add_test(function test_no_output_barrieredCallbacks() {
-  let err;
-  try {
-    Async.barrieredCallbacks([function (x) {}], null);
-  } catch (ex) {
-    err = ex;
-  }
-  do_check_eq(err, "No output callback provided to barrieredCallbacks.");
-  run_next_test();
-});
-
-add_test(function test_serially() {
-  let called = {};
-  let i      = 1;
-  function reset() {
-    called = {};
-    i      = 0;
-  }
-
-  function f(x, cb) {
-    called[x] = ++i;
-    cb(null, x);
-  }
-
-  function err_on(expected) {
-    return function (err, result, context) {
-      if (err) {
-        return err;
-      }
-      if (result == expected) {
-        return expected;
-      }
-      _("Got " + result + ", passing.");
-    };
-  }
-
-  // Fail in the middle.
-  reset();
-  Async.serially(["a", "b", "d"], f, err_on("b"), function (err) {
-    do_check_eq(1, called["a"]);
-    do_check_eq(2, called["b"]);
-    do_check_false(!!called["d"]);
-    do_check_eq(err, "b");
-
-  // Don't fail.
-  reset();
-  Async.serially(["a", "d", "b"], f, err_on("x"), function (err) {
-    do_check_eq(1, called["a"]);
-    do_check_eq(3, called["b"]);
-    do_check_eq(2, called["d"]);
-    do_check_false(!!err);
-
-  // Empty inputs.
-  reset();
-  Async.serially([], f, err_on("a"), function (err) {
-    do_check_false(!!err);
-
-  reset();
-  Async.serially(undefined, f, err_on("a"), function (err) {
-    do_check_false(!!err);
-    run_next_test();
-  });
-  });
-  });
-  });
-});
-
-add_test(function test_countedCallback() {
-  let error   = null;
-  let output  = null;
-  let context = null;
-  let counter = 0;
-  function cb(err, result, ctx) {
-    counter++;
-    output  = result;
-    error   = err;
-    context = ctx;
-    if (err == "error!")
-      return "Oh dear.";
-  }
-
-  let c1;
-
-  c1 = Async.countedCallback(cb, 3, function (err) {
-    do_check_eq(2, counter);
-    do_check_eq("error!", error);
-    do_check_eq(2, output);
-    do_check_eq("b", context);
-    do_check_eq(err, "Oh dear.");
-
-    // If we call the counted callback again (once this output function is
-    // done, that is), then the component callback is not invoked.
-    Utils.nextTick(function () {
-      _("Don't expect component callback.");
-      c1("not", "running", "now");
-      do_check_eq(2, counter);
-      do_check_eq("error!", error);
-      do_check_eq(2, output);
-      do_check_eq("b", context);
-      run_next_test();
-    });
-  });
-
-  c1(1, "foo", "a");
-  do_check_eq(1, counter);
-  do_check_eq(1, error);
-  do_check_eq("foo", output);
-  do_check_eq("a", context);
-
-  c1("error!", 2, "b");
-  // Subsequent checks must now take place inside the 'done' callback... read
-  // above!
-});
-
-add_test(function test_finallyCallback() {
-  let fnCalled = false;
-  let cbCalled = false;
-  let error    = undefined;
-
-  function reset() {
-    fnCalled = cbCalled = false;
-    error = undefined;
-  }
-
-  function fn(arg) {
-    do_check_false(!!arg);
-    fnCalled = true;
-  }
-
-  function fnThrow(arg) {
-    do_check_false(!!arg);
-    fnCalled = true;
-    throw "Foo";
-  }
-
-  function cb(next, err) {
-    _("Called with " + err);
-    cbCalled = true;
-    error  = err;
-    next();
-  }
-
-  function allGood(next) {
-    reset();
-    let callback = cb.bind(this, function() {
-      do_check_true(fnCalled);
-      do_check_true(cbCalled);
-      do_check_false(!!error);
-      next();
-    });
-    Async.finallyCallback(callback, fn)(null);
-  }
-
-  function inboundErr(next) {
-    reset();
-    let callback = cb.bind(this, function() {
-      do_check_true(fnCalled);
-      do_check_true(cbCalled);
-      do_check_eq(error, "Baz");
-      next();
-    });
-    Async.finallyCallback(callback, fn)("Baz");
-  }
-
-  function throwsNoErr(next) {
-    reset();
-    let callback = cb.bind(this, function() {
-      do_check_true(fnCalled);
-      do_check_true(cbCalled);
-      do_check_eq(error, "Foo");
-      next();
-    });
-    Async.finallyCallback(callback, fnThrow)(null);
-  }
-
-  function throwsOverrulesErr(next) {
-    reset();
-    let callback = cb.bind(this, function() {
-      do_check_true(fnCalled);
-      do_check_true(cbCalled);
-      do_check_eq(error, "Foo");
-      next();
-    });
-    Async.finallyCallback(callback, fnThrow)("Bar");
-  }
-
-  chain([throwsOverrulesErr,
-         throwsNoErr,
-         inboundErr,
-         allGood]);
-});
-
-function run_test() {
-  run_next_test();
-}
deleted file mode 100644
--- a/services/sync/tests/unit/test_utils_slices.js
+++ /dev/null
@@ -1,48 +0,0 @@
-Cu.import("resource://services-sync/util.js");
-
-function run_test() {
-  let input = [1, 2, 3, 4, 5];
-
-  let err;
-  try {
-    Utils.slices(input, 0).next();
-  } catch (ex) {
-    err = ex;
-  }
-  do_check_eq("Invalid slice size.", err);
-
-  err = undefined;
-  try {
-    Utils.slices(input).next();
-  } catch (ex) {
-    err = ex;
-  }
-  do_check_eq("Invalid slice size.", err);
-
-  function slurp(g) [x for each (x in g)]
-
-  let sliced1 = slurp(Utils.slices(input, 1));
-  let sliced2 = slurp(Utils.slices(input, 2));
-  let sliced3 = slurp(Utils.slices(input, 5));
-  let sliced4 = slurp(Utils.slices(input, 7));
-
-  do_check_eq(sliced1.length, 5);
-  do_check_eq(sliced2.length, 3);
-  do_check_eq(sliced3.length, 1);
-  do_check_eq(sliced4.length, 1);
-  sliced1.every(function(x) x.length == 1);
-  _(JSON.stringify(sliced2));
-  do_check_eq(sliced2[0].length, 2);
-  do_check_eq(sliced2[1].length, 2);
-  do_check_eq(sliced2[2].length, 1);
-  sliced3.every(function(x) x.length == 5);
-  sliced4.every(function(x) x.length == 5);
-
-  let sliced5 = slurp(Utils.slices(["foo"], 50));
-  do_check_eq(sliced5.length, 1);
-  do_check_eq(sliced5[0], "foo");
-
-  let sliced6 = slurp(Utils.slices([], 50));
-  do_check_eq(sliced6.length, 1);
-  do_check_eq(sliced6[0].length, 0);
-}
--- a/services/sync/tests/unit/xpcshell.ini
+++ b/services/sync/tests/unit/xpcshell.ini
@@ -1,15 +1,14 @@
 [DEFAULT]
 head = head_appinfo.js head_helpers.js head_http_server.js
 tail = 
 
 [test_Observers.js]
 [test_Preferences.js]
-[test_async_helpers.js]
 [test_async_querySpinningly.js]
 [test_auth_manager.js]
 [test_bookmark_batch_fail.js]
 [test_bookmark_engine.js]
 [test_bookmark_legacy_microsummaries_support.js]
 [test_bookmark_livemarks.js]
 [test_bookmark_order.js]
 [test_bookmark_places_query_rewriting.js]
@@ -121,11 +120,10 @@ skip-if = (os == "mac" && debug) || os =
 [test_utils_makeURI.js]
 [test_utils_namedTimer.js]
 [test_utils_notify.js]
 [test_utils_passphrase.js]
 [test_utils_pbkdf2.js]
 [test_utils_sha1.js]
 [test_utils_sha1hmac.js]
 [test_utils_sha256HMAC.js]
-[test_utils_slices.js]
 [test_utils_stackTrace.js]
 [test_utils_utf8.js]