d3888a3808
* Adds filter and try filter implementations * Implement Filter * Remove @testable declaration * Fix linting * Updates tests and creates testing helper * Fix allTests to include all tests * Renames TestHelper to OperatorTestHelper and adds documentation * Adds more test coverage * Updates to use subclasses for filter / tryfilter * Adds subscription test * Fix subscriber demand to be lazy * Fix CustomPublisherBase changes from master * Fix iOS availability on test helper * Updates availability for test functions * Simplify Filter implementation, add more tests * Ensure test suite consistency on Darwin and Linux * Add missing tests to XCTestManifests.swift
72 lines
2.9 KiB
Swift
72 lines
2.9 KiB
Swift
//
|
|
// OperatorTestHelper.swift
|
|
//
|
|
//
|
|
// Created by Joseph Spadafora on 7/6/19.
|
|
//
|
|
|
|
import XCTest
|
|
|
|
#if OPENCOMBINE_COMPATIBILITY_TEST
|
|
import Combine
|
|
#else
|
|
import OpenCombine
|
|
#endif
|
|
|
|
/// `OperatorTestHelper` is an abstraction that helps avoid a lot of boilerplate when
|
|
/// testing an operator. It is initialized with a publisher type and creates a
|
|
/// `CustomSubscription`, `CustomPublisherBase` and `TrackingSubscriberBase`.
|
|
@available(macOS 10.15, iOS 13.0, *)
|
|
class OperatorTestHelper<SourceValue: Equatable,
|
|
SourcePublisher,
|
|
Sut: Publisher>
|
|
where Sut.Output: Equatable,
|
|
SourcePublisher: CustomPublisherBase<SourceValue, TestingError>
|
|
{
|
|
typealias Value = Sut.Output
|
|
typealias Failure = Sut.Failure
|
|
|
|
let subscription: CustomSubscription
|
|
let publisher: SourcePublisher
|
|
let tracking: TrackingSubscriberBase<Value, Failure>
|
|
private(set) var sut: Sut
|
|
|
|
var downstreamSubscription: Subscription?
|
|
|
|
/// This initializes the `OperatorTestHelper`. In most cases,
|
|
/// you can just pass a `publisherType` and closure
|
|
/// for `createSut` to get all the setup that you'll need for a test.
|
|
/// - Parameter publisherType: This should be filled in with the
|
|
/// type of `CustomPublisherBase` that you would like the
|
|
/// operator you are testing to be built from.
|
|
/// - Parameter initialDemand: This is the demand that the
|
|
/// created `TrackingSubscriber` should return upon receiving a subscription.
|
|
/// - Parameter receiveValueDemand: This is the demand that the
|
|
/// created `TrackingSubscriber should return upon receiving a value.
|
|
/// - Parameter customSubscription: This parameter defaults to `CustomSubscription()`,
|
|
/// but can be replaced with your own instance if you want to override
|
|
/// any of the default `CustomSubscription` initializer closures.
|
|
/// - Parameter createSut: This closure takes a new concrete instance
|
|
/// of the `publisherType` as an input to the closure and creates an
|
|
/// instance of the operator that you are trying to test.
|
|
init(publisherType: SourcePublisher.Type,
|
|
initialDemand: Subscribers.Demand,
|
|
receiveValueDemand: Subscribers.Demand,
|
|
customSubscription: CustomSubscription = CustomSubscription(),
|
|
createSut: (SourcePublisher) -> Sut)
|
|
{
|
|
self.subscription = customSubscription
|
|
let createdPublisher = publisherType.init(subscription: customSubscription)
|
|
self.publisher = createdPublisher
|
|
self.sut = createSut(createdPublisher)
|
|
self.tracking = TrackingSubscriberBase<Value, Failure>(
|
|
receiveSubscription: {
|
|
$0.request(initialDemand)
|
|
},
|
|
receiveValue: { _ in receiveValueDemand }
|
|
)
|
|
tracking.onSubscribe = { self.downstreamSubscription = $0 }
|
|
sut.subscribe(tracking)
|
|
}
|
|
}
|