diff --git a/SwiftShell/Command.swift b/SwiftShell/Command.swift index 57cd37e..60fce0b 100644 --- a/SwiftShell/Command.swift +++ b/SwiftShell/Command.swift @@ -42,20 +42,20 @@ public protocol ShellRunnable { var shellcontext: ShellContextType { get } } -/** -If `executable` is not a path and a path for an executable file of that name can be found, return that path. -Otherwise just return `executable`. -*/ -private func pathForExecutable (executable: String) -> String { - guard !executable.characters.contains("/") else { - return executable - } - let path = run("/usr/bin/which", executable) - return path.isEmpty ? executable : path -} - extension ShellRunnable { + /** + If `executable` is not a path and a path for an executable file of that name can be found, return that path. + Otherwise just return `executable`. + */ + private func pathForExecutable (executable: String) -> String { + guard !executable.characters.contains("/") else { + return executable + } + let path = self.run("/usr/bin/which", executable) + return path.isEmpty ? executable : path + } + func createTask (executable: String, args: [String]) -> NSTask { let task = NSTask() task.arguments = args diff --git a/SwiftShellTests/Context_Tests.swift b/SwiftShellTests/Context_Tests.swift index 38bdfe7..eec32a7 100644 --- a/SwiftShellTests/Context_Tests.swift +++ b/SwiftShellTests/Context_Tests.swift @@ -24,12 +24,14 @@ class MainContext_Tests: XCTestCase { } } -class ShellContext_Tests: XCTestCase { +class BlankShellContext_Tests: XCTestCase { - func testBlankShellContext () { + func testIsBlank () { let context = ShellContext() XCTAssert( context.stdin === NSFileHandle.fileHandleWithNullDevice() ) + XCTAssert( context.stdout === NSFileHandle.fileHandleWithNullDevice() ) + XCTAssert( context.stderror === NSFileHandle.fileHandleWithNullDevice() ) } func testCopiedShellContext () { @@ -38,15 +40,23 @@ class ShellContext_Tests: XCTestCase { XCTAssert( context.stdin === main.stdin ) } + func testNonAbsoluteExecutablePathFailsOnEmptyPATHEnvVariable () { + let context = ShellContext() // everything is empty, including .env + + AssertThrows(ShellError.InAccessibleExecutable(path: "echo")) { + try context.runAndPrint("echo", "one") + } + } + func testRunCommand () { let context = ShellContext() - XCTAssertEqual(context.run("echo", "one"), "one") + XCTAssertEqual(context.run("/bin/echo", "one"), "one") } func testRunAsyncCommand () { let context = ShellContext() - let task = context.runAsync("echo", "one") + let task = context.runAsync("/bin/echo", "one") XCTAssertEqual(task.stdout.read(), "one\n") } @@ -55,7 +65,7 @@ class ShellContext_Tests: XCTestCase { var context = ShellContext() AssertNoThrow { - try context.runAndPrint("echo", "one") // sent to null + try context.runAndPrint("/bin/echo", "one") // sent to null } let outputpipe = NSPipe() @@ -63,7 +73,7 @@ class ShellContext_Tests: XCTestCase { let output = outputpipe.fileHandleForReading AssertNoThrow { - try context.runAndPrint("echo", "two") + try context.runAndPrint("/bin/echo", "two") } XCTAssertEqual(output.readSome(), "two\n") }