-
-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #21 from finestructure/integration-test
Add integration test
- Loading branch information
Showing
2 changed files
with
150 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// | ||
// IntegrationTests.swift | ||
// ArenaTests | ||
// | ||
// Created by Sven A. Schmidt on 02/03/2020. | ||
// | ||
|
||
@testable import ArenaCore | ||
import XCTest | ||
|
||
|
||
class IntegrationTests: XCTestCase { | ||
|
||
#if swift(>=5.2) | ||
func test_ArenaTest() throws { | ||
try XCTSkipUnless(ProcessInfo().hostName == "luna.local", "fails on CI, only run locally") | ||
|
||
let output = OutputListener() | ||
output.openConsolePipe() | ||
|
||
let arena = try Arena.parse([ | ||
"https://github.com/finestructure/[email protected]", | ||
"--name=ArenaIntegrationTest", | ||
"--force", | ||
"--skip-open"]) | ||
try arena.run() | ||
|
||
let expectation = """ | ||
🔧 resolving package dependencies | ||
📔 libraries found: ArenaTest | ||
🔨 building package dependencies | ||
✅ created project in folder '../../tmp/ArenaIntegrationTest' | ||
Run | ||
open ../../tmp/ArenaIntegrationTest/ArenaIntegrationTest.xcworkspace | ||
to open the project in Xcode | ||
""" | ||
let predicate = NSPredicate { _,_ in | ||
output.contents == expectation | ||
} | ||
let exp = XCTNSPredicateExpectation(predicate: predicate, object: nil) | ||
wait(for: [exp], timeout: 10) | ||
XCTAssertEqual(output.contents, expectation) | ||
|
||
output.closeConsolePipe() | ||
} | ||
#endif | ||
|
||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
// | ||
// OutputListener.swift | ||
// MasKitTests | ||
// | ||
// Created by Ben Chatelain on 1/7/19. | ||
// Copyright © 2019 mas-cli. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
|
||
/// Test helper for monitoring strings written to stdout. Modified from: | ||
/// https://medium.com/@thesaadismail/eavesdropping-on-swifts-print-statements-57f0215efb42 | ||
class OutputListener { | ||
/// consumes the messages on STDOUT | ||
let inputPipe = Pipe() | ||
|
||
/// outputs messages back to STDOUT | ||
let outputPipe = Pipe() | ||
|
||
/// Buffers strings written to stdout | ||
var contents = "" | ||
|
||
init() { | ||
// Set up a read handler which fires when data is written to our inputPipe | ||
inputPipe.fileHandleForReading.readabilityHandler = { [weak self] fileHandle in | ||
strongify(self) { context in | ||
let data = fileHandle.availableData | ||
if let string = String(data: data, encoding: String.Encoding.utf8) { | ||
context.contents += string | ||
} | ||
|
||
// Write input back to stdout | ||
context.outputPipe.fileHandleForWriting.write(data) | ||
} | ||
} | ||
} | ||
} | ||
|
||
extension OutputListener { | ||
/// Sets up the "tee" of piped output, intercepting stdout then passing it through. | ||
/// | ||
/// ## [dup2 documentation](https://linux.die.net/man/2/dup2) | ||
/// `int dup2(int oldfd, int newfd);` | ||
/// `dup2()` makes `newfd` be the copy of `oldfd`, closing `newfd` first if necessary. | ||
func openConsolePipe() { | ||
var dupStatus: Int32 | ||
|
||
// Copy STDOUT file descriptor to outputPipe for writing strings back to STDOUT | ||
dupStatus = dup2(stdoutFileDescriptor, outputPipe.fileHandleForWriting.fileDescriptor) | ||
// Status should equal newfd | ||
assert(dupStatus == outputPipe.fileHandleForWriting.fileDescriptor) | ||
|
||
// Intercept STDOUT with inputPipe | ||
// newFileDescriptor is the pipe's file descriptor and the old file descriptor is STDOUT_FILENO | ||
dupStatus = dup2(inputPipe.fileHandleForWriting.fileDescriptor, stdoutFileDescriptor) | ||
// Status should equal newfd | ||
assert(dupStatus == stdoutFileDescriptor) | ||
|
||
// Don't have any tests on stderr yet | ||
// dup2(inputPipe.fileHandleForWriting.fileDescriptor, stderr) | ||
} | ||
|
||
/// Tears down the "tee" of piped output. | ||
func closeConsolePipe() { | ||
// Restore stdout | ||
freopen("/dev/stdout", "a", stdout) | ||
|
||
[inputPipe.fileHandleForReading, outputPipe.fileHandleForWriting].forEach { file in | ||
file.closeFile() | ||
} | ||
} | ||
} | ||
|
||
extension OutputListener { | ||
/// File descriptor for stdout (aka STDOUT_FILENO) | ||
var stdoutFileDescriptor: Int32 { | ||
return FileHandle.standardOutput.fileDescriptor | ||
} | ||
|
||
/// File descriptor for stderr (aka STDERR_FILENO) | ||
var stderrFileDescriptor: Int32 { | ||
return FileHandle.standardError.fileDescriptor | ||
} | ||
} | ||
|
||
|
||
// https://medium.com/@merowing_/stop-weak-strong-dance-in-swift-3aec6d3563d4 | ||
func strongify<Context: AnyObject, Arguments>(_ context: Context?, | ||
closure: @escaping (Context, Arguments) -> Void) -> (Arguments) -> Void { | ||
return { [weak context] arguments in | ||
guard let strongContext = context else { return } | ||
closure(strongContext, arguments) | ||
} | ||
} | ||
|
||
func strongify<Context: AnyObject>(_ context: Context?, closure: @escaping (Context) -> Void) { | ||
guard let strongContext = context else { return } | ||
closure(strongContext) | ||
} | ||
|