@@ -40,6 +40,8 @@ struct PackageToJS {
4040        var  inspect :  Bool 
4141        /// The extra arguments to pass to node
4242        var  extraNodeArguments :  [ String ] 
43+         /// Whether to print verbose output
44+         var  verbose :  Bool 
4345        /// The options for packaging
4446        var  packageOptions :  PackageOptions 
4547    } 
@@ -85,6 +87,7 @@ struct PackageToJS {
8587            try   PackageToJS . runSingleTestingLibrary ( 
8688                testRunner:  testRunner,  currentDirectoryURL:  currentDirectoryURL, 
8789                extraArguments:  extraArguments, 
90+                 testParser:  testOptions. verbose ?  nil  :  FancyTestsParser ( ) , 
8891                testOptions:  testOptions
8992            ) 
9093        } 
@@ -119,6 +122,7 @@ struct PackageToJS {
119122        testRunner:  URL , 
120123        currentDirectoryURL:  URL , 
121124        extraArguments:  [ String ] , 
125+         testParser:  ( any  TestsParser ) ?   =  nil , 
122126        testOptions:  TestOptions 
123127    )  throws  { 
124128        let  node  =  try   which ( " node " ) 
@@ -129,11 +133,39 @@ struct PackageToJS {
129133        let  task  =  Process ( ) 
130134        task. executableURL =  node
131135        task. arguments =  arguments
136+ 
137+         var  finalize :  ( )  ->  Void  =  { } 
138+         if  let  testParser =  testParser { 
139+             class  Writer :  InteractiveWriter  { 
140+                 func  write( _ string:  String )  { 
141+                     print ( string,  terminator:  " " ) 
142+                 } 
143+             } 
144+ 
145+             let  writer  =  Writer ( ) 
146+             let  stdoutBuffer  =  LineBuffer  {  line in 
147+                 testParser. onLine ( line,  writer) 
148+             } 
149+             let  stdoutPipe  =  Pipe ( ) 
150+             stdoutPipe. fileHandleForReading. readabilityHandler =  {  handle in 
151+                 stdoutBuffer. append ( handle. availableData) 
152+             } 
153+             task. standardOutput =  stdoutPipe
154+             finalize =  { 
155+                 if  let  data =  try ?   stdoutPipe. fileHandleForReading. readToEnd ( )  { 
156+                     stdoutBuffer. append ( data) 
157+                 } 
158+                 stdoutBuffer. flush ( ) 
159+                 testParser. finalize ( writer) 
160+             } 
161+         } 
162+ 
132163        task. currentDirectoryURL =  currentDirectoryURL
133164        try   task. forwardTerminationSignals  { 
134165            try   task. run ( ) 
135166            task. waitUntilExit ( ) 
136167        } 
168+         finalize ( ) 
137169        // swift-testing returns EX_UNAVAILABLE (which is 69 in wasi-libc) for "no tests found"
138170        guard  task. terminationStatus ==  0  || task. terminationStatus ==  69  else  { 
139171            throw  PackageToJSError ( " Test failed with status  \( task. terminationStatus) " ) 
@@ -151,6 +183,39 @@ struct PackageToJS {
151183            print ( " Saved profile data to  \( mergedCoverageFile. path) " ) 
152184        } 
153185    } 
186+ 
187+     class  LineBuffer :  @unchecked   Sendable  { 
188+         let  lock   =  NSLock ( ) 
189+         var  buffer   =  " " 
190+         let  handler :  ( String )  ->  Void 
191+ 
192+         init ( handler:  @escaping  ( String )  ->  Void )  { 
193+             self . handler =  handler
194+         } 
195+ 
196+         func  append( _ data:  Data )  { 
197+             let  string  =  String ( data:  data,  encoding:  . utf8)  ??  " " 
198+             append ( string) 
199+         } 
200+ 
201+         func  append( _ data:  String )  { 
202+             lock. lock ( ) 
203+             defer  {  lock. unlock ( )  } 
204+             buffer +=  data
205+             let  lines  =  buffer. split ( separator:  " \n " ,  omittingEmptySubsequences:  false ) 
206+             for  line  in  lines. dropLast ( )  { 
207+                 handler ( String ( line) ) 
208+             } 
209+             buffer =  String ( lines. last ??  " " ) 
210+         } 
211+ 
212+         func  flush( )  { 
213+             lock. lock ( ) 
214+             defer  {  lock. unlock ( )  } 
215+             handler ( buffer) 
216+             buffer =  " " 
217+         } 
218+     } 
154219} 
155220
156221struct  PackageToJSError :  Swift . Error ,  CustomStringConvertible  { 
0 commit comments