Skip to content

Commit

Permalink
Use .notify(done) instead of .then(done, done)
Browse files Browse the repository at this point in the history
This is a breaking change, with benefits discussed at https://groups.google.com/d/msg/chaijs/oaA_LZxXUWU/sZdxgG1lvAIJ
  • Loading branch information
domenic committed Apr 9, 2012
1 parent 71e2330 commit 5f9acf7
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 41 deletions.
26 changes: 10 additions & 16 deletions lib/chai-as-promised.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,6 @@

var Assertion = chai.Assertion;

// Chai as Promised needs a way to detect that chaining-time is over and it should return a promise resolved with
// `undefined`, instead of with a chainable assertion. All function asserts make this assumption, but most
// properties exist only for chaining purposes, so we keep a list of the ones that signal "done"ness here. TODO:
// make this less of a hack.
var capstoneProperties = ["arguments", "empty", "exist", "false", "ok", "true"];

function property(name, asserter) {
Object.defineProperty(Assertion.prototype, name, {
get: asserter,
Expand All @@ -39,7 +33,7 @@
}

var fulfilledAsserter = function () {
return this.obj.then(
var transformedPromise = this.obj.then(
function (value) {
if (this.negate) {
// If we're negated, `this.assert`'s behavior is actually flipped, so `this.assert(true, ...)` will
Expand All @@ -57,6 +51,8 @@
chai.inspect(reason));
}.bind(this)
);

return promiseWithAsserters(transformedPromise, this);
};

var rejectedAsserter = function () {
Expand Down Expand Up @@ -178,7 +174,7 @@
}
}.bind(this);

return transformedPromise.then(onTransformedFulfilled, onTransformedRejected);
return promiseWithAsserters(transformedPromise.then(onTransformedFulfilled, onTransformedRejected), this);
}.bind(this);

return transformedPromise;
Expand Down Expand Up @@ -217,26 +213,24 @@
var args = arguments;

return promiseToDoAsserter(function (assertion) {
// Don't pass through the result: this is the end of the chain
assertion[asserterName].apply(assertion, args);
return assertion[asserterName].apply(assertion, args);
});
};
} else if (propertyDescriptor.get) {
propertyDescriptor.get = function () {
return promiseToDoAsserter(function (assertion) {
var result = assertion[asserterName];

// Only pass through the result if we want to continue chaining.
if (capstoneProperties.indexOf(asserterName) === -1) {
return result;
}
return assertion[asserterName];
});
};
}

Object.defineProperty(augmentedPromise, asserterName, propertyDescriptor);
});

augmentedPromise.notify = function (callback) {
return augmentedPromise.then(function () { callback(); }, callback);
};

return augmentedPromise;
}

Expand Down
12 changes: 12 additions & 0 deletions test/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,15 @@ global.expect = chai.expect;
global.AssertionError = chai.AssertionError;
global.Assertion = chai.Assertion;
global.Q = Q;

global.shouldPass = function (promiseProducer) {
it("should return a fulfilled promise", function (done) {
expect(promiseProducer()).to.be.fulfilled.notify(done);
});
};

global.shouldFail = function (promiseProducer) {
it("should return a promise rejected with an assertion error", function (done) {
expect(promiseProducer()).to.be.rejected.with(AssertionError).notify(done);
});
};
30 changes: 13 additions & 17 deletions test/fulfillmentValues.coffee
Original file line number Diff line number Diff line change
@@ -1,31 +1,27 @@
shouldPass = (promiseProducer) ->
it "should return a fulfilled promise", (done) ->
expect(promiseProducer()).to.be.fulfilled.then(done, done)

shouldFail = (promiseProducer) ->
it "should return a promise rejected with an assertion error", (done) ->
expect(promiseProducer()).to.be.rejected.with(AssertionError).then(done, done)

describe "Fulfillment value assertions:", ->
describe "Fulfillment value assertions:", ->
promise = null

describe "Direct tests of fulfilled promises", ->
it ".eventually.equal(42)", (done) ->
Q.resolve(42).should.eventually.equal(42).then(done, done)
Q.resolve(42).should.eventually.equal(42).notify(done)
it ".eventually.be.arguments", (done) ->
Q.resolve(arguments).should.eventually.be.arguments.then(done, done)
Q.resolve(arguments).should.eventually.be.arguments.notify(done)
it ".eventually.be.empty", (done) ->
Q.resolve([]).should.eventually.be.empty.then(done, done)
Q.resolve([]).should.eventually.be.empty.notify(done)
it ".eventually.exist", (done) ->
Q.resolve(true).should.eventually.exist.then(done, done)
Q.resolve(true).should.eventually.exist.notify(done)
it ".eventually.be.false", (done) ->
Q.resolve(false).should.eventually.be.false.then(done, done)
Q.resolve(false).should.eventually.be.false.notify(done)
it ".eventually.be.ok", (done) ->
Q.resolve({}).should.eventually.be.ok.then(done, done)
Q.resolve({}).should.eventually.be.ok.notify(done)
it ".eventually.be.true", (done) ->
Q.resolve(true).should.eventually.be.true.then(done, done)
Q.resolve(true).should.eventually.be.true.notify(done)
it ".become(true)", (done) ->
Q.resolve(true).should.become(true).then(done, done)
Q.resolve(true).should.become(true).notify(done)

describe "Chaining", ->
it ".eventually.be.ok.and.equal(42)", (done) ->
Q.resolve(42).should.eventually.be.ok.and.equal(42).notify(done)

describe "On a promise fulfilled with the number 42", ->
beforeEach ->
Expand Down
8 changes: 0 additions & 8 deletions test/promiseSpecific.coffee
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
shouldPass = (promiseProducer) ->
it "should return a fulfilled promise", (done) ->
expect(promiseProducer()).to.be.fulfilled.then(done, done)

shouldFail = (promiseProducer) ->
it "should return a promise rejected with an assertion error", (done) ->
expect(promiseProducer()).to.be.rejected.with(AssertionError).then(done, done)

describe "Promise-specific extensions:", ->
promise = null

Expand Down

0 comments on commit 5f9acf7

Please sign in to comment.