Skip to content

Commit 5ddc9fd

Browse files
authoredAug 1, 2020
Temporarily uncork report stream when clearing spinner
The spinner is not cleared while the stream is corked, which then corrupts the printing of stdout / stderr chunks received from the test processes. Fixes #2541
1 parent 8d03e1d commit 5ddc9fd

File tree

2 files changed

+50
-23
lines changed

2 files changed

+50
-23
lines changed
 

‎lib/reporters/default.js

+50-10
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ const colors = require('./colors');
1818
const formatSerializedError = require('./format-serialized-error');
1919
const improperUsageMessages = require('./improper-usage-messages');
2020
const prefixTitle = require('./prefix-title');
21-
const whileCorked = require('./while-corked');
2221

2322
const nodeInternals = require('stack-utils').nodeInternals();
2423

@@ -97,6 +96,48 @@ class LineWriterWithSpinner extends LineWriter {
9796
}
9897
}
9998

99+
function manageCorking(stream) {
100+
let corked = false;
101+
const cork = () => {
102+
corked = true;
103+
stream.cork();
104+
};
105+
106+
const uncork = () => {
107+
corked = false;
108+
stream.uncork();
109+
};
110+
111+
return {
112+
decorateFlushingWriter(fn) {
113+
return function (...args) {
114+
if (corked) {
115+
stream.uncork();
116+
}
117+
118+
try {
119+
return fn.apply(this, args);
120+
} finally {
121+
if (corked) {
122+
stream.cork();
123+
}
124+
}
125+
};
126+
},
127+
128+
decorateWriter(fn) {
129+
return function (...args) {
130+
cork();
131+
try {
132+
return fn.apply(this, args);
133+
} finally {
134+
uncork();
135+
}
136+
};
137+
}
138+
};
139+
}
140+
100141
class Reporter {
101142
constructor({
102143
verbose,
@@ -112,13 +153,16 @@ class Reporter {
112153
this.stdStream = stdStream;
113154
this.watching = watching;
114155
this.relativeFile = file => path.relative(projectDir, file);
115-
this.consumeStateChange = whileCorked(this.reportStream, this.consumeStateChange);
156+
157+
const {decorateWriter, decorateFlushingWriter} = manageCorking(this.reportStream);
158+
this.consumeStateChange = decorateWriter(this.consumeStateChange);
159+
this.endRun = decorateWriter(this.endRun);
116160

117161
if (this.verbose) {
118162
this.durationThreshold = durationThreshold || 100;
119163
this.spinner = null;
164+
this.clearSpinner = () => {};
120165
this.lineWriter = new LineWriter(this.reportStream);
121-
this.endRun = whileCorked(this.reportStream, this.endRun);
122166
} else {
123167
this.spinner = ora({
124168
isEnabled: true,
@@ -128,8 +172,8 @@ class Reporter {
128172
spinner: spinner || (process.platform === 'win32' ? 'line' : 'dots'),
129173
stream: reportStream
130174
});
175+
this.clearSpinner = decorateFlushingWriter(this.spinner.clear.bind(this.spinner));
131176
this.lineWriter = new LineWriterWithSpinner(this.reportStream, this.spinner);
132-
this.endRun = whileCorked(this.reportStream, whileCorked(this.lineWriter, this.endRun));
133177
}
134178

135179
this.reset();
@@ -362,9 +406,7 @@ class Reporter {
362406

363407
case 'worker-stderr': {
364408
// Forcibly clear the spinner, writing the chunk corrupts the TTY.
365-
if (this.spinner !== null) {
366-
this.spinner.clear();
367-
}
409+
this.clearSpinner();
368410

369411
this.stdStream.write(event.chunk);
370412
// If the chunk does not end with a linebreak, *forcibly* write one to
@@ -386,9 +428,7 @@ class Reporter {
386428

387429
case 'worker-stdout': {
388430
// Forcibly clear the spinner, writing the chunk corrupts the TTY.
389-
if (this.spinner !== null) {
390-
this.spinner.clear();
391-
}
431+
this.clearSpinner();
392432

393433
this.stdStream.write(event.chunk);
394434
// If the chunk does not end with a linebreak, *forcibly* write one to

‎lib/reporters/while-corked.js

-13
This file was deleted.

0 commit comments

Comments
 (0)
Please sign in to comment.