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:
parent
ea8b932f30
commit
5da834f685
@ -173,24 +173,6 @@ Indicates whether `IPv6` is supported on this platform.
|
||||
|
||||
Indicates if there are multiple localhosts available.
|
||||
|
||||
### hijackStderr(listener)
|
||||
* `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
|
||||
be passed to `listener`. What's more, `process.stderr.writeTimes` is a count of
|
||||
the number of calls.
|
||||
|
||||
### hijackStdout(listener)
|
||||
* `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
|
||||
be passed to `listener`. What's more, `process.stdout.writeTimes` is a count of
|
||||
the number of calls.
|
||||
|
||||
### inFreeBSDJail
|
||||
* [<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
|
||||
* [<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` [<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` [<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
|
||||
[<boolean>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type
|
||||
[<number>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type
|
||||
[<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
|
||||
|
33
test/common/hijackstdio.js
Normal file
33
test/common/hijackstdio.js
Normal 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')
|
||||
};
|
@ -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 ||
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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() {
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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');
|
||||
}
|
||||
|
@ -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) => {
|
||||
|
@ -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) ?
|
||||
|
@ -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',
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user