@@ -27,6 +27,7 @@ const {
2727 ArrayPrototypePush,
2828 ArrayPrototypeSlice,
2929 Error,
30+ ErrorPrototypeToString,
3031 NumberIsNaN,
3132 ObjectAssign,
3233 ObjectDefineProperty,
@@ -53,7 +54,7 @@ const {
5354 } ,
5455} = require ( 'internal/errors' ) ;
5556const AssertionError = require ( 'internal/assert/assertion_error' ) ;
56- const { inspect } = require ( 'internal/util/inspect' ) ;
57+ const { inspect, format } = require ( 'internal/util/inspect' ) ;
5758const {
5859 isPromise,
5960 isRegExp,
@@ -142,9 +143,51 @@ function Assert(options) {
142143// instance's custom options.
143144
144145function innerFail ( obj ) {
145- if ( obj . message instanceof Error ) throw obj . message ;
146+ if ( obj . message . length === 0 ) {
147+ obj . message = undefined ;
148+ } else if ( typeof obj . message [ 0 ] === 'string' ) {
149+ if ( obj . message . length > 1 ) {
150+ obj . message = format ( ...obj . message ) ;
151+ } else {
152+ obj . message = obj . message [ 0 ] ;
153+ }
154+ } else if ( isError ( obj . message [ 0 ] ) ) {
155+ if ( obj . message . length > 1 ) {
156+ throw new ERR_AMBIGUOUS_ARGUMENT (
157+ 'message' ,
158+ `The error message was passed as error object "${ ErrorPrototypeToString ( obj . message [ 0 ] ) } " has trailing arguments that would be ignored.` ,
159+ ) ;
160+ }
161+ throw obj . message [ 0 ] ;
162+ } else if ( typeof obj . message [ 0 ] === 'function' ) {
163+ if ( obj . message . length > 1 ) {
164+ throw new ERR_AMBIGUOUS_ARGUMENT (
165+ 'message' ,
166+ `The error message with function "${ obj . message [ 0 ] . name || 'anonymous' } " has trailing arguments that would be ignored.` ,
167+ ) ;
168+ }
169+ try {
170+ obj . message = obj . message [ 0 ] ( obj . actual , obj . expected ) ;
171+ if ( typeof obj . message !== 'string' ) {
172+ obj . message = undefined ;
173+ }
174+ } catch {
175+ // Ignore and use default message instead
176+ obj . message = undefined ;
177+ }
178+ } else {
179+ throw new ERR_INVALID_ARG_TYPE (
180+ 'message' ,
181+ [ 'string' , 'function' ] ,
182+ obj . message [ 0 ] ,
183+ ) ;
184+ }
146185
147- throw new AssertionError ( obj ) ;
186+ const error = new AssertionError ( obj ) ;
187+ if ( obj . generatedMessage !== undefined ) {
188+ error . generatedMessage = obj . generatedMessage ;
189+ }
190+ throw error ;
148191}
149192
150193/**
@@ -208,7 +251,7 @@ Assert.prototype.ok = function ok(...args) {
208251 * @param {string | Error } [message]
209252 * @returns {void }
210253 */
211- Assert . prototype . equal = function equal ( actual , expected , message ) {
254+ Assert . prototype . equal = function equal ( actual , expected , ... message ) {
212255 if ( arguments . length < 2 ) {
213256 throw new ERR_MISSING_ARGS ( 'actual' , 'expected' ) ;
214257 }
@@ -233,7 +276,7 @@ Assert.prototype.equal = function equal(actual, expected, message) {
233276 * @param {string | Error } [message]
234277 * @returns {void }
235278 */
236- Assert . prototype . notEqual = function notEqual ( actual , expected , message ) {
279+ Assert . prototype . notEqual = function notEqual ( actual , expected , ... message ) {
237280 if ( arguments . length < 2 ) {
238281 throw new ERR_MISSING_ARGS ( 'actual' , 'expected' ) ;
239282 }
@@ -257,7 +300,7 @@ Assert.prototype.notEqual = function notEqual(actual, expected, message) {
257300 * @param {string | Error } [message]
258301 * @returns {void }
259302 */
260- Assert . prototype . deepEqual = function deepEqual ( actual , expected , message ) {
303+ Assert . prototype . deepEqual = function deepEqual ( actual , expected , ... message ) {
261304 if ( arguments . length < 2 ) {
262305 throw new ERR_MISSING_ARGS ( 'actual' , 'expected' ) ;
263306 }
@@ -281,7 +324,7 @@ Assert.prototype.deepEqual = function deepEqual(actual, expected, message) {
281324 * @param {string | Error } [message]
282325 * @returns {void }
283326 */
284- Assert . prototype . notDeepEqual = function notDeepEqual ( actual , expected , message ) {
327+ Assert . prototype . notDeepEqual = function notDeepEqual ( actual , expected , ... message ) {
285328 if ( arguments . length < 2 ) {
286329 throw new ERR_MISSING_ARGS ( 'actual' , 'expected' ) ;
287330 }
@@ -306,7 +349,7 @@ Assert.prototype.notDeepEqual = function notDeepEqual(actual, expected, message)
306349 * @param {string | Error } [message]
307350 * @returns {void }
308351 */
309- Assert . prototype . deepStrictEqual = function deepStrictEqual ( actual , expected , message ) {
352+ Assert . prototype . deepStrictEqual = function deepStrictEqual ( actual , expected , ... message ) {
310353 if ( arguments . length < 2 ) {
311354 throw new ERR_MISSING_ARGS ( 'actual' , 'expected' ) ;
312355 }
@@ -332,7 +375,7 @@ Assert.prototype.deepStrictEqual = function deepStrictEqual(actual, expected, me
332375 * @returns {void }
333376 */
334377Assert . prototype . notDeepStrictEqual = notDeepStrictEqual ;
335- function notDeepStrictEqual ( actual , expected , message ) {
378+ function notDeepStrictEqual ( actual , expected , ... message ) {
336379 if ( arguments . length < 2 ) {
337380 throw new ERR_MISSING_ARGS ( 'actual' , 'expected' ) ;
338381 }
@@ -356,7 +399,7 @@ function notDeepStrictEqual(actual, expected, message) {
356399 * @param {string | Error } [message]
357400 * @returns {void }
358401 */
359- Assert . prototype . strictEqual = function strictEqual ( actual , expected , message ) {
402+ Assert . prototype . strictEqual = function strictEqual ( actual , expected , ... message ) {
360403 if ( arguments . length < 2 ) {
361404 throw new ERR_MISSING_ARGS ( 'actual' , 'expected' ) ;
362405 }
@@ -379,7 +422,7 @@ Assert.prototype.strictEqual = function strictEqual(actual, expected, message) {
379422 * @param {string | Error } [message]
380423 * @returns {void }
381424 */
382- Assert . prototype . notStrictEqual = function notStrictEqual ( actual , expected , message ) {
425+ Assert . prototype . notStrictEqual = function notStrictEqual ( actual , expected , ... message ) {
383426 if ( arguments . length < 2 ) {
384427 throw new ERR_MISSING_ARGS ( 'actual' , 'expected' ) ;
385428 }
@@ -405,7 +448,7 @@ Assert.prototype.notStrictEqual = function notStrictEqual(actual, expected, mess
405448Assert . prototype . partialDeepStrictEqual = function partialDeepStrictEqual (
406449 actual ,
407450 expected ,
408- message ,
451+ ... message
409452) {
410453 if ( arguments . length < 2 ) {
411454 throw new ERR_MISSING_ARGS ( 'actual' , 'expected' ) ;
@@ -462,7 +505,7 @@ function compareExceptionKey(actual, expected, key, message, keys, fn) {
462505 innerFail ( {
463506 actual,
464507 expected,
465- message,
508+ message : [ message ] ,
466509 operator : fn . name ,
467510 stackStartFn : fn ,
468511 diff : this ?. [ kOptions ] ?. diff ,
@@ -664,7 +707,7 @@ function expectsError(stackStartFn, actual, error, message) {
664707 actual : undefined ,
665708 expected : error ,
666709 operator : stackStartFn . name ,
667- message : `Missing expected ${ fnType } ${ details } ` ,
710+ message : [ `Missing expected ${ fnType } ${ details } ` ] ,
668711 stackStartFn,
669712 diff : this ?. [ kOptions ] ?. diff ,
670713 } ) ;
@@ -713,8 +756,8 @@ function expectsNoError(stackStartFn, actual, error, message) {
713756 actual,
714757 expected : error ,
715758 operator : stackStartFn . name ,
716- message : `Got unwanted ${ fnType } ${ details } \n` +
717- `Actual message: "${ actual ?. message } "` ,
759+ message : [ `Got unwanted ${ fnType } ${ details } \n` +
760+ `Actual message: "${ actual ?. message } "` ] ,
718761 stackStartFn,
719762 diff : this ?. [ kOptions ] ?. diff ,
720763 } ) ;
@@ -832,30 +875,26 @@ function internalMatch(string, regexp, message, fn) {
832875 const match = fn === Assert . prototype . match ;
833876 if ( typeof string !== 'string' ||
834877 RegExpPrototypeExec ( regexp , string ) !== null !== match ) {
835- if ( message instanceof Error ) {
836- throw message ;
837- }
838878
839- const generatedMessage = ! message ;
879+ const generatedMessage = message . length === 0 ;
840880
841881 // 'The input was expected to not match the regular expression ' +
842- message ||= ( typeof string !== 'string' ?
882+ message [ 0 ] ||= ( typeof string !== 'string' ?
843883 'The "string" argument must be of type string. Received type ' +
844884 `${ typeof string } (${ inspect ( string ) } )` :
845885 ( match ?
846886 'The input did not match the regular expression ' :
847887 'The input was expected to not match the regular expression ' ) +
848888 `${ inspect ( regexp ) } . Input:\n\n${ inspect ( string ) } \n` ) ;
849- const err = new AssertionError ( {
889+ innerFail ( {
850890 actual : string ,
851891 expected : regexp ,
852892 message,
853893 operator : fn . name ,
854894 stackStartFn : fn ,
855895 diff : this ?. [ kOptions ] ?. diff ,
896+ generatedMessage : generatedMessage ,
856897 } ) ;
857- err . generatedMessage = generatedMessage ;
858- throw err ;
859898 }
860899}
861900
@@ -866,7 +905,7 @@ function internalMatch(string, regexp, message, fn) {
866905 * @param {string | Error } [message]
867906 * @returns {void }
868907 */
869- Assert . prototype . match = function match ( string , regexp , message ) {
908+ Assert . prototype . match = function match ( string , regexp , ... message ) {
870909 internalMatch ( string , regexp , message , match ) ;
871910} ;
872911
@@ -877,7 +916,7 @@ Assert.prototype.match = function match(string, regexp, message) {
877916 * @param {string | Error } [message]
878917 * @returns {void }
879918 */
880- Assert . prototype . doesNotMatch = function doesNotMatch ( string , regexp , message ) {
919+ Assert . prototype . doesNotMatch = function doesNotMatch ( string , regexp , ... message ) {
881920 internalMatch ( string , regexp , message , doesNotMatch ) ;
882921} ;
883922
0 commit comments