diff --git a/lib/chai-as-promised.js b/lib/chai-as-promised.js
index c6808e0..219a504 100644
--- a/lib/chai-as-promised.js
+++ b/lib/chai-as-promised.js
@@ -1,26 +1,24 @@
-(function () {
+(function (factory) {
"use strict";
-
- // Module systems magic dance.
-
/* istanbul ignore else */
if (typeof require === "function" && typeof exports === "object" && typeof module === "object") {
// NodeJS
- module.exports = chaiAsPromised;
+ module.exports = factory(require("check-error"));
} else if (typeof define === "function" && define.amd) {
// AMD
- define(function () {
- return chaiAsPromised;
- });
+ define(["check-error"], factory);
} else {
/*global self: false */
// Other environment (usually
+
diff --git a/test/should-promise-specific.coffee b/test/should-promise-specific.coffee
index 957a83f..39fdd1b 100644
--- a/test/should-promise-specific.coffee
+++ b/test/should-promise-specific.coffee
@@ -3,6 +3,8 @@
describe "Promise-specific extensions:", =>
promise = null
error = new Error("boo")
+ error.myProp = ["myProp value"]
+ custom = "No. I am your father."
assertingDoneFactory = (done) =>
(result) =>
@@ -15,45 +17,70 @@ describe "Promise-specific extensions:", =>
describe "when the promise is fulfilled", =>
beforeEach =>
- promise = fulfilledPromise()
+ promise = fulfilledPromise(42)
return undefined
describe ".fulfilled", =>
shouldPass => promise.should.be.fulfilled
+
+ describe ".fulfilled passes the fulfilled value", =>
+ shouldPass => promise.should.be.fulfilled.then (passedValue) =>
+ passedValue.should.equal(42)
+
+ describe ".fulfilled allows chaining", =>
+ shouldPass => promise.should.be.fulfilled.and.eventually.equal(42)
+
describe ".not.fulfilled", =>
shouldFail
op: => promise.should.not.be.fulfilled
- message: "not to be fulfilled but it was fulfilled with undefined"
+ message: "not to be fulfilled but it was fulfilled with 42"
describe ".rejected", =>
shouldFail
op: => promise.should.be.rejected
- message: "to be rejected but it was fulfilled with undefined"
+ message: "to be rejected but it was fulfilled with 42"
+
+ describe ".not.rejected passes the fulfilled value", =>
+ shouldPass => promise.should.not.be.rejected.then (passedValue) =>
+ passedValue.should.equal(42)
+
+ # .not inverts all following assertions so the following test is
+ # equivalent to promise.should.eventually.not.equal(31)
+ describe ".not.rejected allows chaining", =>
+ shouldPass => promise.should.not.be.rejected.and.eventually.equal(31)
+
describe ".rejectedWith(TypeError)", =>
shouldFail
op: => promise.should.be.rejectedWith(TypeError)
- message: "to be rejected with 'TypeError' but it was fulfilled with undefined"
+ message: "to be rejected with 'TypeError' but it was fulfilled with 42"
+ describe ".not.rejectedWith(TypeError) passes the fulfilled value", =>
+ shouldPass => promise.should.not.be.rejectedWith(TypeError).then (passedValue) =>
+ passedValue.should.equal(42)
+
+ describe ".not.rejectedWith(TypeError) allows chaining", =>
+ shouldPass => promise.should.not.be.rejectedWith(TypeError).and.eventually.equal(31)
+
describe ".rejectedWith('message substring')", =>
shouldFail
op: => promise.should.be.rejectedWith("message substring")
message: "to be rejected with an error including 'message substring' but it was fulfilled with " +
- "undefined"
+ "42"
describe ".rejectedWith(/regexp/)", =>
shouldFail
op: => promise.should.be.rejectedWith(/regexp/)
- message: "to be rejected with an error matching /regexp/ but it was fulfilled with undefined"
+ message: "to be rejected with an error matching /regexp/ but it was fulfilled with 42"
describe ".rejectedWith(TypeError, 'message substring')", =>
shouldFail
op: => promise.should.be.rejectedWith(TypeError, "message substring")
- message: "to be rejected with 'TypeError' but it was fulfilled with undefined"
+ message: "to be rejected with 'TypeError' but it was fulfilled with 42"
describe ".rejectedWith(TypeError, /regexp/)", =>
shouldFail
op: => promise.should.be.rejectedWith(TypeError, /regexp/)
- message: "to be rejected with 'TypeError' but it was fulfilled with undefined"
+ message: "to be rejected with 'TypeError' but it was fulfilled with 42"
describe ".rejectedWith(errorInstance)", =>
shouldFail
op: => promise.should.be.rejectedWith(error)
- message: "to be rejected with [Error: boo] but it was fulfilled with undefined"
+ message: "to be rejected with 'Error: boo' but it was fulfilled with 42"
describe ".not.rejected", =>
shouldPass => promise.should.not.be.rejected
@@ -82,27 +109,67 @@ describe "Promise-specific extensions:", =>
describe ".fulfilled", =>
shouldFail
op: => promise.should.be.fulfilled
- message: "to be fulfilled but it was rejected with [Error: boo]"
+ message: "to be fulfilled but it was rejected with 'Error: boo'"
+
describe ".not.fulfilled", =>
shouldPass => promise.should.not.be.fulfilled
+ describe ".not.fulfilled should allow chaining", =>
+ shouldPass => promise.should.not.be.fulfilled.and.eventually.have.property("nonexistent")
+
+ describe ".not.fulfilled should pass the rejection reason", =>
+ shouldPass => promise.should.not.be.fulfilled.then (passedError) =>
+ passedError.should.equal(error)
+
describe ".rejected", =>
shouldPass => promise.should.be.rejected
+ describe ".not.rejected", =>
+ shouldFail
+ op: => promise.should.not.be.rejected
+ message: "not to be rejected but it was rejected with 'Error: boo'"
+ describe ".rejected should allow chaining", =>
+ shouldPass => promise.should.be.rejected.and.eventually.have.property("myProp")
+
+ describe ".rejected passes the rejection reason", =>
+ shouldPass => promise.should.be.rejected.then (passedError) =>
+ passedError.should.equal(error)
+
describe ".rejectedWith(theError)", =>
shouldPass => promise.should.be.rejectedWith(error)
+
describe ".not.rejectedWith(theError)", =>
shouldFail
op: => promise.should.not.be.rejectedWith(error)
- message: "not to be rejected with [Error: boo]"
+ message: "not to be rejected with 'Error: boo'"
+
+ describe ".rejectedWith(theError) should allow chaining", =>
+ shouldPass => promise.should.be.rejectedWith(error).and.eventually.have.property("myProp")
+
+ describe ".rejectedWith(theError) passes the rejection reason", =>
+ shouldPass => promise.should.be.rejectedWith(error).then (passedError) =>
+ passedError.should.equal(error)
describe ".rejectedWith(differentError)", =>
shouldFail
op: => promise.should.be.rejectedWith(new Error)
- message: "to be rejected with [Error] but it was rejected with [Error: boo]"
+ message: "to be rejected with 'Error' but it was rejected with 'Error: boo'"
+
describe ".not.rejectedWith(differentError)", =>
shouldPass => promise.should.not.be.rejectedWith(new Error)
+ # Chai 3.5.0 never interprets the 2nd paramter to
+ # expect(fn).to.throw(a, b) as a custom error message. This is
+ # what we are testing here.
+ describe ".rejectedWith(differentError, custom)", =>
+ shouldFail
+ op: => promise.should.be.rejectedWith(new Error, custom)
+ message: "to be rejected with 'Error' but it was rejected with 'Error: boo'"
+ notMessage: custom
+
+ describe ".not.rejectedWith(differentError, custom)", =>
+ shouldPass => promise.should.not.be.rejectedWith(new Error, custom)
+
describe "with an Error having message 'foo bar'", =>
beforeEach =>
promise = rejectedPromise(new Error("foo bar"))
@@ -110,31 +177,56 @@ describe "Promise-specific extensions:", =>
describe ".rejectedWith('foo')", =>
shouldPass => promise.should.be.rejectedWith("foo")
+
+ describe ".not.rejectedWith('foo')", =>
+ shouldFail
+ op: => promise.should.not.be.rejectedWith("foo")
+ message: "not to be rejected with an error including 'foo'"
+
describe ".rejectedWith(/bar/)", =>
shouldPass => promise.should.be.rejectedWith(/bar/)
+ describe ".not.rejectedWith(/bar/)", =>
+ shouldFail
+ op: => promise.should.not.be.rejectedWith(/bar/)
+ message: "not to be rejected with an error matching /bar/"
+
describe ".rejectedWith('quux')", =>
shouldFail
op: => promise.should.be.rejectedWith("quux")
- message: "to be rejected with an error including 'quux' but got 'Error: foo bar'"
+ message: "to be rejected with an error including 'quux' but got 'foo bar'"
+
+ describe ".not.rejectedWith('quux')", =>
+ shouldPass => promise.should.be.not.rejectedWith("quux")
+
describe ".rejectedWith(/quux/)", =>
shouldFail
op: => promise.should.be.rejectedWith(/quux/)
- message: "to be rejected with an error matching /quux/ but got 'Error: foo bar'"
+ message: "to be rejected with an error matching /quux/ but got 'foo bar'"
- describe ".not.rejectedWith('foo')", =>
+ describe ".not.rejectedWith(/quux/)", =>
+ shouldPass => promise.should.not.be.rejectedWith(/quux/)
+
+ # Chai 3.5.0 never interprets the 2nd paramter to
+ # expect(fn).to.throw(a, b) as a custom error
+ # message. This is what we are testing here.
+ describe ".rejectedWith('foo', custom)", =>
+ shouldPass => promise.should.be.rejectedWith("foo", custom)
+
+ describe ".not.rejectedWith('foo', custom)", =>
shouldFail
- op: => promise.should.not.be.rejectedWith("foo")
+ op: => promise.should.not.be.rejectedWith("foo", custom)
message: "not to be rejected with an error including 'foo'"
- describe ".not.rejectedWith(/bar/)", =>
+ notMessage: custom
+
+ describe ".rejectedWith(/bar/, custom)", =>
+ shouldPass => promise.should.be.rejectedWith(/bar/, custom)
+
+ describe ".not.rejectedWith(/bar/, custom)", =>
shouldFail
op: => promise.should.not.be.rejectedWith(/bar/)
message: "not to be rejected with an error matching /bar/"
-
- describe ".not.rejectedWith('quux')", =>
- shouldPass => promise.should.not.be.rejectedWith("quux")
- describe ".not.rejectedWith(/quux/)", =>
- shouldPass => promise.should.not.be.rejectedWith(/quux/)
+ notMessage: custom
describe "with a RangeError", =>
beforeEach =>
@@ -143,15 +235,23 @@ describe "Promise-specific extensions:", =>
describe ".rejectedWith(RangeError)", =>
shouldPass => promise.should.be.rejectedWith(RangeError)
+
+ describe ".not.rejectedWith(RangeError)", =>
+ shouldFail
+ op: => promise.should.not.be.rejectedWith(RangeError)
+ message: "not to be rejected with 'RangeError' but it was rejected with 'RangeError'"
+
describe ".rejectedWith(TypeError)", =>
shouldFail
op: => promise.should.be.rejectedWith(TypeError)
- message: "to be rejected with 'TypeError' but it was rejected with [RangeError]"
+ message: "to be rejected with 'TypeError' but it was rejected with 'RangeError'"
- describe ".not.rejectedWith(RangeError)", =>
+ # Case for issue #64.
+ describe ".rejectedWith(Array)", =>
shouldFail
- op: => promise.should.not.be.rejectedWith(RangeError)
- message: "not to be rejected with 'RangeError' but it was rejected with [RangeError]"
+ op: => promise.should.be.rejectedWith(Array)
+ message: "to be rejected with 'Array' but it was rejected with 'RangeError'"
+
describe ".not.rejectedWith(TypeError)", =>
shouldPass => promise.should.not.be.rejectedWith(TypeError)
@@ -162,67 +262,115 @@ describe "Promise-specific extensions:", =>
describe ".rejectedWith(RangeError, 'foo')", =>
shouldPass => promise.should.be.rejectedWith(RangeError, "foo")
+
+ describe ".not.rejectedWith(RangeError, 'foo')", =>
+ shouldFail
+ op: => promise.should.not.be.rejectedWith(RangeError, "foo")
+ message: "not to be rejected with 'RangeError' but it was rejected with 'RangeError: foo bar'"
+
describe ".rejectedWith(RangeError, /bar/)", =>
shouldPass => promise.should.be.rejectedWith(RangeError, /bar/)
+ describe ".not.rejectedWith(RangeError, /bar/)", =>
+ shouldFail
+ op: => promise.should.not.be.rejectedWith(RangeError, /bar/)
+ message: "not to be rejected with 'RangeError' but it was rejected with 'RangeError: foo bar'"
+
describe ".rejectedWith(RangeError, 'quux')", =>
shouldFail
op: => promise.should.be.rejectedWith(RangeError, "quux")
- message: "to be rejected with an error including 'quux' but got 'RangeError: foo bar'"
+ message: "to be rejected with an error including 'quux' but got 'foo bar'"
describe ".rejectedWith(RangeError, /quux/)", =>
shouldFail
op: => promise.should.be.rejectedWith(RangeError, /quux/)
- message: "to be rejected with an error matching /quux/ but got 'RangeError: foo bar'"
+ message: "to be rejected with an error matching /quux/ but got 'foo bar'"
describe ".rejectedWith(TypeError, 'foo')", =>
shouldFail
- op: => promise.should.be.rejectedWith(TypeError)
- message: "to be rejected with 'TypeError' but it was rejected with [RangeError: foo bar]"
+ op: => promise.should.be.rejectedWith(TypeError, 'foo')
+ message: "to be rejected with 'TypeError' but it was rejected with 'RangeError: foo bar'"
describe ".rejectedWith(TypeError, /bar/)", =>
shouldFail
- op: => promise.should.be.rejectedWith(TypeError)
- message: "to be rejected with 'TypeError' but it was rejected with [RangeError: foo bar]"
+ op: => promise.should.be.rejectedWith(TypeError, /bar/)
+ message: "to be rejected with 'TypeError' but it was rejected with 'RangeError: foo bar'"
describe ".rejectedWith(TypeError, 'quux')", =>
shouldFail
- op: => promise.should.be.rejectedWith(TypeError)
- message: "to be rejected with 'TypeError' but it was rejected with [RangeError: foo bar]"
+ op: => promise.should.be.rejectedWith(TypeError, 'quux')
+ message: "to be rejected with 'TypeError' but it was rejected with 'RangeError: foo bar'"
describe ".rejectedWith(TypeError, /quux/)", =>
shouldFail
- op: => promise.should.be.rejectedWith(TypeError)
- message: "to be rejected with 'TypeError' but it was rejected with [RangeError: foo bar]"
+ op: => promise.should.be.rejectedWith(TypeError, /quux/)
+ message: "to be rejected with 'TypeError' but it was rejected with 'RangeError: foo bar'"
describe ".not.rejectedWith(RangeError, 'foo')", =>
shouldFail
- op: => promise.should.not.be.rejectedWith(RangeError)
- message: "not to be rejected with 'RangeError' but it was rejected with [RangeError: foo bar]"
+ op: => promise.should.not.be.rejectedWith(RangeError, 'foo')
+ message: "not to be rejected with 'RangeError' but it was rejected with 'RangeError: foo bar'"
describe ".not.rejectedWith(RangeError, /bar/)", =>
shouldFail
- op: => promise.should.not.be.rejectedWith(RangeError)
- message: "not to be rejected with 'RangeError' but it was rejected with [RangeError: foo bar]"
+ op: => promise.should.not.be.rejectedWith(RangeError, /bar/)
+ message: "not to be rejected with 'RangeError' but it was rejected with 'RangeError: foo bar'"
describe ".not.rejectedWith(RangeError, 'quux')", =>
- shouldFail
- op: => promise.should.not.be.rejectedWith(RangeError)
- message: "not to be rejected with 'RangeError' but it was rejected with [RangeError: foo bar]"
+ shouldPass => promise.should.not.be.rejectedWith(RangeError, 'quux')
describe ".not.rejectedWith(RangeError, /quux/)", =>
- shouldFail
- op: => promise.should.not.be.rejectedWith(RangeError)
- message: "not to be rejected with 'RangeError' but it was rejected with [RangeError: foo bar]"
-
+ shouldPass => promise.should.not.be.rejectedWith(RangeError, /quux/)
describe ".not.rejectedWith(TypeError, 'foo')", =>
- shouldFail
- op: => promise.should.not.be.rejectedWith(TypeError, "foo")
- message: "not to be rejected with an error including 'foo'"
+ shouldPass => promise.should.not.be.rejectedWith(TypeError, "foo")
describe ".not.rejectedWith(TypeError, /bar/)", =>
- shouldFail
- op: => promise.should.not.be.rejectedWith(TypeError, /bar/)
- message: "not to be rejected with an error matching /bar/"
-
+ shouldPass => promise.should.not.be.rejectedWith(TypeError, /bar/)
describe ".not.rejectedWith(TypeError, 'quux')", =>
shouldPass => promise.should.not.be.rejectedWith(TypeError, "quux")
describe ".not.rejectedWith(TypeError, /quux/)", =>
shouldPass => promise.should.not.be.rejectedWith(TypeError, /quux/)
+ describe ".rejectedWith(RangeError, 'foo', custom)", =>
+ shouldPass => promise.should.be.rejectedWith(RangeError, "foo", custom)
+
+ describe ".not.rejectedWith(RangeError, 'foo', custom)", =>
+ shouldFail
+ op: => promise.should.not.be.rejectedWith(RangeError, "foo", custom)
+ message: custom
+
+ describe ".rejectedWith(RangeError, /bar/, custom)", =>
+ shouldPass => promise.should.be.rejectedWith(RangeError, /bar/, custom)
+
+ describe ".not.rejectedWith(RangeError, /bar/, custom)", =>
+ shouldFail
+ op: => promise.should.not.be.rejectedWith(RangeError, /bar/, custom)
+ message: custom
+
+ describe ".rejectedWith(RangeError, 'quux', custom)", =>
+ shouldFail
+ op: => promise.should.be.rejectedWith(RangeError, "quux", custom)
+ message: custom
+
+ describe ".not.rejectedWith(TypeError, 'quux', custom)", =>
+ shouldPass => promise.should.not.be.rejectedWith(TypeError, "quux", custom)
+
+ describe ".rejectedWith(RangeError, /quux/, custom)", =>
+ shouldFail
+ op: => promise.should.be.rejectedWith(RangeError, /quux/, custom)
+ message: custom
+
+ describe ".not.rejectedWith(TypeError, /quux/, custom)", =>
+ shouldPass => promise.should.not.be.rejectedWith(TypeError, /quux/, custom)
+
+ describe ".rejectedWith(RangeError, undefined, custom)", =>
+ shouldPass => promise.should.be.rejectedWith(RangeError, undefined, custom)
+
+ describe ".not.rejectedWith(RangeError, undefined, custom)", =>
+ shouldFail
+ op: => promise.should.not.be.rejectedWith(RangeError, undefined, custom)
+ message: custom
+
+ describe ".rejectedWith(TypeError, undefined, custom)", =>
+ shouldFail
+ op: => promise.should.be.rejectedWith(TypeError, undefined, custom)
+ message: custom
+
+ describe ".not.rejectedWith(TypeError, undefined, custom)", =>
+ shouldPass => promise.should.not.be.rejectedWith(TypeError, undefined, custom)
describe ".should.notify(done)", =>
it "should fail the test with the original error", (done) =>
diff --git a/test/support/common.js b/test/support/common.js
index b11681c..b58ef2e 100644
--- a/test/support/common.js
+++ b/test/support/common.js
@@ -25,22 +25,27 @@ global.shouldPass = function (promiseProducer) {
global.shouldFail = function (options) {
var promiseProducer = options.op;
var desiredMessageSubstring = options.message;
+ var nonDesiredMessageSubstring = options.notMessage;
it("should return a promise rejected with an assertion error", function (done) {
promiseProducer().then(function () {
- done(new Error("Expected promise to be rejected with an assertion error, but it was fulfilled"));
+ throw new Error("Expected promise to be rejected with an assertion error, but it was fulfilled");
}, function (reason) {
if (Object(reason) !== reason || reason.constructor.name !== "AssertionError") {
- done(new Error("Expected promise to be rejected with an AssertionError but it was rejected with " +
- reason));
- } else {
- if (desiredMessageSubstring && reason.message.indexOf(desiredMessageSubstring) === -1) {
- done(new Error("Expected promise to be rejected with an AssertionError containing \"" +
- desiredMessageSubstring + "\" but it was rejected with " + reason));
- } else {
- done();
- }
+ throw new Error("Expected promise to be rejected with an AssertionError but it was rejected with " +
+ reason);
}
- });
+
+ if (desiredMessageSubstring && reason.message.indexOf(desiredMessageSubstring) === -1) {
+ throw new Error("Expected promise to be rejected with an AssertionError containing \"" +
+ desiredMessageSubstring + "\" but it was rejected with " + reason);
+ }
+
+ if (nonDesiredMessageSubstring && reason.message.indexOf(nonDesiredMessageSubstring) !== -1) {
+ throw new Error("Expected promise to be rejected with an AssertionError not containing \"" +
+ nonDesiredMessageSubstring + "\" but it was rejected with " + reason);
+ }
+ }).then(done, done);
+
});
};