1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-30 02:59:11 -05:00
denoland-deno/tests/node_compat/test/parallel/test-assert.js
Matt Mastracci f5e46c9bf2
chore: move cli/tests/ -> tests/ (#22369)
This looks like a massive PR, but it's only a move from cli/tests ->
tests, and updates of relative paths for files.

This is the first step towards aggregate all of the integration test
files under tests/, which will lead to a set of integration tests that
can run without the CLI binary being built.

While we could leave these tests under `cli`, it would require us to
keep a more complex directory structure for the various test runners. In
addition, we have a lot of complexity to ignore various test files in
the `cli` project itself (cargo publish exclusion rules, autotests =
false, etc).

And finally, the `tests/` folder will eventually house the `test_ffi`,
`test_napi` and other testing code, reducing the size of the root repo
directory.

For easier review, the extremely large and noisy "move" is in the first
commit (with no changes -- just a move), while the remainder of the
changes to actual files is in the second commit.
2024-02-10 20:22:13 +00:00

1615 lines
40 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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;
});
}