Skip to content

Commit 38ae449

Browse files
committed
tidy: Don't bypass stderr output capture in unit tests
In unit tests, writes to stderr that don't use `eprint!` or `eprintln!` will not be captured, and instead interfere with test harness output, making it unreadable.
1 parent 72b21e1 commit 38ae449

File tree

1 file changed

+43
-9
lines changed

1 file changed

+43
-9
lines changed

src/tools/tidy/src/diagnostics.rs

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use std::collections::HashSet;
22
use std::fmt::{Display, Formatter};
3+
use std::io;
34
use std::path::{Path, PathBuf};
45
use std::sync::{Arc, Mutex};
56

6-
use termcolor::{Color, WriteColor};
7+
use termcolor::Color;
78

89
#[derive(Clone, Default)]
910
///CLI flags used by tidy.
@@ -245,30 +246,63 @@ pub const COLOR_WARNING: Color = Color::Yellow;
245246
/// Output a message to stderr.
246247
/// The message can be optionally scoped to a certain check, and it can also have a certain color.
247248
pub fn output_message(msg: &str, id: Option<&CheckId>, color: Option<Color>) {
248-
use std::io::Write;
249+
use termcolor::{ColorChoice, ColorSpec};
249250

250-
use termcolor::{ColorChoice, ColorSpec, StandardStream};
251+
let stderr: &mut dyn termcolor::WriteColor = if cfg!(test) {
252+
&mut StderrForUnitTests
253+
} else {
254+
&mut termcolor::StandardStream::stderr(ColorChoice::Auto)
255+
};
251256

252-
let mut stderr = StandardStream::stderr(ColorChoice::Auto);
253257
if let Some(color) = &color {
254258
stderr.set_color(ColorSpec::new().set_fg(Some(*color))).unwrap();
255259
}
256260

257261
match id {
258262
Some(id) => {
259-
write!(&mut stderr, "tidy [{}", id.name).unwrap();
263+
write!(stderr, "tidy [{}", id.name).unwrap();
260264
if let Some(path) = &id.path {
261-
write!(&mut stderr, " ({})", path.display()).unwrap();
265+
write!(stderr, " ({})", path.display()).unwrap();
262266
}
263-
write!(&mut stderr, "]").unwrap();
267+
write!(stderr, "]").unwrap();
264268
}
265269
None => {
266-
write!(&mut stderr, "tidy").unwrap();
270+
write!(stderr, "tidy").unwrap();
267271
}
268272
}
269273
if color.is_some() {
270274
stderr.set_color(&ColorSpec::new()).unwrap();
271275
}
272276

273-
writeln!(&mut stderr, ": {msg}").unwrap();
277+
writeln!(stderr, ": {msg}").unwrap();
278+
}
279+
280+
/// An implementation of `io::Write` and `termcolor::WriteColor` that writes
281+
/// to stderr via `eprint!`, so that the output can be properly captured when
282+
/// running tidy's unit tests.
283+
struct StderrForUnitTests;
284+
285+
impl io::Write for StderrForUnitTests {
286+
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
287+
eprint!("{}", String::from_utf8_lossy(buf));
288+
Ok(buf.len())
289+
}
290+
291+
fn flush(&mut self) -> io::Result<()> {
292+
Ok(())
293+
}
294+
}
295+
296+
impl termcolor::WriteColor for StderrForUnitTests {
297+
fn supports_color(&self) -> bool {
298+
false
299+
}
300+
301+
fn set_color(&mut self, _spec: &termcolor::ColorSpec) -> io::Result<()> {
302+
Ok(())
303+
}
304+
305+
fn reset(&mut self) -> io::Result<()> {
306+
Ok(())
307+
}
274308
}

0 commit comments

Comments
 (0)