chai-as-promised
Advanced tools
Comparing version 5.3.0 to 6.0.0
@@ -1,375 +0,374 @@ | ||
(function () { | ||
"use strict"; | ||
"use strict"; | ||
var checkError = require("check-error"); | ||
// Module systems magic dance. | ||
module.exports = function (chai, utils) { | ||
var Assertion = chai.Assertion; | ||
var assert = chai.assert; | ||
/* istanbul ignore else */ | ||
if (typeof require === "function" && typeof exports === "object" && typeof module === "object") { | ||
// NodeJS | ||
module.exports = chaiAsPromised; | ||
} else if (typeof define === "function" && define.amd) { | ||
// AMD | ||
define(function () { | ||
return chaiAsPromised; | ||
// If we are using a version of Chai that has checkError on it, | ||
// we want to use that version to be consistent. Otherwise, we use | ||
// what was passed to the factory. | ||
if (utils.checkError) { | ||
checkError = utils.checkError; | ||
} | ||
function isLegacyJQueryPromise(thenable) { | ||
// jQuery promises are Promises/A+-compatible since 3.0.0. jQuery 3.0.0 is also the first version | ||
// to define the catch method. | ||
return typeof thenable.catch !== "function" && | ||
typeof thenable.always === "function" && | ||
typeof thenable.done === "function" && | ||
typeof thenable.fail === "function" && | ||
typeof thenable.pipe === "function" && | ||
typeof thenable.progress === "function" && | ||
typeof thenable.state === "function"; | ||
} | ||
function assertIsAboutPromise(assertion) { | ||
if (typeof assertion._obj.then !== "function") { | ||
throw new TypeError(utils.inspect(assertion._obj) + " is not a thenable."); | ||
} | ||
if (isLegacyJQueryPromise(assertion._obj)) { | ||
throw new TypeError("Chai as Promised is incompatible with thenables of jQuery<3.0.0, sorry! Please " + | ||
"upgrade jQuery or use another Promises/A+ compatible library (see " + | ||
"http://promisesaplus.com/)."); | ||
} | ||
} | ||
function method(name, asserter) { | ||
utils.addMethod(Assertion.prototype, name, function () { | ||
assertIsAboutPromise(this); | ||
return asserter.apply(this, arguments); | ||
}); | ||
} else { | ||
/*global self: false */ | ||
} | ||
// Other environment (usually <script> tag): plug in to global chai instance directly. | ||
chai.use(chaiAsPromised); | ||
function property(name, asserter) { | ||
utils.addProperty(Assertion.prototype, name, function () { | ||
assertIsAboutPromise(this); | ||
return asserter.apply(this, arguments); | ||
}); | ||
} | ||
// Expose as a property of the global object so that consumers can configure the `transferPromiseness` property. | ||
self.chaiAsPromised = chaiAsPromised; | ||
function doNotify(promise, done) { | ||
promise.then(function () { done(); }, done); | ||
} | ||
chaiAsPromised.transferPromiseness = function (assertion, promise) { | ||
assertion.then = promise.then.bind(promise); | ||
}; | ||
// These are for clarity and to bypass Chai refusing to allow `undefined` as actual when used with `assert`. | ||
function assertIfNegated(assertion, message, extra) { | ||
assertion.assert(true, null, message, extra.expected, extra.actual); | ||
} | ||
chaiAsPromised.transformAsserterArgs = function (values) { | ||
return values; | ||
}; | ||
function assertIfNotNegated(assertion, message, extra) { | ||
assertion.assert(false, message, null, extra.expected, extra.actual); | ||
} | ||
function chaiAsPromised(chai, utils) { | ||
var Assertion = chai.Assertion; | ||
var assert = chai.assert; | ||
function getBasePromise(assertion) { | ||
// We need to chain subsequent asserters on top of ones in the chain already (consider | ||
// `eventually.have.property("foo").that.equals("bar")`), only running them after the existing ones pass. | ||
// So the first base-promise is `assertion._obj`, but after that we use the assertions themselves, i.e. | ||
// previously derived promises, to chain off of. | ||
return typeof assertion.then === "function" ? assertion : assertion._obj; | ||
} | ||
function isLegacyJQueryPromise(thenable) { | ||
// jQuery promises are Promises/A+-compatible since 3.0.0. jQuery 3.0.0 is also the first version | ||
// to define the catch method. | ||
return typeof thenable.catch !== "function" && | ||
typeof thenable.always === "function" && | ||
typeof thenable.done === "function" && | ||
typeof thenable.fail === "function" && | ||
typeof thenable.pipe === "function" && | ||
typeof thenable.progress === "function" && | ||
typeof thenable.state === "function"; | ||
} | ||
function getReasonName(reason) { | ||
return (reason instanceof Error) ? reason.toString() : checkError.getConstructorName(reason); | ||
} | ||
function assertIsAboutPromise(assertion) { | ||
if (typeof assertion._obj.then !== "function") { | ||
throw new TypeError(utils.inspect(assertion._obj) + " is not a thenable."); | ||
// Grab these first, before we modify `Assertion.prototype`. | ||
var propertyNames = Object.getOwnPropertyNames(Assertion.prototype); | ||
var propertyDescs = {}; | ||
propertyNames.forEach(function (name) { | ||
propertyDescs[name] = Object.getOwnPropertyDescriptor(Assertion.prototype, name); | ||
}); | ||
property("fulfilled", function () { | ||
var that = this; | ||
var derivedPromise = getBasePromise(that).then( | ||
function (value) { | ||
assertIfNegated(that, | ||
"expected promise not to be fulfilled but it was fulfilled with #{act}", | ||
{ actual: value }); | ||
return value; | ||
}, | ||
function (reason) { | ||
assertIfNotNegated(that, | ||
"expected promise to be fulfilled but it was rejected with #{act}", | ||
{ actual: getReasonName(reason) }); | ||
return reason; | ||
} | ||
if (isLegacyJQueryPromise(assertion._obj)) { | ||
throw new TypeError("Chai as Promised is incompatible with thenables of jQuery<3.0.0, sorry! Please " + | ||
"upgrade jQuery or use another Promises/A+ compatible library (see " + | ||
"http://promisesaplus.com/)."); | ||
); | ||
module.exports.transferPromiseness(that, derivedPromise); | ||
}); | ||
property("rejected", function () { | ||
var that = this; | ||
var derivedPromise = getBasePromise(that).then( | ||
function (value) { | ||
assertIfNotNegated(that, | ||
"expected promise to be rejected but it was fulfilled with #{act}", | ||
{ actual: value }); | ||
return value; | ||
}, | ||
function (reason) { | ||
assertIfNegated(that, | ||
"expected promise not to be rejected but it was rejected with #{act}", | ||
{ actual: getReasonName(reason) }); | ||
// Return the reason, transforming this into a fulfillment, to allow further assertions, e.g. | ||
// `promise.should.be.rejected.and.eventually.equal("reason")`. | ||
return reason; | ||
} | ||
} | ||
); | ||
function method(name, asserter) { | ||
utils.addMethod(Assertion.prototype, name, function () { | ||
assertIsAboutPromise(this); | ||
return asserter.apply(this, arguments); | ||
}); | ||
} | ||
module.exports.transferPromiseness(that, derivedPromise); | ||
}); | ||
function property(name, asserter) { | ||
utils.addProperty(Assertion.prototype, name, function () { | ||
assertIsAboutPromise(this); | ||
return asserter.apply(this, arguments); | ||
}); | ||
} | ||
method("rejectedWith", function (errorLike, errMsgMatcher, message) { | ||
var errorLikeName = null; | ||
var negate = utils.flag(this, "negate") || false; | ||
function doNotify(promise, done) { | ||
promise.then(function () { done(); }, done); | ||
// rejectedWith with that is called without arguments is | ||
// the same as a plain ".rejected" use. | ||
if (errorLike === undefined && errMsgMatcher === undefined && | ||
message === undefined) { | ||
/* jshint expr: true */ | ||
this.rejected; | ||
return; | ||
} | ||
// These are for clarity and to bypass Chai refusing to allow `undefined` as actual when used with `assert`. | ||
function assertIfNegated(assertion, message, extra) { | ||
assertion.assert(true, null, message, extra.expected, extra.actual); | ||
if (message !== undefined) { | ||
utils.flag(this, "message", message); | ||
} | ||
function assertIfNotNegated(assertion, message, extra) { | ||
assertion.assert(false, message, null, extra.expected, extra.actual); | ||
if (errorLike instanceof RegExp || typeof errorLike === "string") { | ||
errMsgMatcher = errorLike; | ||
errorLike = null; | ||
} else if (errorLike && errorLike instanceof Error) { | ||
errorLikeName = errorLike.toString(); | ||
} else if (typeof errorLike === "function") { | ||
errorLikeName = checkError.getConstructorName(errorLike); | ||
} else { | ||
errorLike = null; | ||
} | ||
var everyArgIsDefined = Boolean(errorLike && errMsgMatcher); | ||
function getBasePromise(assertion) { | ||
// We need to chain subsequent asserters on top of ones in the chain already (consider | ||
// `eventually.have.property("foo").that.equals("bar")`), only running them after the existing ones pass. | ||
// So the first base-promise is `assertion._obj`, but after that we use the assertions themselves, i.e. | ||
// previously derived promises, to chain off of. | ||
return typeof assertion.then === "function" ? assertion : assertion._obj; | ||
var matcherRelation = "including"; | ||
if (errMsgMatcher instanceof RegExp) { | ||
matcherRelation = "matching"; | ||
} | ||
// Grab these first, before we modify `Assertion.prototype`. | ||
var that = this; | ||
var derivedPromise = getBasePromise(that).then( | ||
function (value) { | ||
var assertionMessage = null; | ||
var expected = null; | ||
var propertyNames = Object.getOwnPropertyNames(Assertion.prototype); | ||
if (errorLike) { | ||
assertionMessage = "expected promise to be rejected with #{exp} but it was fulfilled with " + | ||
"#{act}"; | ||
expected = errorLikeName; | ||
} else if (errMsgMatcher) { | ||
assertionMessage = "expected promise to be rejected with an error " + matcherRelation + | ||
" #{exp} but it was fulfilled with #{act}"; | ||
expected = errMsgMatcher; | ||
} | ||
var propertyDescs = {}; | ||
propertyNames.forEach(function (name) { | ||
propertyDescs[name] = Object.getOwnPropertyDescriptor(Assertion.prototype, name); | ||
}); | ||
assertIfNotNegated(that, assertionMessage, { expected: expected, actual: value }); | ||
return value; | ||
}, | ||
function (reason) { | ||
var errorLikeCompatible = errorLike && (errorLike instanceof Error ? | ||
checkError.compatibleInstance(reason, errorLike) : | ||
checkError.compatibleConstructor(reason, errorLike)); | ||
property("fulfilled", function () { | ||
var that = this; | ||
var derivedPromise = getBasePromise(that).then( | ||
function (value) { | ||
that._obj = value; | ||
assertIfNegated(that, | ||
"expected promise not to be fulfilled but it was fulfilled with #{act}", | ||
{ actual: value }); | ||
return value; | ||
}, | ||
function (reason) { | ||
assertIfNotNegated(that, | ||
"expected promise to be fulfilled but it was rejected with #{act}", | ||
{ actual: reason }); | ||
} | ||
); | ||
var errMsgMatcherCompatible = errMsgMatcher && checkError.compatibleMessage(reason, errMsgMatcher); | ||
chaiAsPromised.transferPromiseness(that, derivedPromise); | ||
}); | ||
var reasonName = getReasonName(reason); | ||
property("rejected", function () { | ||
var that = this; | ||
var derivedPromise = getBasePromise(that).then( | ||
function (value) { | ||
that._obj = value; | ||
assertIfNotNegated(that, | ||
"expected promise to be rejected but it was fulfilled with #{act}", | ||
{ actual: value }); | ||
return value; | ||
}, | ||
function (reason) { | ||
assertIfNegated(that, | ||
"expected promise not to be rejected but it was rejected with #{act}", | ||
{ actual: reason }); | ||
if (negate && everyArgIsDefined) { | ||
if (errorLikeCompatible && errMsgMatcherCompatible) { | ||
that.assert(true, | ||
null, | ||
"expected promise not to be rejected with #{exp} but it was rejected " + | ||
"with #{act}", | ||
errorLikeName, | ||
reasonName); | ||
} | ||
} | ||
else { | ||
if (errorLike) { | ||
that.assert(errorLikeCompatible, | ||
"expected promise to be rejected with #{exp} but it was rejected with #{act}", | ||
"expected promise not to be rejected with #{exp} but it was rejected " + | ||
"with #{act}", | ||
errorLikeName, | ||
reasonName); | ||
} | ||
// Return the reason, transforming this into a fulfillment, to allow further assertions, e.g. | ||
// `promise.should.be.rejected.and.eventually.equal("reason")`. | ||
return reason; | ||
if (errMsgMatcher) { | ||
that.assert(errMsgMatcherCompatible, | ||
"expected promise to be rejected with an error " + matcherRelation + | ||
" #{exp} but got #{act}", | ||
"expected promise not to be rejected with an error " + matcherRelation + | ||
" #{exp}", | ||
errMsgMatcher, | ||
checkError.getMessage(reason)); | ||
} | ||
} | ||
); | ||
chaiAsPromised.transferPromiseness(that, derivedPromise); | ||
}); | ||
method("rejectedWith", function (Constructor, message) { | ||
var desiredReason = null; | ||
var constructorName = null; | ||
if (Constructor instanceof RegExp || typeof Constructor === "string") { | ||
message = Constructor; | ||
Constructor = null; | ||
} else if (Constructor && Constructor instanceof Error) { | ||
desiredReason = Constructor; | ||
Constructor = null; | ||
message = null; | ||
} else if (typeof Constructor === "function") { | ||
constructorName = (new Constructor()).name; | ||
} else { | ||
Constructor = null; | ||
return reason; | ||
} | ||
); | ||
var that = this; | ||
var derivedPromise = getBasePromise(that).then( | ||
function (value) { | ||
var assertionMessage = null; | ||
var expected = null; | ||
module.exports.transferPromiseness(that, derivedPromise); | ||
}); | ||
if (Constructor) { | ||
assertionMessage = "expected promise to be rejected with #{exp} but it was fulfilled with " + | ||
"#{act}"; | ||
expected = constructorName; | ||
} else if (message) { | ||
var verb = message instanceof RegExp ? "matching" : "including"; | ||
assertionMessage = "expected promise to be rejected with an error " + verb + " #{exp} but it " + | ||
"was fulfilled with #{act}"; | ||
expected = message; | ||
} else if (desiredReason) { | ||
assertionMessage = "expected promise to be rejected with #{exp} but it was fulfilled with " + | ||
"#{act}"; | ||
expected = desiredReason; | ||
} | ||
property("eventually", function () { | ||
utils.flag(this, "eventually", true); | ||
}); | ||
that._obj = value; | ||
method("notify", function (done) { | ||
doNotify(getBasePromise(this), done); | ||
}); | ||
assertIfNotNegated(that, assertionMessage, { expected: expected, actual: value }); | ||
}, | ||
function (reason) { | ||
if (Constructor) { | ||
that.assert(reason instanceof Constructor, | ||
"expected promise to be rejected with #{exp} but it was rejected with #{act}", | ||
"expected promise not to be rejected with #{exp} but it was rejected with #{act}", | ||
constructorName, | ||
reason); | ||
} | ||
method("become", function (value, message) { | ||
return this.eventually.deep.equal(value, message); | ||
}); | ||
var reasonMessage = utils.type(reason) === "object" && "message" in reason ? | ||
reason.message : | ||
"" + reason; | ||
if (message && reasonMessage !== null && reasonMessage !== undefined) { | ||
if (message instanceof RegExp) { | ||
that.assert(message.test(reasonMessage), | ||
"expected promise to be rejected with an error matching #{exp} but got #{act}", | ||
"expected promise not to be rejected with an error matching #{exp}", | ||
message, | ||
reasonMessage); | ||
} | ||
if (typeof message === "string") { | ||
that.assert(reasonMessage.indexOf(message) !== -1, | ||
"expected promise to be rejected with an error including #{exp} but got #{act}", | ||
"expected promise not to be rejected with an error including #{exp}", | ||
message, | ||
reasonMessage); | ||
} | ||
} | ||
//////// | ||
// `eventually` | ||
if (desiredReason) { | ||
that.assert(reason === desiredReason, | ||
"expected promise to be rejected with #{exp} but it was rejected with #{act}", | ||
"expected promise not to be rejected with #{exp}", | ||
desiredReason, | ||
reason); | ||
} | ||
} | ||
); | ||
// We need to be careful not to trigger any getters, thus `Object.getOwnPropertyDescriptor` usage. | ||
var methodNames = propertyNames.filter(function (name) { | ||
return name !== "assert" && typeof propertyDescs[name].value === "function"; | ||
}); | ||
chaiAsPromised.transferPromiseness(that, derivedPromise); | ||
methodNames.forEach(function (methodName) { | ||
Assertion.overwriteMethod(methodName, function (originalMethod) { | ||
return function () { | ||
doAsserterAsyncAndAddThen(originalMethod, this, arguments); | ||
}; | ||
}); | ||
}); | ||
property("eventually", function () { | ||
utils.flag(this, "eventually", true); | ||
}); | ||
var getterNames = propertyNames.filter(function (name) { | ||
return name !== "_obj" && typeof propertyDescs[name].get === "function"; | ||
}); | ||
method("notify", function (done) { | ||
doNotify(getBasePromise(this), done); | ||
}); | ||
getterNames.forEach(function (getterName) { | ||
// Chainable methods are things like `an`, which can work both for `.should.be.an.instanceOf` and as | ||
// `should.be.an("object")`. We need to handle those specially. | ||
var isChainableMethod = Assertion.prototype.__methods.hasOwnProperty(getterName); | ||
method("become", function (value, message) { | ||
return this.eventually.deep.equal(value, message); | ||
}); | ||
//////// | ||
// `eventually` | ||
// We need to be careful not to trigger any getters, thus `Object.getOwnPropertyDescriptor` usage. | ||
var methodNames = propertyNames.filter(function (name) { | ||
return name !== "assert" && typeof propertyDescs[name].value === "function"; | ||
}); | ||
methodNames.forEach(function (methodName) { | ||
Assertion.overwriteMethod(methodName, function (originalMethod) { | ||
if (isChainableMethod) { | ||
Assertion.overwriteChainableMethod( | ||
getterName, | ||
function (originalMethod) { | ||
return function() { | ||
doAsserterAsyncAndAddThen(originalMethod, this, arguments); | ||
}; | ||
}, | ||
function (originalGetter) { | ||
return function() { | ||
doAsserterAsyncAndAddThen(originalGetter, this); | ||
}; | ||
} | ||
); | ||
} else { | ||
Assertion.overwriteProperty(getterName, function (originalGetter) { | ||
return function () { | ||
doAsserterAsyncAndAddThen(originalMethod, this, arguments); | ||
doAsserterAsyncAndAddThen(originalGetter, this); | ||
}; | ||
}); | ||
}); | ||
} | ||
}); | ||
var getterNames = propertyNames.filter(function (name) { | ||
return name !== "_obj" && typeof propertyDescs[name].get === "function"; | ||
}); | ||
function doAsserterAsyncAndAddThen(asserter, assertion, args) { | ||
// Since we're intercepting all methods/properties, we need to just pass through if they don't want | ||
// `eventually`, or if we've already fulfilled the promise (see below). | ||
if (!utils.flag(assertion, "eventually")) { | ||
return asserter.apply(assertion, args); | ||
} | ||
getterNames.forEach(function (getterName) { | ||
// Chainable methods are things like `an`, which can work both for `.should.be.an.instanceOf` and as | ||
// `should.be.an("object")`. We need to handle those specially. | ||
var isChainableMethod = Assertion.prototype.__methods.hasOwnProperty(getterName); | ||
var derivedPromise = getBasePromise(assertion).then(function (value) { | ||
// Set up the environment for the asserter to actually run: `_obj` should be the fulfillment value, and | ||
// now that we have the value, we're no longer in "eventually" mode, so we won't run any of this code, | ||
// just the base Chai code that we get to via the short-circuit above. | ||
assertion._obj = value; | ||
utils.flag(assertion, "eventually", false); | ||
if (isChainableMethod) { | ||
Assertion.overwriteChainableMethod( | ||
getterName, | ||
function (originalMethod) { | ||
return function() { | ||
doAsserterAsyncAndAddThen(originalMethod, this, arguments); | ||
}; | ||
}, | ||
function (originalGetter) { | ||
return function() { | ||
doAsserterAsyncAndAddThen(originalGetter, this); | ||
}; | ||
} | ||
); | ||
} else { | ||
Assertion.overwriteProperty(getterName, function (originalGetter) { | ||
return function () { | ||
doAsserterAsyncAndAddThen(originalGetter, this); | ||
}; | ||
}); | ||
} | ||
return args ? module.exports.transformAsserterArgs(args) : args; | ||
}).then(function (args) { | ||
asserter.apply(assertion, args); | ||
// Because asserters, for example `property`, can change the value of `_obj` (i.e. change the "object" | ||
// flag), we need to communicate this value change to subsequent chained asserters. Since we build a | ||
// promise chain paralleling the asserter chain, we can use it to communicate such changes. | ||
return assertion._obj; | ||
}); | ||
function doAsserterAsyncAndAddThen(asserter, assertion, args) { | ||
// Since we're intercepting all methods/properties, we need to just pass through if they don't want | ||
// `eventually`, or if we've already fulfilled the promise (see below). | ||
if (!utils.flag(assertion, "eventually")) { | ||
return asserter.apply(assertion, args); | ||
} | ||
module.exports.transferPromiseness(assertion, derivedPromise); | ||
} | ||
var derivedPromise = getBasePromise(assertion).then(function (value) { | ||
// Set up the environment for the asserter to actually run: `_obj` should be the fulfillment value, and | ||
// now that we have the value, we're no longer in "eventually" mode, so we won't run any of this code, | ||
// just the base Chai code that we get to via the short-circuit above. | ||
assertion._obj = value; | ||
utils.flag(assertion, "eventually", false); | ||
/////// | ||
// Now use the `Assertion` framework to build an `assert` interface. | ||
var originalAssertMethods = Object.getOwnPropertyNames(assert).filter(function (propName) { | ||
return typeof assert[propName] === "function"; | ||
}); | ||
return args ? chaiAsPromised.transformAsserterArgs(args) : args; | ||
}).then(function (args) { | ||
asserter.apply(assertion, args); | ||
assert.isFulfilled = function (promise, message) { | ||
return (new Assertion(promise, message)).to.be.fulfilled; | ||
}; | ||
// Because asserters, for example `property`, can change the value of `_obj` (i.e. change the "object" | ||
// flag), we need to communicate this value change to subsequent chained asserters. Since we build a | ||
// promise chain paralleling the asserter chain, we can use it to communicate such changes. | ||
return assertion._obj; | ||
}); | ||
assert.isRejected = function (promise, errorLike, errMsgMatcher, message) { | ||
var assertion = (new Assertion(promise, message)); | ||
return assertion.to.be.rejectedWith(errorLike, errMsgMatcher, message); | ||
}; | ||
chaiAsPromised.transferPromiseness(assertion, derivedPromise); | ||
} | ||
assert.becomes = function (promise, value, message) { | ||
return assert.eventually.deepEqual(promise, value, message); | ||
}; | ||
/////// | ||
// Now use the `Assertion` framework to build an `assert` interface. | ||
var originalAssertMethods = Object.getOwnPropertyNames(assert).filter(function (propName) { | ||
return typeof assert[propName] === "function"; | ||
}); | ||
assert.doesNotBecome = function (promise, value, message) { | ||
return assert.eventually.notDeepEqual(promise, value, message); | ||
}; | ||
assert.isFulfilled = function (promise, message) { | ||
return (new Assertion(promise, message)).to.be.fulfilled; | ||
}; | ||
assert.eventually = {}; | ||
originalAssertMethods.forEach(function (assertMethodName) { | ||
assert.eventually[assertMethodName] = function (promise) { | ||
var otherArgs = Array.prototype.slice.call(arguments, 1); | ||
assert.isRejected = function (promise, toTestAgainst, message) { | ||
if (typeof toTestAgainst === "string") { | ||
message = toTestAgainst; | ||
toTestAgainst = undefined; | ||
var customRejectionHandler; | ||
var message = arguments[assert[assertMethodName].length - 1]; | ||
if (typeof message === "string") { | ||
customRejectionHandler = function (reason) { | ||
throw new chai.AssertionError(message + "\n\nOriginal reason: " + utils.inspect(reason)); | ||
}; | ||
} | ||
var assertion = (new Assertion(promise, message)); | ||
return toTestAgainst !== undefined ? assertion.to.be.rejectedWith(toTestAgainst) : assertion.to.be.rejected; | ||
}; | ||
var returnedPromise = promise.then( | ||
function (fulfillmentValue) { | ||
return assert[assertMethodName].apply(assert, [fulfillmentValue].concat(otherArgs)); | ||
}, | ||
customRejectionHandler | ||
); | ||
assert.becomes = function (promise, value, message) { | ||
return assert.eventually.deepEqual(promise, value, message); | ||
}; | ||
returnedPromise.notify = function (done) { | ||
doNotify(returnedPromise, done); | ||
}; | ||
assert.doesNotBecome = function (promise, value, message) { | ||
return assert.eventually.notDeepEqual(promise, value, message); | ||
return returnedPromise; | ||
}; | ||
}); | ||
}; | ||
assert.eventually = {}; | ||
originalAssertMethods.forEach(function (assertMethodName) { | ||
assert.eventually[assertMethodName] = function (promise) { | ||
var otherArgs = Array.prototype.slice.call(arguments, 1); | ||
module.exports.transferPromiseness = function (assertion, promise) { | ||
assertion.then = promise.then.bind(promise); | ||
}; | ||
var customRejectionHandler; | ||
var message = arguments[assert[assertMethodName].length - 1]; | ||
if (typeof message === "string") { | ||
customRejectionHandler = function (reason) { | ||
throw new chai.AssertionError(message + "\n\nOriginal reason: " + utils.inspect(reason)); | ||
}; | ||
} | ||
var returnedPromise = promise.then( | ||
function (fulfillmentValue) { | ||
return assert[assertMethodName].apply(assert, [fulfillmentValue].concat(otherArgs)); | ||
}, | ||
customRejectionHandler | ||
); | ||
returnedPromise.notify = function (done) { | ||
doNotify(returnedPromise, done); | ||
}; | ||
return returnedPromise; | ||
}; | ||
}); | ||
} | ||
}()); | ||
module.exports.transformAsserterArgs = function (values) { | ||
return values; | ||
}; |
@@ -1,2 +0,2 @@ | ||
Copyright © 2012–2015 Domenic Denicola <d@domenic.me> | ||
Copyright © 2012–2016 Domenic Denicola <d@domenic.me> | ||
@@ -3,0 +3,0 @@ This work is free. You can redistribute it and/or modify it under the |
@@ -14,3 +14,3 @@ { | ||
], | ||
"version": "5.3.0", | ||
"version": "6.0.0", | ||
"author": "Domenic Denicola <d@domenic.me> (https://domenic.me)", | ||
@@ -27,8 +27,8 @@ "license": "WTFPL", | ||
"test-intercompatibility": "mocha test-intercompatibility --opts test-intercompatibility/mocha.opts", | ||
"test-browser-jquery": "coffee ./test/browser/runner.coffee jquery", | ||
"test-browser-q": "coffee ./test/browser/runner.coffee q", | ||
"test-browser-when": "coffee ./test/browser/runner.coffee when", | ||
"lint": "jshint ./lib", | ||
"cover": "istanbul cover node_modules/mocha/bin/_mocha && opener ./coverage/lcov-report/lib/chai-as-promised.js.html" | ||
}, | ||
"dependencies": { | ||
"check-error": "^1.0.2" | ||
}, | ||
"peerDependencies": { | ||
@@ -40,5 +40,5 @@ "chai": ">= 2.1.2 < 4" | ||
"coffee-script": "1.10.0", | ||
"istanbul": "0.4.1", | ||
"ecstatic": "^1.3.1", | ||
"glob": "^6.0.1", | ||
"istanbul": "0.4.1", | ||
"jshint": "^2.8.0", | ||
@@ -45,0 +45,0 @@ "mocha": "^2.3.4", |
@@ -127,3 +127,3 @@ <a href="http://promisesaplus.com/"> | ||
Promise.resolve(2).should.eventually.equal(2); // will now fail! | ||
Promise.resolve(2).should.eventually.equal(3); // will now pass! | ||
Promise.resolve(3).should.eventually.equal(2); // will now pass! | ||
``` | ||
@@ -148,4 +148,8 @@ | ||
Chai as Promised is compatible with all promises following the [Promises/A+ specification][spec]. Notably, jQuery's promises were not up to spec before jQuery 3.0, and Chai as Promised will not work with them. In particular, Chai as Promised makes extensive use of the standard [transformation behavior][] of `then`, which jQuery<3.0 does not support. | ||
Chai as Promised is compatible with all promises following the [Promises/A+ specification][spec]. | ||
Notably, jQuery's promises were not up to spec before jQuery 3.0, and Chai as Promised will not work with them. In particular, Chai as Promised makes extensive use of the standard [transformation behavior][] of `then`, which jQuery<3.0 does not support. | ||
Angular promises have a special digest cycle for their processing, and [need extra setup code to work with Chai as Promised](http://stackoverflow.com/a/37374041/3191). | ||
### Working with Non-Promise–Friendly Test Runners | ||
@@ -207,2 +211,10 @@ | ||
chai.use(chaiAsPromised); | ||
// Then either: | ||
var expect = chai.expect; | ||
// or: | ||
var assert = chai.assert; | ||
// or: | ||
chai.should(); | ||
// according to your preference of assertion style | ||
``` | ||
@@ -212,24 +224,6 @@ | ||
### AMD | ||
### In the Browser | ||
Chai as Promised supports being used as an [AMD][amd] module, registering itself anonymously (just like Chai). So, assuming you have configured your loader to map the Chai and Chai as Promised files to the respective module IDs `"chai"` and `"chai-as-promised"`, you can use them as follows: | ||
To use Chai as Promised in environments that don't support Node.js-like CommonJS modules, you'll need to use a bundling tool like [browserify][]. | ||
```javascript | ||
define(function (require, exports, module) { | ||
var chai = require("chai"); | ||
var chaiAsPromised = require("chai-as-promised"); | ||
chai.use(chaiAsPromised); | ||
}); | ||
``` | ||
### `<script>` tag | ||
If you include Chai as Promised directly with a `<script>` tag, after the one for Chai itself, then it will automatically plug in to Chai and be ready for use: | ||
```html | ||
<script src="chai.js"></script> | ||
<script src="chai-as-promised.js"></script> | ||
``` | ||
### Karma | ||
@@ -257,1 +251,2 @@ | ||
[karma-chai-as-promised]: https://github.com/vlkosinov/karma-chai-as-promised | ||
[browserify]: http://browserify.org/ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
27905
2
315
248
+ Addedcheck-error@^1.0.2
+ Addedcheck-error@1.0.3(transitive)
+ Addedget-func-name@2.0.2(transitive)