mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 10:59:27 +00:00
test: add hijackStdout and hijackStderr
Add `common.hijackStdout` and `common.hijackStderr` to provide monitor for console output. PR-URL: https://github.com/nodejs/node/pull/13439 Reviewed-By: Refael Ackermann <refack@gmail.com>
This commit is contained in:
parent
27de36926b
commit
d00e5f1a04
@ -116,6 +116,22 @@ Checks whether `IPv6` is supported on this platform.
|
||||
|
||||
Checks if there are multiple localhosts available.
|
||||
|
||||
### hijackStderr(listener)
|
||||
* `listener` [<Function>][MDN-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>][MDN-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
|
||||
* return [<Boolean>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type)
|
||||
|
||||
@ -256,6 +272,14 @@ Port tests are running on.
|
||||
|
||||
Deletes the 'tmp' dir and recreates it
|
||||
|
||||
### restoreStderr()
|
||||
|
||||
Restore the original `process.stderr.write`.
|
||||
|
||||
### restoreStdout()
|
||||
|
||||
Restore the original `process.stdout.write`.
|
||||
|
||||
### rootDir
|
||||
* return [<String>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type)
|
||||
|
||||
@ -296,3 +320,5 @@ Node.js
|
||||
[WHATWG URL API](https://nodejs.org/api/url.html#url_the_whatwg_url_api)
|
||||
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
|
||||
|
@ -759,3 +759,27 @@ exports.getTTYfd = function getTTYfd() {
|
||||
}
|
||||
return tty_fd;
|
||||
};
|
||||
|
||||
// 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) {
|
||||
listener(data);
|
||||
_write.call(stream, data, callback);
|
||||
stream.writeTimes++;
|
||||
};
|
||||
}
|
||||
|
||||
function restoreWritable(name) {
|
||||
process[name].write = stdWrite[name];
|
||||
delete process[name].writeTimes;
|
||||
}
|
||||
|
||||
exports.hijackStdout = hijackStdWritable.bind(null, 'stdout');
|
||||
exports.hijackStderr = hijackStdWritable.bind(null, 'stderr');
|
||||
exports.restoreStdout = restoreWritable.bind(null, 'stdout');
|
||||
exports.restoreStderr = restoreWritable.bind(null, 'stderr');
|
||||
|
2
test/fixtures/echo-close-check.js
vendored
2
test/fixtures/echo-close-check.js
vendored
@ -26,7 +26,7 @@ const fs = require('fs');
|
||||
|
||||
process.stdout.write('hello world\r\n');
|
||||
|
||||
var stdin = process.openStdin();
|
||||
const stdin = process.openStdin();
|
||||
|
||||
stdin.on('data', function(data) {
|
||||
process.stdout.write(data.toString());
|
||||
|
@ -88,3 +88,23 @@ for (const p of failFixtures) {
|
||||
assert.strictEqual(firstLine, expected);
|
||||
}));
|
||||
}
|
||||
|
||||
// hijackStderr and hijackStdout
|
||||
const HIJACK_TEST_ARRAY = [ 'foo\n', 'bar\n', 'baz\n' ];
|
||||
[ 'err', 'out' ].forEach((txt) => {
|
||||
const stream = process[`std${txt}`];
|
||||
const originalWrite = stream.write;
|
||||
|
||||
common[`hijackStd${txt}`](common.mustCall(function(data) {
|
||||
assert.strictEqual(data, HIJACK_TEST_ARRAY[stream.writeTimes]);
|
||||
}, HIJACK_TEST_ARRAY.length));
|
||||
assert.notStrictEqual(originalWrite, stream.write);
|
||||
|
||||
HIJACK_TEST_ARRAY.forEach((val) => {
|
||||
stream.write(val, common.mustCall(common.noop));
|
||||
});
|
||||
|
||||
assert.strictEqual(HIJACK_TEST_ARRAY.length, stream.writeTimes);
|
||||
common[`restoreStd${txt}`]();
|
||||
assert.strictEqual(originalWrite, stream.write);
|
||||
});
|
||||
|
@ -45,16 +45,14 @@ assert.doesNotThrow(function() {
|
||||
// an Object with a custom .inspect() function
|
||||
const custom_inspect = { foo: 'bar', inspect: () => 'inspect' };
|
||||
|
||||
const stdout_write = global.process.stdout.write;
|
||||
const stderr_write = global.process.stderr.write;
|
||||
const strings = [];
|
||||
const errStrings = [];
|
||||
global.process.stdout.write = function(string) {
|
||||
strings.push(string);
|
||||
};
|
||||
global.process.stderr.write = function(string) {
|
||||
errStrings.push(string);
|
||||
};
|
||||
common.hijackStdout(function(data) {
|
||||
strings.push(data);
|
||||
});
|
||||
common.hijackStderr(function(data) {
|
||||
errStrings.push(data);
|
||||
});
|
||||
|
||||
// test console.log() goes to stdout
|
||||
console.log('foo');
|
||||
@ -105,8 +103,10 @@ console.timeEnd('constructor');
|
||||
console.time('hasOwnProperty');
|
||||
console.timeEnd('hasOwnProperty');
|
||||
|
||||
global.process.stdout.write = stdout_write;
|
||||
global.process.stderr.write = stderr_write;
|
||||
assert.strictEqual(strings.length, process.stdout.writeTimes);
|
||||
assert.strictEqual(errStrings.length, process.stderr.writeTimes);
|
||||
common.restoreStdout();
|
||||
common.restoreStderr();
|
||||
|
||||
// verify that console.timeEnd() doesn't leave dead links
|
||||
const timesMapSize = console._times.size;
|
||||
@ -146,9 +146,6 @@ assert.ok(/^hasOwnProperty: \d+\.\d{3}ms$/.test(strings.shift().trim()));
|
||||
assert.strictEqual('Trace: This is a {"formatted":"trace"} 10 foo',
|
||||
errStrings.shift().split('\n').shift());
|
||||
|
||||
assert.strictEqual(strings.length, 0);
|
||||
assert.strictEqual(errStrings.length, 0);
|
||||
|
||||
assert.throws(() => {
|
||||
console.assert(false, 'should throw');
|
||||
}, common.expectsError({
|
||||
@ -159,3 +156,14 @@ assert.throws(() => {
|
||||
assert.doesNotThrow(() => {
|
||||
console.assert(true, 'this should not throw');
|
||||
});
|
||||
|
||||
// hijack stderr to catch `process.emitWarning` which is using
|
||||
// `process.nextTick`
|
||||
common.hijackStderr(common.mustCall(function(data) {
|
||||
common.restoreStderr();
|
||||
|
||||
// stderr.write will catch sync error, so use `process.nextTick` here
|
||||
process.nextTick(function() {
|
||||
assert.strictEqual(data.includes('no such label'), true);
|
||||
});
|
||||
}));
|
||||
|
@ -7,31 +7,28 @@
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const EventEmitter = require('events');
|
||||
const leak_warning = /EventEmitter memory leak detected\. 2 hello listeners/;
|
||||
const leakWarning = /EventEmitter memory leak detected\. 2 hello listeners/;
|
||||
|
||||
let write_calls = 0;
|
||||
common.hijackStderr(common.mustCall(function(data) {
|
||||
if (process.stderr.writeTimes === 0) {
|
||||
assert.ok(data.match(leakWarning));
|
||||
} else {
|
||||
assert.fail('stderr.write should be called only once');
|
||||
}
|
||||
}));
|
||||
|
||||
process.on('warning', (warning) => {
|
||||
process.on('warning', function(warning) {
|
||||
// This will be called after the default internal
|
||||
// process warning handler is called. The default
|
||||
// process warning writes to the console, which will
|
||||
// invoke the monkeypatched process.stderr.write
|
||||
// below.
|
||||
assert.strictEqual(write_calls, 1);
|
||||
EventEmitter.defaultMaxListeners = old_default;
|
||||
assert.strictEqual(process.stderr.writeTimes, 1);
|
||||
EventEmitter.defaultMaxListeners = oldDefault;
|
||||
// when we get here, we should be done
|
||||
});
|
||||
|
||||
process.stderr.write = (data) => {
|
||||
if (write_calls === 0)
|
||||
assert.ok(data.match(leak_warning));
|
||||
else
|
||||
assert.fail('stderr.write should be called only once');
|
||||
|
||||
write_calls++;
|
||||
};
|
||||
|
||||
const old_default = EventEmitter.defaultMaxListeners;
|
||||
const oldDefault = EventEmitter.defaultMaxListeners;
|
||||
EventEmitter.defaultMaxListeners = 1;
|
||||
|
||||
const e = new EventEmitter();
|
||||
|
@ -20,7 +20,7 @@
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
require('../common');
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const os = require('os');
|
||||
|
||||
@ -63,10 +63,7 @@ function child() {
|
||||
throw new Error('No ticking!');
|
||||
};
|
||||
|
||||
const stderr = process.stderr;
|
||||
stderr.write = function() {
|
||||
throw new Error('No writing to stderr!');
|
||||
};
|
||||
common.hijackStderr(common.mustNotCall('stderr.write must not be called.'));
|
||||
|
||||
process._rawDebug('I can still %s!', 'debug');
|
||||
}
|
||||
|
@ -20,19 +20,18 @@
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
'use strict';
|
||||
require('../common');
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const util = require('util');
|
||||
|
||||
assert.ok(process.stdout.writable);
|
||||
assert.ok(process.stderr.writable);
|
||||
|
||||
const stdout_write = global.process.stdout.write;
|
||||
const strings = [];
|
||||
global.process.stdout.write = function(string) {
|
||||
strings.push(string);
|
||||
};
|
||||
console._stderr = process.stdout;
|
||||
common.hijackStdout(function(data) {
|
||||
strings.push(data);
|
||||
});
|
||||
common.hijackStderr(common.mustNotCall('stderr.write must not be called'));
|
||||
|
||||
const tests = [
|
||||
{input: 'foo', output: 'foo'},
|
||||
@ -56,4 +55,6 @@ tests.forEach(function(test) {
|
||||
assert.strictEqual(match[1], test.output);
|
||||
});
|
||||
|
||||
global.process.stdout.write = stdout_write;
|
||||
assert.strictEqual(process.stdout.writeTimes, tests.length);
|
||||
|
||||
common.restoreStdout();
|
||||
|
Loading…
Reference in New Issue
Block a user