1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-26 17:19:06 -05:00
denoland-deno/cli/tests/node_compat/test/parallel/test-assert.js

1616 lines
40 KiB
JavaScript
Raw Normal View History

// deno-fmt-ignore-file
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node 15.5.1
// This file is automatically generated by "node/_tools/setup.ts". Do not modify this file manually
// Flags: --expose-internals
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
const common = require('../common');
const assert = require('assert');
const { inspect } = require('util');
// TODO(kt3k): Enable these when "vm" is ready.
// const vm = require('vm');
// TODO(kt3k): Enable these when "internal/test/binding" is ready.
// const { internalBinding } = require('internal/test/binding');
const a = assert;
// Disable colored output to prevent color codes from breaking assertion
// message comparisons. This should only be an issue when process.stdout
// is a TTY.
if (process.stdout.isTTY)
process.env.NODE_DISABLE_COLORS = '1';
const strictEqualMessageStart = 'Expected values to be strictly equal:\n';
const start = 'Expected values to be strictly deep-equal:';
const actExp = '+ actual - expected';
assert.ok(a.AssertionError.prototype instanceof Error,
'a.AssertionError instanceof Error');
assert.throws(() => a(false), a.AssertionError, 'ok(false)');
assert.throws(() => a.ok(false), a.AssertionError, 'ok(false)');
// Throw message if the message is instanceof Error.
{
let threw = false;
try {
assert.ok(false, new Error('ok(false)'));
} catch (e) {
threw = true;
assert.ok(e instanceof Error);
}
assert.ok(threw, 'Error: ok(false)');
}
a(true);
a('test', 'ok(\'test\')');
a.ok(true);
a.ok('test');
assert.throws(() => a.equal(true, false),
a.AssertionError, 'equal(true, false)');
a.equal(null, null);
a.equal(undefined, undefined);
a.equal(null, undefined);
a.equal(true, true);
a.equal(2, '2');
a.notEqual(true, false);
assert.throws(() => a.notEqual(true, true),
a.AssertionError, 'notEqual(true, true)');
assert.throws(() => a.strictEqual(2, '2'),
a.AssertionError, 'strictEqual(2, \'2\')');
assert.throws(() => a.strictEqual(null, undefined),
a.AssertionError, 'strictEqual(null, undefined)');
assert.throws(
() => a.notStrictEqual(2, 2),
{
message: 'Expected "actual" to be strictly unequal to: 2\n',
name: 'AssertionError'
}
);
assert.throws(
() => a.notStrictEqual('a '.repeat(30), 'a '.repeat(30)),
{
message: 'Expected "actual" to be strictly unequal to: ' +
`"${'a '.repeat(30)}"\n`,
name: 'AssertionError'
}
);
assert.throws(
() => a.notEqual(1, 1),
{
message: '1 != 1',
operator: '!='
}
);
a.notStrictEqual(2, '2');
// Testing the throwing.
function thrower(errorConstructor) {
throw new errorConstructor({});
}
// The basic calls work.
assert.throws(() => thrower(a.AssertionError), a.AssertionError, 'message');
assert.throws(() => thrower(a.AssertionError), a.AssertionError);
assert.throws(() => thrower(a.AssertionError));
// If not passing an error, catch all.
assert.throws(() => thrower(TypeError));
// When passing a type, only catch errors of the appropriate type.
assert.throws(
() => a.throws(() => thrower(TypeError), a.AssertionError),
{
// generatedMessage: true,
// actual: new TypeError({}),
expected: a.AssertionError,
code: 'ERR_ASSERTION',
name: 'AssertionError',
operator: 'throws',
message: 'The error is expected to be an instance of "AssertionError". ' +
'Received "TypeError"\n\nError message:\n\n[object Object]'
}
);
// doesNotThrow should pass through all errors.
{
let threw = false;
try {
a.doesNotThrow(() => thrower(TypeError), a.AssertionError);
} catch (e) {
threw = true;
assert.ok(e instanceof TypeError);
}
assert(threw, 'a.doesNotThrow with an explicit error is eating extra errors');
}
// Key difference is that throwing our correct error makes an assertion error.
{
let threw = false;
try {
a.doesNotThrow(() => thrower(TypeError), TypeError);
} catch (e) {
threw = true;
assert.ok(e instanceof a.AssertionError);
// Commented out the following assertion
// assert.ok(!e.stack.includes('at Function.doesNotThrow'));
}
assert.ok(threw, 'a.doesNotThrow is not catching type matching errors');
}
assert.throws(
() => a.doesNotThrow(() => thrower(Error), 'user message'),
{
name: 'AssertionError',
code: 'ERR_ASSERTION',
operator: 'doesNotThrow',
message: 'Got unwanted exception: user message\n' +
'Actual message: "[object Object]"'
}
);
assert.throws(
() => a.doesNotThrow(() => thrower(Error)),
{
code: 'ERR_ASSERTION',
message: 'Got unwanted exception.\nActual message: "[object Object]"'
}
);
assert.throws(
() => a.doesNotThrow(() => thrower(Error), /\[[a-z]{6}\s[A-z]{6}\]/g, 'user message'),
{
name: 'AssertionError',
code: 'ERR_ASSERTION',
operator: 'doesNotThrow',
message: 'Got unwanted exception: user message\n' +
'Actual message: "[object Object]"'
}
);
// Make sure that validating using constructor really works.
{
let threw = false;
try {
assert.throws(
() => {
throw ({});
},
Array
);
} catch {
threw = true;
}
assert.ok(threw, 'wrong constructor validation');
}
// Use a RegExp to validate the error message.
{
a.throws(() => thrower(TypeError), /\[object Object\]/);
const symbol = Symbol('foo');
a.throws(() => {
throw symbol;
}, /foo/);
a.throws(() => {
a.throws(() => {
throw symbol;
}, /abc/);
}, {
message: 'The input did not match the regular expression /abc/. ' +
"Input:\n\n'Symbol(foo)'\n",
code: 'ERR_ASSERTION',
operator: 'throws',
actual: symbol,
expected: /abc/
});
}
// Use a fn to validate the error object.
a.throws(() => thrower(TypeError), (err) => {
if ((err instanceof TypeError) && /\[object Object\]/.test(err)) {
return true;
}
});
// https://github.com/nodejs/node/issues/3188
{
let actual;
assert.throws(
() => {
const ES6Error = class extends Error {};
const AnotherErrorType = class extends Error {};
assert.throws(() => {
actual = new AnotherErrorType('foo');
throw actual;
}, ES6Error);
},
(err) => {
assert.strictEqual(
err.message,
'The error is expected to be an instance of "ES6Error". ' +
'Received "AnotherErrorType"\n\nError message:\n\nfoo'
);
assert.strictEqual(err.actual, actual);
return true;
}
);
}
// Check messages from assert.throws().
{
const noop = () => {};
assert.throws(
() => { a.throws((noop)); },
{
code: 'ERR_ASSERTION',
message: 'Missing expected exception.',
operator: 'throws',
actual: undefined,
expected: undefined
});
assert.throws(
() => { a.throws(noop, TypeError); },
{
code: 'ERR_ASSERTION',
message: 'Missing expected exception (TypeError).',
actual: undefined,
expected: TypeError
});
assert.throws(
() => { a.throws(noop, 'fhqwhgads'); },
{
code: 'ERR_ASSERTION',
message: 'Missing expected exception: fhqwhgads',
actual: undefined,
expected: undefined
});
assert.throws(
() => { a.throws(noop, TypeError, 'fhqwhgads'); },
{
code: 'ERR_ASSERTION',
message: 'Missing expected exception (TypeError): fhqwhgads',
actual: undefined,
expected: TypeError
});
let threw = false;
try {
a.throws(noop);
} catch (e) {
threw = true;
assert.ok(e instanceof a.AssertionError);
// TODO(kt3k): enable this assertion
// assert.ok(!e.stack.includes('at Function.throws'));
}
assert.ok(threw);
}
const circular = { y: 1 };
circular.x = circular;
function testAssertionMessage(actual, expected, msg) {
assert.throws(
() => assert.strictEqual(actual, ''),
{
generatedMessage: true,
message: msg || strictEqualMessageStart +
`+ actual - expected\n\n+ ${expected}\n- ''`
}
);
}
function testShortAssertionMessage(actual, expected) {
testAssertionMessage(actual, expected, strictEqualMessageStart +
`\n${inspect(actual)} !== ''\n`);
}
// TODO(kt3k): Do we need completely simulate
// Node.js assertion error messages?
/*
testShortAssertionMessage(null, 'null');
testShortAssertionMessage(true, 'true');
testShortAssertionMessage(false, 'false');
testShortAssertionMessage(100, '100');
testShortAssertionMessage(NaN, 'NaN');
testShortAssertionMessage(Infinity, 'Infinity');
testShortAssertionMessage('a', '"a"');
testShortAssertionMessage('foo', '\'foo\'');
testShortAssertionMessage(0, '0');
testShortAssertionMessage(Symbol(), 'Symbol()');
testShortAssertionMessage(undefined, 'undefined');
testShortAssertionMessage(-Infinity, '-Infinity');
testAssertionMessage([], '[]');
testAssertionMessage(/a/, '/a/');
testAssertionMessage(/abc/gim, '/abc/gim');
testAssertionMessage({}, '{}');
testAssertionMessage([1, 2, 3], '[\n+ 1,\n+ 2,\n+ 3\n+ ]');
testAssertionMessage(function f() {}, '[Function: f]');
testAssertionMessage(function() {}, '[Function (anonymous)]');
testAssertionMessage(circular,
'<ref *1> {\n+ x: [Circular *1],\n+ y: 1\n+ }');
testAssertionMessage({ a: undefined, b: null },
'{\n+ a: undefined,\n+ b: null\n+ }');
testAssertionMessage({ a: NaN, b: Infinity, c: -Infinity },
'{\n+ a: NaN,\n+ b: Infinity,\n+ c: -Infinity\n+ }');
*/
// https://github.com/nodejs/node-v0.x-archive/issues/5292
assert.throws(
() => assert.strictEqual(1, 2),
/* Memo: Disabled this object assertion
{
message: `${strictEqualMessageStart}\n1 !== 2\n`,
generatedMessage: true
}
*/
);
assert.throws(
() => assert.strictEqual(1, 2, 'oh no'),
{
message: 'oh no',
generatedMessage: false
}
);
{
let threw = false;
const rangeError = new RangeError('my range');
// Verify custom errors.
try {
assert.strictEqual(1, 2, rangeError);
} catch (e) {
assert.strictEqual(e, rangeError);
threw = true;
assert.ok(e instanceof RangeError, 'Incorrect error type thrown');
}
assert.ok(threw);
threw = false;
// Verify AssertionError is the result from doesNotThrow with custom Error.
try {
a.doesNotThrow(() => {
throw new TypeError('wrong type');
}, TypeError, rangeError);
} catch (e) {
threw = true;
assert.ok(e.message.includes(rangeError.message));
assert.ok(e instanceof assert.AssertionError);
// TODO(kt3k): Enable this assertion
// assert.ok(!e.stack.includes('doesNotThrow'), e);
}
assert.ok(threw);
}
{
// Verify that throws() and doesNotThrow() throw on non-functions.
const testBlockTypeError = (method, fn) => {
assert.throws(
() => method(fn),
{
code: 'ERR_INVALID_ARG_TYPE',
name: 'TypeError',
message: 'The "fn" argument must be of type function.' +
common.invalidArgTypeHelper(fn)
}
);
};
testBlockTypeError(assert.throws, 'string');
testBlockTypeError(assert.doesNotThrow, 'string');
testBlockTypeError(assert.throws, 1);
testBlockTypeError(assert.doesNotThrow, 1);
testBlockTypeError(assert.throws, true);
testBlockTypeError(assert.doesNotThrow, true);
testBlockTypeError(assert.throws, false);
testBlockTypeError(assert.doesNotThrow, false);
testBlockTypeError(assert.throws, []);
testBlockTypeError(assert.doesNotThrow, []);
testBlockTypeError(assert.throws, {});
testBlockTypeError(assert.doesNotThrow, {});
testBlockTypeError(assert.throws, /foo/);
testBlockTypeError(assert.doesNotThrow, /foo/);
testBlockTypeError(assert.throws, null);
testBlockTypeError(assert.doesNotThrow, null);
testBlockTypeError(assert.throws, undefined);
testBlockTypeError(assert.doesNotThrow, undefined);
}
// https://github.com/nodejs/node/issues/3275
assert.throws(() => { throw 'error'; }, (err) => err === 'error');
assert.throws(() => { throw new Error(); }, (err) => err instanceof Error);
// Long values should be truncated for display.
assert.throws(() => {
assert.strictEqual('A'.repeat(1000), '');
}, (err) => {
assert.strictEqual(err.code, 'ERR_ASSERTION');
/* TODO(kt3k): Enable this assertion
assert.strictEqual(err.message,
`${strictEqualMessageStart}+ actual - expected\n\n` +
`+ '${'A'.repeat(1000)}'\n- ''`);
*/
assert.strictEqual(err.actual.length, 1000);
// TODO(kt3k): Enable this after fixing 'inspect'
// assert.ok(inspect(err).includes(`actual: '${'A'.repeat(488)}...'`));
return true;
});
// Output that extends beyond 10 lines should also be truncated for display.
{
const multilineString = 'fhqwhgads\n'.repeat(15);
assert.throws(() => {
assert.strictEqual(multilineString, '');
}, (err) => {
assert.strictEqual(err.code, 'ERR_ASSERTION');
// TODO(kt3k): Enable these assertion when the strictEqual message is aligned
// to Node.js API.
// assert.strictEqual(err.message.split('\n').length, 19);
assert.strictEqual(err.actual.split('\n').length, 16);
// TODO(kt3k): inspect(err) causes Maximum call stack error.
/*
assert.ok(inspect(err).includes(
"actual: 'fhqwhgads\\n' +\n" +
" 'fhqwhgads\\n' +\n".repeat(9) +
" '...'"));
*/
return true;
});
}
{
// Bad args to AssertionError constructor should throw TypeError.
const args = [1, true, false, '', null, Infinity, Symbol('test'), undefined];
args.forEach((input) => {
assert.throws(
() => new assert.AssertionError(input),
{
code: 'ERR_INVALID_ARG_TYPE',
name: 'TypeError',
message: 'The "options" argument must be of type object.' +
common.invalidArgTypeHelper(input)
});
});
}
assert.throws(
() => assert.strictEqual(new Error('foo'), new Error('foobar')),
{
code: 'ERR_ASSERTION',
name: 'AssertionError',
/* TODO(kt3k): Enable this assertion when the assertion error message is fixed.
message: 'Expected "actual" to be reference-equal to "expected":\n' +
'+ actual - expected\n\n' +
'+ [Error: foo]\n- [Error: foobar]'
*/
}
);
a.equal(NaN, NaN);
a.throws(
() => a.notEqual(NaN, NaN),
a.AssertionError
);
// Test strict assert.
{
const a = require('assert');
const assert = require('assert').strict;
assert.throws(() => assert.equal(1, true), assert.AssertionError);
assert.notEqual(0, false);
assert.throws(() => assert.deepEqual(1, true), assert.AssertionError);
assert.notDeepEqual(0, false);
assert.equal(assert.strict, assert.strict.strict);
assert.equal(assert.equal, assert.strictEqual);
assert.equal(assert.deepEqual, assert.deepStrictEqual);
assert.equal(assert.notEqual, assert.notStrictEqual);
assert.equal(assert.notDeepEqual, assert.notDeepStrictEqual);
assert.equal(Object.keys(assert).length, Object.keys(a).length);
assert(7);
assert.throws(
() => assert(...[]),
{
message: 'No value argument passed to `assert.ok()`',
name: 'AssertionError',
// TODO(kt3k): Enable this
// generatedMessage: true
}
);
assert.throws(
() => a(),
{
message: 'No value argument passed to `assert.ok()`',
name: 'AssertionError'
}
);
// Test setting the limit to zero and that assert.strict works properly.
const tmpLimit = Error.stackTraceLimit;
Error.stackTraceLimit = 0;
assert.throws(
() => {
assert.ok(
typeof 123 === 'string'
);
},
{
code: 'ERR_ASSERTION',
constructor: assert.AssertionError,
/* TODO(kt3k): Enable this assertion
message: 'The expression evaluated to a falsy value:\n\n ' +
"assert.ok(\n typeof 123 === 'string'\n )\n"
*/
}
);
Error.stackTraceLimit = tmpLimit;
// Test error diffs.
let message = [
start,
`${actExp} ... Lines skipped`,
'',
' [',
' [',
' [',
' 1,',
' 2,',
'+ 3',
"- '3'",
' ]',
'...',
' 4,',
' 5',
' ]'].join('\n');
assert.throws(
() => assert.deepEqual([[[1, 2, 3]], 4, 5], [[[1, 2, '3']], 4, 5]),
/* TODO(kt3k): Enable this assertion
{ message }
*/
);
message = [
start,
`${actExp} ... Lines skipped`,
'',
' [',
' 1,',
'...',
' 1,',
' 0,',
'- 1,',
' 1,',
'...',
' 1,',
' 1',
' ]'
].join('\n');
assert.throws(
() => assert.deepEqual(
[1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1]),
/* TODO(kt3k): Enable this assertion
{ message }
*/
);
message = [
start,
`${actExp} ... Lines skipped`,
'',
' [',
' 1,',
'...',
' 1,',
' 0,',
'+ 1,',
' 1,',
' 1,',
' 1',
' ]'
].join('\n');
assert.throws(
() => assert.deepEqual(
[1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1]),
/* TODO(kt3k): Enable this assertion
{ message }
*/
);
message = [
start,
actExp,
'',
' [',
' 1,',
'+ 2,',
'- 1,',
' 1,',
' 1,',
' 0,',
'+ 1,',
' 1',
' ]'
].join('\n');
assert.throws(
() => assert.deepEqual(
[1, 2, 1, 1, 0, 1, 1],
[1, 1, 1, 1, 0, 1]),
/* TODO(kt3k): Enable this assertion
{ message }
*/
);
message = [
start,
actExp,
'',
'+ [',
'+ 1,',
'+ 2,',
'+ 1',
'+ ]',
'- undefined',
].join('\n');
assert.throws(
() => assert.deepEqual([1, 2, 1], undefined),
/* TODO(kt3k): Enable this assertion
{ message }
*/
);
message = [
start,
actExp,
'',
' [',
'+ 1,',
' 2,',
' 1',
' ]'
].join('\n');
assert.throws(
() => assert.deepEqual([1, 2, 1], [2, 1]),
/* TODO(kt3k): Enable this assertion
{ message }
*/
);
message = `${start}\n` +
`${actExp} ... Lines skipped\n` +
'\n' +
' [\n' +
'+ 1,\n'.repeat(25) +
'...\n' +
'- 2,\n'.repeat(25) +
'...';
assert.throws(
() => assert.deepEqual(Array(28).fill(1), Array(28).fill(2)),
/* TODO(kt3k): Enable this assertion
{ message }
*/
);
const obj1 = {};
const obj2 = { loop: 'forever' };
obj2[inspect.custom] = () => '{}';
// No infinite loop and no custom inspect.
assert.throws(() => assert.deepEqual(obj1, obj2), {
code: "ERR_ASSERTION",
/* TODO(kt3k): Enable this assertion
message: `${start}\n` +
`${actExp}\n` +
'\n' +
'+ {}\n' +
'- {\n' +
'- [Symbol(nodejs.util.inspect.custom)]: [Function (anonymous)],\n' +
"- loop: 'forever'\n" +
'- }'
*/
});
// notDeepEqual tests
assert.throws(
() => assert.notDeepEqual([1], [1]),
{
code: "ERR_ASSERTION",
/* TODO(kt3k): Enable this assertion
message: 'Expected "actual" not to be strictly deep-equal to:\n\n' +
'[\n 1\n]\n'
*/
}
);
message = 'Expected "actual" not to be strictly deep-equal to:' +
`\n\n[${'\n 1,'.repeat(45)}\n...\n`;
const data = Array(51).fill(1);
assert.throws(
() => assert.notDeepEqual(data, data),
/* TODO(kt3k): Enable this assertion
{ message }
*/
);
}
assert.throws(
() => assert.ok(null),
{
code: 'ERR_ASSERTION',
constructor: assert.AssertionError,
generatedMessage: true,
/* TODO(kt3k): Enable this assertion
message: 'The expression evaluated to a falsy value:\n\n ' +
'assert.ok(null)\n'
*/
}
);
assert.throws(
() => assert(typeof 123n === 'string'),
{
code: 'ERR_ASSERTION',
constructor: assert.AssertionError,
generatedMessage: true,
/* TODO(kt3k): Enable this assertion
message: 'The expression evaluated to a falsy value:\n\n ' +
"assert(typeof 123n === 'string')\n"
*/
}
);
assert.throws(
() => assert(false, Symbol('foo')),
{
code: 'ERR_ASSERTION',
constructor: assert.AssertionError,
/* TODO(kt3k): Enable this assertion
generatedMessage: false,
message: 'Symbol(foo)'
*/
}
);
// TODO(kt3k): Enable these when "internal/test/binding" is ready.
/*
{
// Test caching.
const fs = internalBinding('fs');
const tmp = fs.close;
fs.close = common.mustCall(tmp, 1);
function throwErr() {
assert(
(Buffer.from('test') instanceof Error)
);
}
assert.throws(
() => throwErr(),
{
code: 'ERR_ASSERTION',
constructor: assert.AssertionError,
message: 'The expression evaluated to a falsy value:\n\n ' +
"assert(\n (Buffer.from('test') instanceof Error)\n )\n"
}
);
assert.throws(
() => throwErr(),
{
code: 'ERR_ASSERTION',
constructor: assert.AssertionError,
message: 'The expression evaluated to a falsy value:\n\n ' +
"assert(\n (Buffer.from('test') instanceof Error)\n )\n"
}
);
fs.close = tmp;
}
*/
assert.throws(
() => {
a(
(() => 'string')()
===
123 instanceof
Buffer
);
},
{
code: 'ERR_ASSERTION',
constructor: assert.AssertionError,
/* TODO(kt3k): Enable this assertion
message: 'The expression evaluated to a falsy value:\n\n' +
' a(\n' +
' (() => \'string\')()\n' +
' ===\n' +
' 123 instanceof\n' +
' Buffer\n' +
' )\n'
*/
}
);
assert.throws(
() => {
a(
(() => 'string')()
===
123 instanceof
Buffer
);
},
{
code: 'ERR_ASSERTION',
constructor: assert.AssertionError,
/* TODO(kt3k): Enable this assertion
message: 'The expression evaluated to a falsy value:\n\n' +
' a(\n' +
' (() => \'string\')()\n' +
' ===\n' +
' 123 instanceof\n' +
' Buffer\n' +
' )\n'
*/
}
);
assert.throws(() => {
a((
() => 'string')() ===
123 instanceof
Buffer
);
}, {
code: 'ERR_ASSERTION',
constructor: assert.AssertionError,
/* TODO(kt3k): Enable this assertion
message: 'The expression evaluated to a falsy value:\n\n' +
' a((\n' +
' () => \'string\')() ===\n' +
' 123 instanceof\n' +
' Buffer\n' +
' )\n'
*/
}
);
assert.throws(
() => {
assert(true); assert(null, undefined);
},
{
code: 'ERR_ASSERTION',
constructor: assert.AssertionError,
/* TODO(kt3k): Enable this assertion
message: 'The expression evaluated to a falsy value:\n\n ' +
'assert(null, undefined)\n'
*/
}
);
assert.throws(
() => {
assert
.ok(null, undefined);
},
{
code: 'ERR_ASSERTION',
constructor: assert.AssertionError,
/* TODO(kt3k): Enable this assertion
message: 'The expression evaluated to a falsy value:\n\n ' +
'ok(null, undefined)\n'
*/
}
);
assert.throws(
() => assert['ok']["apply"](null, [0]),
{
code: 'ERR_ASSERTION',
constructor: assert.AssertionError,
/* TODO(kt3k): Enable this assertion
message: 'The expression evaluated to a falsy value:\n\n ' +
'assert[\'ok\']["apply"](null, [0])\n'
*/
}
);
assert.throws(
() => {
const wrapper = (fn, value) => fn(value);
wrapper(assert, false);
},
{
code: 'ERR_ASSERTION',
constructor: assert.AssertionError,
/* TODO(kt3k): Enable this assertion
message: 'The expression evaluated to a falsy value:\n\n fn(value)\n'
*/
}
);
assert.throws(
() => assert.ok.call(null, 0),
{
code: 'ERR_ASSERTION',
constructor: assert.AssertionError,
/* TODO(kt3k): Enable this assertion
message: 'The expression evaluated to a falsy value:\n\n ' +
'assert.ok.call(null, 0)\n',
generatedMessage: true
*/
}
);
assert.throws(
() => assert.ok.call(null, 0, 'test'),
{
code: 'ERR_ASSERTION',
constructor: assert.AssertionError,
message: 'test',
generatedMessage: false
}
);
// Works in eval.
assert.throws(
() => new Function('assert', 'assert(1 === 2);')(assert),
{
code: 'ERR_ASSERTION',
constructor: assert.AssertionError,
/* TODO(kt3k): Enable this assertion
message: 'The expression evaluated to a falsy value:\n\n assert(1 === 2)\n'
*/
}
);
assert.throws(
() => eval('console.log("FOO");\nassert.ok(1 === 2);'),
{
code: 'ERR_ASSERTION',
/* TODO(kt3k): Enable this assertion
message: 'false == true'
*/
}
);
assert.throws(
() => assert.throws(() => {}, 'Error message', 'message'),
{
code: 'ERR_INVALID_ARG_TYPE',
name: 'TypeError',
/* TODO(kt3k): Enable this assertion
message: 'The "error" argument must be of type function or ' +
'an instance of Error, RegExp, or Object. Received type string ' +
"('Error message')"
*/
}
);
[
1,
false,
Symbol()
].forEach((input) => {
assert.throws(
() => assert.throws(() => {}, input),
{
code: 'ERR_INVALID_ARG_TYPE',
/* TODO(kt3k): Enable this assertion
message: 'The "error" argument must be of type function or ' +
'an instance of Error, RegExp, or Object.' +
common.invalidArgTypeHelper(input)
*/
}
);
});
{
assert.throws(() => {
assert.ok((() => Boolean('' === false))());
}, {
code: "ERR_ASSERTION",
/* TODO(kt3k): Enable this assertion
message: 'The expression evaluated to a falsy value:\n\n' +
" assert.ok((() => Boolean('\\u0001' === false))())\n"
*/
});
const errFn = () => {
const err = new TypeError('Wrong value');
err.code = 404;
throw err;
};
const errObj = {
name: 'TypeError',
message: 'Wrong value'
};
assert.throws(errFn, errObj);
errObj.code = 404;
assert.throws(errFn, errObj);
// Fail in case a expected property is undefined and not existent on the
// error.
errObj.foo = undefined;
assert.throws(
() => assert.throws(errFn, errObj),
{
code: 'ERR_ASSERTION',
name: 'AssertionError',
/* TODO(kt3k): Enable this assertion
message: `${start}\n${actExp}\n\n` +
' Comparison {\n' +
' code: 404,\n' +
'- foo: undefined,\n' +
" message: 'Wrong value',\n" +
" name: 'TypeError'\n" +
' }'
*/
}
);
// Show multiple wrong properties at the same time.
errObj.code = '404';
assert.throws(
() => assert.throws(errFn, errObj),
{
code: 'ERR_ASSERTION',
name: 'AssertionError',
/* TODO(kt3k): Enable this assertion
message: `${start}\n${actExp}\n\n` +
' Comparison {\n' +
'+ code: 404,\n' +
"- code: '404',\n" +
'- foo: undefined,\n' +
" message: 'Wrong value',\n" +
" name: 'TypeError'\n" +
' }'
*/
}
);
assert.throws(
() => assert.throws(() => { throw new Error(); }, { foo: 'bar' }, 'foobar'),
{
constructor: assert.AssertionError,
code: 'ERR_ASSERTION',
message: 'foobar'
}
);
assert.throws(
() => a.doesNotThrow(() => { throw new Error(); }, { foo: 'bar' }),
{
name: 'TypeError',
code: 'ERR_INVALID_ARG_TYPE',
/* TODO(kt3k): Enable this assertion
message: 'The "expected" argument must be of type function or an ' +
'instance of RegExp. Received an instance of Object'
*/
}
);
assert.throws(() => { throw new Error('e'); }, new Error('e'));
assert.throws(
() => assert.throws(() => { throw new TypeError('e'); }, new Error('e')),
{
name: 'AssertionError',
code: 'ERR_ASSERTION',
/* TODO(kt3k): Enable this assertion
message: `${start}\n${actExp}\n\n` +
' Comparison {\n' +
" message: 'e',\n" +
"+ name: 'TypeError'\n" +
"- name: 'Error'\n" +
' }'
*/
}
);
assert.throws(
() => assert.throws(() => { throw new Error('foo'); }, new Error('')),
{
name: 'AssertionError',
code: 'ERR_ASSERTION',
/* TODO(kt3k): Enable this assertion
generatedMessage: true,
message: `${start}\n${actExp}\n\n` +
' Comparison {\n' +
"+ message: 'foo',\n" +
"- message: '',\n" +
" name: 'Error'\n" +
' }'
*/
}
);
assert.throws(() => { throw undefined; }, /undefined/);
assert.throws(
() => a.doesNotThrow(() => { throw undefined; }),
{
name: 'AssertionError',
code: 'ERR_ASSERTION',
message: 'Got unwanted exception.\nActual message: "undefined"'
}
);
}
assert.throws(
() => assert.throws(() => { throw new Error(); }, {}),
{
message: "The argument 'error' may not be an empty object. Received {}",
code: 'ERR_INVALID_ARG_VALUE'
}
);
assert.throws(
() => a.throws(
() => { throw 'foo'; },
'foo'
),
{
code: 'ERR_AMBIGUOUS_ARGUMENT',
message: 'The "error/message" argument is ambiguous. ' +
'The error "foo" is identical to the message.'
}
);
assert.throws(
() => a.throws(
() => { throw new TypeError('foo'); },
'foo'
),
{
code: 'ERR_AMBIGUOUS_ARGUMENT',
message: 'The "error/message" argument is ambiguous. ' +
'The error message "foo" is identical to the message.'
}
);
// Should not throw.
assert.throws(() => { throw null; }, 'foo');
assert.throws(
() => assert.strictEqual([], []),
{
code: 'ERR_ASSERTION',
/* TODO(kt3k): Enable this assertion
message: 'Values have same structure but are not reference-equal:\n\n[]\n'
*/
}
);
{
const args = (function() { return arguments; })('a');
assert.throws(
() => assert.strictEqual(args, { 0: 'a' }),
{
code: 'ERR_ASSERTION',
/* TODO(kt3k): Enable this assertion
message: 'Expected "actual" to be reference-equal to "expected":\n' +
'+ actual - expected\n\n' +
"+ [Arguments] {\n- {\n '0': 'a'\n }"
*/
}
);
}
assert.throws(
() => { throw new TypeError('foobar'); },
{
message: /foo/,
name: /^TypeError$/
}
);
assert.throws(
() => assert.throws(
() => { throw new TypeError('foobar'); },
{
message: /fooa/,
name: /^TypeError$/
}
),
{
code: 'ERR_ASSERTION',
/* TODO(kt3k): Enable this assertion
message: `${start}\n${actExp}\n\n` +
' Comparison {\n' +
"+ message: 'foobar',\n" +
'- message: /fooa/,\n' +
" name: 'TypeError'\n" +
' }'
*/
}
);
{
let actual = null;
const expected = { message: 'foo' };
assert.throws(
() => assert.throws(
() => { throw actual; },
expected
),
{
operator: 'throws',
actual,
expected,
code: 'ERR_ASSERTION',
/* TODO(kt3k): Enable this assertion
generatedMessage: true,
message: `${start}\n${actExp}\n\n` +
'+ null\n' +
'- {\n' +
"- message: 'foo'\n" +
'- }'
*/
}
);
actual = 'foobar';
const message = 'message';
assert.throws(
() => assert.throws(
() => { throw actual; },
{ message: 'foobar' },
message
),
{
actual,
message,
operator: 'throws',
generatedMessage: false
}
);
}
// Indicate where the strings diverge.
assert.throws(
() => assert.strictEqual('test test', 'test foobar'),
{
code: 'ERR_ASSERTION',
name: 'AssertionError',
/* TODO(kt3k): Enable this assertion
message: strictEqualMessageStart +
'+ actual - expected\n\n' +
"+ 'test test'\n" +
"- 'test foobar'\n" +
' ^'
*/
}
);
// Check for reference-equal objects in `notStrictEqual()`
assert.throws(
() => {
const obj = {};
assert.notStrictEqual(obj, obj);
},
{
code: 'ERR_ASSERTION',
name: 'AssertionError',
/* TODO(kt3k): Enable this assertion
message: 'Expected "actual" not to be reference-equal to "expected": {}'
*/
}
);
assert.throws(
() => {
const obj = { a: true };
assert.notStrictEqual(obj, obj);
},
{
code: 'ERR_ASSERTION',
name: 'AssertionError',
/* TODO(kt3k): Enable this assertion
message: 'Expected "actual" not to be reference-equal to "expected":\n\n' +
'{\n a: true\n}\n'
*/
}
);
{
let threw = false;
try {
assert.deepStrictEqual(Array(100).fill(1), 'foobar');
} catch (err) {
threw = true;
/* TODO(kt3k): Enable this assertion
assert(/actual: \[Array],\n expected: 'foobar',/.test(inspect(err)));
*/
}
assert(threw);
}
assert.throws(
() => a.equal(1),
{ code: 'ERR_MISSING_ARGS' }
);
assert.throws(
() => a.deepEqual(/a/),
{ code: 'ERR_MISSING_ARGS' }
);
assert.throws(
() => a.notEqual(null),
{ code: 'ERR_MISSING_ARGS' }
);
assert.throws(
() => a.notDeepEqual('test'),
{ code: 'ERR_MISSING_ARGS' }
);
assert.throws(
() => a.strictEqual({}),
{ code: 'ERR_MISSING_ARGS' }
);
assert.throws(
() => a.deepStrictEqual(Symbol()),
{ code: 'ERR_MISSING_ARGS' }
);
assert.throws(
() => a.notStrictEqual(5n),
{ code: 'ERR_MISSING_ARGS' }
);
assert.throws(
() => a.notDeepStrictEqual(undefined),
{ code: 'ERR_MISSING_ARGS' }
);
assert.throws(
() => a.strictEqual(),
{ code: 'ERR_MISSING_ARGS' }
);
assert.throws(
() => a.deepStrictEqual(),
{ code: 'ERR_MISSING_ARGS' }
);
// Verify that `stackStartFunction` works as alternative to `stackStartFn`.
{
(function hidden() {
const err = new assert.AssertionError({
actual: 'foo',
operator: 'strictEqual',
stackStartFunction: hidden
});
const err2 = new assert.AssertionError({
actual: 'foo',
operator: 'strictEqual',
stackStartFn: hidden
});
assert(!err.stack.includes('hidden'));
assert(!err2.stack.includes('hidden'));
})();
}
assert.throws(
() => assert.throws(() => { throw Symbol('foo'); }, RangeError),
{
code: 'ERR_ASSERTION',
/* TODO(kt3k): Enable this assertion
message: 'The error is expected to be an instance of "RangeError". ' +
'Received "Symbol(foo)"'
*/
}
);
assert.throws(
() => assert.throws(() => { throw [1, 2]; }, RangeError),
{
code: 'ERR_ASSERTION',
/* TODO(kt3k): Enable this assertion
message: 'The error is expected to be an instance of "RangeError". ' +
'Received "[Array]"'
*/
}
);
{
const err = new TypeError('foo');
const validate = (() => () => ({ a: true, b: [ 1, 2, 3 ] }))();
assert.throws(
() => assert.throws(() => { throw err; }, validate),
{
message: 'The validation function is expected to ' +
`return "true". Received ${inspect(validate())}\n\nCaught ` +
`error:\n\n${err}`,
code: 'ERR_ASSERTION',
actual: err,
expected: validate,
name: 'AssertionError',
operator: 'throws',
}
);
}
// TODO(kt3k): Enable these when "vm" is ready.
/*
assert.throws(
() => {
const script = new vm.Script('new RangeError("foobar");');
const context = vm.createContext();
const err = script.runInContext(context);
assert.throws(() => { throw err; }, RangeError);
},
{
message: 'The error is expected to be an instance of "RangeError". ' +
'Received an error with identical name but a different ' +
'prototype.\n\nError message:\n\nfoobar'
}
);
*/
// Multiple assert.match() tests.
{
assert.throws(
() => assert.match(/abc/, 'string'),
{
code: 'ERR_INVALID_ARG_TYPE',
/* TODO(kt3k): Enable this assertion
message: 'The "regexp" argument must be an instance of RegExp. ' +
"Received type string ('string')"
*/
}
);
assert.throws(
() => assert.match('string', /abc/),
{
actual: 'string',
expected: /abc/,
operator: 'match',
/* TODO(kt3k): Enable this assertion
message: 'The input did not match the regular expression /abc/. ' +
"Input:\n\n'string'\n",
generatedMessage: true
*/
}
);
assert.throws(
() => assert.match('string', /abc/, 'foobar'),
{
actual: 'string',
expected: /abc/,
operator: 'match',
message: 'foobar',
generatedMessage: false
}
);
const errorMessage = new RangeError('foobar');
assert.throws(
() => assert.match('string', /abc/, errorMessage),
errorMessage
);
assert.throws(
() => assert.match({ abc: 123 }, /abc/),
{
actual: { abc: 123 },
expected: /abc/,
operator: 'match',
/* TODO(kt3k): Enable this assertion
message: 'The "string" argument must be of type string. ' +
'Received type object ({ abc: 123 })',
generatedMessage: true
*/
}
);
assert.match('I will pass', /pass$/);
}
// Multiple assert.doesNotMatch() tests.
{
assert.throws(
() => assert.doesNotMatch(/abc/, 'string'),
{
code: 'ERR_INVALID_ARG_TYPE',
/* TODO(kt3k): Enable this assertion
message: 'The "regexp" argument must be an instance of RegExp. ' +
"Received type string ('string')"
*/
}
);
assert.throws(
() => assert.doesNotMatch('string', /string/),
{
actual: 'string',
expected: /string/,
operator: 'doesNotMatch',
/* TODO(kt3k): Enable this assertion
message: 'The input was expected to not match the regular expression ' +
"/string/. Input:\n\n'string'\n",
generatedMessage: true
*/
}
);
assert.throws(
() => assert.doesNotMatch('string', /string/, 'foobar'),
{
actual: 'string',
expected: /string/,
operator: 'doesNotMatch',
message: 'foobar',
generatedMessage: false
}
);
const errorMessage = new RangeError('foobar');
assert.throws(
() => assert.doesNotMatch('string', /string/, errorMessage),
errorMessage
);
assert.throws(
() => assert.doesNotMatch({ abc: 123 }, /abc/),
{
actual: { abc: 123 },
expected: /abc/,
operator: 'doesNotMatch',
message: 'The "string" argument must be of type string. ' +
'Received type object ({ abc: 123 })',
/* TODO(kt3k): Enable this assertion
generatedMessage: true
*/
}
);
assert.doesNotMatch('I will pass', /different$/);
}
{
const tempColor = inspect.defaultOptions.colors;
assert.throws(() => {
inspect.defaultOptions.colors = true;
// Guarantee the position indicator is placed correctly.
assert.strictEqual(111554n, 11111115);
}, (err) => {
// TODO(kt3k): Enable this assertion
// assert.strictEqual(inspect(err).split('\n')[5], ' ^');
inspect.defaultOptions.colors = tempColor;
return true;
});
}