Skip to content

Instantly share code, notes, and snippets.

@mdb1
Created February 3, 2023 19:45
Show Gist options
  • Save mdb1/4240b2f34a862f1ca88bfa6223b7a1a0 to your computer and use it in GitHub Desktop.
Save mdb1/4240b2f34a862f1ca88bfa6223b7a1a0 to your computer and use it in GitHub Desktop.
assertState
import Combine
import XCTest
/// Runs the assertions provided for the publisher variable.
public class AssertState {
private var subscribers: Set<AnyCancellable> = []
/// Initializes AssertState object.
public init() {}
}
public extension AssertState {
/// Runs the assertions provided for the publisher variable.
/// Useful for testing ValueState objects.
/// - Parameters:
/// - when: The method triggering the publisher values.
/// - type: The type of the values emitted by the publisher.
/// - testCase: The object running the test case.
/// - publisher: The publisher emitting the state changes.
/// - valuesLimit: The maximum amount of values emitted by the publisher. Default is `3`.
/// - initialAssertions: The initial assertions, before executing the `when` closure.
/// - valueAssertions: The assertions considering the values emitted by the publisher.
func assert<T>(
when: () -> Void,
type _: T.Type,
testCase: XCTestCase,
publisher: any Publisher<T, Never>,
valuesLimit: Int = 3,
initialAssertions: () -> Void,
valuesAssertions: @escaping ([T]) -> Void
) {
var stateValues = [T]()
let expectation = XCTestExpectation(description: "Awaits published values, then finishes")
initialAssertions()
publisher.sink { value in
stateValues.append(value)
if stateValues.count == valuesLimit {
valuesAssertions(stateValues)
expectation.fulfill()
} else if stateValues.count > valuesLimit {
XCTFail("Expecting only \(valuesLimit) values")
}
}.store(in: &subscribers)
when()
testCase.wait(for: [expectation], timeout: 0.5)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment