Skip to content

Commit bdbeb33

Browse files
XadillaXaddaleax
authored andcommitted
test: add hijackStdout and hijackStderr
Add `common.hijackStdout` and `common.hijackStderr` to provide monitor for console output. PR-URL: #13439 Reviewed-By: Refael Ackermann <[email protected]>
1 parent 4a96ed4 commit bdbeb33

8 files changed

+114
-41
lines changed

test/common/README.md

+26
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,22 @@ Checks whether `IPv6` is supported on this platform.
116116

117117
Checks if there are multiple localhosts available.
118118

119+
### hijackStderr(listener)
120+
* `listener` [&lt;Function>][MDN-Function]: a listener with a single parameter called `data`.
121+
122+
Eavesdrop to `process.stderr.write` calls. Once `process.stderr.write` is
123+
called, `listener` will also be called and the `data` of `write` function will
124+
be passed to `listener`. What's more, `process.stderr.writeTimes` is a count of
125+
the number of calls.
126+
127+
### hijackStdout(listener)
128+
* `listener` [&lt;Function>][MDN-Function]: a listener with a single parameter called `data`.
129+
130+
Eavesdrop to `process.stdout.write` calls. Once `process.stdout.write` is
131+
called, `listener` will also be called and the `data` of `write` function will
132+
be passed to `listener`. What's more, `process.stdout.writeTimes` is a count of
133+
the number of calls.
134+
119135
### inFreeBSDJail
120136
* return [&lt;Boolean>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type)
121137

@@ -256,6 +272,14 @@ Port tests are running on.
256272

257273
Deletes the 'tmp' dir and recreates it
258274

275+
### restoreStderr()
276+
277+
Restore the original `process.stderr.write`.
278+
279+
### restoreStdout()
280+
281+
Restore the original `process.stdout.write`.
282+
259283
### rootDir
260284
* return [&lt;String>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type)
261285

@@ -296,3 +320,5 @@ Node.js
296320
[WHATWG URL API](https://nodejs.org/api/url.html#url_the_whatwg_url_api)
297321
implementation with tests from
298322
[W3C Web Platform Tests](https://github.com/w3c/web-platform-tests).
323+
324+
[MDN-Function]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Normal_objects_and_functions

test/common/index.js

+24
Original file line numberDiff line numberDiff line change
@@ -759,3 +759,27 @@ exports.getTTYfd = function getTTYfd() {
759759
}
760760
return tty_fd;
761761
};
762+
763+
// Hijack stdout and stderr
764+
const stdWrite = {};
765+
function hijackStdWritable(name, listener) {
766+
const stream = process[name];
767+
const _write = stdWrite[name] = stream.write;
768+
769+
stream.writeTimes = 0;
770+
stream.write = function(data, callback) {
771+
listener(data);
772+
_write.call(stream, data, callback);
773+
stream.writeTimes++;
774+
};
775+
}
776+
777+
function restoreWritable(name) {
778+
process[name].write = stdWrite[name];
779+
delete process[name].writeTimes;
780+
}
781+
782+
exports.hijackStdout = hijackStdWritable.bind(null, 'stdout');
783+
exports.hijackStderr = hijackStdWritable.bind(null, 'stderr');
784+
exports.restoreStdout = restoreWritable.bind(null, 'stdout');
785+
exports.restoreStderr = restoreWritable.bind(null, 'stderr');

test/fixtures/echo-close-check.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const fs = require('fs');
2626

2727
process.stdout.write('hello world\r\n');
2828

29-
var stdin = process.openStdin();
29+
const stdin = process.openStdin();
3030

3131
stdin.on('data', function(data) {
3232
process.stdout.write(data.toString());

test/parallel/test-common.js

+20
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,23 @@ for (const p of failFixtures) {
8888
assert.strictEqual(firstLine, expected);
8989
}));
9090
}
91+
92+
// hijackStderr and hijackStdout
93+
const HIJACK_TEST_ARRAY = [ 'foo\n', 'bar\n', 'baz\n' ];
94+
[ 'err', 'out' ].forEach((txt) => {
95+
const stream = process[`std${txt}`];
96+
const originalWrite = stream.write;
97+
98+
common[`hijackStd${txt}`](common.mustCall(function(data) {
99+
assert.strictEqual(data, HIJACK_TEST_ARRAY[stream.writeTimes]);
100+
}, HIJACK_TEST_ARRAY.length));
101+
assert.notStrictEqual(originalWrite, stream.write);
102+
103+
HIJACK_TEST_ARRAY.forEach((val) => {
104+
stream.write(val, common.mustCall(common.noop));
105+
});
106+
107+
assert.strictEqual(HIJACK_TEST_ARRAY.length, stream.writeTimes);
108+
common[`restoreStd${txt}`]();
109+
assert.strictEqual(originalWrite, stream.write);
110+
});

test/parallel/test-console.js

