1- use std :: path :: PathBuf ;
1+ # [ cfg ( windows ) ]
22use std:: fs;
3+ use std:: path:: PathBuf ;
4+ #[ cfg( windows) ]
5+ use std:: sync:: Once ;
36use swc_core:: ecma:: {
47 transforms:: testing:: { FixtureTestConfig , test_fixture} ,
58 visit:: visit_mut_pass,
@@ -8,36 +11,61 @@ use swc_workflow::{StepTransform, TransformMode};
811
912// Normalize line endings in stderr files for Windows compatibility
1013// SWC's error handler on Windows outputs CRLF, but expected files have LF
11- // We normalize the expected file to CRLF on Windows to match the actual output
12- fn normalize_stderr_file ( path : & PathBuf ) {
14+ // We normalize all expected files once at test startup to match Windows output
15+ #[ cfg( windows) ]
16+ static NORMALIZE_STDERR_FILES : Once = Once :: new ( ) ;
17+
18+ fn normalize_stderr_files ( ) {
1319 #[ cfg( windows) ]
1420 {
15- if let Ok ( content) = fs:: read_to_string ( path) {
16- // Normalize: remove all CR, then add CRLF for each line
17- // This handles files that might already have CRLF, LF, or mixed
18- let normalized = content
19- . replace ( "\r \n " , "\n " ) // First normalize CRLF to LF
20- . replace ( "\r " , "\n " ) // Handle old Mac-style CR
21- . replace ( "\n " , "\r \n " ) ; // Convert all LF to CRLF
22- let _ = fs:: write ( path, normalized) ;
23- }
21+ NORMALIZE_STDERR_FILES . call_once ( || {
22+ // Use env! to get the manifest directory at compile time
23+ // This ensures we have the correct path regardless of where the test runs from
24+ let manifest_dir = env ! ( "CARGO_MANIFEST_DIR" ) ;
25+ let test_dir = PathBuf :: from ( manifest_dir) . join ( "tests/errors" ) ;
26+ if let Ok ( entries) = fs:: read_dir ( & test_dir) {
27+ for entry in entries. flatten ( ) {
28+ let path = entry. path ( ) ;
29+ if path. is_dir ( ) {
30+ // Look for .stderr files in subdirectories
31+ if let Ok ( sub_entries) = fs:: read_dir ( & path) {
32+ for sub_entry in sub_entries. flatten ( ) {
33+ let sub_path = sub_entry. path ( ) ;
34+ if sub_path. extension ( ) . and_then ( |s| s. to_str ( ) ) == Some ( "stderr" ) {
35+ if let Ok ( content) = fs:: read_to_string ( & sub_path) {
36+ // Normalize: remove all CR, then add CRLF for each line
37+ let normalized = content
38+ . replace ( "\r \n " , "\n " ) // First normalize CRLF to LF
39+ . replace ( "\r " , "\n " ) // Handle old Mac-style CR
40+ . replace ( "\n " , "\r \n " ) ; // Convert all LF to CRLF
41+ let _ = fs:: write ( & sub_path, normalized) ;
42+ }
43+ }
44+ }
45+ }
46+ }
47+ }
48+ }
49+ } ) ;
2450 }
2551}
2652
2753#[ testing:: fixture( "tests/errors/**/input.js" ) ]
2854fn step_mode ( input : PathBuf ) {
55+ normalize_stderr_files ( ) ;
2956 let output = input. parent ( ) . unwrap ( ) . join ( "output-step.js" ) ;
3057 if !output. exists ( ) {
3158 return ;
3259 }
33- let stderr_file = input. parent ( ) . unwrap ( ) . join ( "output-step.stderr" ) ;
34- if stderr_file. exists ( ) {
35- normalize_stderr_file ( & stderr_file) ;
36- }
3760 test_fixture (
3861 Default :: default ( ) ,
3962 // The errors occur in any mode, so it doesn't matter
40- & |_| visit_mut_pass ( StepTransform :: new ( TransformMode :: Step , input. file_name ( ) . unwrap ( ) . to_string_lossy ( ) . to_string ( ) ) ) ,
63+ & |_| {
64+ visit_mut_pass ( StepTransform :: new (
65+ TransformMode :: Step ,
66+ input. file_name ( ) . unwrap ( ) . to_string_lossy ( ) . to_string ( ) ,
67+ ) )
68+ } ,
4169 & input,
4270 & output,
4371 FixtureTestConfig {
@@ -50,18 +78,20 @@ fn step_mode(input: PathBuf) {
5078
5179#[ testing:: fixture( "tests/errors/**/input.js" ) ]
5280fn workflow_mode ( input : PathBuf ) {
81+ normalize_stderr_files ( ) ;
5382 let output = input. parent ( ) . unwrap ( ) . join ( "output-workflow.js" ) ;
5483 if !output. exists ( ) {
5584 return ;
5685 }
57- let stderr_file = input. parent ( ) . unwrap ( ) . join ( "output-workflow.stderr" ) ;
58- if stderr_file. exists ( ) {
59- normalize_stderr_file ( & stderr_file) ;
60- }
6186 test_fixture (
6287 Default :: default ( ) ,
6388 // The errors occur in any mode, so it doesn't matter
64- & |_| visit_mut_pass ( StepTransform :: new ( TransformMode :: Workflow , input. file_name ( ) . unwrap ( ) . to_string_lossy ( ) . to_string ( ) ) ) ,
89+ & |_| {
90+ visit_mut_pass ( StepTransform :: new (
91+ TransformMode :: Workflow ,
92+ input. file_name ( ) . unwrap ( ) . to_string_lossy ( ) . to_string ( ) ,
93+ ) )
94+ } ,
6595 & input,
6696 & output,
6797 FixtureTestConfig {
@@ -74,18 +104,20 @@ fn workflow_mode(input: PathBuf) {
74104
75105#[ testing:: fixture( "tests/errors/**/input.js" ) ]
76106fn client_mode ( input : PathBuf ) {
107+ normalize_stderr_files ( ) ;
77108 let output = input. parent ( ) . unwrap ( ) . join ( "output-client.js" ) ;
78109 if !output. exists ( ) {
79110 return ;
80111 }
81- let stderr_file = input. parent ( ) . unwrap ( ) . join ( "output-client.stderr" ) ;
82- if stderr_file. exists ( ) {
83- normalize_stderr_file ( & stderr_file) ;
84- }
85112 test_fixture (
86113 Default :: default ( ) ,
87114 // The errors occur in any mode, so it doesn't matter
88- & |_| visit_mut_pass ( StepTransform :: new ( TransformMode :: Client , input. file_name ( ) . unwrap ( ) . to_string_lossy ( ) . to_string ( ) ) ) ,
115+ & |_| {
116+ visit_mut_pass ( StepTransform :: new (
117+ TransformMode :: Client ,
118+ input. file_name ( ) . unwrap ( ) . to_string_lossy ( ) . to_string ( ) ,
119+ ) )
120+ } ,
89121 & input,
90122 & output,
91123 FixtureTestConfig {
0 commit comments