Skip to content

Commit

Permalink
[Breaking] throws: bring into line with node’s assert.throws
Browse files Browse the repository at this point in the history
  • Loading branch information
ljharb committed Dec 26, 2019
1 parent bffb60c commit 547dc14
Show file tree
Hide file tree
Showing 4 changed files with 243 additions and 126 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 140
max_line_length = 180
block_comment_start = /*
block_comment = *
block_comment_end = */
Expand Down
46 changes: 37 additions & 9 deletions lib/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ var isRegExp = require('is-regex');
var trim = require('string.prototype.trim');
var bind = require('function-bind');
var forEach = require('for-each');
var inspect = require('object-inspect');
var isEnumerable = bind.call(Function.call, Object.prototype.propertyIsEnumerable);
var toLowerCase = bind.call(Function.call, String.prototype.toLowerCase);
var isProto = bind.call(Function.call, Object.prototype.isPrototypeOf);

module.exports = Test;

Expand Down Expand Up @@ -514,7 +516,7 @@ Test.prototype['throws'] = function (fn, expected, msg, extra) {
fn();
} catch (err) {
caught = { error: err };
if ((err != null) && (!isEnumerable(err, 'message') || !has(err, 'message'))) {
if (err != null && (!isEnumerable(err, 'message') || !has(err, 'message'))) {
var message = err.message;
delete err.message;
err.message = message;
Expand All @@ -523,16 +525,42 @@ Test.prototype['throws'] = function (fn, expected, msg, extra) {

var passed = caught;

if (isRegExp(expected)) {
passed = expected.test(caught && caught.error);
expected = String(expected);
}

if (typeof expected === 'function' && caught) {
passed = caught.error instanceof expected;
if (caught) {
if (typeof expected === 'string' && caught.error && caught.error.message === expected) {
throw new TypeError('The "error/message" argument is ambiguous. The error message ' + inspect(expected) + ' is identical to the message.');
}
if (typeof expected === 'function') {
if (typeof expected.prototype !== 'undefined' && caught.error instanceof expected) {
passed = true;
} else if (isProto(Error, expected)) {
passed = false;
} else {
passed = expected.call({}, caught.error) === true;
}
} else if (isRegExp(expected)) {
passed = expected.test(caught.error);
expected = inspect(expected);
} else if (expected && typeof expected === 'object') { // Handle validation objects.
var keys = Object.keys(expected);
// Special handle errors to make sure the name and the message are compared as well.
if (expected instanceof Error) {
keys.push('name', 'message');
} else if (keys.length === 0) {
throw new TypeError('`throws` validation object must not be empty');
}
passed = keys.every(function (key) {
if (typeof caught.error[key] === 'string' && isRegExp(expected[key]) && expected[key].test(caught.error[key])) {
return true;
}
if (key in caught.error && deepEqual(caught.error[key], expected[key], { strict: true })) {
return true;
}
return false;
});
}
}

this._assert(typeof fn === 'function' && passed, {
this._assert(!!passed, {
message: defined(msg, 'should throw'),
operator: 'throws',
actual: caught && caught.error,
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"is-regex": "^1.0.5",
"minimist": "^1.2.0",
"object-inspect": "^1.7.0",
"object.assign": "^4.1.0",
"resolve": "^1.14.1",
"resumer": "^0.0.0",
"string.prototype.trim": "^1.2.1",
Expand Down
Loading

0 comments on commit 547dc14

Please sign in to comment.