Bug 984172 (part 1) - add Assert.rejects. r=mikedeboer
authorMark Hammond <mhammond@skippinet.com.au>
Fri, 17 Oct 2014 13:06:38 +1100
changeset 210905 7f47fcab5b5c60bd9fa6ffcd6846564e5492b9b8
parent 210904 6e7bdaa5a71ff2e87cbca793a3e4ab2630828f70
child 210906 b2a0cc22e9a62ecb55164d4b126d958671a2850e
push id50591
push usercbook@mozilla.com
push dateFri, 17 Oct 2014 14:38:40 +0000
treeherdermozilla-inbound@2ce3adda218b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmikedeboer
bugs984172
milestone36.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 984172 (part 1) - add Assert.rejects. r=mikedeboer
testing/modules/Assert.jsm
testing/modules/tests/xpcshell/test_assert.js
--- a/testing/modules/Assert.jsm
+++ b/testing/modules/Assert.jsm
@@ -11,16 +11,20 @@
 // MIT license: http://opensource.org/licenses/MIT
 
 "use strict";
 
 this.EXPORTED_SYMBOLS = [
   "Assert"
 ];
 
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+XPCOMUtils.defineLazyModuleGetter(this, "Promise",
+                                  "resource://gre/modules/Promise.jsm");
 /**
  * 1. The assert module provides functions that throw AssertionError's when
  * particular conditions are not met.
  *
  * To use the module you'll need to instantiate it first, which allows consumers
  * to override certain behavior on the newly obtained instance. For examples,
  * see the javadoc comments for the `report` member function.
  */
@@ -437,8 +441,39 @@ proto.throws = function(block, expected,
   }
 
   if ((actual && expected && !expectedException(actual, expected))) {
     throw actual;
   }
 
   this.report(false, expected, expected, message);
 };
+
+/**
+ * A promise that is expected to reject:
+ * assert.rejects(promise, expected, message);
+ *
+ * @param promise
+ *        (promise) A promise that is expected to reject
+ * @param expected (optional)
+ *        (mixed) Test reference to evaluate against the rejection result
+ * @param message (optional)
+ *        (string) Short explanation of the expected result
+ */
+proto.rejects = function(promise, expected, message) {
+  return new Promise((resolve, reject) => {
+    if (typeof expected === "string") {
+      message = expected;
+      expected = null;
+    }
+    return promise.then(
+      () => this.report(true, null, expected, "Missing expected exception " + message),
+      err => {
+        if (expected && !expectedException(err, expected)) {
+          reject(err);
+          return;
+        }
+        this.report(false, err, expected, message);
+        resolve();
+      }
+    ).then(null, reject);
+  });
+};
--- a/testing/modules/tests/xpcshell/test_assert.js
+++ b/testing/modules/tests/xpcshell/test_assert.js
@@ -292,9 +292,52 @@ function run_test() {
     actual: {
       toJSON: function() {
         throw "bam!";
       }
     },
     expected: "foo",
     operator: "="
   }).message, "[object Object] = \"foo\"");
+
+  run_next_test();
 }
+
+add_task(function* test_rejects() {
+  let ns = {};
+  Components.utils.import("resource://testing-common/Assert.jsm", ns);
+  let assert = new ns.Assert();
+
+  // A helper function to test failures.
+  function* checkRejectsFails(err, expected) {
+    try {
+      yield assert.rejects(Promise.reject(err), expected);
+      ok(false, "should have thrown");
+    } catch(ex) {
+      deepEqual(ex, err, "Assert.rejects threw the original unexpected error");
+    }
+  }
+
+  // A "throwable" error that's not an actual Error().
+  let SomeErrorLikeThing = function() {};
+
+  // The actual tests...
+  // No "expected" or "message" values supplied.
+  yield assert.rejects(Promise.reject(new Error("oh no")));
+  yield assert.rejects(Promise.reject("oh no"));
+
+  // An explicit error object:
+  // An instance to check against.
+  yield assert.rejects(Promise.reject(new Error("oh no")), Error, "rejected");
+  // A regex to match against the message.
+  yield assert.rejects(Promise.reject(new Error("oh no")), /oh no/, "rejected");
+
+  // Failure cases:
+  // An instance to check against that doesn't match.
+  yield checkRejectsFails(new Error("something else"), SomeErrorLikeThing);
+  // A regex that doesn't match.
+  yield checkRejectsFails(new Error("something else"), /oh no/);
+
+  // Check simple string messages.
+  yield assert.rejects(Promise.reject("oh no"), /oh no/, "rejected");
+  // Wrong message.
+  yield checkRejectsFails("something else", /oh no/);
+});