Files
Kare Morstol a1ad3fb25c Reformat code using swiftformat 0.40.14
Because it is the last version that does indentation and alignment correctly (tabs for indentation, spaces for alignment).
2020-07-11 15:33:57 +02:00

264 lines
7.8 KiB
Swift
Executable File

//
// Command_Tests.swift
// SwiftShell
//
// Created by Kåre Morstøl on 15/08/14.
// Copyright (c) 2014 NotTooBad Software. All rights reserved.
//
import Foundation
import SwiftShell
import XCTest
#if os(Linux)
import Glibc
#endif
public class Run_Tests: XCTestCase {
func testCompilesWhenNotDefiningReturnType() {
_ = SwiftShell.run("echo", "hi")
_ = SwiftShell.run(bash: "echo hi")
main.run("echo", "hi")
main.run(bash: "echo hi")
}
func testBashCommand() {
XCTAssertEqual(SwiftShell.run(bash: "echo one").stdout, "one")
}
func testArgumentsFromArray() {
let stringarray = ["one", "two"]
XCTAssertEqual(SwiftShell.run("/bin/echo", stringarray).stdout, "one two")
}
func testSinglelineOutput() {
XCTAssertEqual(SwiftShell.run("/bin/echo", "one", "two").stdout, "one two")
}
func testMultilineOutput() {
XCTAssertEqual(SwiftShell.run("/bin/echo", "one\ntwo").stdout, "one\ntwo\n")
}
func testStandardErrorOutput() {
XCTAssertEqual(SwiftShell.run(bash: "echo one 1>&2").stderror, "one")
}
func testCombinesOutput() {
XCTAssertEqual(SwiftShell.run(bash: "echo stdout; echo stderr > /dev/stderr", combineOutput: true).stdout, "stdout\nstderr\n")
}
func testExecutableWithoutPath() {
XCTAssertEqual(SwiftShell.run("echo", "one").stdout, "one")
}
func testSuccess() {
let success = SwiftShell.run(bash: "exit 0")
XCTAssertEqual(success.exitcode, 0)
XCTAssertEqual(success.succeeded, true)
let failure = SwiftShell.run(bash: "exit 1")
XCTAssertEqual(failure.exitcode, 1)
XCTAssertEqual(failure.succeeded, false)
}
func testAnd() {
main.currentdirectory = main.tempdirectory
let bothsucceed = SwiftShell.run("touch", "created") && SwiftShell.run("echo", "thisran")
XCTAssert(Files.fileExists(atPath: "created"))
XCTAssertEqual(bothsucceed.stdout, "thisran")
let firstfails = SwiftShell.run(bash: "exit 1") && SwiftShell.run("touch", "notcreated")
XCTAssertFalse(firstfails.succeeded)
XCTAssertFalse(Files.fileExists(atPath: "notcreated"))
}
func testOr() {
main.currentdirectory = main.tempdirectory
let firstran = SwiftShell.run("echo", "thisran") || SwiftShell.run("touch", "notcreated")
XCTAssertEqual(firstran.stdout, "thisran")
XCTAssertFalse(Files.fileExists(atPath: "notcreated"))
let firstfailedsecondran = SwiftShell.run(bash: "exit 1") || SwiftShell.run("echo", "thisran")
XCTAssertEqual(firstfailedsecondran.stdout, "thisran")
}
// https://github.com/kareman/SwiftShell/issues/52
func testDoesNotHaltOnLargeOutput() {
SwiftShell.run(bash: "for i in {1..65537}; do echo -n '='; done") // standard output
SwiftShell.run(bash: "for i in {1..65537}; do echo -n '=' 1>&2; done") // standard error
SwiftShell.run(bash: "for i in {1..65537}; do echo -n '='; echo -n '=' 1>&2; done") // both
}
}
public class RunAsync_Tests: XCTestCase {
func testReturnsStandardOutput() throws {
let asynccommand = runAsync("/bin/echo", "one", "two")
try asynccommand.finish()
XCTAssertEqual(asynccommand.stdout.read(), "one two\n")
XCTAssertEqual(asynccommand.stderror.read(), "")
}
func testReturnsStandardError() throws {
let asynccommand = runAsync(bash: "echo one two > /dev/stderr")
try asynccommand.finish()
XCTAssertEqual(asynccommand.stderror.read(), "one two\n")
XCTAssertEqual(asynccommand.stdout.read(), "")
}
func testArgumentsFromArray() throws {
let output = try runAsync("/bin/echo", ["one", "two"]).finish().stdout.read()
XCTAssertEqual(output, "one two\n")
}
func testFinishThrowsErrorOnExitcodeNotZero() {
let asynccommand = runAsync(bash: "echo errormessage > /dev/stderr; exit 1")
XCTAssertThrowsError(try asynccommand.finish())
XCTAssertEqual(asynccommand.stderror.read(), "errormessage\n")
}
func testExitCode() {
let asynccommand = runAsync(bash: "exit 1")
XCTAssertEqual(asynccommand.exitcode(), 1)
}
func testOnCompletion() {
let expectcompletion = expectation(description: "onCompletion will be called when command has finished.")
runAsync("echo").onCompletion { command in
XCTAssertFalse(command.isRunning)
expectcompletion.fulfill()
}
waitForExpectations(timeout: 0.5, handler: nil)
}
func testStop() {
// Start a command that won't exit for a long time
let command = runAsync(bash: "sleep 100")
XCTAssertTrue(command.isRunning)
command.stop()
// On Linux, command.isRunning becomes false once the command has been
// stopped, but the terminationReason does not become .uncaughtSignal
#if os(Linux)
// Checking the isRunning occasionally happens too quick for the
// assert. Sleeping for 1 second ensures the assert should pass
sleep(1)
XCTAssertFalse(command.isRunning)
// On macOS, command.isRunning is true until waitUntilExit() has been
// called, but the process's terminationReason becomes .uncaughtSignal.
#else
XCTAssertEqual(command.terminationReason(), Process.TerminationReason.uncaughtSignal)
#endif
}
func testInterrupt() {
// Start a command that won't exit for a long time
let command = runAsync(bash: "sleep 100")
XCTAssertTrue(command.isRunning)
command.interrupt()
// On Linux, command.isRunning becomes false once the command has been
// interrupted, but the terminationReason does not become
// .uncaughtSignal
#if os(Linux)
// Checking the isRunning occasionally happens too quick for the
// assert. Sleeping for 1 second ensures the assert should pass
sleep(1)
XCTAssertFalse(command.isRunning)
// On macOS, command.isRunning is true until waitUntilExit() has been
// called, but the process's terminationReason becomes .uncaughtSignal.
#else
XCTAssertEqual(command.terminationReason(), Process.TerminationReason.uncaughtSignal)
#endif
}
/*
Cannot test the suspend/resume calls reliably
func testSuspendAndResume() {
// Start a command that wouldn't ever exit normally
let command = runAsync("cat")
XCTAssertTrue(command.isRunning)
command.suspend()
XCTAssertFalse(command.isRunning)
command.resume()
XCTAssertTrue(command.isRunning)
}
*/
}
public class XCTestCase_TestOutput: XCTestCase {
var test_stdout: FileHandle!
var test_stderr: FileHandle!
public override func setUp() {
let outputpipe = Pipe()
main.stdout = FileHandleStream(outputpipe.fileHandleForWriting, encoding: .utf8)
test_stdout = outputpipe.fileHandleForReading
let errorpipe = Pipe()
main.stderror = FileHandleStream(errorpipe.fileHandleForWriting, encoding: .utf8)
test_stderr = errorpipe.fileHandleForReading
}
}
public class RunAsyncAndPrint_Tests: XCTestCase_TestOutput {
func testReturnsStandardOutput() throws {
try runAsyncAndPrint("/bin/echo", "one", "two").finish()
XCTAssertEqual(test_stdout.readSome(encoding: .utf8), "one two\n")
}
func testReturnsStandardError() throws {
try runAsyncAndPrint(bash: "echo one two > /dev/stderr").finish()
XCTAssertEqual(test_stderr.readSome(encoding: .utf8), "one two\n")
}
func testOnCompletion() {
let expectcompletion = expectation(description: "onCompletion will be called when command has finished.")
runAsyncAndPrint("echo").onCompletion { command in
XCTAssertFalse(command.isRunning)
expectcompletion.fulfill()
}
waitForExpectations(timeout: 0.5, handler: nil)
}
}
public class RunAndPrint_Tests: XCTestCase_TestOutput {
func testArgumentsFromArray() throws {
try runAndPrint("/bin/echo", ["one", "two"])
XCTAssertEqual(test_stdout.readSome(encoding: .utf8), "one two\n")
}
func testReturnsStandardOutput() throws {
try runAndPrint("/bin/echo", "one", "two")
XCTAssertEqual(test_stdout.readSome(encoding: .utf8), "one two\n")
}
func testReturnsStandardError() throws {
try runAndPrint(bash: "echo one two > /dev/stderr")
XCTAssertEqual(test_stderr.readSome(encoding: .utf8), "one two\n")
}
func testThrowsErrorOnExitcodeNotZero() {
XCTAssertThrowsError(try runAndPrint("bash", "-c", "exit 1"))
}
func testThrowsErrorOnInaccessibleExecutable() {
XCTAssertThrowsError(try runAndPrint("notachance"))
}
}