@@ -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} ;
@@ -2292,17 +2292,31 @@ impl<'test> TestCx<'test> {
2292
2292
match output_kind {
2293
2293
TestOutput :: Compile => {
2294
2294
if !self . props . dont_check_compiler_stdout {
2295
- errors +=
2296
- self . compare_output ( stdout_kind, & normalized_stdout, & expected_stdout) ;
2295
+ errors += self . compare_output (
2296
+ stdout_kind,
2297
+ & normalized_stdout,
2298
+ & proc_res. stdout ,
2299
+ & expected_stdout,
2300
+ ) ;
2297
2301
}
2298
2302
if !self . props . dont_check_compiler_stderr {
2299
- errors +=
2300
- self . compare_output ( stderr_kind, & normalized_stderr, & expected_stderr) ;
2303
+ errors += self . compare_output (
2304
+ stderr_kind,
2305
+ & normalized_stderr,
2306
+ & stderr,
2307
+ & expected_stderr,
2308
+ ) ;
2301
2309
}
2302
2310
}
2303
2311
TestOutput :: Run => {
2304
- errors += self . compare_output ( stdout_kind, & normalized_stdout, & expected_stdout) ;
2305
- errors += self . compare_output ( stderr_kind, & normalized_stderr, & expected_stderr) ;
2312
+ errors += self . compare_output (
2313
+ stdout_kind,
2314
+ & normalized_stdout,
2315
+ & proc_res. stdout ,
2316
+ & expected_stdout,
2317
+ ) ;
2318
+ errors +=
2319
+ self . compare_output ( stderr_kind, & normalized_stderr, & stderr, & expected_stderr) ;
2306
2320
}
2307
2321
}
2308
2322
errors
@@ -2530,7 +2544,13 @@ impl<'test> TestCx<'test> {
2530
2544
}
2531
2545
}
2532
2546
2533
- fn compare_output ( & self , stream : & str , actual : & str , expected : & str ) -> usize {
2547
+ fn compare_output (
2548
+ & self ,
2549
+ stream : & str ,
2550
+ actual : & str ,
2551
+ actual_unnormalized : & str ,
2552
+ expected : & str ,
2553
+ ) -> usize {
2534
2554
let are_different = match ( self . force_color_svg ( ) , expected. find ( '\n' ) , actual. find ( '\n' ) ) {
2535
2555
// FIXME: We ignore the first line of SVG files
2536
2556
// 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,73 @@ 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
+ println ! ( "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
+ print ! ( "{output}" ) ;
2665
+ }
2666
+ }
2667
+ } else {
2668
+ print ! ( "{}" , write_diff( expected, actual, context_size) ) ;
2669
+ }
2670
+
2671
+ let context_size = 3 ;
2672
+ // 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.
2673
+ let diff_results = make_diff ( actual, expected, context_size) ;
2674
+
2675
+ let ( mut mismatches_normalized, mut mismatch_line_nos) = ( String :: new ( ) , vec ! [ ] ) ;
2676
+ for hunk in diff_results {
2677
+ let mut line_no = hunk. line_number ;
2678
+ for line in hunk. lines {
2679
+ // NOTE: `Expected` is actually correct here, the argument order is reversed so our line numbers match up
2680
+ if let DiffLine :: Expected ( normalized) = line {
2681
+ mismatches_normalized += & normalized;
2682
+ mismatches_normalized += "\n " ;
2683
+ mismatch_line_nos. push ( line_no) ;
2684
+ line_no += 1 ;
2685
+ }
2686
+ }
2687
+ }
2688
+ let mut mismatches_unnormalized = String :: new ( ) ;
2689
+ let diff_normalized = make_diff ( actual, actual_unnormalized, 0 ) ;
2690
+ for hunk in diff_normalized {
2691
+ if mismatch_line_nos. contains ( & hunk. line_number ) {
2692
+ for line in hunk. lines {
2693
+ if let DiffLine :: Resulting ( unnormalized) = line {
2694
+ mismatches_unnormalized += & unnormalized;
2695
+ mismatches_unnormalized += "\n " ;
2696
+ }
2697
+ }
2698
+ }
2699
+ }
2700
+
2701
+ let normalized_diff = make_diff ( & mismatches_normalized, & mismatches_unnormalized, 0 ) ;
2702
+ if !normalized_diff. is_empty ( ) {
2703
+ println ! ( "Note: some mismatched output was normalized before being compared" ) ;
2704
+ // FIXME: respect diff_command
2705
+ print ! ( "{}" , write_diff( & mismatches_unnormalized, & mismatches_normalized, 0 ) ) ;
2706
+ }
2707
+ }
2708
+
2636
2709
fn check_and_prune_duplicate_outputs (
2637
2710
& self ,
2638
2711
proc_res : & ProcRes ,
0 commit comments