|
@ -20,12 +20,11 @@ |
|
|
|
|
|
|
|
|
'use strict'; |
|
|
'use strict'; |
|
|
|
|
|
|
|
|
// UTILITY
|
|
|
const { compare } = process.binding('buffer'); |
|
|
const compare = process.binding('buffer').compare; |
|
|
|
|
|
const util = require('util'); |
|
|
const util = require('util'); |
|
|
const { isSet, isMap } = process.binding('util'); |
|
|
const { isSet, isMap } = process.binding('util'); |
|
|
const objectToString = require('internal/util').objectToString; |
|
|
const { objectToString } = require('internal/util'); |
|
|
const Buffer = require('buffer').Buffer; |
|
|
const { Buffer } = require('buffer'); |
|
|
|
|
|
|
|
|
var errors; |
|
|
var errors; |
|
|
function lazyErrors() { |
|
|
function lazyErrors() { |
|
@ -47,10 +46,21 @@ const assert = module.exports = ok; |
|
|
|
|
|
|
|
|
// All of the following functions must throw an AssertionError
|
|
|
// All of the following functions must throw an AssertionError
|
|
|
// when a corresponding condition is not met, with a message that
|
|
|
// when a corresponding condition is not met, with a message that
|
|
|
// may be undefined if not provided. All assertion methods provide
|
|
|
// may be undefined if not provided. All assertion methods provide
|
|
|
// both the actual and expected values to the assertion error for
|
|
|
// both the actual and expected values to the assertion error for
|
|
|
// display purposes.
|
|
|
// display purposes.
|
|
|
|
|
|
|
|
|
|
|
|
function innerFail(actual, expected, message, operator, stackStartFunction) { |
|
|
|
|
|
const errors = lazyErrors(); |
|
|
|
|
|
throw new errors.AssertionError({ |
|
|
|
|
|
message, |
|
|
|
|
|
actual, |
|
|
|
|
|
expected, |
|
|
|
|
|
operator, |
|
|
|
|
|
stackStartFunction |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
function fail(actual, expected, message, operator, stackStartFunction) { |
|
|
function fail(actual, expected, message, operator, stackStartFunction) { |
|
|
if (arguments.length === 0) { |
|
|
if (arguments.length === 0) { |
|
|
message = 'Failed'; |
|
|
message = 'Failed'; |
|
@ -59,19 +69,11 @@ function fail(actual, expected, message, operator, stackStartFunction) { |
|
|
message = actual; |
|
|
message = actual; |
|
|
actual = undefined; |
|
|
actual = undefined; |
|
|
} |
|
|
} |
|
|
if (arguments.length === 2) |
|
|
if (arguments.length === 2) { |
|
|
operator = '!='; |
|
|
operator = '!='; |
|
|
const errors = lazyErrors(); |
|
|
} |
|
|
throw new errors.AssertionError({ |
|
|
innerFail(actual, expected, message, operator, stackStartFunction || fail); |
|
|
message: message, |
|
|
|
|
|
actual: actual, |
|
|
|
|
|
expected: expected, |
|
|
|
|
|
operator: operator, |
|
|
|
|
|
stackStartFunction: stackStartFunction |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// EXTENSION! allows for well behaved errors defined elsewhere.
|
|
|
|
|
|
assert.fail = fail; |
|
|
assert.fail = fail; |
|
|
|
|
|
|
|
|
// The AssertionError is defined in internal/error.
|
|
|
// The AssertionError is defined in internal/error.
|
|
@ -82,50 +84,39 @@ assert.AssertionError = lazyErrors().AssertionError; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Pure assertion tests whether a value is truthy, as determined
|
|
|
// Pure assertion tests whether a value is truthy, as determined
|
|
|
// by !!guard.
|
|
|
// by !!value.
|
|
|
// assert.ok(guard, message_opt);
|
|
|
|
|
|
// This statement is equivalent to assert.equal(true, !!guard,
|
|
|
|
|
|
// message_opt);. To test strictly for the value true, use
|
|
|
|
|
|
// assert.strictEqual(true, guard, message_opt);.
|
|
|
|
|
|
|
|
|
|
|
|
function ok(value, message) { |
|
|
function ok(value, message) { |
|
|
if (!value) fail(value, true, message, '==', assert.ok); |
|
|
if (!value) innerFail(value, true, message, '==', ok); |
|
|
} |
|
|
} |
|
|
assert.ok = ok; |
|
|
assert.ok = ok; |
|
|
|
|
|
|
|
|
// The equality assertion tests shallow, coercive equality with
|
|
|
// The equality assertion tests shallow, coercive equality with ==.
|
|
|
// ==.
|
|
|
|
|
|
// assert.equal(actual, expected, message_opt);
|
|
|
|
|
|
/* eslint-disable no-restricted-properties */ |
|
|
/* eslint-disable no-restricted-properties */ |
|
|
assert.equal = function equal(actual, expected, message) { |
|
|
assert.equal = function equal(actual, expected, message) { |
|
|
// eslint-disable-next-line eqeqeq
|
|
|
// eslint-disable-next-line eqeqeq
|
|
|
if (actual != expected) fail(actual, expected, message, '==', assert.equal); |
|
|
if (actual != expected) innerFail(actual, expected, message, '==', equal); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
// The non-equality assertion tests for whether two objects are not
|
|
|
// The non-equality assertion tests for whether two objects are not
|
|
|
// equal with !=.
|
|
|
// equal with !=.
|
|
|
// assert.notEqual(actual, expected, message_opt);
|
|
|
|
|
|
|
|
|
|
|
|
assert.notEqual = function notEqual(actual, expected, message) { |
|
|
assert.notEqual = function notEqual(actual, expected, message) { |
|
|
// eslint-disable-next-line eqeqeq
|
|
|
// eslint-disable-next-line eqeqeq
|
|
|
if (actual == expected) { |
|
|
if (actual == expected) { |
|
|
fail(actual, expected, message, '!=', assert.notEqual); |
|
|
innerFail(actual, expected, message, '!=', notEqual); |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
// The equivalence assertion tests a deep equality relation.
|
|
|
// The equivalence assertion tests a deep equality relation.
|
|
|
// assert.deepEqual(actual, expected, message_opt);
|
|
|
|
|
|
|
|
|
|
|
|
assert.deepEqual = function deepEqual(actual, expected, message) { |
|
|
assert.deepEqual = function deepEqual(actual, expected, message) { |
|
|
if (!_deepEqual(actual, expected, false)) { |
|
|
if (!innerDeepEqual(actual, expected, false)) { |
|
|
fail(actual, expected, message, 'deepEqual', assert.deepEqual); |
|
|
innerFail(actual, expected, message, 'deepEqual', deepEqual); |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
/* eslint-enable */ |
|
|
/* eslint-enable */ |
|
|
|
|
|
|
|
|
assert.deepStrictEqual = function deepStrictEqual(actual, expected, message) { |
|
|
assert.deepStrictEqual = function deepStrictEqual(actual, expected, message) { |
|
|
if (!_deepEqual(actual, expected, true)) { |
|
|
if (!innerDeepEqual(actual, expected, true)) { |
|
|
fail(actual, expected, message, 'deepStrictEqual', assert.deepStrictEqual); |
|
|
innerFail(actual, expected, message, 'deepStrictEqual', deepStrictEqual); |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
@ -154,7 +145,7 @@ function isArguments(tag) { |
|
|
return tag === '[object Arguments]'; |
|
|
return tag === '[object Arguments]'; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function _deepEqual(actual, expected, strict, memos) { |
|
|
function innerDeepEqual(actual, expected, strict, memos) { |
|
|
// All identical values are equivalent, as determined by ===.
|
|
|
// All identical values are equivalent, as determined by ===.
|
|
|
if (actual === expected) { |
|
|
if (actual === expected) { |
|
|
return true; |
|
|
return true; |
|
@ -307,7 +298,7 @@ function setHasSimilarElement(set, val1, usedEntries, strict, memo) { |
|
|
if (usedEntries && usedEntries.has(val2)) |
|
|
if (usedEntries && usedEntries.has(val2)) |
|
|
continue; |
|
|
continue; |
|
|
|
|
|
|
|
|
if (_deepEqual(val1, val2, strict, memo)) { |
|
|
if (innerDeepEqual(val1, val2, strict, memo)) { |
|
|
if (usedEntries) |
|
|
if (usedEntries) |
|
|
usedEntries.add(val2); |
|
|
usedEntries.add(val2); |
|
|
return true; |
|
|
return true; |
|
@ -364,7 +355,7 @@ function mapHasSimilarEntry(map, key1, item1, usedEntries, strict, memo) { |
|
|
// This check is not strictly necessary. The loop performs this check, but
|
|
|
// This check is not strictly necessary. The loop performs this check, but
|
|
|
// doing it here improves performance of the common case when reference-equal
|
|
|
// doing it here improves performance of the common case when reference-equal
|
|
|
// keys exist (which includes all primitive-valued keys).
|
|
|
// keys exist (which includes all primitive-valued keys).
|
|
|
if (map.has(key1) && _deepEqual(item1, map.get(key1), strict, memo)) { |
|
|
if (map.has(key1) && innerDeepEqual(item1, map.get(key1), strict, memo)) { |
|
|
if (usedEntries) |
|
|
if (usedEntries) |
|
|
usedEntries.add(key1); |
|
|
usedEntries.add(key1); |
|
|
return true; |
|
|
return true; |
|
@ -381,8 +372,8 @@ function mapHasSimilarEntry(map, key1, item1, usedEntries, strict, memo) { |
|
|
if (usedEntries && usedEntries.has(key2)) |
|
|
if (usedEntries && usedEntries.has(key2)) |
|
|
continue; |
|
|
continue; |
|
|
|
|
|
|
|
|
if (_deepEqual(key1, key2, strict, memo) && |
|
|
if (innerDeepEqual(key1, key2, strict, memo) && |
|
|
_deepEqual(item1, item2, strict, memo)) { |
|
|
innerDeepEqual(item1, item2, strict, memo)) { |
|
|
if (usedEntries) |
|
|
if (usedEntries) |
|
|
usedEntries.add(key2); |
|
|
usedEntries.add(key2); |
|
|
return true; |
|
|
return true; |
|
@ -459,44 +450,39 @@ function objEquiv(a, b, strict, actualVisitedObjects) { |
|
|
// Possibly expensive deep test:
|
|
|
// Possibly expensive deep test:
|
|
|
for (i = aKeys.length - 1; i >= 0; i--) { |
|
|
for (i = aKeys.length - 1; i >= 0; i--) { |
|
|
key = aKeys[i]; |
|
|
key = aKeys[i]; |
|
|
if (!_deepEqual(a[key], b[key], strict, actualVisitedObjects)) |
|
|
if (!innerDeepEqual(a[key], b[key], strict, actualVisitedObjects)) |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// The non-equivalence assertion tests for any deep inequality.
|
|
|
// The non-equivalence assertion tests for any deep inequality.
|
|
|
// assert.notDeepEqual(actual, expected, message_opt);
|
|
|
|
|
|
|
|
|
|
|
|
assert.notDeepEqual = function notDeepEqual(actual, expected, message) { |
|
|
assert.notDeepEqual = function notDeepEqual(actual, expected, message) { |
|
|
if (_deepEqual(actual, expected, false)) { |
|
|
if (innerDeepEqual(actual, expected, false)) { |
|
|
fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); |
|
|
innerFail(actual, expected, message, 'notDeepEqual', notDeepEqual); |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
assert.notDeepStrictEqual = notDeepStrictEqual; |
|
|
assert.notDeepStrictEqual = notDeepStrictEqual; |
|
|
function notDeepStrictEqual(actual, expected, message) { |
|
|
function notDeepStrictEqual(actual, expected, message) { |
|
|
if (_deepEqual(actual, expected, true)) { |
|
|
if (innerDeepEqual(actual, expected, true)) { |
|
|
fail(actual, expected, message, 'notDeepStrictEqual', notDeepStrictEqual); |
|
|
innerFail(actual, expected, message, 'notDeepStrictEqual', |
|
|
|
|
|
notDeepStrictEqual); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// The strict equality assertion tests strict equality, as determined by ===.
|
|
|
// The strict equality assertion tests strict equality, as determined by ===.
|
|
|
// assert.strictEqual(actual, expected, message_opt);
|
|
|
|
|
|
|
|
|
|
|
|
assert.strictEqual = function strictEqual(actual, expected, message) { |
|
|
assert.strictEqual = function strictEqual(actual, expected, message) { |
|
|
if (actual !== expected) { |
|
|
if (actual !== expected) { |
|
|
fail(actual, expected, message, '===', assert.strictEqual); |
|
|
innerFail(actual, expected, message, '===', strictEqual); |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
// The strict non-equality assertion tests for strict inequality, as
|
|
|
// The strict non-equality assertion tests for strict inequality, as
|
|
|
// determined by !==.
|
|
|
// determined by !==.
|
|
|
// assert.notStrictEqual(actual, expected, message_opt);
|
|
|
|
|
|
|
|
|
|
|
|
assert.notStrictEqual = function notStrictEqual(actual, expected, message) { |
|
|
assert.notStrictEqual = function notStrictEqual(actual, expected, message) { |
|
|
if (actual === expected) { |
|
|
if (actual === expected) { |
|
|
fail(actual, expected, message, '!==', assert.notStrictEqual); |
|
|
innerFail(actual, expected, message, '!==', notStrictEqual); |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
@ -525,7 +511,7 @@ function expectedException(actual, expected) { |
|
|
return expected.call({}, actual) === true; |
|
|
return expected.call({}, actual) === true; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function _tryBlock(block) { |
|
|
function tryBlock(block) { |
|
|
var error; |
|
|
var error; |
|
|
try { |
|
|
try { |
|
|
block(); |
|
|
block(); |
|
@ -535,7 +521,7 @@ function _tryBlock(block) { |
|
|
return error; |
|
|
return error; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function _throws(shouldThrow, block, expected, message) { |
|
|
function innerThrows(shouldThrow, block, expected, message) { |
|
|
var actual; |
|
|
var actual; |
|
|
|
|
|
|
|
|
if (typeof block !== 'function') { |
|
|
if (typeof block !== 'function') { |
|
@ -549,13 +535,13 @@ function _throws(shouldThrow, block, expected, message) { |
|
|
expected = null; |
|
|
expected = null; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
actual = _tryBlock(block); |
|
|
actual = tryBlock(block); |
|
|
|
|
|
|
|
|
message = (expected && expected.name ? ' (' + expected.name + ')' : '') + |
|
|
message = (expected && expected.name ? ' (' + expected.name + ')' : '') + |
|
|
(message ? ': ' + message : '.'); |
|
|
(message ? ': ' + message : '.'); |
|
|
|
|
|
|
|
|
if (shouldThrow && !actual) { |
|
|
if (shouldThrow && !actual) { |
|
|
fail(actual, expected, 'Missing expected exception' + message); |
|
|
innerFail(actual, expected, 'Missing expected exception' + message, fail); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const userProvidedMessage = typeof message === 'string'; |
|
|
const userProvidedMessage = typeof message === 'string'; |
|
@ -566,7 +552,7 @@ function _throws(shouldThrow, block, expected, message) { |
|
|
userProvidedMessage && |
|
|
userProvidedMessage && |
|
|
expectedException(actual, expected)) || |
|
|
expectedException(actual, expected)) || |
|
|
isUnexpectedException) { |
|
|
isUnexpectedException) { |
|
|
fail(actual, expected, 'Got unwanted exception' + message); |
|
|
innerFail(actual, expected, 'Got unwanted exception' + message, fail); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if ((shouldThrow && actual && expected && |
|
|
if ((shouldThrow && actual && expected && |
|
@ -576,16 +562,12 @@ function _throws(shouldThrow, block, expected, message) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Expected to throw an error.
|
|
|
// Expected to throw an error.
|
|
|
// assert.throws(block, Error_opt, message_opt);
|
|
|
assert.throws = function throws(block, error, message) { |
|
|
|
|
|
innerThrows(true, block, error, message); |
|
|
assert.throws = function throws(block, /*optional*/error, /*optional*/message) { |
|
|
|
|
|
_throws(true, block, error, message); |
|
|
|
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
// EXTENSION! This is annoying to write outside this module.
|
|
|
assert.doesNotThrow = function doesNotThrow(block, error, message) { |
|
|
assert.doesNotThrow = doesNotThrow; |
|
|
innerThrows(false, block, error, message); |
|
|
function doesNotThrow(block, /*optional*/error, /*optional*/message) { |
|
|
}; |
|
|
_throws(false, block, error, message); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
assert.ifError = function ifError(err) { if (err) throw err; }; |
|
|
assert.ifError = function ifError(err) { if (err) throw err; }; |
|
|