+21-13
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,14 @@ assert.doesNotThrow(function() {
4545
// an Object with a custom .inspect() function
4646
const custom_inspect = { foo: 'bar', inspect: () => 'inspect' };
4747

48-
const stdout_write = global.process.stdout.write;
49-
const stderr_write = global.process.stderr.write;
5048
const strings = [];
5149
const errStrings = [];
52-
global.process.stdout.write = function(string) {
53-
strings.push(string);
54-
};
55-
global.process.stderr.write = function(string) {
56-
errStrings.push(string);
57-
};
50+
common.hijackStdout(function(data) {
51+
strings.push(data);
52+
});
53+
common.hijackStderr(function(data) {
54+
errStrings.push(data);
55+
});
5856

5957
// test console.log() goes to stdout
6058
console.log('foo');
@@ -105,8 +103,10 @@ console.timeEnd('constructor');
105103
console.time('hasOwnProperty');
106104
console.timeEnd('hasOwnProperty');
107105

108-
global.process.stdout.write = stdout_write;
109-
global.process.stderr.write = stderr_write;
106+
assert.strictEqual(strings.length, process.stdout.writeTimes);
107+
assert.strictEqual(errStrings.length, process.stderr.writeTimes);
108+
common.restoreStdout();
109+
common.restoreStderr();
110110

111111
// verify that console.timeEnd() doesn't leave dead links
112112
const timesMapSize = console._times.size;
@@ -146,9 +146,6 @@ assert.ok(/^hasOwnProperty: \d+\.\d{3}ms$/.test(strings.shift().trim()));
146146
assert.strictEqual('Trace: This is a {"formatted":"trace"} 10 foo',
147147
errStrings.shift().split('\n').shift());
148148

149-
assert.strictEqual(strings.length, 0);
150-
assert.strictEqual(errStrings.length, 0);
151-
152149
assert.throws(() => {
153150
console.assert(false, 'should throw');
154151
}, common.expectsError({
@@ -159,3 +156,14 @@ assert.throws(() => {
159156
assert.doesNotThrow(() => {
160157
console.assert(true, 'this should not throw');
161158
});
159+
160+
// hijack stderr to catch `process.emitWarning` which is using
161+
// `process.nextTick`
162+
common.hijackStderr(common.mustCall(function(data) {
163+
common.restoreStderr();
164+
165+
// stderr.write will catch sync error, so use `process.nextTick` here
166+
process.nextTick(function() {
167+
assert.strictEqual(data.includes('no such label'), true);
168+
});
169+
}));

test/parallel/test-global-console-exists.js

+12-15
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,28 @@
77
const common = require('../common');
88
const assert = require('assert');
99
const EventEmitter = require('events');
10-
const leak_warning = /EventEmitter memory leak detected\. 2 hello listeners/;
10+
const leakWarning = /EventEmitter memory leak detected\. 2 hello listeners/;
1111

12-
let write_calls = 0;
12+
common.hijackStderr(common.mustCall(function(data) {
13+
if (process.stderr.writeTimes === 0) {
14+
assert.ok(data.match(leakWarning));
15+
} else {
16+
assert.fail('stderr.write should be called only once');
17+
}
18+
}));
1319

14-
process.on('warning', (warning) => {
20+
process.on('warning', function(warning) {
1521
// This will be called after the default internal
1622
// process warning handler is called. The default
1723
// process warning writes to the console, which will
1824
// invoke the monkeypatched process.stderr.write
1925
// below.
20-
assert.strictEqual(write_calls, 1);
21-
EventEmitter.defaultMaxListeners = old_default;
26+
assert.strictEqual(process.stderr.writeTimes, 1);
27+
EventEmitter.defaultMaxListeners = oldDefault;
2228
// when we get here, we should be done
2329
});
2430

25-
process.stderr.write = (data) => {
26-
if (write_calls === 0)
27-
assert.ok(data.match(leak_warning));
28-
else
29-
assert.fail('stderr.write should be called only once');
30-
31-
write_calls++;
32-
};
33-
34-
const old_default = EventEmitter.defaultMaxListeners;
31+
const oldDefault = EventEmitter.defaultMaxListeners;
3532
EventEmitter.defaultMaxListeners = 1;
3633

3734
const e = new EventEmitter();

test/parallel/test-process-raw-debug.js

+2-5
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
// USE OR OTHER DEALINGS IN THE SOFTWARE.
2121

2222
'use strict';
23-
require('../common');
23+
const common = require('../common');
2424
const assert = require('assert');
2525
const os = require('os');
2626

@@ -63,10 +63,7 @@ function child() {
6363
throw new Error('No ticking!');
6464
};
6565

66-
const stderr = process.stderr;
67-
stderr.write = function() {
68-
throw new Error('No writing to stderr!');
69-
};
66+
common.hijackStderr(common.mustNotCall('stderr.write must not be called.'));
7067

7168
process._rawDebug('I can still %s!', 'debug');
7269
}

test/parallel/test-util-log.js

+8-7
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,18 @@
2020
// USE OR OTHER DEALINGS IN THE SOFTWARE.
2121

2222
'use strict';
23-
require('../common');
23+
const common = require('../common');
2424
const assert = require('assert');
2525
const util = require('util');
2626

2727
assert.ok(process.stdout.writable);
2828
assert.ok(process.stderr.writable);
2929

30-
const stdout_write = global.process.stdout.write;
3130
const strings = [];
32-
global.process.stdout.write = function(string) {
33-
strings.push(string);
34-
};
35-
console._stderr = process.stdout;
31+
common.hijackStdout(function(data) {
32+
strings.push(data);
33+
});
34+
common.hijackStderr(common.mustNotCall('stderr.write must not be called'));
3635

3736
const tests = [
3837
{input: 'foo', output: 'foo'},
@@ -56,4 +55,6 @@ tests.forEach(function(test) {
5655
assert.strictEqual(match[1], test.output);
5756
});
5857

59-
global.process.stdout.write = stdout_write;
58+
assert.strictEqual(process.stdout.writeTimes, tests.length);
59+
60+
common.restoreStdout();

0 commit comments

Comments
 (0)