diff --git a/lib/assertions.js b/lib/assertions.js index 96161b0d2..d401fa18c 100644 --- a/lib/assertions.js +++ b/lib/assertions.js @@ -619,14 +619,19 @@ module.exports = function (expect) { } }); }); - } else if (this.flags.assertion) { + } + + if (this.flags.assertion) { this.errorMode = 'bubble'; // to satisfy assertion 'to be a number' => to be a number if (typeof value === 'string') { return expect.apply(expect, Array.prototype.slice.call(arguments, 1)); } else { return expect.apply(expect, [subject, this.flags.exhaustively ? 'to exhaustively satisfy' : 'to satisfy'].concat(Array.prototype.slice.call(arguments, 2))); } - } else if (value && value._expectIt) { + } + + var valueType = expect.findTypeOf(value); + if (valueType.is('expect.it')) { return expect.withError(function () { return value(subject); }, function (e) { @@ -639,150 +644,153 @@ module.exports = function (expect) { } }); }); - } else if (typeof value === 'function') { + } + + if (valueType.is('function')) { return expect.promise(function () { return value(subject); }); - } else if (isRegExp(value)) { - expect(subject, 'to match', value); - } else { - var subjectType = expect.findTypeOf(subject), - commonType = expect.findCommonType(subject, value), - valueType = expect.findTypeOf(value), - bothAreArrayLike = commonType.is('array-like'); - if (commonType.is('array-like') || commonType.is('object')) { - expect(subject, 'to be an object'); - var promiseByKey = {}; - var keys = valueType.getKeys(value); - keys.forEach(function (key, index) { - promiseByKey[key] = expect.promise(function () { - if (typeof value[key] === 'function') { - return value[key](subject[key]); - } else { - return expect(subject[key], 'to [exhaustively] satisfy', value[key]); - } - }); - }); + } + + if (valueType.is('regexp')) { + return expect(subject, 'to match', value); + } - var flags = this.flags; + var subjectType = expect.findTypeOf(subject), + commonType = expect.findCommonType(subject, value), + bothAreArrayLike = commonType.is('array-like'); + if (commonType.is('array-like') || commonType.is('object')) { + expect(subject, 'to be an object'); + var promiseByKey = {}; + var keys = valueType.getKeys(value); + keys.forEach(function (key, index) { + promiseByKey[key] = expect.promise(function () { + if (typeof value[key] === 'function') { + return value[key](subject[key]); + } else { + return expect(subject[key], 'to [exhaustively] satisfy', value[key]); + } + }); + }); - return expect.promise.all([ - expect.promise(function () { - if (commonType.is('array-like') || flags.exhaustively) { - expect(subject, 'to only have keys', keys); - } - }), - expect.promise.all(promiseByKey) - ]).caught(function () { - return expect.promise.settle(promiseByKey).then(function () { - expect.fail({ - diff: function (output, diff, inspect, equal) { - var result = { - diff: output, - inline: true - }; - - var valueType = expect.findTypeOf(value), - keyIndex = {}; - subjectType.getKeys(subject).concat(valueType.getKeys(value)).forEach(function (key) { - if (!(key in keyIndex)) { - keyIndex[key] = key; - } - }); + var flags = this.flags; - var keys = Object.keys(keyIndex); + return expect.promise.all([ + expect.promise(function () { + if (commonType.is('array-like') || flags.exhaustively) { + expect(subject, 'to only have keys', keys); + } + }), + expect.promise.all(promiseByKey) + ]).caught(function () { + return expect.promise.settle(promiseByKey).then(function () { + expect.fail({ + diff: function (output, diff, inspect, equal) { + var result = { + diff: output, + inline: true + }; - if (bothAreArrayLike && subjectType.name !== 'array') { - output.text(subjectType.name); + var valueType = expect.findTypeOf(value), + keyIndex = {}; + subjectType.getKeys(subject).concat(valueType.getKeys(value)).forEach(function (key) { + if (!(key in keyIndex)) { + keyIndex[key] = key; } - output.text(bothAreArrayLike ? '[' : '{').nl().indentLines(); + }); - keys.forEach(function (key, index) { - output.i().block(function () { - var valueOutput; - var annotation = output.clone(); - var conflicting; + var keys = Object.keys(keyIndex); - if (promiseByKey[key] && promiseByKey[key].isRejected()) { - conflicting = promiseByKey[key].reason(); - } - var arrayItemOutOfRange = bothAreArrayLike && (index >= subject.length || index >= value.length); + if (bothAreArrayLike && subjectType.name !== 'array') { + output.text(subjectType.name); + } + output.text(bothAreArrayLike ? '[' : '{').nl().indentLines(); - var isInlineDiff = true; + keys.forEach(function (key, index) { + output.i().block(function () { + var valueOutput; + var annotation = output.clone(); + var conflicting; - if (!(key in value)) { - if (commonType.is('array-like') || flags.exhaustively) { - annotation.error('should be removed'); - } else { - conflicting = null; - } - } else if (conflicting || arrayItemOutOfRange) { - var keyDiff = conflicting && conflicting.createDiff && conflicting.createDiff(output.clone(), diff, inspect, equal); - isInlineDiff = !keyDiff || keyDiff.inline ; - if (typeof value[key] === 'function') { - isInlineDiff = false; - annotation.append(conflicting.output); - } else if (!keyDiff || (keyDiff && !keyDiff.inline)) { - annotation.error((conflicting && conflicting.label) || 'should satisfy').sp() - .block(inspect(value[key])); - - if (keyDiff) { - annotation.nl().append(keyDiff.diff); - } - } else { - valueOutput = keyDiff.diff; - } - } + if (promiseByKey[key] && promiseByKey[key].isRejected()) { + conflicting = promiseByKey[key].reason(); + } + var arrayItemOutOfRange = bothAreArrayLike && (index >= subject.length || index >= value.length); + + var isInlineDiff = true; - var last = index === keys.length - 1; - if (!valueOutput) { - if (bothAreArrayLike && key >= subject.length) { - valueOutput = output.clone(); - } else { - valueOutput = inspect(subject[key], conflicting ? Infinity : 1); + if (!(key in value)) { + if (commonType.is('array-like') || flags.exhaustively) { + annotation.error('should be removed'); + } else { + conflicting = null; + } + } else if (conflicting || arrayItemOutOfRange) { + var keyDiff = conflicting && conflicting.createDiff && conflicting.createDiff(output.clone(), diff, inspect, equal); + isInlineDiff = !keyDiff || keyDiff.inline ; + if (typeof value[key] === 'function') { + isInlineDiff = false; + annotation.append(conflicting.output); + } else if (!keyDiff || (keyDiff && !keyDiff.inline)) { + annotation.error((conflicting && conflicting.label) || 'should satisfy').sp() + .block(inspect(value[key])); + + if (keyDiff) { + annotation.nl().append(keyDiff.diff); } + } else { + valueOutput = keyDiff.diff; } + } - if (!bothAreArrayLike) { - this.key(key).text(':'); + var last = index === keys.length - 1; + if (!valueOutput) { + if (bothAreArrayLike && key >= subject.length) { + valueOutput = output.clone(); + } else { + valueOutput = inspect(subject[key], conflicting ? Infinity : 1); } - valueOutput.amend('text', last ? '' : ','); + } + if (!bothAreArrayLike) { + this.key(key).text(':'); + } + valueOutput.amend('text', last ? '' : ','); - if (!bothAreArrayLike) { - if (valueOutput.isBlock() && valueOutput.isMultiline()) { - this.indentLines(); - this.nl().i(); - } else { - this.sp(); - } - } - if (isInlineDiff) { - this.append(valueOutput); + if (!bothAreArrayLike) { + if (valueOutput.isBlock() && valueOutput.isMultiline()) { + this.indentLines(); + this.nl().i(); } else { - this.block(valueOutput); - } - if (!annotation.isEmpty()) { - this.sp(valueOutput.isEmpty() ? 0 : 1).annotationBlock(annotation); + this.sp(); } - }).nl(); - }); + } - output.outdentLines().text(bothAreArrayLike ? ']' : '}'); + if (isInlineDiff) { + this.append(valueOutput); + } else { + this.block(valueOutput); + } + if (!annotation.isEmpty()) { + this.sp(valueOutput.isEmpty() ? 0 : 1).annotationBlock(annotation); + } + }).nl(); + }); - if (!bothAreArrayLike) { - result.diff = utils.wrapConstructorNameAroundOutput(result.diff, subject); - } + output.outdentLines().text(bothAreArrayLike ? ']' : '}'); - return result; + if (!bothAreArrayLike) { + result.diff = utils.wrapConstructorNameAroundOutput(result.diff, subject); } - }); + + return result; + } }); }); - } else { - expect(subject, 'to equal', value); - } + }); + } else { + expect(subject, 'to equal', value); } }); diff --git a/test/mocha.opts b/test/mocha.opts index dd67a7d98..44a6bd96e 100644 --- a/test/mocha.opts +++ b/test/mocha.opts @@ -1,4 +1,4 @@ --reporter spec --recursive --check-leaks ---require ./test/common.js +--require ./test/common