Created
July 19, 2024 15:47
-
-
Save jkereako/c864537636747912ab00ea72e06094e5 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
import Foundation | |
import XCTest | |
final class STDOUTListener { | |
/// Consume messages sent to STDOUT | |
let input = Pipe() | |
/// Sends messages back to STDOUT | |
let output = Pipe() | |
/// Buffers strings written to stdout | |
private(set) var buffer = "" | |
/// Fulfilled when buffer is captured. | |
/// | |
/// This is needed because writing to STDOUT is asynchronous | |
let expectation = XCTestExpectation( | |
description: "Fulfilled when buffer is captured" | |
) | |
init() { | |
// Set up a read handler which fires when data is written to our inputPipe | |
input.fileHandleForReading.readabilityHandler = { [weak self] handle in | |
guard let self else { | |
assertionFailure("`self` is nil") | |
return | |
} | |
let data = handle.availableData | |
if let string = String(data: data, encoding: String.Encoding.utf8) { | |
self.buffer += string | |
} | |
// Write input back to stdout | |
self.output.fileHandleForWriting.write(data) | |
expectation.fulfill() | |
} | |
} | |
/// Intercepts messages written to STDOUT | |
func open() { | |
// Copy the STDOUT file descriptor to `output` | |
dup2(STDOUT_FILENO, output.fileHandleForWriting.fileDescriptor) | |
// Intercept STDOUT with `inputPipe` | |
dup2(input.fileHandleForWriting.fileDescriptor, STDOUT_FILENO) | |
} | |
/// Removes the interceptor | |
func close() { | |
// Restore stdout | |
freopen("/dev/stdout", "a", stdout) | |
[input.fileHandleForReading, output.fileHandleForWriting].forEach { | |
$0.closeFile() | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Description
Captures stdout messages for use in XCTests
Credit
Lifted from the blog post Intercepting stdout in Swift