@@ -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