test: move hijackstdio out of require('common')

Move the hijackstdio functions out of common so that they are
imported only into the tests that actually need them

PR-URL: https://github.com/nodejs/node/pull/22462
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
This commit is contained in:
James M Snell 2018-08-22 09:17:19 -07:00
parent ea8b932f30
commit 5da834f685
No known key found for this signature in database
GPG Key ID: 7341B15C070877AC
13 changed files with 146 additions and 96 deletions

View File

@ -173,24 +173,6 @@ Indicates whether `IPv6` is supported on this platform.
Indicates if there are multiple localhosts available.
### hijackStderr(listener)
* `listener` [&lt;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
be passed to `listener`. What's more, `process.stderr.writeTimes` is a count of
the number of calls.
### hijackStdout(listener)
* `listener` [&lt;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
be passed to `listener`. What's more, `process.stdout.writeTimes` is a count of
the number of calls.
### inFreeBSDJail
* [&lt;boolean>]
@ -355,16 +337,6 @@ A port number for tests to use if one is needed.
Logs '1..0 # Skipped: ' + `msg`
### restoreStderr()
Restore the original `process.stderr.write`. Used to restore `stderr` to its
original state after calling [`common.hijackStdErr()`][].
### restoreStdout()
Restore the original `process.stdout.write`. Used to restore `stdout` to its
original state after calling [`common.hijackStdOut()`][].
### rootDir
* [&lt;string>]
@ -596,6 +568,52 @@ validateSnapshotNodes('TLSWRAP', [
]);
```
## hijackstdio Module
The `hijackstdio` module provides utility functions for temporarily redirecting
`stdout` and `stderr` output.
<!-- eslint-disable no-undef, node-core/required-modules -->
```js
const { hijackStdout, restoreStdout } = require('../common/hijackstdio');
hijackStdout((data) => {
/* Do something with data */
restoreStdout();
});
console.log('this is sent to the hijacked listener');
```
### hijackStderr(listener)
* `listener` [&lt;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
be passed to `listener`. What's more, `process.stderr.writeTimes` is a count of
the number of calls.
### hijackStdout(listener)
* `listener` [&lt;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
be passed to `listener`. What's more, `process.stdout.writeTimes` is a count of
the number of calls.
### restoreStderr()
Restore the original `process.stderr.write()`. Used to restore `stderr` to its
original state after calling [`hijackstdio.hijackStdErr()`][].
### restoreStdout()
Restore the original `process.stdout.write()`. Used to restore `stdout` to its
original state after calling [`hijackstdio.hijackStdOut()`][].
## HTTP/2 Module
The http2.js module provides a handful of utilities for creating mock HTTP/2
@ -773,6 +791,6 @@ implementation with tests from
[&lt;boolean>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type
[&lt;number>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type
[&lt;string>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type
[`common.hijackStdErr()`]: #hijackstderrlistener
[`common.hijackStdOut()`]: #hijackstdoutlistener
[`hijackstdio.hijackStdErr()`]: #hijackstderrlistener
[`hijackstdio.hijackStdOut()`]: #hijackstdoutlistener
[internationalization]: https://github.com/nodejs/node/wiki/Intl

View File

@ -0,0 +1,33 @@
/* eslint-disable node-core/required-modules */
'use strict';
// Hijack stdout and stderr
const stdWrite = {};
function hijackStdWritable(name, listener) {
const stream = process[name];
const _write = stdWrite[name] = stream.write;
stream.writeTimes = 0;
stream.write = function(data, callback) {
try {
listener(data);
} catch (e) {
process.nextTick(() => { throw e; });
}
_write.call(stream, data, callback);
stream.writeTimes++;
};
}
function restoreWritable(name) {
process[name].write = stdWrite[name];
delete process[name].writeTimes;
}
module.exports = {
hijackStdout: hijackStdWritable.bind(null, 'stdout'),
hijackStderr: hijackStdWritable.bind(null, 'stderr'),
restoreStdout: restoreWritable.bind(null, 'stdout'),
restoreStderr: restoreWritable.bind(null, 'stderr')
};

View File

@ -787,30 +787,6 @@ exports.getTTYfd = function getTTYfd() {
return ttyFd;
};
// Hijack stdout and stderr
const stdWrite = {};
function hijackStdWritable(name, listener) {
const stream = process[name];
const _write = stdWrite[name] = stream.write;
stream.writeTimes = 0;
stream.write = function(data, callback) {
try {
listener(data);
} catch (e) {
process.nextTick(() => { throw e; });
}
_write.call(stream, data, callback);
stream.writeTimes++;
};
}
function restoreWritable(name) {
process[name].write = stdWrite[name];
delete process[name].writeTimes;
}
exports.runWithInvalidFD = function(func) {
let fd = 1 << 30;
// Get first known bad file descriptor. 1 << 30 is usually unlikely to
@ -824,10 +800,6 @@ exports.runWithInvalidFD = function(func) {
exports.printSkipMessage('Could not generate an invalid fd');
};
exports.hijackStdout = hijackStdWritable.bind(null, 'stdout');
exports.hijackStderr = hijackStdWritable.bind(null, 'stderr');
exports.restoreStdout = restoreWritable.bind(null, 'stdout');
exports.restoreStderr = restoreWritable.bind(null, 'stderr');
exports.isCPPSymbolsNotMapped = exports.isWindows ||
exports.isSunOS ||
exports.isAIX ||

View File

@ -52,10 +52,6 @@ const {
disableCrashOnUnhandledRejection,
getTTYfd,
runWithInvalidFD,
hijackStdout,
hijackStderr,
restoreStdout,
restoreStderr,
isCPPSymbolsNotMapped
} = common;
@ -109,9 +105,5 @@ export {
disableCrashOnUnhandledRejection,
getTTYfd,
runWithInvalidFD,
hijackStdout,
hijackStderr,
restoreStdout,
restoreStderr,
isCPPSymbolsNotMapped
};

View File

@ -21,6 +21,7 @@
'use strict';
const common = require('../common');
const hijackstdio = require('../common/hijackstdio');
const fixtures = require('../common/fixtures');
const assert = require('assert');
const { execFile } = require('child_process');
@ -95,7 +96,7 @@ const HIJACK_TEST_ARRAY = [ 'foo\n', 'bar\n', 'baz\n' ];
const stream = process[`std${txt}`];
const originalWrite = stream.write;
common[`hijackStd${txt}`](common.mustCall(function(data) {
hijackstdio[`hijackStd${txt}`](common.mustCall(function(data) {
assert.strictEqual(data, HIJACK_TEST_ARRAY[stream.writeTimes]);
}, HIJACK_TEST_ARRAY.length));
assert.notStrictEqual(originalWrite, stream.write);
@ -105,14 +106,14 @@ const HIJACK_TEST_ARRAY = [ 'foo\n', 'bar\n', 'baz\n' ];
});
assert.strictEqual(HIJACK_TEST_ARRAY.length, stream.writeTimes);
common[`restoreStd${txt}`]();
hijackstdio[`restoreStd${txt}`]();
assert.strictEqual(originalWrite, stream.write);
});
// hijackStderr and hijackStdout again
// for console
[[ 'err', 'error' ], [ 'out', 'log' ]].forEach(([ type, method ]) => {
common[`hijackStd${type}`](common.mustCall(function(data) {
hijackstdio[`hijackStd${type}`](common.mustCall(function(data) {
assert.strictEqual(data, 'test\n');
// throw an error
@ -120,7 +121,7 @@ const HIJACK_TEST_ARRAY = [ 'foo\n', 'bar\n', 'baz\n' ];
}));
console[method]('test');
common[`restoreStd${type}`]();
hijackstdio[`restoreStd${type}`]();
});
let uncaughtTimes = 0;

View File

@ -1,5 +1,11 @@
'use strict';
const common = require('../common');
require('../common');
const {
hijackStdout,
hijackStderr,
restoreStdout,
restoreStderr
} = require('../common/hijackstdio');
const assert = require('assert');
const Console = require('console').Console;
@ -8,12 +14,12 @@ let c, stdout, stderr;
function setup() {
stdout = '';
common.hijackStdout(function(data) {
hijackStdout(function(data) {
stdout += data;
});
stderr = '';
common.hijackStderr(function(data) {
hijackStderr(function(data) {
stderr += data;
});
@ -21,8 +27,8 @@ function setup() {
}
function teardown() {
common.restoreStdout();
common.restoreStderr();
restoreStdout();
restoreStderr();
}
// Basic group() functionality

View File

@ -24,6 +24,13 @@ const common = require('../common');
const assert = require('assert');
const util = require('util');
const {
hijackStdout,
hijackStderr,
restoreStdout,
restoreStderr
} = require('../common/hijackstdio');
assert.ok(process.stdout.writable);
assert.ok(process.stderr.writable);
// Support legacy API
@ -63,11 +70,11 @@ const custom_inspect = { foo: 'bar', [util.inspect.custom]: () => 'inspect' };
const strings = [];
const errStrings = [];
process.stdout.isTTY = false;
common.hijackStdout(function(data) {
hijackStdout(function(data) {
strings.push(data);
});
process.stderr.isTTY = false;
common.hijackStderr(function(data) {
hijackStderr(function(data) {
errStrings.push(data);
});
@ -175,8 +182,8 @@ console.assert(true, 'this should not throw');
assert.strictEqual(strings.length, process.stdout.writeTimes);
assert.strictEqual(errStrings.length, process.stderr.writeTimes);
common.restoreStdout();
common.restoreStderr();
restoreStdout();
restoreStderr();
// verify that console.timeEnd() doesn't leave dead links
const timesMapSize = console._times.size;
@ -246,8 +253,8 @@ assert.strictEqual(errStrings.shift().split('\n').shift(),
// hijack stderr to catch `process.emitWarning` which is using
// `process.nextTick`
common.hijackStderr(common.mustCall(function(data) {
common.restoreStderr();
hijackStderr(common.mustCall(function(data) {
restoreStderr();
// stderr.write will catch sync error, so use `process.nextTick` here
process.nextTick(function() {

View File

@ -1,7 +1,10 @@
// Flags: --expose-internals
'use strict';
const common = require('../common');
const {
hijackStdout,
restoreStdout,
} = require('../common/hijackstdio');
const assert = require('assert');
const errors = require('internal/errors');
@ -241,22 +244,22 @@ assert.strictEqual(
// browser. Note that `message` remains non-enumerable after being assigned.
{
let initialConsoleLog = '';
common.hijackStdout((data) => { initialConsoleLog += data; });
hijackStdout((data) => { initialConsoleLog += data; });
const myError = new errors.codes.ERR_TLS_HANDSHAKE_TIMEOUT();
assert.deepStrictEqual(Object.keys(myError), []);
const initialToString = myError.toString();
console.log(myError);
assert.notStrictEqual(initialConsoleLog, '');
common.restoreStdout();
restoreStdout();
let subsequentConsoleLog = '';
common.hijackStdout((data) => { subsequentConsoleLog += data; });
hijackStdout((data) => { subsequentConsoleLog += data; });
myError.message = 'Fhqwhgads';
assert.deepStrictEqual(Object.keys(myError), []);
assert.notStrictEqual(myError.toString(), initialToString);
console.log(myError);
assert.strictEqual(subsequentConsoleLog, initialConsoleLog);
common.restoreStdout();
restoreStdout();
}

View File

@ -21,6 +21,7 @@
'use strict';
const common = require('../common');
const { hijackStderr } = require('../common/hijackstdio');
const assert = require('assert');
const os = require('os');
@ -63,7 +64,7 @@ function child() {
throw new Error('No ticking!');
};
common.hijackStderr(common.mustNotCall('stderr.write must not be called.'));
hijackStderr(common.mustNotCall('stderr.write must not be called.'));
process._rawDebug('I can still %s!', 'debug');
}

View File

@ -1,12 +1,16 @@
'use strict';
const common = require('../common');
const {
hijackStderr,
restoreStderr
} = require('../common/hijackstdio');
const assert = require('assert');
function test1() {
// Output is skipped if the argument to the 'warning' event is
// not an Error object.
common.hijackStderr(common.mustNotCall('stderr.write must not be called'));
hijackStderr(common.mustNotCall('stderr.write must not be called'));
process.emit('warning', 'test');
setImmediate(test2);
}
@ -21,7 +25,7 @@ function test2() {
}
function test3() {
common.restoreStderr();
restoreStderr();
// Type defaults to warning when the second argument is an object
process.emitWarning('test', {});
process.once('warning', common.mustCall((warning) => {

View File

@ -23,6 +23,10 @@
const common = require('../common');
const ArrayStream = require('../common/arraystream');
const {
hijackStderr,
restoreStderr
} = require('../common/hijackstdio');
const assert = require('assert');
const fixtures = require('../common/fixtures');
const hasInspector = process.config.variables.v8_enable_inspector === 1;
@ -423,9 +427,9 @@ testMe.complete('obj.', common.mustCall((error, data) => {
putIn.run([`var ele = new ${type.name}(1e6 + 1); ele.biu = 1;`]);
}
common.hijackStderr(common.mustNotCall());
hijackStderr(common.mustNotCall());
testMe.complete('ele.', common.mustCall((err, data) => {
common.restoreStderr();
restoreStderr();
assert.ifError(err);
const ele = (type === Array) ?

View File

@ -5,13 +5,17 @@ const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');
const {
hijackStderr,
restoreStderr
} = require('../common/hijackstdio');
const assert = require('assert');
// Flags: --expose_internals
const internalTLS = require('internal/tls');
const tls = require('tls');
const noOutput = common.mustNotCall();
common.hijackStderr(noOutput);
hijackStderr(noOutput);
{
const singles = 'C=US\nST=CA\nL=SF\nO=Node.js Foundation\nOU=Node.js\n' +
@ -54,7 +58,7 @@ common.hijackStderr(noOutput);
assert.deepStrictEqual(internalTLS.parseCertString(input), expected);
}
common.restoreStderr();
restoreStderr();
{
common.expectWarning('DeprecationWarning',

View File

@ -21,6 +21,11 @@
'use strict';
const common = require('../common');
const {
hijackStdout,
hijackStderr,
restoreStdout,
} = require('../common/hijackstdio');
const assert = require('assert');
const util = require('util');
@ -28,10 +33,10 @@ assert.ok(process.stdout.writable);
assert.ok(process.stderr.writable);
const strings = [];
common.hijackStdout(function(data) {
hijackStdout(function(data) {
strings.push(data);
});
common.hijackStderr(common.mustNotCall('stderr.write must not be called'));
hijackStderr(common.mustNotCall('stderr.write must not be called'));
const tests = [
{ input: 'foo', output: 'foo' },
@ -57,4 +62,4 @@ tests.forEach(function(test) {
assert.strictEqual(process.stdout.writeTimes, tests.length);
common.restoreStdout();
restoreStdout();