Skip to content

Instantly share code, notes, and snippets.

@tngranados
Created December 19, 2022 17:21
Show Gist options
  • Save tngranados/e551bbaf608b061789daa477fb10ba49 to your computer and use it in GitHub Desktop.
Save tngranados/e551bbaf608b061789daa477fb10ba49 to your computer and use it in GitHub Desktop.
An extension to Combine's Publisher that adds a function `expectChange` that takes a predicate and returns an expectation that is fulfilled whenever that predicate evaluates true
import XCTest
import Combine
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension Publisher where Self.Failure == Never {
func expectChange(where predicate: ((Self.Output) -> Bool)? = nil, timeout: Int = 5) -> XCTestExpectation {
let expectation = XCTestExpectation(description: "something changed")
let cancellable = self.sink { value in
guard let predicate else {
expectation.fulfill()
return
}
if predicate(value) {
expectation.fulfill()
}
}
// This is needed because the sink's Cancellable ref needs to be hold in order for it to not be deallocated.
// Handling it here allows the caller of this function to be free of handling it.
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(timeout)) {
cancellable.cancel()
}
return expectation
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment