@@ -22,7 +22,7 @@ use crate::common::{
2222 UI_STDERR , UI_STDOUT , UI_SVG , UI_WINDOWS_SVG , Ui , expected_output_path, incremental_dir,
2323 output_base_dir, output_base_name, output_testname_unique,
2424} ;
25- use crate :: compute_diff:: { write_diff, write_filtered_diff} ;
25+ use crate :: compute_diff:: { DiffLine , make_diff , write_diff, write_filtered_diff} ;
2626use crate :: errors:: { self , Error , ErrorKind } ;
2727use crate :: header:: TestProps ;
2828use crate :: read2:: { Truncated , read2_abbreviated} ;
@@ -2292,17 +2292,31 @@ impl<'test> TestCx<'test> {
22922292 match output_kind {
22932293 TestOutput :: Compile => {
22942294 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+ ) ;
22972301 }
22982302 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+ ) ;
23012309 }
23022310 }
23032311 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) ;
23062320 }
23072321 }
23082322 errors
@@ -2530,7 +2544,13 @@ impl<'test> TestCx<'test> {
25302544 }
25312545 }
25322546
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 {
25342554 let are_different = match ( self . force_color_svg ( ) , expected. find ( '\n' ) , actual. find ( '\n' ) ) {
25352555 // FIXME: We ignore the first line of SVG files
25362556 // because the width parameter is non-deterministic.
@@ -2590,28 +2610,14 @@ impl<'test> TestCx<'test> {
25902610 if expected. is_empty ( ) {
25912611 println ! ( "normalized {}:\n {}\n " , stream, actual) ;
25922612 } 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+ ) ;
26152621 }
26162622 } else {
26172623 // Delete non-revision .stderr/.stdout file if revisions are used.
@@ -2633,6 +2639,73 @@ impl<'test> TestCx<'test> {
26332639 if self . config . bless { 0 } else { 1 }
26342640 }
26352641
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+
26362709 fn check_and_prune_duplicate_outputs (
26372710 & self ,
26382711 proc_res : & ProcRes ,
0 commit comments