@@ -19,10 +19,6 @@ typealias ProcessID = TSCBasic.Process.ProcessID
19
19
typealias Process = TSCBasic . Process
20
20
21
21
class ProcessTests : XCTestCase {
22
- func script( _ name: String ) -> String {
23
- return AbsolutePath ( path: #file) . parentDirectory. appending ( components: " processInputs " , name) . pathString
24
- }
25
-
26
22
func testBasics( ) throws {
27
23
do {
28
24
let process = Process ( args: " echo " , " hello " )
@@ -34,7 +30,7 @@ class ProcessTests: XCTestCase {
34
30
}
35
31
36
32
do {
37
- let process = Process ( args : script ( " exit4 " ) )
33
+ let process = Process ( scriptName : " exit4 " )
38
34
try process. launch ( )
39
35
let result = try process. waitUntilExit ( )
40
36
XCTAssertEqual ( result. exitStatus, . terminated( code: 4 ) )
@@ -100,7 +96,7 @@ class ProcessTests: XCTestCase {
100
96
}
101
97
102
98
do {
103
- let output = try Process . checkNonZeroExit ( args : script ( " exit4 " ) )
99
+ let output = try Process . checkNonZeroExit ( scriptName : " exit4 " )
104
100
XCTFail ( " Unexpected success \( output) " )
105
101
} catch ProcessResult . Error . nonZeroExit( let result) {
106
102
XCTAssertEqual ( result. exitStatus, . terminated( code: 4 ) )
@@ -162,7 +158,7 @@ class ProcessTests: XCTestCase {
162
158
try testWithTemporaryDirectory { tmpdir in
163
159
let file = tmpdir. appending ( component: " pidfile " )
164
160
let waitFile = tmpdir. appending ( component: " waitFile " )
165
- let process = Process ( args : self . script ( " print-pid " ) , file. pathString, waitFile. pathString)
161
+ let process = Process ( scriptName : " print-pid " , arguments : [ file. pathString, waitFile. pathString] )
166
162
try processes. add ( process)
167
163
try process. launch ( )
168
164
guard waitForFile ( waitFile) else {
@@ -190,7 +186,7 @@ class ProcessTests: XCTestCase {
190
186
try testWithTemporaryDirectory { tmpdir in
191
187
let file = tmpdir. appending ( component: " pidfile " )
192
188
let waitFile = tmpdir. appending ( component: " waitFile " )
193
- let process = Process ( args : self . script ( " subprocess " ) , file. pathString, waitFile. pathString)
189
+ let process = Process ( scriptName : " subprocess " , arguments : [ file. pathString, waitFile. pathString] )
194
190
try processes. add ( process)
195
191
try process. launch ( )
196
192
guard waitForFile ( waitFile) else {
@@ -255,7 +251,7 @@ class ProcessTests: XCTestCase {
255
251
256
252
func testStdin( ) throws {
257
253
var stdout = [ UInt8] ( )
258
- let process = Process ( args : script ( " in-to-out " ) , outputRedirection: . stream( stdout: { stdoutBytes in
254
+ let process = Process ( scriptName : " in-to-out " , outputRedirection: . stream( stdout: { stdoutBytes in
259
255
stdout += stdoutBytes
260
256
} , stderr: { _ in } ) )
261
257
let stdinStream = try process. launch ( )
@@ -273,22 +269,22 @@ class ProcessTests: XCTestCase {
273
269
func testStdoutStdErr( ) throws {
274
270
// A simple script to check that stdout and stderr are captured separatly.
275
271
do {
276
- let result = try Process . popen ( args : script ( " simple-stdout-stderr " ) )
272
+ let result = try Process . popen ( scriptName : " simple-stdout-stderr " )
277
273
XCTAssertEqual ( try result. utf8Output ( ) , " simple output \n " )
278
274
XCTAssertEqual ( try result. utf8stderrOutput ( ) , " simple error \n " )
279
275
}
280
276
281
277
// A long stdout and stderr output.
282
278
do {
283
- let result = try Process . popen ( args : script ( " long-stdout-stderr " ) )
279
+ let result = try Process . popen ( scriptName : " long-stdout-stderr " )
284
280
let count = 16 * 1024
285
281
XCTAssertEqual ( try result. utf8Output ( ) , String ( repeating: " 1 " , count: count) )
286
282
XCTAssertEqual ( try result. utf8stderrOutput ( ) , String ( repeating: " 2 " , count: count) )
287
283
}
288
284
289
285
// This script will block if the streams are not read.
290
286
do {
291
- let result = try Process . popen ( args : script ( " deadlock-if-blocking-io " ) )
287
+ let result = try Process . popen ( scriptName : " deadlock-if-blocking-io " )
292
288
let count = 16 * 1024
293
289
XCTAssertEqual ( try result. utf8Output ( ) , String ( repeating: " 1 " , count: count) )
294
290
XCTAssertEqual ( try result. utf8stderrOutput ( ) , String ( repeating: " 2 " , count: count) )
@@ -298,7 +294,7 @@ class ProcessTests: XCTestCase {
298
294
func testStdoutStdErrRedirected( ) throws {
299
295
// A simple script to check that stdout and stderr are captured in the same location.
300
296
do {
301
- let process = Process ( args : script ( " simple-stdout-stderr " ) , outputRedirection: . collect( redirectStderr: true ) )
297
+ let process = Process ( scriptName : " simple-stdout-stderr " , outputRedirection: . collect( redirectStderr: true ) )
302
298
try process. launch ( )
303
299
let result = try process. waitUntilExit ( )
304
300
XCTAssertEqual ( try result. utf8Output ( ) , " simple error \n simple output \n " )
@@ -307,7 +303,7 @@ class ProcessTests: XCTestCase {
307
303
308
304
// A long stdout and stderr output.
309
305
do {
310
- let process = Process ( args : script ( " long-stdout-stderr " ) , outputRedirection: . collect( redirectStderr: true ) )
306
+ let process = Process ( scriptName : " long-stdout-stderr " , outputRedirection: . collect( redirectStderr: true ) )
311
307
try process. launch ( )
312
308
let result = try process. waitUntilExit ( )
313
309
@@ -320,7 +316,7 @@ class ProcessTests: XCTestCase {
320
316
func testStdoutStdErrStreaming( ) throws {
321
317
var stdout = [ UInt8] ( )
322
318
var stderr = [ UInt8] ( )
323
- let process = Process ( args : script ( " long-stdout-stderr " ) , outputRedirection: . stream( stdout: { stdoutBytes in
319
+ let process = Process ( scriptName : " long-stdout-stderr " , outputRedirection: . stream( stdout: { stdoutBytes in
324
320
stdout += stdoutBytes
325
321
} , stderr: { stderrBytes in
326
322
stderr += stderrBytes
@@ -336,7 +332,7 @@ class ProcessTests: XCTestCase {
336
332
func testStdoutStdErrStreamingRedirected( ) throws {
337
333
var stdout = [ UInt8] ( )
338
334
var stderr = [ UInt8] ( )
339
- let process = Process ( args : script ( " long-stdout-stderr " ) , outputRedirection: . stream( stdout: { stdoutBytes in
335
+ let process = Process ( scriptName : " long-stdout-stderr " , outputRedirection: . stream( stdout: { stdoutBytes in
340
336
stdout += stdoutBytes
341
337
} , stderr: { stderrBytes in
342
338
stderr += stderrBytes
@@ -386,3 +382,39 @@ class ProcessTests: XCTestCase {
386
382
}
387
383
}
388
384
}
385
+
386
+ fileprivate extension Process {
387
+ private static func env( ) -> [ String : String ] {
388
+ var env = ProcessEnv . vars
389
+ #if os(macOS)
390
+ // Many of these tests use Python which might not be in the default `PATH` when running these tests from Xcode.
391
+ env [ " PATH " ] = " \( env [ " PATH " ] ?? " " ) :/usr/local/bin "
392
+ #endif
393
+ return env
394
+ }
395
+
396
+ private static func script( _ name: String ) -> String {
397
+ return AbsolutePath ( path: #file) . parentDirectory. appending ( components: " processInputs " , name) . pathString
398
+ }
399
+
400
+ convenience init ( scriptName: String , arguments: [ String ] = [ ] , outputRedirection: OutputRedirection = . collect) {
401
+ self . init ( arguments: [ Self . script ( scriptName) ] + arguments, environment: Self . env ( ) , outputRedirection: outputRedirection)
402
+ }
403
+
404
+ static func checkNonZeroExit(
405
+ scriptName: String ,
406
+ environment: [ String : String ] = ProcessEnv . vars,
407
+ loggingHandler: LoggingHandler ? = . none
408
+ ) throws -> String {
409
+ return try checkNonZeroExit ( args: script ( scriptName) , environment: environment, loggingHandler: loggingHandler)
410
+ }
411
+
412
+ @discardableResult
413
+ static func popen(
414
+ scriptName: String ,
415
+ environment: [ String : String ] = ProcessEnv . vars,
416
+ loggingHandler: LoggingHandler ? = . none
417
+ ) throws -> ProcessResult {
418
+ return try popen ( arguments: [ script ( scriptName) ] , environment: Self . env ( ) , loggingHandler: loggingHandler)
419
+ }
420
+ }
0 commit comments