11use crate :: backends:: TestLogBackend ;
22use crate :: options:: approximations:: Approximations ;
3+ use crate :: options:: known_failure:: KnownFailure ;
34use anyhow:: { Error , anyhow} ;
45use pretty_assertions:: Comparison ;
56use vfs:: VfsPath ;
67
78pub fn compare_trace_output (
89 log : & TestLogBackend ,
910 expected_path : & VfsPath ,
10- approximations : Option < & Approximations > ,
11- known_failure : bool ,
11+ approx : Option < & Approximations > ,
12+ known_failure : & KnownFailure ,
1213) -> anyhow:: Result < ( ) > {
1314 let expected_trace = expected_path. read_to_string ( ) ?. replace ( "\r \n " , "\n " ) ;
1415
@@ -17,23 +18,54 @@ pub fn compare_trace_output(
1718 // bytes should explicitly test for them in ActionScript.
1819 let actual_trace = log. trace_output ( ) . replace ( '\0' , "" ) ;
1920
20- let result = test ( & expected_trace, approximations, & actual_trace) ;
21- match ( result, known_failure) {
22- ( res, false ) => res,
23- ( Ok ( ( ) ) , true ) => Err ( anyhow ! (
24- "Trace output check was known to be failing, but now passes successfully. \
25- Please update the test and remove `known_failure = true`!",
26- ) ) ,
27- ( Err ( _) , true ) => Ok ( ( ) ) ,
21+ let result = test ( "flash_expected" , approx, & expected_trace, & actual_trace) ;
22+
23+ match known_failure {
24+ KnownFailure :: None | KnownFailure :: Panic { .. } => result,
25+ KnownFailure :: TraceOutput {
26+ ruffle_check : false ,
27+ } => {
28+ if result. is_ok ( ) {
29+ Err ( anyhow ! (
30+ "Trace output check was known to be failing, but now passes successfully. \
31+ Please update the test and remove `known_failure = true`!"
32+ ) )
33+ } else {
34+ Ok ( ( ) )
35+ }
36+ }
37+ KnownFailure :: TraceOutput { ruffle_check : true } => {
38+ let path = path_with_suffix ( expected_path, "ruffle" ) ?;
39+
40+ if result. is_ok ( ) {
41+ return Err ( anyhow ! (
42+ "Trace output check was known to be failing, but now passes successfully. \
43+ Please update the test, and remove `known_failure = true` and `{}`!",
44+ path. as_str( ) ,
45+ ) ) ;
46+ }
47+
48+ let expected_trace = if path. exists ( ) ? {
49+ path. read_to_string ( ) ?. replace ( "\r \n " , "\n " )
50+ } else {
51+ path. create_file ( ) ?. write_all ( actual_trace. as_bytes ( ) ) ?;
52+ return Err ( anyhow ! (
53+ "No trace to compare to! Saved actual trace as Ruffle-expected."
54+ ) ) ;
55+ } ;
56+
57+ test ( "ruffle_expected" , approx, & expected_trace, & actual_trace)
58+ }
2859 }
2960}
3061
31- pub fn test (
62+ fn test (
63+ expected_name : & str ,
64+ approx : Option < & Approximations > ,
3265 expected_output : & str ,
33- approximations : Option < & Approximations > ,
3466 actual_output : & str ,
3567) -> anyhow:: Result < ( ) > {
36- if let Some ( approximations ) = approximations {
68+ if let Some ( approx ) = approx {
3769 let add_comparison_to_err = |err : Error | -> Error {
3870 let left_pretty = PrettyString ( actual_output) ;
3971 let right_pretty = PrettyString ( expected_output) ;
@@ -44,7 +76,7 @@ pub fn test(
4476
4577 if actual_output. lines ( ) . count ( ) != expected_output. lines ( ) . count ( ) {
4678 return Err ( anyhow ! (
47- "# of lines of output didn't match (expected {} from Flash, got {} from Ruffle " ,
79+ "# of lines of output didn't match ({expected_name}: {}, ruffle_actual: {}) " ,
4880 expected_output. lines( ) . count( ) ,
4981 actual_output. lines( ) . count( )
5082 ) ) ;
@@ -58,21 +90,21 @@ pub fn test(
5890 continue ;
5991 }
6092
61- approximations
93+ approx
6294 . compare ( actual, expected)
6395 . map_err ( add_comparison_to_err) ?;
6496 } else {
6597 let mut found = false ;
6698
6799 // Check each of the user-provided regexes for a match
68- for pattern in approximations . number_patterns ( ) {
100+ for pattern in approx . number_patterns ( ) {
69101 if let ( Some ( actual_captures) , Some ( expected_captures) ) =
70102 ( pattern. captures ( actual) , pattern. captures ( expected) )
71103 {
72104 found = true ;
73105 if expected_captures. len ( ) != actual_captures. len ( ) {
74106 return Err ( anyhow ! (
75- "Differing numbers of regex captures (expected {}, actually {})" ,
107+ "Differing numbers of regex captures ({expected_name}: {}, ruffle_actual: {})" ,
76108 expected_captures. len( ) ,
77109 actual_captures. len( ) ,
78110 ) ) ;
@@ -95,25 +127,29 @@ pub fn test(
95127 . as_str ( )
96128 . parse :: < f64 > ( )
97129 . expect ( "Failed to parse 'expected' capture group as float" ) ;
98- approximations
130+ approx
99131 . compare ( actual_num, expected_num)
100132 . map_err ( add_comparison_to_err) ?;
101133 }
102134 let modified_actual = pattern. replace_all ( actual, "" ) ;
103135 let modified_expected = pattern. replace_all ( expected, "" ) ;
104136
105- assert_text_matches ( modified_actual. as_ref ( ) , modified_expected. as_ref ( ) ) ?;
137+ assert_text_matches (
138+ modified_actual. as_ref ( ) ,
139+ modified_expected. as_ref ( ) ,
140+ expected_name,
141+ ) ?;
106142 break ;
107143 }
108144 }
109145
110146 if !found {
111- assert_text_matches ( actual, expected) ?;
147+ assert_text_matches ( actual, expected, expected_name ) ?;
112148 }
113149 }
114150 }
115151 } else {
116- assert_text_matches ( actual_output, expected_output) ?;
152+ assert_text_matches ( actual_output, expected_output, expected_name ) ?;
117153 }
118154
119155 Ok ( ( ) )
@@ -134,14 +170,14 @@ impl std::fmt::Debug for PrettyString<'_> {
134170 }
135171}
136172
137- fn assert_text_matches ( ruffle : & str , flash : & str ) -> anyhow:: Result < ( ) > {
138- if ruffle != flash {
173+ fn assert_text_matches ( ruffle : & str , expected : & str , expected_name : & str ) -> anyhow:: Result < ( ) > {
174+ if ruffle != expected {
139175 let left_pretty = PrettyString ( ruffle) ;
140- let right_pretty = PrettyString ( flash ) ;
176+ let right_pretty = PrettyString ( expected ) ;
141177 let comparison = Comparison :: new ( & left_pretty, & right_pretty) ;
142178
143179 Err ( anyhow ! (
144- "assertion failed: `(ruffle_actual == flash_expected )`\
180+ "assertion failed: `(ruffle_actual == {expected_name} )`\
145181 \n \
146182 \n {}\
147183 \n ",
@@ -151,3 +187,20 @@ fn assert_text_matches(ruffle: &str, flash: &str) -> anyhow::Result<()> {
151187 Ok ( ( ) )
152188 }
153189}
190+
191+ /// Adds a suffix to the filename: e.g. `foo/bar.txt` -> `foo/bar.suffix.txt`
192+ fn path_with_suffix ( path : & VfsPath , suffix : & str ) -> anyhow:: Result < VfsPath > {
193+ // `VfsPath`'s API is less nice than std's `Path`... :(
194+ let mut name = path. filename ( ) ;
195+ name. insert_str ( 0 , "../" ) ;
196+ if let Some ( ext) = path. extension ( ) {
197+ name. truncate ( name. len ( ) - ext. len ( ) ) ;
198+ name. push_str ( suffix) ;
199+ name. push ( '.' ) ;
200+ name. push_str ( & ext) ;
201+ } else {
202+ name. push ( '.' ) ;
203+ name. push_str ( suffix) ;
204+ }
205+ Ok ( path. join ( & name) ?)
206+ }
0 commit comments