Skip to content

Instantly share code, notes, and snippets.

@rhysm94
Created August 31, 2024 09:54
Show Gist options
  • Save rhysm94/ad36db321f172b7c9e9ddbf60f0cca88 to your computer and use it in GitHub Desktop.
Save rhysm94/ad36db321f172b7c9e9ddbf60f0cca88 to your computer and use it in GitHub Desktop.
Demonstrates a protocol which can help with overriding protocol-witness style dependencies, adding expectations when called.
protocol Overrideable {}
extension Overrideable {
mutating func `override`<Input: Equatable, Output>(
method: WritableKeyPath<Self, @Sendable (Input) async throws -> Output>,
expectedInput: Input,
returning value: Output,
name: String
) {
let expectation = expectation(description: name)
let capturedMethod = self[keyPath: method]
self[keyPath: method] = { input in
if input == expectedInput {
expectation.fulfill()
return value
} else {
return try await capturedMethod(input)
}
}
}
}
extension Overrideable {
mutating func `override`<each Input: Equatable, Output>(
method: WritableKeyPath<Self, @Sendable (repeat each Input) async throws -> Output>,
expectedInput: (repeat each Input),
returning value: Output,
name: String
) {
let expectation = expectation(description: name)
let capturedMethod = self[keyPath: method]
// Cannot assign through subscript: 'self' is immutable
self[keyPath: method] = { (inputs: (repeat each Input)) in
let equal = isEqual(lhs: expectedInput, rhs: inputs)
if equal {
expectation.fulfill()
return value
} else {
// Cannot pass value pack expansion to non-pack parameter of type 'repeat each Input'
return try await capturedMethod(inputs)
}
}
}
}
private func isEqual<each Element: Equatable>(lhs: (repeat each Element), rhs: (repeat each Element)) -> Bool {
for (left, right) in repeat (each lhs, each rhs) {
guard left == right else { return false }
}
return true
}
// Substitute for XCTest expectation
struct Expectation {
var name: String
func fulfill() {
print("Fulfilled expectation \(name)")
}
}
func expectation(description: String) -> Expectation {
let expectation = Expectation(name: description)
print("Created expectation")
return expectation
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment