Skip to content

Commit

Permalink
Merge pull request #428 from unexpectedjs/fix/errorOnPromiseAnd
Browse files Browse the repository at this point in the history
Fix error on promise .and()
  • Loading branch information
alexjeffburke committed Nov 20, 2017
2 parents bf22cde + 959e32e commit af56da0
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 27 deletions.
25 changes: 13 additions & 12 deletions lib/Unexpected.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ var extend = utils.extend;
var leven = require('leven');
var makePromise = require('./makePromise');
var addAdditionalPromiseMethods = require('./addAdditionalPromiseMethods');
var isPendingPromise = require('./isPendingPromise');
var wrapPromiseIfNecessary = require('./wrapPromiseIfNecessary');
var oathbreaker = require('./oathbreaker');
var UnexpectedError = require('./UnexpectedError');
var notifyPendingPromise = require('./notifyPendingPromise');
Expand Down Expand Up @@ -1207,18 +1207,19 @@ Unexpected.prototype._expect = function expect(context, args) {

try {
var result = executeExpect(context, subject, testDescriptionString, Array.prototype.slice.call(args, 2));
if (isPendingPromise(result)) {
that.expect.notifyPendingPromise(result);
result = result.then(undefined, function (e) {
if (e && e._isUnexpected && context.level === 0) {
that.setErrorMessage(e);
}
throw e;
});
} else {
if (!result || typeof result.then !== 'function') {
result = makePromise.resolve(result);
if (utils.isPromise(result)) {
result = wrapPromiseIfNecessary(result);
if (result.isPending()) {
that.expect.notifyPendingPromise(result);
result = result.then(undefined, function (e) {
if (e && e._isUnexpected && context.level === 0) {
that.setErrorMessage(e);
}
throw e;
});
}
} else {
result = makePromise.resolve(result);
}
return addAdditionalPromiseMethods(result, that.expect, subject);
} catch (e) {
Expand Down
27 changes: 15 additions & 12 deletions lib/createWrappedExpectProto.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
var createStandardErrorMessage = require('./createStandardErrorMessage');
var makePromise = require('./makePromise');
var isPendingPromise = require('./isPendingPromise');
var addAdditionalPromiseMethods = require('./addAdditionalPromiseMethods');
var wrapPromiseIfNecessary = require('./wrapPromiseIfNecessary');
var oathbreaker = require('./oathbreaker');
var UnexpectedError = require('./UnexpectedError');
var addAdditionalPromiseMethods = require('./addAdditionalPromiseMethods');
var utils = require('./utils');

function isAssertionArg(arg) {
Expand Down Expand Up @@ -89,16 +89,19 @@ module.exports = function createWrappedExpectProto(unexpected) {

try {
var result = oathbreaker(callback());
if (isPendingPromise(result)) {
result = result.then(undefined, function (e) {
if (e && e._isUnexpected) {
var wrappedError = new UnexpectedError(that, e);
wrappedError.originalError = e.originalError;
throw wrappedError;
}
throw e;
});
} else if (!result || typeof result.then !== 'function') {
if (utils.isPromise(result)) {
result = wrapPromiseIfNecessary(result);
if (result.isPending()) {
result = result.then(undefined, function (e) {
if (e && e._isUnexpected) {
var wrappedError = new UnexpectedError(that, e);
wrappedError.originalError = e.originalError;
throw wrappedError;
}
throw e;
});
}
} else {
result = makePromise.resolve(result);
}
return addAdditionalPromiseMethods(result, that.execute, that.subject);
Expand Down
3 changes: 0 additions & 3 deletions lib/isPendingPromise.js

This file was deleted.

4 changes: 4 additions & 0 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ var utils = module.exports = {
return Object.prototype.toString.call(ar) === '[object Array]';
},

isPromise: function (obj) {
return obj && typeof obj.then === 'function';
},

isRegExp: function (re) {
return (Object.prototype.toString.call(re) === '[object RegExp]');
},
Expand Down
12 changes: 12 additions & 0 deletions lib/wrapPromiseIfNecessary.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
var makePromise = require('./makePromise');

module.exports = function (promise) {
if (typeof promise.isPending !== 'function') {
// wrap any non-Unexpected promise
return makePromise(function () {
return promise;
});
} else {
return promise;
}
};
29 changes: 29 additions & 0 deletions test/api/shift.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,4 +202,33 @@ describe('expect.shift', function () {
);
});
});

describe('when a non-Unexpected promise is passed to shift', function () {
it('should allow a subsequent .and()', function () {
var clonedExpect = expect.clone().addAssertion('promisified', function (expect, subject) {
return expect.shift(new Promise(subject));
});
return clonedExpect(resolve => {
setTimeout(function () {
resolve('usefully');
}, 100);
}, 'promisified').and('to be truthy');
});

it('should allow a subsequent .and() within a nested context', function () {
var clonedExpect = expect.clone().addAssertion('promisified', function (expect, subject) {
return expect.shift(new Promise(subject));
}).addAssertion('<function> executed inside an assertion', function (expect, subject) {
return subject(expect);
});

return clonedExpect(expect => {
expect(resolve => {
setTimeout(function () {
resolve('usefully');
}, 100);
}, 'promisified').and('to be truthy');
}, 'executed inside an assertion');
});
});
});

0 comments on commit af56da0

Please sign in to comment.