Skip to content

Commit 9086891

Browse files
authored
Merge pull request #167 from RalfJung/error-render
make individual errors in a failed test more clearly visible
2 parents f05e9d1 + c816d89 commit 9086891

File tree

2 files changed

+131
-116
lines changed

2 files changed

+131
-116
lines changed

src/status_emitter.rs

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::{
1717
};
1818
use std::{
1919
collections::HashMap,
20-
fmt::{Debug, Write as _},
20+
fmt::{Debug, Display, Write as _},
2121
io::Write as _,
2222
num::NonZeroUsize,
2323
panic::RefUnwindSafe,
@@ -201,11 +201,12 @@ struct TextTest {
201201
}
202202

203203
impl TextTest {
204+
/// Prints the user-visible name for this test.
204205
fn msg(&self) -> String {
205206
if self.revision.is_empty() {
206207
self.path.display().to_string()
207208
} else {
208-
format!("{} ({})", self.path.display(), self.revision)
209+
format!("{} (revision `{}`)", self.path.display(), self.revision)
209210
}
210211
}
211212
}
@@ -218,7 +219,7 @@ impl TestStatus for TextTest {
218219
} else {
219220
let result = match result {
220221
Ok(TestOk::Ok) => "ok".green(),
221-
Err(Errored { .. }) => "FAILED".red().bold(),
222+
Err(Errored { .. }) => "FAILED".bright_red().bold(),
222223
Ok(TestOk::Ignored) => "ignored (in-test comment)".yellow(),
223224
Ok(TestOk::Filtered) => return,
224225
};
@@ -243,17 +244,10 @@ impl TestStatus for TextTest {
243244
stderr: &'a [u8],
244245
stdout: &'a [u8],
245246
) -> Box<dyn Debug + 'a> {
247+
let text = format!("{} {}", "FAILED TEST:".bright_red(), self.msg());
248+
246249
println!();
247-
let path = self.path.display().to_string();
248-
print!("{}", path.underline().bold());
249-
let revision = if self.revision.is_empty() {
250-
String::new()
251-
} else {
252-
format!(" (revision `{}`)", self.revision)
253-
};
254-
print!("{revision}");
255-
print!(" {}", "FAILED:".red().bold());
256-
println!();
250+
println!("{}", text.bold().underline());
257251
println!("command: {cmd:?}");
258252
println!();
259253

@@ -264,10 +258,10 @@ impl TestStatus for TextTest {
264258
}
265259
impl<'a> Drop for Guard<'a> {
266260
fn drop(&mut self) {
267-
println!("full stderr:");
261+
println!("{}", "full stderr:".bold());
268262
std::io::stdout().write_all(self.stderr).unwrap();
269263
println!();
270-
println!("full stdout:");
264+
println!("{}", "full stdout:".bold());
271265
std::io::stdout().write_all(self.stdout).unwrap();
272266
println!();
273267
println!();
@@ -374,12 +368,12 @@ impl StatusEmitter for Text {
374368

375369
impl Drop for Summarizer {
376370
fn drop(&mut self) {
377-
println!("{}", "FAILURES:".red().underline().bold());
371+
println!("{}", "FAILURES:".bright_red().underline().bold());
378372
for line in &self.failures {
379373
println!("{line}");
380374
}
381375
println!();
382-
print!("test result: {}.", "FAIL".red());
376+
print!("test result: {}.", "FAIL".bright_red());
383377
print!(" {} failed;", self.failures.len().to_string().green());
384378
if self.succeeded > 0 {
385379
print!(" {} passed;", self.succeeded.to_string().green());
@@ -405,16 +399,27 @@ impl StatusEmitter for Text {
405399
}
406400

407401
fn print_error(error: &Error, path: &Path) {
402+
/// Every error starts with a header like that, to make them all easy to find.
403+
/// It is made to look like the headers printed for spanned errors.
404+
fn print_error_header(msg: impl Display) {
405+
let text = format!("{} {msg}", "error:".bright_red());
406+
println!("{}", text.bold());
407+
}
408+
408409
match error {
409410
Error::ExitStatus {
410411
mode,
411412
status,
412413
expected,
413414
} => {
414-
println!("{mode} test got {status}, but expected {expected}")
415+
// `status` prints as `exit status: N`.
416+
print_error_header(format_args!(
417+
"{mode} test got {status}, but expected {expected}"
418+
))
415419
}
416420
Error::Command { kind, status } => {
417-
println!("{kind} failed with {status}");
421+
// `status` prints as `exit status: N`.
422+
print_error_header(format_args!("{kind} failed with {status}"));
418423
}
419424
Error::PatternNotFound {
420425
pattern,
@@ -432,6 +437,7 @@ fn print_error(error: &Error, path: &Path) {
432437
format!("`/{r}/` does not match diagnostics {line}",)
433438
}
434439
};
440+
// This will print a suitable error header.
435441
create_error(
436442
msg,
437443
&[(
@@ -442,7 +448,7 @@ fn print_error(error: &Error, path: &Path) {
442448
);
443449
}
444450
Error::NoPatternsFound => {
445-
println!("{}", "no error patterns found in fail test".red());
451+
print_error_header("no error patterns found in fail test");
446452
}
447453
Error::PatternFoundInPassTest { mode, span } => {
448454
let annot = [("expected because of this annotation", Some(*span))];
@@ -451,6 +457,7 @@ fn print_error(error: &Error, path: &Path) {
451457
if let Some(mode) = mode {
452458
lines.push((&annot, mode.line_start))
453459
}
460+
// This will print a suitable error header.
454461
create_error("error pattern found in pass test", &lines, path);
455462
}
456463
Error::OutputDiffers {
@@ -459,7 +466,7 @@ fn print_error(error: &Error, path: &Path) {
459466
expected,
460467
bless_command,
461468
} => {
462-
println!("{}", "actual output differed from expected".underline());
469+
print_error_header("actual output differed from expected");
463470
println!(
464471
"Execute `{}` to update `{}` to the actual output",
465472
bless_command,
@@ -483,8 +490,9 @@ fn print_error(error: &Error, path: &Path) {
483490
.iter()
484491
.map(|msg| (format!("{:?}: {}", msg.level, msg.message), msg.line_col))
485492
.collect::<Vec<_>>();
493+
// This will print a suitable error header.
486494
create_error(
487-
format!("There were {} unmatched diagnostics", msgs.len()),
495+
format!("there were {} unmatched diagnostics", msgs.len()),
488496
&[(
489497
&msgs
490498
.iter()
@@ -495,10 +503,10 @@ fn print_error(error: &Error, path: &Path) {
495503
path,
496504
);
497505
} else {
498-
println!(
499-
"There were {} unmatched diagnostics that occurred outside the testfile and had no pattern",
506+
print_error_header(format_args!(
507+
"there were {} unmatched diagnostics that occurred outside the testfile and had no pattern",
500508
msgs.len(),
501-
);
509+
));
502510
for Message {
503511
level,
504512
message,
@@ -510,10 +518,12 @@ fn print_error(error: &Error, path: &Path) {
510518
}
511519
}
512520
Error::InvalidComment { msg, span } => {
521+
// This will print a suitable error header.
513522
create_error(msg, &[(&[("", Some(*span))], span.line_start)], path)
514523
}
515524
Error::MultipleRevisionsWithResults { kind, lines } => {
516525
let title = format!("multiple {kind} found");
526+
// This will print a suitable error header.
517527
create_error(
518528
title,
519529
&lines
@@ -524,23 +534,28 @@ fn print_error(error: &Error, path: &Path) {
524534
)
525535
}
526536
Error::Bug(msg) => {
527-
println!("A bug in `ui_test` occurred: {msg}");
537+
print_error_header("a bug in `ui_test` occurred");
538+
println!("{msg}");
528539
}
529540
Error::Aux {
530541
path: aux_path,
531542
errors,
532543
line,
533544
} => {
534-
println!("Aux build from {}:{line} failed", path.display());
545+
print_error_header(format_args!(
546+
"aux build from {}:{line} failed",
547+
path.display()
548+
));
535549
for error in errors {
536550
print_error(error, aux_path);
537551
}
538552
}
539553
Error::Rustfix(error) => {
540-
println!(
541-
"failed to apply suggestions for {} with rustfix: {error}",
554+
print_error_header(format_args!(
555+
"failed to apply suggestions for {} with rustfix",
542556
path.display()
543-
);
557+
));
558+
println!("{error}");
544559
println!("Add //@no-rustfix to the test file to ignore rustfix suggestions");
545560
}
546561
}

0 commit comments

Comments
 (0)