Skip to content

Commit 547dc14

Browse files
committed
[Breaking] throws: bring into line with node’s assert.throws
1 parent bffb60c commit 547dc14

File tree

4 files changed

+243
-126
lines changed

4 files changed

+243
-126
lines changed

.editorconfig

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ end_of_line = lf
77
charset = utf-8
88
trim_trailing_whitespace = true
99
insert_final_newline = true
10-
max_line_length = 140
10+
max_line_length = 180
1111
block_comment_start = /*
1212
block_comment = *
1313
block_comment_end = */

lib/test.js

+37-9
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ var isRegExp = require('is-regex');
88
var trim = require('string.prototype.trim');
99
var bind = require('function-bind');
1010
var forEach = require('for-each');
11+
var inspect = require('object-inspect');
1112
var isEnumerable = bind.call(Function.call, Object.prototype.propertyIsEnumerable);
1213
var toLowerCase = bind.call(Function.call, String.prototype.toLowerCase);
14+
var isProto = bind.call(Function.call, Object.prototype.isPrototypeOf);
1315

1416
module.exports = Test;
1517

@@ -514,7 +516,7 @@ Test.prototype['throws'] = function (fn, expected, msg, extra) {
514516
fn();
515517
} catch (err) {
516518
caught = { error: err };
517-
if ((err != null) && (!isEnumerable(err, 'message') || !has(err, 'message'))) {
519+
if (err != null && (!isEnumerable(err, 'message') || !has(err, 'message'))) {
518520
var message = err.message;
519521
delete err.message;
520522
err.message = message;
@@ -523,16 +525,42 @@ Test.prototype['throws'] = function (fn, expected, msg, extra) {
523525

524526
var passed = caught;
525527

526-
if (isRegExp(expected)) {
527-
passed = expected.test(caught && caught.error);
528-
expected = String(expected);
529-
}
530-
531-
if (typeof expected === 'function' && caught) {
532-
passed = caught.error instanceof expected;
528+
if (caught) {
529+
if (typeof expected === 'string' && caught.error && caught.error.message === expected) {
530+
throw new TypeError('The "error/message" argument is ambiguous. The error message ' + inspect(expected) + ' is identical to the message.');
531+
}
532+
if (typeof expected === 'function') {
533+
if (typeof expected.prototype !== 'undefined' && caught.error instanceof expected) {
534+
passed = true;
535+
} else if (isProto(Error, expected)) {
536+
passed = false;
537+
} else {
538+
passed = expected.call({}, caught.error) === true;
539+
}
540+
} else if (isRegExp(expected)) {
541+
passed = expected.test(caught.error);
542+
expected = inspect(expected);
543+
} else if (expected && typeof expected === 'object') { // Handle validation objects.
544+
var keys = Object.keys(expected);
545+
// Special handle errors to make sure the name and the message are compared as well.
546+
if (expected instanceof Error) {
547+
keys.push('name', 'message');
548+
} else if (keys.length === 0) {
549+
throw new TypeError('`throws` validation object must not be empty');
550+
}
551+
passed = keys.every(function (key) {
552+
if (typeof caught.error[key] === 'string' && isRegExp(expected[key]) && expected[key].test(caught.error[key])) {
553+
return true;
554+
}
555+
if (key in caught.error && deepEqual(caught.error[key], expected[key], { strict: true })) {
556+
return true;
557+
}
558+
return false;
559+
});
560+
}
533561
}
534562

535-
this._assert(typeof fn === 'function' && passed, {
563+
this._assert(!!passed, {
536564
message: defined(msg, 'should throw'),
537565
operator: 'throws',
538566
actual: caught && caught.error,

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"is-regex": "^1.0.5",
2020
"minimist": "^1.2.0",
2121
"object-inspect": "^1.7.0",
22+
"object.assign": "^4.1.0",
2223
"resolve": "^1.14.1",
2324
"resumer": "^0.0.0",
2425
"string.prototype.trim": "^1.2.1",

0 commit comments

Comments
 (0)