diff --git a/Documentation/Units.md b/Documentation/Units.md index 904474aa..22a504c5 100644 --- a/Documentation/Units.md +++ b/Documentation/Units.md @@ -13,10 +13,12 @@ The purpose of units is to use the Swift compiler static type checking to prove RxCocoa project already contains several units, but the most elaborate one is called `Driver`, so this unit will be used to explain the idea behind units. -`Driver` was named that way because it describes sequences that drive certain parts of the app. Those sequences will usually drive UI bindings, UI event pumps that keep your application responsive but also drive application services, etc. +`Driver` was named that way because it describes sequences that drive certain parts of the app. Those sequences will usually drive UI bindings, UI event pumps that keep your application responsive, but also drive application services, etc. The purpose of `Driver` unit is to ensure the underlying observable sequence has the following properties. * can't fail, all failures are being handled properly * elements are delivered on main thread * sequence computation resources are shared + +TBD... diff --git a/RxCocoa/Common/CocoaUnits/Driver/Driver.swift b/RxCocoa/Common/CocoaUnits/Driver/Driver.swift index c4b11260..a101a020 100644 --- a/RxCocoa/Common/CocoaUnits/Driver/Driver.swift +++ b/RxCocoa/Common/CocoaUnits/Driver/Driver.swift @@ -56,10 +56,10 @@ public struct Driver : DriverConvertibleType { init(raw: Observable) { self._source = raw } - + #if EXPANDABLE_DRIVER public static func createUnsafe(source: O) -> Driver { - return Driver(source.asObservable()) + return Driver(raw: source.asObservable()) } #endif @@ -82,7 +82,7 @@ public struct Drive { - returns: An observable sequence with no elements. */ public static func empty() -> Driver { - return Driver(raw: RxSwift.empty()) + return Driver(raw: RxSwift.empty().subscribeOn(ConcurrentMainScheduler.sharedInstance)) } /** @@ -91,7 +91,7 @@ public struct Drive { - returns: An observable sequence whose observers will never get called. */ public static func never() -> Driver { - return Driver(raw: RxSwift.never()) + return Driver(raw: RxSwift.never().subscribeOn(ConcurrentMainScheduler.sharedInstance)) } /** @@ -101,7 +101,7 @@ public struct Drive { - returns: An observable sequence containing the single specified element. */ public static func just(element: E) -> Driver { - return Driver(raw: RxSwift.just(element)) + return Driver(raw: RxSwift.just(element).subscribeOn(ConcurrentMainScheduler.sharedInstance)) } #else @@ -112,7 +112,7 @@ public struct Drive { - returns: An observable sequence with no elements. */ public static func empty() -> Driver { - return Driver(raw: _empty()) + return Driver(raw: _empty().subscribeOn(ConcurrentMainScheduler.sharedInstance)) } /** @@ -121,7 +121,7 @@ public struct Drive { - returns: An observable sequence whose observers will never get called. */ public static func never() -> Driver { - return Driver(raw: _never()) + return Driver(raw: _never().subscribeOn(ConcurrentMainScheduler.sharedInstance)) } /** @@ -131,13 +131,13 @@ public struct Drive { - returns: An observable sequence containing the single specified element. */ public static func just(element: E) -> Driver { - return Driver(raw: _just(element)) + return Driver(raw: _just(element).subscribeOn(ConcurrentMainScheduler.sharedInstance)) } #endif public static func sequenceOf(elements: E ...) -> Driver { - let source = elements.asObservable() + let source = elements.asObservable().subscribeOn(ConcurrentMainScheduler.sharedInstance) return Driver(raw: source) } diff --git a/RxCocoa/Common/CocoaUnits/Driver/ObservableConvertibleType+Driver.swift b/RxCocoa/Common/CocoaUnits/Driver/ObservableConvertibleType+Driver.swift index 95f6e4ba..41abe7de 100644 --- a/RxCocoa/Common/CocoaUnits/Driver/ObservableConvertibleType+Driver.swift +++ b/RxCocoa/Common/CocoaUnits/Driver/ObservableConvertibleType+Driver.swift @@ -21,7 +21,6 @@ extension ObservableConvertibleType { public func asDriver(onErrorJustReturn onErrorJustReturn: E) -> Driver { let source = self .asObservable() - .subscribeOn(ConcurrentMainScheduler.sharedInstance) .observeOn(MainScheduler.sharedInstance) .catchErrorJustReturn(onErrorJustReturn) return Driver(source) @@ -36,7 +35,6 @@ extension ObservableConvertibleType { public func asDriver(onErrorDriveWith onErrorDriveWith: Driver) -> Driver { let source = self .asObservable() - .subscribeOn(ConcurrentMainScheduler.sharedInstance) .observeOn(MainScheduler.sharedInstance) .catchError { _ in onErrorDriveWith.asObservable() @@ -53,7 +51,6 @@ extension ObservableConvertibleType { public func asDriver(onErrorRecover onErrorRecover: (error: ErrorType) -> Driver) -> Driver { let source = self .asObservable() - .subscribeOn(ConcurrentMainScheduler.sharedInstance) .observeOn(MainScheduler.sharedInstance) .catchError { error in onErrorRecover(error: error).asObservable() diff --git a/RxTests/RxSwiftTests/TestImplementations/Mocks/BackgroundThreadPrimitiveHotObservable.swift b/RxTests/RxSwiftTests/TestImplementations/Mocks/BackgroundThreadPrimitiveHotObservable.swift new file mode 100644 index 00000000..9a733e44 --- /dev/null +++ b/RxTests/RxSwiftTests/TestImplementations/Mocks/BackgroundThreadPrimitiveHotObservable.swift @@ -0,0 +1,18 @@ +// +// BackgroundThreadPrimitiveHotObservable.swift +// RxTests +// +// Created by Krunoslav Zaher on 10/19/15. +// +// + +import Foundation +import RxSwift +import XCTest + +class BackgroundThreadPrimitiveHotObservable : PrimitiveHotObservable { + override func subscribe(observer: O) -> Disposable { + XCTAssertTrue(!NSThread.isMainThread()) + return super.subscribe(observer) + } +} \ No newline at end of file diff --git a/RxTests/RxSwiftTests/TestImplementations/Mocks/PrimitiveHotObservable.swift b/RxTests/RxSwiftTests/TestImplementations/Mocks/PrimitiveHotObservable.swift index 5fb9c977..14056f6a 100644 --- a/RxTests/RxSwiftTests/TestImplementations/Mocks/PrimitiveHotObservable.swift +++ b/RxTests/RxSwiftTests/TestImplementations/Mocks/PrimitiveHotObservable.swift @@ -20,6 +20,8 @@ class PrimitiveHotObservable : ObservableType { var subscriptions: [Subscription] var observers: Bag> + + let lock = NSRecursiveLock() init() { self.subscriptions = [] @@ -31,12 +33,18 @@ class PrimitiveHotObservable : ObservableType { } func subscribe(observer: O) -> Disposable { + lock.lock() + defer { lock.unlock() } + let key = observers.insert(AnyObserver(observer)) subscriptions.append(SubscribedToHotObservable) let i = self.subscriptions.count - 1 return AnonymousDisposable { + self.lock.lock() + defer { self.lock.unlock() } + let removed = self.observers.removeKey(key) assert(removed != nil) diff --git a/RxTests/RxSwiftTests/Tests/Driver+Test.swift b/RxTests/RxSwiftTests/Tests/Driver+Test.swift index 5b70203e..afeac06a 100644 --- a/RxTests/RxSwiftTests/Tests/Driver+Test.swift +++ b/RxTests/RxSwiftTests/Tests/Driver+Test.swift @@ -26,7 +26,7 @@ class DriverTest : RxTest { // * it can't error out - it needs to have catch somewhere extension DriverTest { - func subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver: Driver, subscribedOnBackground: () -> ()) -> [R] { + func subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver: Driver, subscribedOnBackground: () -> ()) -> [R] { var firstElements = [R]() var secondElements = [R]() @@ -65,7 +65,6 @@ extension DriverTest { MainScheduler.sharedInstance.schedule(()) { _ in subscribeFinished.fulfill() return NopDisposable.instance - } return NopDisposable.instance @@ -93,10 +92,10 @@ extension DriverTest { // conversions extension DriverTest { func testAsDriver_onErrorJustReturn() { - let hotObservable = MainThreadPrimitiveHotObservable() + let hotObservable = BackgroundThreadPrimitiveHotObservable() let driver = hotObservable.asDriver(onErrorJustReturn: -1) - let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) { + let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) { XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable]) hotObservable.on(.Next(1)) @@ -110,10 +109,10 @@ extension DriverTest { } func testAsDriver_onErrorDriveWith() { - let hotObservable = MainThreadPrimitiveHotObservable() + let hotObservable = BackgroundThreadPrimitiveHotObservable() let driver = hotObservable.asDriver(onErrorDriveWith: Drive.just(-1)) - let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) { + let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) { XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable]) hotObservable.on(.Next(1)) @@ -127,12 +126,12 @@ extension DriverTest { } func testAsDriver_onErrorRecover() { - let hotObservable = MainThreadPrimitiveHotObservable() + let hotObservable = BackgroundThreadPrimitiveHotObservable() let driver = hotObservable.asDriver { e in return Drive.empty() } - let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) { + let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) { XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable]) hotObservable.on(.Next(1)) @@ -149,13 +148,13 @@ extension DriverTest { // map extension DriverTest { func testAsDriver_map() { - let hotObservable = MainThreadPrimitiveHotObservable() + let hotObservable = BackgroundThreadPrimitiveHotObservable() let driver = hotObservable.asDriver(onErrorJustReturn: -1).map { (n: Int) -> Int in XCTAssertTrue(NSThread.isMainThread()) return n + 1 } - let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) { + let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) { XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable]) hotObservable.on(.Next(1)) @@ -173,13 +172,13 @@ extension DriverTest { // filter extension DriverTest { func testAsDriver_filter() { - let hotObservable = MainThreadPrimitiveHotObservable() + let hotObservable = BackgroundThreadPrimitiveHotObservable() let driver = hotObservable.asDriver(onErrorJustReturn: -1).filter { n in XCTAssertTrue(NSThread.isMainThread()) return n % 2 == 0 } - let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) { + let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) { XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable]) hotObservable.on(.Next(1)) @@ -197,13 +196,13 @@ extension DriverTest { // switch latest extension DriverTest { func testAsDriver_switchLatest() { - let hotObservable = MainThreadPrimitiveHotObservable>() + let hotObservable = BackgroundThreadPrimitiveHotObservable>() let hotObservable1 = MainThreadPrimitiveHotObservable() let hotObservable2 = MainThreadPrimitiveHotObservable() let driver = hotObservable.asDriver(onErrorJustReturn: hotObservable1.asDriver(onErrorJustReturn: -1)).switchLatest() - let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) { + let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) { XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable]) hotObservable.on(.Next(hotObservable1.asDriver(onErrorJustReturn: -2))) @@ -236,7 +235,7 @@ extension DriverTest { // doOn extension DriverTest { func testAsDriver_doOn() { - let hotObservable = MainThreadPrimitiveHotObservable() + let hotObservable = BackgroundThreadPrimitiveHotObservable() var events = [Event]() @@ -246,7 +245,7 @@ extension DriverTest { events.append(e) } - let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) { + let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) { XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable]) hotObservable.on(.Next(1)) @@ -265,11 +264,11 @@ extension DriverTest { // distinct until change extension DriverTest { func testAsDriver_distinctUntilChanged1() { - let hotObservable = MainThreadPrimitiveHotObservable() + let hotObservable = BackgroundThreadPrimitiveHotObservable() let driver = hotObservable.asDriver(onErrorJustReturn: -1).distinctUntilChanged() - let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) { + let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) { XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable]) hotObservable.on(.Next(1)) @@ -284,11 +283,11 @@ extension DriverTest { } func testAsDriver_distinctUntilChanged2() { - let hotObservable = MainThreadPrimitiveHotObservable() + let hotObservable = BackgroundThreadPrimitiveHotObservable() let driver = hotObservable.asDriver(onErrorJustReturn: -1).distinctUntilChanged({ $0 }) - let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) { + let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) { XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable]) hotObservable.on(.Next(1)) @@ -303,11 +302,11 @@ extension DriverTest { } func testAsDriver_distinctUntilChanged3() { - let hotObservable = MainThreadPrimitiveHotObservable() + let hotObservable = BackgroundThreadPrimitiveHotObservable() let driver = hotObservable.asDriver(onErrorJustReturn: -1).distinctUntilChanged({ $0 == $1 }) - let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) { + let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) { XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable]) hotObservable.on(.Next(1)) @@ -323,11 +322,11 @@ extension DriverTest { func testAsDriver_distinctUntilChanged4() { - let hotObservable = MainThreadPrimitiveHotObservable() + let hotObservable = BackgroundThreadPrimitiveHotObservable() let driver = hotObservable.asDriver(onErrorJustReturn: -1).distinctUntilChanged({ $0 }) { $0 == $1 } - let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) { + let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) { XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable]) hotObservable.on(.Next(1)) @@ -346,13 +345,13 @@ extension DriverTest { // flat map extension DriverTest { func testAsDriver_flatMap() { - let hotObservable = MainThreadPrimitiveHotObservable() + let hotObservable = BackgroundThreadPrimitiveHotObservable() let driver = hotObservable.asDriver(onErrorJustReturn: -1).flatMap { (n: Int) -> Driver in XCTAssertTrue(NSThread.isMainThread()) return Drive.just(n + 1) } - let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) { + let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) { XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable]) hotObservable.on(.Next(1)) @@ -370,13 +369,13 @@ extension DriverTest { // merge extension DriverTest { func testAsDriver_merge() { - let hotObservable = MainThreadPrimitiveHotObservable() + let hotObservable = BackgroundThreadPrimitiveHotObservable() let driver = hotObservable.asDriver(onErrorJustReturn: -1).map { (n: Int) -> Driver in XCTAssertTrue(NSThread.isMainThread()) return Drive.just(n + 1) }.merge() - let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) { + let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) { XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable]) hotObservable.on(.Next(1)) @@ -390,13 +389,13 @@ extension DriverTest { } func testAsDriver_merge2() { - let hotObservable = MainThreadPrimitiveHotObservable() + let hotObservable = BackgroundThreadPrimitiveHotObservable() let driver = hotObservable.asDriver(onErrorJustReturn: -1).map { (n: Int) -> Driver in XCTAssertTrue(NSThread.isMainThread()) return Drive.just(n + 1) }.merge(maxConcurrent: 1) - let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) { + let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) { XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable]) hotObservable.on(.Next(1)) @@ -413,10 +412,10 @@ extension DriverTest { // debounce extension DriverTest { func testAsDriver_debounce() { - let hotObservable = MainThreadPrimitiveHotObservable() + let hotObservable = BackgroundThreadPrimitiveHotObservable() let driver = hotObservable.asDriver(onErrorJustReturn: -1).debounce(0.0, MainScheduler.sharedInstance) - let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) { + let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) { XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable]) hotObservable.on(.Error(testError)) @@ -428,10 +427,10 @@ extension DriverTest { } func testAsDriver_throttle() { - let hotObservable = MainThreadPrimitiveHotObservable() + let hotObservable = BackgroundThreadPrimitiveHotObservable() let driver = hotObservable.asDriver(onErrorJustReturn: -1).throttle(0.0, MainScheduler.sharedInstance) - let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) { + let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) { XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable]) hotObservable.on(.Next(1)) @@ -449,13 +448,13 @@ extension DriverTest { // scan extension DriverTest { func testAsDriver_scan() { - let hotObservable = MainThreadPrimitiveHotObservable() + let hotObservable = BackgroundThreadPrimitiveHotObservable() let driver = hotObservable.asDriver(onErrorJustReturn: -1).scan(0) { (a: Int, n: Int) -> Int in XCTAssertTrue(NSThread.isMainThread()) return a + n } - let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) { + let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) { XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable]) hotObservable.on(.Next(1)) @@ -473,12 +472,12 @@ extension DriverTest { // concat extension DriverTest { func testAsDriver_concat() { - let hotObservable1 = MainThreadPrimitiveHotObservable() + let hotObservable1 = BackgroundThreadPrimitiveHotObservable() let hotObservable2 = MainThreadPrimitiveHotObservable() let driver = [hotObservable1.asDriver(onErrorJustReturn: -1), hotObservable2.asDriver(onErrorJustReturn: -2)].concat() - let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) { + let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) { XCTAssertTrue(hotObservable1.subscriptions == [SubscribedToHotObservable]) hotObservable1.on(.Next(1)) @@ -502,12 +501,12 @@ extension DriverTest { // combine latest extension DriverTest { func testAsDriver_combineLatest_array() { - let hotObservable1 = MainThreadPrimitiveHotObservable() - let hotObservable2 = MainThreadPrimitiveHotObservable() + let hotObservable1 = BackgroundThreadPrimitiveHotObservable() + let hotObservable2 = BackgroundThreadPrimitiveHotObservable() let driver = [hotObservable1.asDriver(onErrorJustReturn: -1), hotObservable2.asDriver(onErrorJustReturn: -2)].combineLatest { a in a.reduce(0, combine: +) } - let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) { + let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) { XCTAssertTrue(hotObservable1.subscriptions == [SubscribedToHotObservable]) XCTAssertTrue(hotObservable2.subscriptions == [SubscribedToHotObservable]) @@ -528,12 +527,12 @@ extension DriverTest { } func testAsDriver_combineLatest() { - let hotObservable1 = MainThreadPrimitiveHotObservable() - let hotObservable2 = MainThreadPrimitiveHotObservable() + let hotObservable1 = BackgroundThreadPrimitiveHotObservable() + let hotObservable2 = BackgroundThreadPrimitiveHotObservable() let driver = combineLatest(hotObservable1.asDriver(onErrorJustReturn: -1), hotObservable2.asDriver(onErrorJustReturn: -2), resultSelector: +) - let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) { + let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) { XCTAssertTrue(hotObservable1.subscriptions == [SubscribedToHotObservable]) XCTAssertTrue(hotObservable2.subscriptions == [SubscribedToHotObservable]) @@ -557,12 +556,12 @@ extension DriverTest { // zip extension DriverTest { func testAsDriver_zip_array() { - let hotObservable1 = MainThreadPrimitiveHotObservable() - let hotObservable2 = MainThreadPrimitiveHotObservable() + let hotObservable1 = BackgroundThreadPrimitiveHotObservable() + let hotObservable2 = BackgroundThreadPrimitiveHotObservable() let driver = [hotObservable1.asDriver(onErrorJustReturn: -1), hotObservable2.asDriver(onErrorJustReturn: -2)].zip { a in a.reduce(0, combine: +) } - let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) { + let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) { XCTAssertTrue(hotObservable1.subscriptions == [SubscribedToHotObservable]) XCTAssertTrue(hotObservable2.subscriptions == [SubscribedToHotObservable]) @@ -583,12 +582,12 @@ extension DriverTest { } func testAsDriver_zip() { - let hotObservable1 = MainThreadPrimitiveHotObservable() - let hotObservable2 = MainThreadPrimitiveHotObservable() + let hotObservable1 = BackgroundThreadPrimitiveHotObservable() + let hotObservable2 = BackgroundThreadPrimitiveHotObservable() let driver = zip(hotObservable1.asDriver(onErrorJustReturn: -1), hotObservable2.asDriver(onErrorJustReturn: -2), resultSelector: +) - let results = subscribeTwiceOnBackgroundSchedulerAndExpectResultsOnMainScheduler(driver) { + let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) { XCTAssertTrue(hotObservable1.subscriptions == [SubscribedToHotObservable]) XCTAssertTrue(hotObservable2.subscriptions == [SubscribedToHotObservable]) diff --git a/RxTests/RxTests.xcodeproj/project.pbxproj b/RxTests/RxTests.xcodeproj/project.pbxproj index 8fe89feb..0feddd04 100644 --- a/RxTests/RxTests.xcodeproj/project.pbxproj +++ b/RxTests/RxTests.xcodeproj/project.pbxproj @@ -87,6 +87,9 @@ C88BB8AC1B07E64B0064D411 /* AssumptionsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C81108401AF50E2A001C13E4 /* AssumptionsTest.swift */; }; C88BB8AD1B07E64B0064D411 /* TestConnectableObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C81108311AF50E2A001C13E4 /* TestConnectableObservable.swift */; }; C88BB8AE1B07E64B0064D411 /* VariableTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C814CEA21AF5622600E98087 /* VariableTest.swift */; }; + C8941BD91BD4F58C00A0E874 /* BackgroundThreadPrimitiveHotObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8941BD81BD4F58C00A0E874 /* BackgroundThreadPrimitiveHotObservable.swift */; }; + C8941BDA1BD4F58C00A0E874 /* BackgroundThreadPrimitiveHotObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8941BD81BD4F58C00A0E874 /* BackgroundThreadPrimitiveHotObservable.swift */; }; + C8941BDB1BD4F58C00A0E874 /* BackgroundThreadPrimitiveHotObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8941BD81BD4F58C00A0E874 /* BackgroundThreadPrimitiveHotObservable.swift */; }; C897EC3B1B10E000009C2CB0 /* BehaviorSubjectTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C897EC3A1B10E000009C2CB0 /* BehaviorSubjectTest.swift */; }; C897EC3C1B10E000009C2CB0 /* BehaviorSubjectTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C897EC3A1B10E000009C2CB0 /* BehaviorSubjectTest.swift */; }; C897EC4A1B1123DA009C2CB0 /* Observable+MultipleTest+Zip.swift in Sources */ = {isa = PBXBuildFile; fileRef = C897EC491B1123DA009C2CB0 /* Observable+MultipleTest+Zip.swift */; }; @@ -112,10 +115,10 @@ C8E3812B1B2083C2008CDC33 /* PrimitiveMockObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E3812A1B2083C2008CDC33 /* PrimitiveMockObserver.swift */; }; C8E3812C1B2083C2008CDC33 /* PrimitiveMockObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E3812A1B2083C2008CDC33 /* PrimitiveMockObserver.swift */; }; C8E3813A1B21B77E008CDC33 /* Observable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E381221B2063CC008CDC33 /* Observable+Extensions.swift */; }; - C8E9D2BD1BD422D80079D0DB /* Control+RxTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E9D2BC1BD422D80079D0DB /* Control+RxTests.swift */; settings = {ASSET_TAGS = (); }; }; - C8E9D2BE1BD422D80079D0DB /* Control+RxTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E9D2BC1BD422D80079D0DB /* Control+RxTests.swift */; settings = {ASSET_TAGS = (); }; }; - C8E9D2BF1BD422D80079D0DB /* Control+RxTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E9D2BC1BD422D80079D0DB /* Control+RxTests.swift */; settings = {ASSET_TAGS = (); }; }; - C8E9D2C41BD452650079D0DB /* Control+RxTests+Cocoa.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E9D2C01BD4525B0079D0DB /* Control+RxTests+Cocoa.swift */; settings = {ASSET_TAGS = (); }; }; + C8E9D2BD1BD422D80079D0DB /* Control+RxTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E9D2BC1BD422D80079D0DB /* Control+RxTests.swift */; }; + C8E9D2BE1BD422D80079D0DB /* Control+RxTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E9D2BC1BD422D80079D0DB /* Control+RxTests.swift */; }; + C8E9D2BF1BD422D80079D0DB /* Control+RxTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E9D2BC1BD422D80079D0DB /* Control+RxTests.swift */; }; + C8E9D2C41BD452650079D0DB /* Control+RxTests+Cocoa.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8E9D2C01BD4525B0079D0DB /* Control+RxTests+Cocoa.swift */; }; C8EA2D371BD02E1900FB22AC /* EquatableArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8EA2D361BD02E1900FB22AC /* EquatableArray.swift */; }; C8EA2D381BD02E1900FB22AC /* EquatableArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8EA2D361BD02E1900FB22AC /* EquatableArray.swift */; }; C8EA2D391BD02E1900FB22AC /* EquatableArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8EA2D361BD02E1900FB22AC /* EquatableArray.swift */; }; @@ -221,6 +224,7 @@ C868D10B1BB950D4003D1474 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; C868D1121BB950D4003D1474 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; C88BB8B71B07E64B0064D411 /* RxTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RxTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + C8941BD81BD4F58C00A0E874 /* BackgroundThreadPrimitiveHotObservable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BackgroundThreadPrimitiveHotObservable.swift; sourceTree = ""; }; C897EC3A1B10E000009C2CB0 /* BehaviorSubjectTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BehaviorSubjectTest.swift; sourceTree = ""; }; C897EC461B112070009C2CB0 /* Observable+MultipleTest+Zip.tt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "Observable+MultipleTest+Zip.tt"; sourceTree = ""; }; C897EC491B1123DA009C2CB0 /* Observable+MultipleTest+Zip.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Observable+MultipleTest+Zip.swift"; sourceTree = ""; }; @@ -380,6 +384,7 @@ C8E3812A1B2083C2008CDC33 /* PrimitiveMockObserver.swift */, C80DDEDF1BCEE898006A1832 /* MainThreadPrimitiveHotObservable.swift */, D2AF91961BD2EBB900A008C1 /* MockDisposable.swift */, + C8941BD81BD4F58C00A0E874 /* BackgroundThreadPrimitiveHotObservable.swift */, ); path = Mocks; sourceTree = ""; @@ -583,6 +588,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + C8941BD91BD4F58C00A0E874 /* BackgroundThreadPrimitiveHotObservable.swift in Sources */, C8B787FA1AF55CDE00206D02 /* Observable+ConcurrencyTest.swift in Sources */, C81108691AF50E2A001C13E4 /* RxTest.swift in Sources */, C81108671AF50E2A001C13E4 /* Observable+TimeTest.swift in Sources */, @@ -663,6 +669,7 @@ C88BB8991B07E64B0064D411 /* Observable+BindingTest.swift in Sources */, C88BB89A1B07E64B0064D411 /* NSNotificationCenterTests.swift in Sources */, C88BB89B1B07E64B0064D411 /* Observable+MultipleTest+CombineLatest.swift in Sources */, + C8941BDA1BD4F58C00A0E874 /* BackgroundThreadPrimitiveHotObservable.swift in Sources */, C88BB89C1B07E64B0064D411 /* ConcurrencyTest.swift in Sources */, C88BB89D1B07E64B0064D411 /* TestObserver.swift in Sources */, C88BB89E1B07E64B0064D411 /* VirtualTimeSchedulerBase.swift in Sources */, @@ -709,6 +716,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + C8941BDB1BD4F58C00A0E874 /* BackgroundThreadPrimitiveHotObservable.swift in Sources */, D2EBEB5A1BB9B7CC003A27DC /* PrimitiveHotObservable.swift in Sources */, D2EBEB521BB9B7CC003A27DC /* ColdObservable.swift in Sources */, D2EBEB551BB9B7CC003A27DC /* MockObserver.swift in Sources */,