Adds tests for `shareReplayLatestWhileConnected`, adds type hints to `createObserver` and adds additional `Driver` tests.

This commit is contained in:
Krunoslav Zaher 2015-12-06 14:51:07 +01:00
parent 532c6c2c7b
commit 3cfccfafed
7 changed files with 440 additions and 55 deletions

View File

@ -394,6 +394,10 @@
C8B145011BD2D80100267DCE /* ImmediateScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8B144FF1BD2D80100267DCE /* ImmediateScheduler.swift */; };
C8B145021BD2D80100267DCE /* ImmediateScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8B144FF1BD2D80100267DCE /* ImmediateScheduler.swift */; };
C8B145031BD2D80100267DCE /* ImmediateScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8B144FF1BD2D80100267DCE /* ImmediateScheduler.swift */; };
C8BCD3C71C1468D4005F1280 /* ShareReplay1WhileConnected.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8BCD3C61C1468D4005F1280 /* ShareReplay1WhileConnected.swift */; };
C8BCD3C81C1468D4005F1280 /* ShareReplay1WhileConnected.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8BCD3C61C1468D4005F1280 /* ShareReplay1WhileConnected.swift */; };
C8BCD3C91C1468D4005F1280 /* ShareReplay1WhileConnected.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8BCD3C61C1468D4005F1280 /* ShareReplay1WhileConnected.swift */; };
C8BCD3CA1C1468D4005F1280 /* ShareReplay1WhileConnected.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8BCD3C61C1468D4005F1280 /* ShareReplay1WhileConnected.swift */; };
C8C3D9FE1B935EDF004D233E /* Zip+CollectionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8C3D9FD1B935EDF004D233E /* Zip+CollectionType.swift */; };
C8C3D9FF1B935EDF004D233E /* Zip+CollectionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8C3D9FD1B935EDF004D233E /* Zip+CollectionType.swift */; };
C8C3DA031B9390C4004D233E /* Just.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8C3DA021B9390C4004D233E /* Just.swift */; };
@ -1081,6 +1085,7 @@
C8A56AD71AD7424700B4673B /* RxSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RxSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
C8B144FA1BD2D44500267DCE /* ConcurrentMainScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConcurrentMainScheduler.swift; sourceTree = "<group>"; };
C8B144FF1BD2D80100267DCE /* ImmediateScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImmediateScheduler.swift; sourceTree = "<group>"; };
C8BCD3C61C1468D4005F1280 /* ShareReplay1WhileConnected.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShareReplay1WhileConnected.swift; sourceTree = "<group>"; };
C8C3D9FD1B935EDF004D233E /* Zip+CollectionType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Zip+CollectionType.swift"; sourceTree = "<group>"; };
C8C3DA021B9390C4004D233E /* Just.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Just.swift; sourceTree = "<group>"; };
C8C3DA051B9393AC004D233E /* Empty.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Empty.swift; sourceTree = "<group>"; };
@ -1341,6 +1346,7 @@
C8093C871B8A72BE0088E94D /* Scan.swift */,
C83100631BF7D51600AAE3CD /* Sequence.swift */,
C89CDB351BCB0DD7002063D9 /* ShareReplay1.swift */,
C8BCD3C61C1468D4005F1280 /* ShareReplay1WhileConnected.swift */,
CB30D9E81BF0E3500084C1C0 /* SingleAsync.swift */,
C8093C881B8A72BE0088E94D /* Sink.swift */,
C8093C891B8A72BE0088E94D /* Skip.swift */,
@ -2294,6 +2300,7 @@
C8093D4A1B8A72BE0088E94D /* Throttle.swift in Sources */,
C8B145011BD2D80100267DCE /* ImmediateScheduler.swift in Sources */,
C8093D061B8A72BE0088E94D /* Catch.swift in Sources */,
C8BCD3C81C1468D4005F1280 /* ShareReplay1WhileConnected.swift in Sources */,
C8F6A0FA1BEE33C1007DF367 /* InvocableScheduledItem.swift in Sources */,
C8093D0C1B8A72BE0088E94D /* CombineLatest.swift in Sources */,
D2FC15B31BCB95E5007361FF /* SkipWhile.swift in Sources */,
@ -2433,6 +2440,7 @@
C8093D491B8A72BE0088E94D /* Throttle.swift in Sources */,
C8B145001BD2D80100267DCE /* ImmediateScheduler.swift in Sources */,
C8093D051B8A72BE0088E94D /* Catch.swift in Sources */,
C8BCD3C71C1468D4005F1280 /* ShareReplay1WhileConnected.swift in Sources */,
C8F6A0F91BEE33C1007DF367 /* InvocableScheduledItem.swift in Sources */,
C8093D0B1B8A72BE0088E94D /* CombineLatest.swift in Sources */,
D22B6D261BC8504A00BCE0AB /* SkipWhile.swift in Sources */,
@ -2572,6 +2580,7 @@
C8F0BFAA1BBBFB8B001B112F /* Throttle.swift in Sources */,
C8B145031BD2D80100267DCE /* ImmediateScheduler.swift in Sources */,
C8F0BFAC1BBBFB8B001B112F /* Catch.swift in Sources */,
C8BCD3CA1C1468D4005F1280 /* ShareReplay1WhileConnected.swift in Sources */,
C8F6A0FC1BEE33C1007DF367 /* InvocableScheduledItem.swift in Sources */,
C8F0BFAD1BBBFB8B001B112F /* CombineLatest.swift in Sources */,
D2FC15B51BCB95E8007361FF /* SkipWhile.swift in Sources */,
@ -2874,6 +2883,7 @@
D2EBEB2D1BB9B6CA003A27DC /* Observable+Concurrency.swift in Sources */,
D2EBEB381BB9B6D8003A27DC /* ConcurrentDispatchQueueScheduler.swift in Sources */,
C8B145021BD2D80100267DCE /* ImmediateScheduler.swift in Sources */,
C8BCD3C91C1468D4005F1280 /* ShareReplay1WhileConnected.swift in Sources */,
C8F6A0FB1BEE33C1007DF367 /* InvocableScheduledItem.swift in Sources */,
D2EBEB131BB9B6C1003A27DC /* Multicast.swift in Sources */,
D2EBEB111BB9B6C1003A27DC /* Map.swift in Sources */,

