Skip to content

Commit

Permalink
fix: avoid stub deadlock
Browse files Browse the repository at this point in the history
  • Loading branch information
swift-student committed Jan 28, 2025
1 parent 15e909e commit 1dc7031
Showing 1 changed file with 11 additions and 8 deletions.
19 changes: 11 additions & 8 deletions Sources/TestDRS/Stub/StubRegistry/StubRegistry.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,22 +48,25 @@ public final class StubRegistry: @unchecked Sendable {
/// - Returns: The output value for the given input and function signature.
/// - Throws: `StubError.noStub` if no stub is registered for the given input and function signature, or any error thrown by the registered closure.
func getOutput<Input, Output>(for input: Input, withSignature signature: FunctionSignature) throws -> Output {
try storageQueue.sync {
let stub = storageQueue.sync {
let identifier = FunctionStubIdentifier(signature: signature, inputType: Input.self, outputType: Output.self)

// Stubs could be set with either the full signature like `foo(paramOne:)`
// or if there is no ambiguity, they could be set with an abbreviated signature like `foo`.
// When we go to retrieve them, we should have the full signature since it is captured by #function.
// So first we try to retrieve using the full signature provided, and then using the abbreviated version.
guard let stub = functionStubs[identifier] ?? functionStubs[identifier.abbreviatedIdentifier] else {
if let void = Void() as? Output {
return void
}
throw StubError.noStub
}
return functionStubs[identifier] ?? functionStubs[identifier.abbreviatedIdentifier]
}

return try stub.evaluate(with: input)
guard let stub else {
if let void = Void() as? Output {
return void
}
throw StubError.noStub
}

// Evaluate the stub outside of the storageQueue so that we don't deadlock
return try stub.evaluate(with: input)
}

}
Expand Down

0 comments on commit 1dc7031

Please sign in to comment.