diff --git a/test/common/README.md b/test/common/README.md index 57f607153aa8c1..32ca6711573daa 100644 --- a/test/common/README.md +++ b/test/common/README.md @@ -13,8 +13,8 @@ The `common` module is used by tests for consistency across repeated tasks. ### allowGlobals(...whitelist) -* `whitelist` [<Array>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) Array of Globals -* return [<Array>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) +* `whitelist` [<Array>] Array of Globals +* return [<Array>] Takes `whitelist` and concats that with predefined `knownGlobals`. @@ -22,7 +22,7 @@ Takes `whitelist` and concats that with predefined `knownGlobals`. A stream to push an array into a REPL ### busyLoop(time) -* `time` [<Number>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type) +* `time` [<Number>] Blocks for `time` amount of time. @@ -41,93 +41,113 @@ no unexpected rejections occur, because currently they result in silent failures. ### ddCommand(filename, kilobytes) -* return [<Object>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) +* return [<Object>] Platform normalizes the `dd` command ### enoughTestMem -* return [<Boolean>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type) +* return [<Boolean>] Check if there is more than 1gb of total memory. -### expectsError(settings) -* `settings` [<Object>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) - with the following optional properties: - * `code` [<String>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type) - expected error must have this value for its `code` property - * `type` [<Function>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function) - expected error must be an instance of `type` - * `message` [<String>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type) - or [<RegExp>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp) +### expectsError([fn, ]settings[, exact]) +* `fn` [<Function>] a function that should throw. +* `settings` [<Object>] + that must contain the `code` property plus any of the other following + properties (some properties only apply for `AssertionError`): + * `code` [<String>] + expected error must have this value for its `code` property. + * `type` [<Function>] + expected error must be an instance of `type` and must be an Error subclass. + * `message` [<String>] or [<RegExp>] if a string is provided for `message`, expected error must have it for its `message` property; if a regular expression is provided for `message`, the - regular expression must match the `message` property of the expected error - -* return function suitable for use as a validation function passed as the second - argument to `assert.throws()` - -The expected error should be [subclassed by the `internal/errors` module](https://github.com/nodejs/node/blob/master/doc/guides/using-internal-errors.md#api). + regular expression must match the `message` property of the expected error. + * `name` [<String>] + expected error must have this value for its `name` property. + * `generatedMessage` [<String>] + (`AssertionError` only) expected error must have this value for its + `generatedMessage` property. + * `actual` <any> + (`AssertionError` only) expected error must have this value for its + `actual` property. + * `expected` <any> + (`AssertionError` only) expected error must have this value for its + `expected` property. + * `operator` <any> + (`AssertionError` only) expected error must have this value for its + `operator` property. +* `exact` [<Number>] default = 1 +* return [<Function>] + + If `fn` is provided, it will be passed to `assert.throws` as first argument + and `undefined` will be returned. + Otherwise a function suitable as callback or for use as a validation function + passed as the second argument to `assert.throws()` will be returned. If the + returned function has not been called exactly `exact` number of times when the + test is complete, then the test will fail. ### expectWarning(name, expected) -* `name` [<String>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type) -* `expected` [<String>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type) | [<Array>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) +* `name` [<String>] +* `expected` [<String>] | [<Array>] Tests whether `name` and `expected` are part of a raised warning. ### fileExists(pathname) -* pathname [<String>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type) -* return [<Boolean>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type) +* pathname [<String>] +* return [<Boolean>] Checks if `pathname` exists ### fixturesDir -* return [<String>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type) +* return [<String>] Path to the 'fixtures' directory. ### getArrayBufferViews(buf) -* `buf` [<Buffer>](https://nodejs.org/api/buffer.html#buffer_class_buffer) -* return [<ArrayBufferView[]>](https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView) +* `buf` [<Buffer>] +* return [<ArrayBufferView[]>] Returns an instance of all possible `ArrayBufferView`s of the provided Buffer. ### globalCheck -* return [<Boolean>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type) +* return [<Boolean>] Turn this off if the test should not check for global leaks. ### hasCrypto -* return [<Boolean>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type) +* return [<Boolean>] Checks for 'openssl'. ### hasFipsCrypto -* return [<Boolean>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type) +* return [<Boolean>] Checks `hasCrypto` and `crypto` with fips. ### hasIntl -* return [<Boolean>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type) +* return [<Boolean>] Checks if [internationalization] is supported. ### hasSmallICU -* return [<Boolean>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type) +* return [<Boolean>] Checks `hasIntl` and `small-icu` is supported. ### hasIPv6 -* return [<Boolean>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type) +* return [<Boolean>] Checks whether `IPv6` is supported on this platform. ### hasMultiLocalhost -* return [<Boolean>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type) +* return [<Boolean>] Checks if there are multiple localhosts available. ### hijackStderr(listener) -* `listener` [<Function>][MDN-Function]: a listener with a single parameter called `data`. +* `listener` [<Function>]: a listener with a single parameter + called `data`. Eavesdrop to `process.stderr.write` calls. Once `process.stderr.write` is called, `listener` will also be called and the `data` of `write` function will @@ -135,7 +155,8 @@ be passed to `listener`. What's more, `process.stderr.writeTimes` is a count of the number of calls. ### hijackStdout(listener) -* `listener` [<Function>][MDN-Function]: a listener with a single parameter called `data`. +* `listener` [<Function>]: a listener with a single parameter + called `data`. Eavesdrop to `process.stdout.write` calls. Once `process.stdout.write` is called, `listener` will also be called and the `data` of `write` function will @@ -143,86 +164,86 @@ be passed to `listener`. What's more, `process.stdout.writeTimes` is a count of the number of calls. ### inFreeBSDJail -* return [<Boolean>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type) +* return [<Boolean>] Checks whether free BSD Jail is true or false. ### isAIX -* return [<Boolean>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type) +* return [<Boolean>] Platform check for Advanced Interactive eXecutive (AIX). ### isAlive(pid) -* `pid` [<Number>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type) -* return [<Boolean>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type) +* `pid` [<Number>] +* return [<Boolean>] Attempts to 'kill' `pid` ### isFreeBSD -* return [<Boolean>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type) +* return [<Boolean>] Platform check for Free BSD. ### isLinux -* return [<Boolean>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type) +* return [<Boolean>] Platform check for Linux. ### isLinuxPPCBE -* return [<Boolean>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type) +* return [<Boolean>] Platform check for Linux on PowerPC. ### isOSX -* return [<Boolean>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type) +* return [<Boolean>] Platform check for macOS. ### isSunOS -* return [<Boolean>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type) +* return [<Boolean>] Platform check for SunOS. ### isWindows -* return [<Boolean>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type) +* return [<Boolean>] Platform check for Windows. ### isWOW64 -* return [<Boolean>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type) +* return [<Boolean>] Platform check for Windows 32-bit on Windows 64-bit. ### leakedGlobals -* return [<Array>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) +* return [<Array>] Checks whether any globals are not on the `knownGlobals` list. ### localhostIPv4 -* return [<String>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type) +* return [<String>] Gets IP of localhost ### localIPv6Hosts -* return [<Array>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) +* return [<Array>] Array of IPV6 hosts. ### mustCall([fn][, exact]) -* `fn` [<Function>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function) default = () => {} -* `exact` [<Number>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type) default = 1 -* return [<Function>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function) +* `fn` [<Function>] default = () => {} +* `exact` [<Number>] default = 1 +* return [<Function>] Returns a function that calls `fn`. If the returned function has not been called -exactly `expected` number of times when the test is complete, then the test will +exactly `exact` number of times when the test is complete, then the test will fail. If `fn` is not provided, an empty function will be used. ### mustCallAtLeast([fn][, minimum]) -* `fn` [<Function>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function) default = () => {} -* `minimum` [<Number>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type) default = 1 -* return [<Function>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function) +* `fn` [<Function>] default = () => {} +* `minimum` [<Number>] default = 1 +* return [<Function>] Returns a function that calls `fn`. If the returned function has not been called at least `minimum` number of times when the test is complete, then the test will @@ -231,46 +252,49 @@ fail. If `fn` is not provided, an empty function will be used. ### mustNotCall([msg]) -* `msg` [<String>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type) default = 'function should not have been called' -* return [<Function>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function) +* `msg` [<String>] default = 'function should not have been called' +* return [<Function>] -Returns a function that triggers an `AssertionError` if it is invoked. `msg` is used as the error message for the `AssertionError`. +Returns a function that triggers an `AssertionError` if it is invoked. `msg` is +used as the error message for the `AssertionError`. ### nodeProcessAborted(exitCode, signal) -* `exitCode` [<Number>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type) -* `signal` [<String>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type) -* return [<Boolean>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type) +* `exitCode` [<Number>] +* `signal` [<String>] +* return [<Boolean>] -Returns `true` if the exit code `exitCode` and/or signal name `signal` represent the exit code and/or signal name of a node process that aborted, `false` otherwise. +Returns `true` if the exit code `exitCode` and/or signal name `signal` represent +the exit code and/or signal name of a node process that aborted, `false` +otherwise. ### opensslCli -* return [<Boolean>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type) +* return [<Boolean>] Checks whether 'opensslCli' is supported. ### platformTimeout(ms) -* `ms` [<Number>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type) -* return [<Number>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type) +* `ms` [<Number>] +* return [<Number>] Platform normalizes timeout. ### PIPE -* return [<String>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type) +* return [<String>] Path to the test sock. ### PORT -* return [<Number>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type) default = `12346` +* return [<Number>] default = `12346` Port tests are running on. ### printSkipMessage(msg) -* `msg` [<String>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type) +* `msg` [<String>] Logs '1..0 # Skipped: ' + `msg` ### refreshTmpDir -* return [<String>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type) +* return [<String>] Deletes the 'tmp' dir and recreates it @@ -283,34 +307,34 @@ Restore the original `process.stderr.write`. Restore the original `process.stdout.write`. ### rootDir -* return [<String>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type) +* return [<String>] Path to the 'root' directory. either `/` or `c:\\` (windows) ### skip(msg) -* `msg` [<String>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type) +* `msg` [<String>] Logs '1..0 # Skipped: ' + `msg` and exits with exit code `0`. ### spawnPwd(options) -* `options` [<Object>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) -* return [<Object>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) +* `options` [<Object>] +* return [<Object>] Platform normalizes the `pwd` command. ### spawnSyncPwd(options) -* `options` [<Object>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) -* return [<Object>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) +* `options` [<Object>] +* return [<Object>] Synchronous version of `spawnPwd`. ### tmpDir -* return [<String>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type) +* return [<String>] The realpath of the 'tmp' directory. ### tmpDirName -* return [<String>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type) +* return [<String>] Name of the temp directory used by tests. @@ -323,5 +347,13 @@ Node.js implementation with tests from [W3C Web Platform Tests](https://github.com/w3c/web-platform-tests). -[MDN-Function]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Normal_objects_and_functions +[<Array>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array +[<ArrayBufferView[]>]: https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView +[<Boolean>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type +[<Buffer>]: https://nodejs.org/api/buffer.html#buffer_class_buffer +[<Function>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function +[<Number>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type +[<Object>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object +[<RegExp>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp +[<String>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type [internationalization]: https://github.com/nodejs/node/wiki/Intl diff --git a/test/common/index.js b/test/common/index.js index 2b90ed66780f75..fc14cdacacc587 100644 --- a/test/common/index.js +++ b/test/common/index.js @@ -25,12 +25,10 @@ const path = require('path'); const fs = require('fs'); const assert = require('assert'); const os = require('os'); -const child_process = require('child_process'); +const { exec, execSync, spawn, spawnSync } = require('child_process'); const stream = require('stream'); -const buffer = require('buffer'); const util = require('util'); const Timer = process.binding('timer_wrap').Timer; -const execSync = require('child_process').execSync; const testRoot = process.env.NODE_TEST_DIR ? fs.realpathSync(process.env.NODE_TEST_DIR) : path.resolve(__dirname, '..'); @@ -54,8 +52,6 @@ exports.isLinux = process.platform === 'linux'; exports.isOSX = process.platform === 'darwin'; exports.enoughTestMem = os.totalmem() > 0x40000000; /* 1 Gb */ -exports.bufferMaxSizeMsg = new RegExp( - `^RangeError: "size" argument must not be larger than ${buffer.kMaxLength}$`); const cpus = os.cpus(); exports.enoughTestCpu = Array.isArray(cpus) && (cpus.length > 1 || cpus[0].speed > 999); @@ -189,7 +185,7 @@ Object.defineProperty(exports, 'inFreeBSDJail', { if (inFreeBSDJail !== null) return inFreeBSDJail; if (exports.isFreeBSD && - child_process.execSync('sysctl -n security.jail.jailed').toString() === + execSync('sysctl -n security.jail.jailed').toString() === '1\n') { inFreeBSDJail = true; } else { @@ -223,7 +219,7 @@ Object.defineProperty(exports, 'localhostIPv4', { }); // opensslCli defined lazily to reduce overhead of spawnSync -Object.defineProperty(exports, 'opensslCli', {get: function() { +Object.defineProperty(exports, 'opensslCli', { get: function() { if (opensslCli !== null) return opensslCli; if (process.config.variables.node_shared_openssl) { @@ -236,13 +232,13 @@ Object.defineProperty(exports, 'opensslCli', {get: function() { if (exports.isWindows) opensslCli += '.exe'; - const opensslCmd = child_process.spawnSync(opensslCli, ['version']); + const opensslCmd = spawnSync(opensslCli, ['version']); if (opensslCmd.status !== 0 || opensslCmd.error !== undefined) { // openssl command cannot be executed opensslCli = false; } return opensslCli; -}, enumerable: true}); +}, enumerable: true }); Object.defineProperty(exports, 'hasCrypto', { get: function() { @@ -286,7 +282,7 @@ exports.childShouldThrowAndAbort = function() { } testCmd += `"${process.argv[0]}" --abort-on-uncaught-exception `; testCmd += `"${process.argv[1]}" child`; - const child = child_process.exec(testCmd); + const child = exec(testCmd); child.on('exit', function onExit(exitCode, signal) { const errMsg = 'Test should have aborted ' + `but instead exited with exit code ${exitCode}` + @@ -306,8 +302,6 @@ exports.ddCommand = function(filename, kilobytes) { exports.spawnPwd = function(options) { - const spawn = require('child_process').spawn; - if (exports.isWindows) { return spawn('cmd.exe', ['/d', '/c', 'cd'], options); } else { @@ -317,8 +311,6 @@ exports.spawnPwd = function(options) { exports.spawnSyncPwd = function(options) { - const spawnSync = require('child_process').spawnSync; - if (exports.isWindows) { return spawnSync('cmd.exe', ['/d', '/c', 'cd'], options); } else { @@ -487,7 +479,7 @@ exports.mustCallAtLeast = function(fn, minimum) { return _mustCallInner(fn, minimum, 'minimum'); }; -function _mustCallInner(fn, criteria, field) { +function _mustCallInner(fn, criteria = 1, field) { if (typeof fn === 'number') { criteria = fn; fn = noop; @@ -495,9 +487,7 @@ function _mustCallInner(fn, criteria, field) { fn = noop; } - if (criteria === undefined) - criteria = 1; - else if (typeof criteria !== 'number') + if (typeof criteria !== 'number') throw new TypeError(`Invalid ${field} value: ${criteria}`); const context = { @@ -701,21 +691,51 @@ Object.defineProperty(exports, 'hasSmallICU', { }); // Useful for testing expected internal/error objects -exports.expectsError = function expectsError({code, type, message}) { - return function(error) { - assert.strictEqual(error.code, code); - if (type !== undefined) { +exports.expectsError = function expectsError(fn, settings, exact) { + if (typeof fn !== 'function') { + exact = settings; + settings = fn; + fn = undefined; + } + const innerFn = exports.mustCall(function(error) { + assert.strictEqual(error.code, settings.code); + if ('type' in settings) { + const type = settings.type; + if (type !== Error && !Error.isPrototypeOf(type)) { + throw new TypeError('`settings.type` must inherit from `Error`'); + } assert(error instanceof type, - `${error} is not the expected type ${type}`); + `${error.name} is not instance of ${type.name}`); + } + if ('message' in settings) { + const message = settings.message; + if (typeof message === 'string') { + assert.strictEqual(error.message, message); + } else { + assert(message.test(error.message), + `${error.message} does not match ${message}`); + } + } + if ('name' in settings) { + assert.strictEqual(error.name, settings.name); } - if (message instanceof RegExp) { - assert(message.test(error.message), - `${error.message} does not match ${message}`); - } else if (typeof message === 'string') { - assert.strictEqual(error.message, message); + if (error.constructor.name === 'AssertionError') { + ['generatedMessage', 'actual', 'expected', 'operator'].forEach((key) => { + if (key in settings) { + const actual = error[key]; + const expected = settings[key]; + assert.strictEqual(actual, expected, + `${key}: expected ${expected}, not ${actual}`); + } + }); } return true; - }; + }, exact); + if (fn) { + assert.throws(fn, innerFn); + return; + } + return innerFn; }; exports.skipIfInspectorDisabled = function skipIfInspectorDisabled() { @@ -764,7 +784,7 @@ exports.getTTYfd = function getTTYfd() { else if (!tty.isatty(tty_fd)) tty_fd++; else { try { - tty_fd = require('fs').openSync('/dev/tty'); + tty_fd = fs.openSync('/dev/tty'); } catch (e) { // There aren't any tty fd's available to use. return -1;