View File

@ -43,6 +43,4 @@ extension Recorded {
func == <T: Equatable>(lhs: Recorded<T>, rhs: Recorded<T>) -> Bool {
return lhs.time == rhs.time && lhs.event == rhs.event
}
}

View File

@ -9,18 +9,6 @@
import Foundation
import RxSwift
func createHotObservable<Element>(scheduler: TestScheduler, events: [Recorded<Element>]) -> HotObservable<Element> {
return HotObservable(testScheduler: scheduler, recordedEvents: events)
}
func createColdObservable<Element>(scheduler: TestScheduler, events: [Recorded<Element>]) -> ColdObservable<Element> {
return ColdObservable(testScheduler: scheduler, recordedEvents: events)
}
func createObserver<E>(scheduler: TestScheduler) -> MockObserver<E> {
return MockObserver(scheduler: scheduler)
}
class TestScheduler : VirtualTimeSchedulerBase {
override init(initialClock: Time) {
@ -34,8 +22,8 @@ class TestScheduler : VirtualTimeSchedulerBase {
func createColdObservable<Element>(events: [Recorded<Element>]) -> ColdObservable<Element> {
return ColdObservable(testScheduler: self as AnyObject as! TestScheduler, recordedEvents: events)
}
func createObserver<E>() -> MockObserver<E> {
func createObserver<E>(type: E.Type) -> MockObserver<E> {
return MockObserver(scheduler: self as AnyObject as! TestScheduler)
}
@ -49,7 +37,7 @@ class TestScheduler : VirtualTimeSchedulerBase {
func start<Element : Equatable>(created: Time, subscribed: Time, disposed: Time, create: () -> Observable<Element>) -> MockObserver<Element> {
var source : Observable<Element>? = nil
var subscription : Disposable? = nil
let observer: MockObserver<Element> = createObserver()
let observer: MockObserver<Element> = createObserver(Element)
let state : Void = ()

View File

@ -33,13 +33,13 @@ class BehaviorSubjectTest : RxTest {
var subject: BehaviorSubject<Int>! = nil
var subscription: Disposable! = nil
let results1: MockObserver<Int> = scheduler.createObserver()
let results1 = scheduler.createObserver(Int)
var subscription1: Disposable! = nil
let results2: MockObserver<Int> = scheduler.createObserver()
let results2 = scheduler.createObserver(Int)
var subscription2: Disposable! = nil
let results3: MockObserver<Int> = scheduler.createObserver()
let results3 = scheduler.createObserver(Int)
var subscription3: Disposable! = nil
scheduler.scheduleAt(100) { subject = BehaviorSubject<Int>(value: 100) }
@ -97,13 +97,13 @@ class BehaviorSubjectTest : RxTest {
var subject: BehaviorSubject<Int>! = nil
var subscription: Disposable! = nil
let results1: MockObserver<Int> = scheduler.createObserver()
let results1 = scheduler.createObserver(Int)
var subscription1: Disposable! = nil
let results2: MockObserver<Int> = scheduler.createObserver()
let results2 = scheduler.createObserver(Int)
var subscription2: Disposable! = nil
let results3: MockObserver<Int> = scheduler.createObserver()
let results3 = scheduler.createObserver(Int)
var subscription3: Disposable! = nil
scheduler.scheduleAt(100) { subject = BehaviorSubject<Int>(value: 100) }
@ -160,13 +160,13 @@ class BehaviorSubjectTest : RxTest {
var subject: BehaviorSubject<Int>! = nil
var subscription: Disposable! = nil
let results1: MockObserver<Int> = scheduler.createObserver()
let results1 = scheduler.createObserver(Int)
var subscription1: Disposable! = nil
let results2: MockObserver<Int> = scheduler.createObserver()
let results2 = scheduler.createObserver(Int)
var subscription2: Disposable! = nil
let results3: MockObserver<Int> = scheduler.createObserver()
let results3 = scheduler.createObserver(Int)
var subscription3: Disposable! = nil
scheduler.scheduleAt(100) { subject = BehaviorSubject<Int>(value: 100) }
@ -216,13 +216,13 @@ class BehaviorSubjectTest : RxTest {
var subject: BehaviorSubject<Int>! = nil
var subscription: Disposable! = nil
let results1: MockObserver<Int> = scheduler.createObserver()
let results1 = scheduler.createObserver(Int)
var subscription1: Disposable! = nil
let results2: MockObserver<Int> = scheduler.createObserver()
let results2 = scheduler.createObserver(Int)
var subscription2: Disposable! = nil
let results3: MockObserver<Int> = scheduler.createObserver()
let results3 = scheduler.createObserver(Int)
var subscription3: Disposable! = nil
scheduler.scheduleAt(100) { subject = BehaviorSubject<Int>(value: 100) }

View File

@ -89,6 +89,154 @@ extension DriverTest {
}
}
// MARK: properties
extension DriverTest {
func testDriverSharing_WhenErroring() {
let scheduler = TestScheduler(initialClock: 0)
let observer1 = scheduler.createObserver(Int)
let observer2 = scheduler.createObserver(Int)
let observer3 = scheduler.createObserver(Int)
var disposable1: Disposable!
var disposable2: Disposable!
var disposable3: Disposable!
let coldObservable = scheduler.createColdObservable([
next(10, 0),
next(20, 1),
next(30, 2),
next(40, 3),
error(50, testError)
])
let driver = coldObservable.asDriver(onErrorJustReturn: -1)
scheduler.scheduleAt(200) {
disposable1 = driver.asObservable().subscribe(observer1)
}
scheduler.scheduleAt(225) {
disposable2 = driver.asObservable().subscribe(observer2)
}
scheduler.scheduleAt(235) {
disposable1.dispose()
}
scheduler.scheduleAt(260) {
disposable2.dispose()
}
// resubscription
scheduler.scheduleAt(260) {
disposable3 = driver.asObservable().subscribe(observer3)
}
scheduler.scheduleAt(285) {
disposable3.dispose()
}
scheduler.start()
XCTAssertEqual(observer1.messages, [
next(210, 0),
next(220, 1),
next(230, 2)
])
XCTAssertEqual(observer2.messages, [
next(225, 1),
next(230, 2),
next(240, 3),
next(250, -1),
completed(250)
])
XCTAssertEqual(observer3.messages, [
next(270, 0),
next(280, 1),
])
XCTAssertEqual(coldObservable.subscriptions, [
Subscription(200, 250),
Subscription(260, 285),
])
}
func testDriverSharing_WhenCompleted() {
let scheduler = TestScheduler(initialClock: 0)
let observer1 = scheduler.createObserver(Int)
let observer2 = scheduler.createObserver(Int)
let observer3 = scheduler.createObserver(Int)
var disposable1: Disposable!
var disposable2: Disposable!
var disposable3: Disposable!
let coldObservable = scheduler.createColdObservable([
next(10, 0),
next(20, 1),
next(30, 2),
next(40, 3),
error(50, testError)
])
let driver = coldObservable.asDriver(onErrorJustReturn: -1)
scheduler.scheduleAt(200) {
disposable1 = driver.asObservable().subscribe(observer1)
}
scheduler.scheduleAt(225) {
disposable2 = driver.asObservable().subscribe(observer2)
}
scheduler.scheduleAt(235) {
disposable1.dispose()
}
scheduler.scheduleAt(260) {
disposable2.dispose()
}
// resubscription
scheduler.scheduleAt(260) {
disposable3 = driver.asObservable().subscribe(observer3)
}
scheduler.scheduleAt(285) {
disposable3.dispose()
}
scheduler.start()
XCTAssertEqual(observer1.messages, [
next(210, 0),
next(220, 1),
next(230, 2)
])
XCTAssertEqual(observer2.messages, [
next(225, 1),
next(230, 2),
next(240, 3),
next(250, -1),
completed(250)
])
XCTAssertEqual(observer3.messages, [
next(270, 0),
next(280, 1),
])
XCTAssertEqual(coldObservable.subscriptions, [
Subscription(200, 250),
Subscription(260, 285),
])
}
}
// MARK: conversions
extension DriverTest {
func testAsDriver_onErrorJustReturn() {

View File

@ -210,22 +210,22 @@ extension ObservableBindingTest {
let res = xs.publish().refCount()
var d1: Disposable!
let o1: MockObserver<Int> = scheduler.createObserver()
let o1 = scheduler.createObserver(Int)
scheduler.scheduleAt(215) { d1 = res.subscribe(o1) }
scheduler.scheduleAt(235) { d1.dispose() }
var d2: Disposable!
let o2: MockObserver<Int> = scheduler.createObserver()
let o2 = scheduler.createObserver(Int)
scheduler.scheduleAt(225) { d2 = res.subscribe(o2) }
scheduler.scheduleAt(275) { d2.dispose() }
var d3: Disposable!
let o3: MockObserver<Int> = scheduler.createObserver()
let o3 = scheduler.createObserver(Int)
scheduler.scheduleAt(255) { d3 = res.subscribe(o3) }
scheduler.scheduleAt(265) { d3.dispose() }
var d4: Disposable!
let o4: MockObserver<Int> = scheduler.createObserver()
let o4 = scheduler.createObserver(Int)
scheduler.scheduleAt(285) { d4 = res.subscribe(o4) }
scheduler.scheduleAt(320) { d4.dispose() }
@ -285,7 +285,7 @@ extension ObservableBindingTest {
var ys: ConnectableObservable<ReplaySubject<Int>>! = nil
var subscription: Disposable! = nil
var connection: Disposable! = nil
let res: MockObserver<Int> = scheduler.createObserver()
let res = scheduler.createObserver(Int)
scheduler.scheduleAt(Defaults.created) { ys = xs.replay(3) }
scheduler.scheduleAt(450, action: { subscription = ys.subscribe(res) })
@ -339,7 +339,7 @@ extension ObservableBindingTest {
var ys: ConnectableObservable<ReplaySubject<Int>>! = nil
var subscription: Disposable! = nil
var connection: Disposable! = nil
let res: MockObserver<Int> = scheduler.createObserver()
let res = scheduler.createObserver(Int)
scheduler.scheduleAt(Defaults.created) { ys = xs.replay(3) }
scheduler.scheduleAt(450, action: { subscription = ys.subscribe(res) })
@ -391,7 +391,7 @@ extension ObservableBindingTest {
var ys: ConnectableObservable<ReplaySubject<Int>>! = nil
var subscription: Disposable! = nil
var connection: Disposable! = nil
let res: MockObserver<Int> = scheduler.createObserver()
let res = scheduler.createObserver(Int)
scheduler.scheduleAt(Defaults.created) { ys = xs.replay(3) }
scheduler.scheduleAt(450, action: { subscription = ys.subscribe(res) })
@ -443,7 +443,7 @@ extension ObservableBindingTest {
var ys: ConnectableObservable<ReplaySubject<Int>>! = nil
var subscription: Disposable! = nil
var connection: Disposable! = nil
let res: MockObserver<Int> = scheduler.createObserver()
let res = scheduler.createObserver(Int)
scheduler.scheduleAt(Defaults.created) { ys = xs.replay(3) }
scheduler.scheduleAt(450, action: { subscription = ys.subscribe(res) })
@ -496,7 +496,7 @@ extension ObservableBindingTest {
var ys: ConnectableObservable<ReplaySubject<Int>>! = nil
var subscription: Disposable! = nil
var connection: Disposable! = nil
let res: MockObserver<Int> = scheduler.createObserver()
let res = scheduler.createObserver(Int)
scheduler.scheduleAt(Defaults.created) { ys = xs.replay(1) }
scheduler.scheduleAt(450, action: { subscription = ys.subscribe(res) })
@ -548,7 +548,7 @@ extension ObservableBindingTest {
var ys: ConnectableObservable<ReplaySubject<Int>>! = nil
var subscription: Disposable! = nil
var connection: Disposable! = nil
let res: MockObserver<Int> = scheduler.createObserver()
let res = scheduler.createObserver(Int)
scheduler.scheduleAt(Defaults.created) { ys = xs.replay(1) }
scheduler.scheduleAt(450, action: { subscription = ys.subscribe(res) })
@ -598,7 +598,7 @@ extension ObservableBindingTest {
var ys: ConnectableObservable<ReplaySubject<Int>>! = nil
var subscription: Disposable! = nil
var connection: Disposable! = nil
let res: MockObserver<Int> = scheduler.createObserver()
let res = scheduler.createObserver(Int)
scheduler.scheduleAt(Defaults.created) { ys = xs.replay(1) }
scheduler.scheduleAt(450, action: { subscription = ys.subscribe(res) })
@ -648,7 +648,7 @@ extension ObservableBindingTest {
var ys: ConnectableObservable<ReplaySubject<Int>>! = nil
var subscription: Disposable! = nil
var connection: Disposable! = nil
let res: MockObserver<Int> = scheduler.createObserver()
let res = scheduler.createObserver(Int)
scheduler.scheduleAt(Defaults.created) { ys = xs.replay(1) }
scheduler.scheduleAt(450, action: { subscription = ys.subscribe(res) })
@ -699,7 +699,7 @@ extension ObservableBindingTest {
var ys: ConnectableObservable<ReplaySubject<Int>>! = nil
var subscription: Disposable! = nil
var connection: Disposable! = nil
let res: MockObserver<Int> = scheduler.createObserver()
let res = scheduler.createObserver(Int)
scheduler.scheduleAt(Defaults.created) { ys = xs.replayAll() }
scheduler.scheduleAt(450, action: { subscription = ys.subscribe(res) })
@ -758,7 +758,7 @@ extension ObservableBindingTest {
var ys: ConnectableObservable<ReplaySubject<Int>>! = nil
var subscription: Disposable! = nil
var connection: Disposable! = nil
let res: MockObserver<Int> = scheduler.createObserver()
let res = scheduler.createObserver(Int)
scheduler.scheduleAt(Defaults.created) { ys = xs.replayAll() }
scheduler.scheduleAt(450, action: { subscription = ys.subscribe(res) })
@ -811,7 +811,7 @@ extension ObservableBindingTest {
var ys: ConnectableObservable<ReplaySubject<Int>>! = nil
var subscription: Disposable! = nil
var connection: Disposable! = nil
let res: MockObserver<Int> = scheduler.createObserver()
let res = scheduler.createObserver(Int)
scheduler.scheduleAt(Defaults.created) { ys = xs.replayAll() }
scheduler.scheduleAt(450, action: { subscription = ys.subscribe(res) })
@ -864,7 +864,7 @@ extension ObservableBindingTest {
var ys: ConnectableObservable<ReplaySubject<Int>>! = nil
var subscription: Disposable! = nil
var connection: Disposable! = nil
let res: MockObserver<Int> = scheduler.createObserver()
let res = scheduler.createObserver(Int)
scheduler.scheduleAt(Defaults.created) { ys = xs.replayAll() }
scheduler.scheduleAt(450, action: { subscription = ys.subscribe(res) })
@ -984,8 +984,8 @@ extension ObservableBindingTest {
var subscription1: Disposable! = nil
var subscription2: Disposable! = nil
let res1: MockObserver<Int> = scheduler.createObserver()
let res2: MockObserver<Int> = scheduler.createObserver()
let res1 = scheduler.createObserver(Int)
let res2 = scheduler.createObserver(Int)
scheduler.scheduleAt(Defaults.created) { ys = transform(xs.asObservable()) }
@ -1053,8 +1053,8 @@ extension ObservableBindingTest {
var subscription1: Disposable! = nil
var subscription2: Disposable! = nil
let res1: MockObserver<Int> = scheduler.createObserver()
let res2: MockObserver<Int> = scheduler.createObserver()
let res1 = scheduler.createObserver(Int)
let res2 = scheduler.createObserver(Int)
scheduler.scheduleAt(Defaults.created) { ys = transform(xs.asObservable()) }
@ -1119,8 +1119,8 @@ extension ObservableBindingTest {
var subscription1: Disposable! = nil
var subscription2: Disposable! = nil
let res1: MockObserver<Int> = scheduler.createObserver()
let res2: MockObserver<Int> = scheduler.createObserver()
let res1 = scheduler.createObserver(Int)
let res2 = scheduler.createObserver(Int)
scheduler.scheduleAt(Defaults.created) { ys = transform(xs.asObservable()) }
@ -1179,8 +1179,8 @@ extension ObservableBindingTest {
var subscription1: Disposable! = nil
var subscription2: Disposable! = nil
let res1: MockObserver<Int> = scheduler.createObserver()
let res2: MockObserver<Int> = scheduler.createObserver()
let res1 = scheduler.createObserver(Int)
let res2 = scheduler.createObserver(Int)
scheduler.scheduleAt(Defaults.created) { ys = transform(xs.asObservable()) }
@ -1213,4 +1213,245 @@ extension ObservableBindingTest {
XCTAssertTrue(xs.subscriptions.count == 1 || xs.subscriptions[1] == Subscription(440, 440))
}
}
}
// shareReplay(1)
extension ObservableBindingTest {
func testShareReplayLatestWhileConnected_DeadlockImmediatelly() {
var nEvents = 0
let observable = sequenceOf(0, 1, 2).shareReplayLatestWhileConnected()
_ = observable.subscribeNext { n in
nEvents++
}
XCTAssertEqual(nEvents, 3)
}
func testShareReplayLatestWhileConnected_DeadlockEmpty() {
var nEvents = 0
let observable = empty(Int).shareReplayLatestWhileConnected()
_ = observable.subscribeCompleted { n in
nEvents++
}
XCTAssertEqual(nEvents, 1)
}
func testShareReplayLatestWhileConnected_DeadlockError() {
var nEvents = 0
let observable = failWith(testError, Int.self).shareReplayLatestWhileConnected()
_ = observable.subscribeError { _ in
nEvents++
}
XCTAssertEqual(nEvents, 1)
}
func testShareReplayLatestWhileConnected_DeadlockErrorAfterN() {
var nEvents = 0
let observable = [sequenceOf(0, 1, 2), failWith(testError)].concat().shareReplayLatestWhileConnected()
_ = observable.subscribeError { n in
nEvents++
}
XCTAssertEqual(nEvents, 1)
}
func testShareReplayLatestWhileConnected_Basic() {
let scheduler = TestScheduler(initialClock: 0)
let xs = scheduler.createHotObservable([
next(110, 7),
next(220, 3),
next(280, 4),
next(290, 1),
next(340, 8),
next(360, 5),
next(370, 6),
next(390, 7),
next(410, 13),
next(430, 2),
next(450, 9),
next(520, 11),
next(560, 20),
error(600, testError)
])
var ys: Observable<Int>! = nil
var subscription1: Disposable! = nil
var subscription2: Disposable! = nil
let res1 = scheduler.createObserver(Int)
let res2 = scheduler.createObserver(Int)
scheduler.scheduleAt(Defaults.created) { ys = xs.shareReplayLatestWhileConnected() }
scheduler.scheduleAt(335) { subscription1 = ys.subscribe(res1) }
scheduler.scheduleAt(400) { subscription1.dispose() }
scheduler.scheduleAt(355) { subscription2 = ys.subscribe(res2) }
scheduler.scheduleAt(415) { subscription2.dispose() }
scheduler.scheduleAt(440) { subscription1 = ys.subscribe(res1) }
scheduler.scheduleAt(455) { subscription1.dispose() }
scheduler.start();
XCTAssertEqual(res1.messages, [
// 1rt batch
next(340, 8),
next(360, 5),
next(370, 6),
next(390, 7),
// 2nd batch
next(450, 9)
])
XCTAssertEqual(res2.messages, [
next(355, 8),
next(360, 5),
next(370, 6),
next(390, 7),
next(410, 13)
])
XCTAssertEqual(xs.subscriptions, [
Subscription(335, 415),
Subscription(440, 455)
])
}
func testShareReplayLatestWhileConnected_Error() {
let scheduler = TestScheduler(initialClock: 0)
let xs = scheduler.createHotObservable([
next(110, 7),
next(220, 3),
next(280, 4),
next(290, 1),
next(340, 8),
next(360, 5),
error(365, testError),
next(370, 6),
next(390, 7),
next(410, 13),
next(430, 2),
next(450, 9),
next(520, 11),
next(560, 20),
])
var ys: Observable<Int>! = nil
var subscription1: Disposable! = nil
var subscription2: Disposable! = nil
let res1 = scheduler.createObserver(Int)
let res2 = scheduler.createObserver(Int)
scheduler.scheduleAt(Defaults.created) { ys = xs.shareReplayLatestWhileConnected() }
scheduler.scheduleAt(335) { subscription1 = ys.subscribe(res1) }
scheduler.scheduleAt(400) { subscription1.dispose() }
scheduler.scheduleAt(355) { subscription2 = ys.subscribe(res2) }
scheduler.scheduleAt(415) { subscription2.dispose() }
scheduler.scheduleAt(440) { subscription1 = ys.subscribe(res1) }
scheduler.scheduleAt(455) { subscription1.dispose() }
scheduler.start();
XCTAssertEqual(res1.messages, [
// 1rt batch
next(340, 8),
next(360, 5),
error(365, testError),
// 2nd batch
next(450, 9),
])
XCTAssertEqual(res2.messages, [
next(355, 8),
next(360, 5),
error(365, testError),
])
XCTAssertEqual(xs.subscriptions, [
Subscription(335, 365),
Subscription(440, 455)
])
}
func testShareReplayLatestWhileConnected_Completed() {
_testIdenticalBehaviorOfShareReplayOptimizedAndComposed { transform in
let scheduler = TestScheduler(initialClock: 0)
let xs = scheduler.createHotObservable([
next(110, 7),
next(220, 3),
next(280, 4),
next(290, 1),
next(340, 8),
next(360, 5),
completed(365),
next(370, 6),
next(390, 7),
next(410, 13),
next(430, 2),
next(450, 9),
next(520, 11),
next(560, 20),
])
var ys: Observable<Int>! = nil
var subscription1: Disposable! = nil
var subscription2: Disposable! = nil
let res1 = scheduler.createObserver(Int)
let res2 = scheduler.createObserver(Int)
scheduler.scheduleAt(Defaults.created) { ys = xs.shareReplayLatestWhileConnected() }
scheduler.scheduleAt(335) { subscription1 = ys.subscribe(res1) }
scheduler.scheduleAt(400) { subscription1.dispose() }
scheduler.scheduleAt(355) { subscription2 = ys.subscribe(res2) }
scheduler.scheduleAt(415) { subscription2.dispose() }
scheduler.scheduleAt(440) { subscription1 = ys.subscribe(res1) }
scheduler.scheduleAt(455) { subscription1.dispose() }
scheduler.start();
XCTAssertEqual(res1.messages, [
// 1rt batch
next(340, 8),
next(360, 5),
completed(365),
// 2nd batch
next(450, 9),
])
XCTAssertEqual(res2.messages, [
next(355, 8),
next(360, 5),
completed(365)
])
XCTAssertEqual(xs.subscriptions, [
Subscription(335, 365),
Subscription(440, 455)
])
}
}
}

View File

@ -58,7 +58,7 @@ extension ObservableCreationTests {
let d = SingleAssignmentDisposable()
let res = createObserver(scheduler) as MockObserver<Int>
let res = scheduler.createObserver(Int)
scheduler.scheduleAt(100) {
d.disposable = just(42, scheduler: scheduler).subscribe { e in