Skip to content

Instantly share code, notes, and snippets.

@domenic
Created October 3, 2012 02:32
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save domenic/3824602 to your computer and use it in GitHub Desktop.
Save domenic/3824602 to your computer and use it in GitHub Desktop.
Promise test suite
"use strict"
Q = require("..")
other = {} # a dummy value we don't want to be strict equal to
sentinel = {} # a sentinel fulfillment value to test for with strict equality
describe "Chaining off of a fulfilled promise", =>
describe "when the first fulfillment callback returns a new value", =>
it "should call the second fulfillment callback with that new value", (done) =>
Q.resolve(other)
.then(=> sentinel)
.then (value) =>
value.should.equal(sentinel)
done()
describe "when the first fulfillment callback throws an error", =>
it "should call the second rejection callback with that error as the reason", (done) =>
Q.resolve(other)
.then(=> throw sentinel)
.then null, (reason) =>
reason.should.equal(sentinel)
done()
describe "with only a rejection callback", =>
it "should call the second fulfillment callback with the original value", (done) =>
Q.resolve(sentinel)
.then(null, => other)
.then (value) =>
value.should.equal(sentinel)
done()
describe "Chaining off of an eventually-fulfilled promise", =>
describe "when the first fulfillment callback returns a new value", =>
it "should call the second fulfillment callback with that new value", (done) =>
deferred = Q.defer()
deferred.promise
.then(=> sentinel)
.then (value) =>
value.should.equal(sentinel)
done()
deferred.resolve(other)
describe "when the first fulfillment callback throws an error", =>
it "should call the second rejection callback with that error as the reason", (done) =>
deferred = Q.defer()
deferred.promise
.then(=> throw sentinel)
.then null, (reason) =>
reason.should.equal(sentinel)
done()
deferred.resolve(other)
describe "with only a rejection callback", =>
it "should call the second fulfillment callback with the original value", (done) =>
deferred = Q.defer()
deferred.promise
.then(null, => other)
.then (value) =>
value.should.equal(sentinel)
done()
deferred.resolve(sentinel)
describe "Chaining off of a rejected promise", =>
describe "when the first rejection callback returns a new value", =>
it "should call the second fulfillment callback with that new value", (done) =>
Q.reject(other)
.then(null, => sentinel)
.then (value) =>
value.should.equal(sentinel)
done()
describe "when the first rejection callback throws a new reason", =>
it "should call the second rejection callback with that new reason", (done) =>
Q.reject(other)
.then(null, => throw sentinel)
.then null, (reason) =>
reason.should.equal(sentinel)
done()
describe "when there is only a fulfillment callback", =>
it "should call the second rejection callback with the original reason", (done) =>
Q.reject(sentinel)
.then(=> other)
.then null, (reason) =>
reason.should.equal(sentinel)
done()
describe "Chaining off of an eventually-rejected promise", =>
describe "when the first rejection callback returns a new value", =>
it "should call the second fulfillment callback with that new value", (done) =>
deferred = Q.defer()
deferred.promise
.then(null, => sentinel)
.then (value) =>
value.should.equal(sentinel)
done()
deferred.reject(other)
describe "when the first rejection callback throws a new reason", =>
it "should call the second rejection callback with that new reason", (done) =>
deferred = Q.defer()
deferred.promise
.then(null, => throw sentinel)
.then null, (reason) =>
reason.should.equal(sentinel)
done()
deferred.reject(other)
describe "when there is only a fulfillment callback", =>
it "should call the second rejection callback with the original reason", (done) =>
deferred = Q.defer()
deferred.promise
.then(=> other)
.then null, (reason) =>
reason.should.equal(sentinel)
done()
deferred.reject(sentinel)
"use strict"
Q = require("..")
sinon = require("sinon")
sentinel = {} # a sentinel fulfillment value to test for with strict equality
describe "Multiple handlers", =>
describe "when there are multiple fulfillment handlers for a fulfilled promise", =>
it "should call them all, in order, with the fulfillment value", (done) =>
deferred = Q.defer()
deferred.resolve(sentinel)
[spyA, spyB, spyC] = [sinon.spy(), sinon.spy(), sinon.spy()]
deferred.promise.then(spyA)
deferred.promise.then(spyB)
deferred.promise.then(spyC)
deferred.promise.then =>
spyA.should.have.been.calledWithExactly(sinon.match.same(sentinel))
spyB.should.have.been.calledWithExactly(sinon.match.same(sentinel))
spyC.should.have.been.calledWithExactly(sinon.match.same(sentinel))
spyA.should.have.been.calledBefore(spyB)
spyB.should.have.been.calledBefore(spyC)
done()
it "should not be impeded by one of them throwing an error", (done) =>
deferred = Q.defer()
deferred.resolve(sentinel)
[spyA, spyB] = [sinon.stub().throws(), sinon.spy()]
deferred.promise.then(spyA)
deferred.promise.then(spyB)
deferred.promise.then =>
spyA.should.have.been.calledWithExactly(sinon.match.same(sentinel))
spyB.should.have.been.calledWithExactly(sinon.match.same(sentinel))
spyA.should.have.been.calledBefore(spyB)
done()
describe "when there are multiple rejection handlers for a rejected promise", =>
it "should call them all, in order, with the rejection reason", (done) =>
deferred = Q.defer()
deferred.reject(sentinel)
[spyA, spyB, spyC] = [sinon.spy(), sinon.spy(), sinon.spy()]
deferred.promise.then(null, spyA)
deferred.promise.then(null, spyB)
deferred.promise.then(null, spyC)
deferred.promise.then null, =>
spyA.should.have.been.calledWithExactly(sinon.match.same(sentinel))
spyB.should.have.been.calledWithExactly(sinon.match.same(sentinel))
spyC.should.have.been.calledWithExactly(sinon.match.same(sentinel))
spyA.should.have.been.calledBefore(spyB)
spyB.should.have.been.calledBefore(spyC)
done()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment