compiletest: show the difference between the normalized output and th… · rust-lang/rust@8aacd1c (original) (raw)
`@@ -22,7 +22,7 @@ use crate::common::{
`
22
22
`UI_STDERR, UI_STDOUT, UI_SVG, UI_WINDOWS_SVG, Ui, expected_output_path, incremental_dir,
`
23
23
` output_base_dir, output_base_name, output_testname_unique,
`
24
24
`};
`
25
``
`-
use crate::compute_diff::{write_diff, write_filtered_diff};
`
``
25
`+
use crate::compute_diff::{DiffLine, make_diff, write_diff, write_filtered_diff};
`
26
26
`use crate::errors::{self, Error, ErrorKind};
`
27
27
`use crate::header::TestProps;
`
28
28
`use crate::read2::{Truncated, read2_abbreviated};
`
`@@ -2295,17 +2295,31 @@ impl<'test> TestCx<'test> {
`
2295
2295
`match output_kind {
`
2296
2296
`TestOutput::Compile => {
`
2297
2297
`if !self.props.dont_check_compiler_stdout {
`
2298
``
`-
errors +=
`
2299
``
`-
self.compare_output(stdout_kind, &normalized_stdout, &expected_stdout);
`
``
2298
`+
errors += self.compare_output(
`
``
2299
`+
stdout_kind,
`
``
2300
`+
&normalized_stdout,
`
``
2301
`+
&proc_res.stdout,
`
``
2302
`+
&expected_stdout,
`
``
2303
`+
);
`
2300
2304
`}
`
2301
2305
`if !self.props.dont_check_compiler_stderr {
`
2302
``
`-
errors +=
`
2303
``
`-
self.compare_output(stderr_kind, &normalized_stderr, &expected_stderr);
`
``
2306
`+
errors += self.compare_output(
`
``
2307
`+
stderr_kind,
`
``
2308
`+
&normalized_stderr,
`
``
2309
`+
&stderr,
`
``
2310
`+
&expected_stderr,
`
``
2311
`+
);
`
2304
2312
`}
`
2305
2313
`}
`
2306
2314
`TestOutput::Run => {
`
2307
``
`-
errors += self.compare_output(stdout_kind, &normalized_stdout, &expected_stdout);
`
2308
``
`-
errors += self.compare_output(stderr_kind, &normalized_stderr, &expected_stderr);
`
``
2315
`+
errors += self.compare_output(
`
``
2316
`+
stdout_kind,
`
``
2317
`+
&normalized_stdout,
`
``
2318
`+
&proc_res.stdout,
`
``
2319
`+
&expected_stdout,
`
``
2320
`+
);
`
``
2321
`+
errors +=
`
``
2322
`+
self.compare_output(stderr_kind, &normalized_stderr, &stderr, &expected_stderr);
`
2309
2323
`}
`
2310
2324
`}
`
2311
2325
` errors
`
`@@ -2533,7 +2547,13 @@ impl<'test> TestCx<'test> {
`
2533
2547
`}
`
2534
2548
`}
`
2535
2549
``
2536
``
`-
fn compare_output(&self, stream: &str, actual: &str, expected: &str) -> usize {
`
``
2550
`+
fn compare_output(
`
``
2551
`+
&self,
`
``
2552
`+
stream: &str,
`
``
2553
`+
actual: &str,
`
``
2554
`+
actual_unnormalized: &str,
`
``
2555
`+
expected: &str,
`
``
2556
`+
) -> usize {
`
2537
2557
`let are_different = match (self.force_color_svg(), expected.find('\n'), actual.find('\n')) {
`
2538
2558
`// FIXME: We ignore the first line of SVG files
`
2539
2559
`// because the width parameter is non-deterministic.
`
`@@ -2590,28 +2610,14 @@ impl<'test> TestCx<'test> {
`
2590
2610
`if expected.is_empty() {
`
2591
2611
`println!("normalized {}:\n{}\n", stream, actual);
`
2592
2612
`} else {
`
2593
``
`-
println!("diff of {stream}:\n");
`
2594
``
`-
if let Some(diff_command) = self.config.diff_command.as_deref() {
`
2595
``
`-
let mut args = diff_command.split_whitespace();
`
2596
``
`-
let name = args.next().unwrap();
`
2597
``
`-
match Command::new(name)
`
2598
``
`-
.args(args)
`
2599
``
`-
.args([&expected_path, &actual_path])
`
2600
``
`-
.output()
`
2601
``
`-
{
`
2602
``
`-
Err(err) => {
`
2603
``
`-
self.fatal(&format!(
`
2604
``
`` -
"failed to call custom diff command {diff_command}
: {err}"
``
2605
``
`-
));
`
2606
``
`-
}
`
2607
``
`-
Ok(output) => {
`
2608
``
`-
let output = String::from_utf8_lossy(&output.stdout);
`
2609
``
`-
print!("{output}");
`
2610
``
`-
}
`
2611
``
`-
}
`
2612
``
`-
} else {
`
2613
``
`-
print!("{}", write_diff(expected, actual, 3));
`
2614
``
`-
}
`
``
2613
`+
self.show_diff(
`
``
2614
`+
stream,
`
``
2615
`+
&expected_path,
`
``
2616
`+
&actual_path,
`
``
2617
`+
expected,
`
``
2618
`+
actual,
`
``
2619
`+
actual_unnormalized,
`
``
2620
`+
);
`
2615
2621
`}
`
2616
2622
`} else {
`
2617
2623
`// Delete non-revision .stderr/.stdout file if revisions are used.
`
`@@ -2633,6 +2639,76 @@ impl<'test> TestCx<'test> {
`
2633
2639
`if self.config.bless { 0 } else { 1 }
`
2634
2640
`}
`
2635
2641
``
``
2642
`+
/// Returns whether to show the full stderr/stdout.
`
``
2643
`+
fn show_diff(
`
``
2644
`+
&self,
`
``
2645
`+
stream: &str,
`
``
2646
`+
expected_path: &Path,
`
``
2647
`+
actual_path: &Path,
`
``
2648
`+
expected: &str,
`
``
2649
`+
actual: &str,
`
``
2650
`+
actual_unnormalized: &str,
`
``
2651
`+
) {
`
``
2652
`+
eprintln!("diff of {stream}:\n");
`
``
2653
`+
if let Some(diff_command) = self.config.diff_command.as_deref() {
`
``
2654
`+
let mut args = diff_command.split_whitespace();
`
``
2655
`+
let name = args.next().unwrap();
`
``
2656
`+
match Command::new(name).args(args).args([expected_path, actual_path]).output() {
`
``
2657
`+
Err(err) => {
`
``
2658
`+
self.fatal(&format!(
`
``
2659
`` +
"failed to call custom diff command {diff_command}
: {err}"
``
``
2660
`+
));
`
``
2661
`+
}
`
``
2662
`+
Ok(output) => {
`
``
2663
`+
let output = String::from_utf8_lossy(&output.stdout);
`
``
2664
`+
eprint!("{output}");
`
``
2665
`+
}
`
``
2666
`+
}
`
``
2667
`+
} else {
`
``
2668
`+
eprint!("{}", write_diff(expected, actual, 3));
`
``
2669
`+
}
`
``
2670
+
``
2671
`` +
// NOTE: argument order is important, we need actual
to be on the left so the line number match up when we compare it to actual_unnormalized
below.
``
``
2672
`+
let diff_results = make_diff(actual, expected, 0);
`
``
2673
+
``
2674
`+
let (mut mismatches_normalized, mut mismatch_line_nos) = (String::new(), vec![]);
`
``
2675
`+
for hunk in diff_results {
`
``
2676
`+
let mut line_no = hunk.line_number;
`
``
2677
`+
for line in hunk.lines {
`
``
2678
`` +
// NOTE: Expected
is actually correct here, the argument order is reversed so our line numbers match up
``
``
2679
`+
if let DiffLine::Expected(normalized) = line {
`
``
2680
`+
mismatches_normalized += &normalized;
`
``
2681
`+
mismatches_normalized += "\n";
`
``
2682
`+
mismatch_line_nos.push(line_no);
`
``
2683
`+
line_no += 1;
`
``
2684
`+
}
`
``
2685
`+
}
`
``
2686
`+
}
`
``
2687
`+
let mut mismatches_unnormalized = String::new();
`
``
2688
`+
let diff_normalized = make_diff(actual, actual_unnormalized, 0);
`
``
2689
`+
for hunk in diff_normalized {
`
``
2690
`+
if mismatch_line_nos.contains(&hunk.line_number) {
`
``
2691
`+
for line in hunk.lines {
`
``
2692
`+
if let DiffLine::Resulting(unnormalized) = line {
`
``
2693
`+
mismatches_unnormalized += &unnormalized;
`
``
2694
`+
mismatches_unnormalized += "\n";
`
``
2695
`+
}
`
``
2696
`+
}
`
``
2697
`+
}
`
``
2698
`+
}
`
``
2699
+
``
2700
`+
let normalized_diff = make_diff(&mismatches_normalized, &mismatches_unnormalized, 0);
`
``
2701
`+
// HACK: instead of checking if each hunk is empty, this only checks if the whole input is empty. we should be smarter about this so we don't treat added or removed output as normalized.
`
``
2702
`+
if !normalized_diff.is_empty()
`
``
2703
`+
&& !mismatches_unnormalized.is_empty()
`
``
2704
`+
&& !mismatches_normalized.is_empty()
`
``
2705
`+
{
`
``
2706
`+
eprintln!("Note: some mismatched output was normalized before being compared");
`
``
2707
`+
// FIXME: respect diff_command
`
``
2708
`+
eprint!("{}", write_diff(&mismatches_unnormalized, &mismatches_normalized, 0));
`
``
2709
`+
}
`
``
2710
`+
}
`
``
2711
+
2636
2712
`fn check_and_prune_duplicate_outputs(
`
2637
2713
`&self,
`
2638
2714
`proc_res: &ProcRes,
`