From 388ebac8cd88591cbf579a0adbc920d21cfaa8d4 Mon Sep 17 00:00:00 2001 From: Krunoslav Zaher Date: Sun, 27 Dec 2015 16:21:53 +0100 Subject: [PATCH] Deprecates `MainThreadScheduler.sharedInstance` in favor of `MainThreadScheduler.instance`. Adds unit tests for `CurrentThreadScheduler` and `MainThreadScheduler`. --- RxSwift/Schedulers/MainScheduler.swift | 6 + Tests/RxCocoaTests/Driver+Test.swift | 6 +- .../Tests/CurrentThreadSchedulerTest.swift | 102 ++++++++++++++++ .../Tests/MainSchedulerTests.swift | 109 ++++++++++++++++++ .../Tests/Observable+CreationTest.swift | 2 +- Tests/Tests.xcodeproj/project.pbxproj | 16 +++ 6 files changed, 237 insertions(+), 4 deletions(-) create mode 100644 Tests/RxSwiftTests/Tests/CurrentThreadSchedulerTest.swift create mode 100644 Tests/RxSwiftTests/Tests/MainSchedulerTests.swift diff --git a/RxSwift/Schedulers/MainScheduler.swift b/RxSwift/Schedulers/MainScheduler.swift index 70350475..1597650a 100644 --- a/RxSwift/Schedulers/MainScheduler.swift +++ b/RxSwift/Schedulers/MainScheduler.swift @@ -32,8 +32,14 @@ public final class MainScheduler : SerialDispatchQueueScheduler { /** Singleton instance of `MainScheduler` */ + @available(*, deprecated=2.0.0, message="Please use `MainScheduler.instance`") public static let sharedInstance = MainScheduler() + /** + Singleton instance of `MainScheduler` + */ + public static let instance = MainScheduler() + /** In case this method is called on a background thread it will throw an exception. */ diff --git a/Tests/RxCocoaTests/Driver+Test.swift b/Tests/RxCocoaTests/Driver+Test.swift index 650cb1eb..62ca99ef 100644 --- a/Tests/RxCocoaTests/Driver+Test.swift +++ b/Tests/RxCocoaTests/Driver+Test.swift @@ -63,7 +63,7 @@ extension DriverTest { // Subscription should be made on main scheduler // so this will make sure execution is continued after // subscription because of serial nature of main scheduler. - MainScheduler.sharedInstance.schedule(()) { _ in + MainScheduler.instance.schedule(()) { _ in subscribeFinished.fulfill() return NopDisposable.instance } @@ -671,7 +671,7 @@ extension DriverTest { extension DriverTest { func testAsDriver_debounce() { let hotObservable = BackgroundThreadPrimitiveHotObservable() - let driver = hotObservable.asDriver(onErrorJustReturn: -1).debounce(0.0, scheduler: MainScheduler.sharedInstance) + let driver = hotObservable.asDriver(onErrorJustReturn: -1).debounce(0.0, scheduler: MainScheduler.instance) let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) { XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable]) @@ -686,7 +686,7 @@ extension DriverTest { func testAsDriver_throttle() { let hotObservable = BackgroundThreadPrimitiveHotObservable() - let driver = hotObservable.asDriver(onErrorJustReturn: -1).throttle(0.0, scheduler: MainScheduler.sharedInstance) + let driver = hotObservable.asDriver(onErrorJustReturn: -1).throttle(0.0, scheduler: MainScheduler.instance) let results = subscribeTwiceOnBackgroundSchedulerAndOnlyOneSubscription(driver) { XCTAssertTrue(hotObservable.subscriptions == [SubscribedToHotObservable]) diff --git a/Tests/RxSwiftTests/Tests/CurrentThreadSchedulerTest.swift b/Tests/RxSwiftTests/Tests/CurrentThreadSchedulerTest.swift new file mode 100644 index 00000000..b609377b --- /dev/null +++ b/Tests/RxSwiftTests/Tests/CurrentThreadSchedulerTest.swift @@ -0,0 +1,102 @@ +// +// CurrentThreadSchedulerTest.swift +// Tests +// +// Created by Krunoslav Zaher on 12/27/15. +// +// + +import Foundation +import RxSwift +import XCTest + +class CurrentThreadSchedulerTest : RxTest { + +} + +extension CurrentThreadSchedulerTest { + func testCurrentThreadScheduler_scheduleRequired() { + + XCTAssertTrue(CurrentThreadScheduler.isScheduleRequired) + + var executed = false + _ = CurrentThreadScheduler.instance.schedule(()) { s in + executed = true + XCTAssertTrue(!CurrentThreadScheduler.isScheduleRequired) + return NopDisposable.instance + } + + XCTAssertTrue(executed) + } + + func testCurrentThreadScheduler_basicScenario() { + + XCTAssertTrue(CurrentThreadScheduler.isScheduleRequired) + + var messages = [Int]() + _ = CurrentThreadScheduler.instance.schedule(()) { s in + messages.append(1) + CurrentThreadScheduler.instance.schedule(()) { s in + messages.append(3) + CurrentThreadScheduler.instance.schedule(()) { + messages.append(5) + return NopDisposable.instance + } + messages.append(4) + return NopDisposable.instance + } + messages.append(2) + return NopDisposable.instance + } + + XCTAssertEqual(messages, [1, 2, 3, 4, 5]) + } + + func testCurrentThreadScheduler_disposing1() { + + XCTAssertTrue(CurrentThreadScheduler.isScheduleRequired) + + var messages = [Int]() + _ = CurrentThreadScheduler.instance.schedule(()) { s in + messages.append(1) + let disposable = CurrentThreadScheduler.instance.schedule(()) { s in + messages.append(3) + let disposable = CurrentThreadScheduler.instance.schedule(()) { + messages.append(5) + return NopDisposable.instance + } + disposable.dispose() + messages.append(4) + return disposable + } + messages.append(2) + return disposable + } + + XCTAssertEqual(messages, [1, 2, 3, 4]) + } + + func testCurrentThreadScheduler_disposing2() { + + XCTAssertTrue(CurrentThreadScheduler.isScheduleRequired) + + var messages = [Int]() + _ = CurrentThreadScheduler.instance.schedule(()) { s in + messages.append(1) + let disposable = CurrentThreadScheduler.instance.schedule(()) { s in + messages.append(3) + let disposable = CurrentThreadScheduler.instance.schedule(()) { + messages.append(5) + return NopDisposable.instance + } + messages.append(4) + return disposable + } + disposable.dispose() + messages.append(2) + return disposable + } + + XCTAssertEqual(messages, [1, 2]) + } +} \ No newline at end of file diff --git a/Tests/RxSwiftTests/Tests/MainSchedulerTests.swift b/Tests/RxSwiftTests/Tests/MainSchedulerTests.swift new file mode 100644 index 00000000..9db06822 --- /dev/null +++ b/Tests/RxSwiftTests/Tests/MainSchedulerTests.swift @@ -0,0 +1,109 @@ +// +// MainSchedulerTests.swift +// Tests +// +// Created by Krunoslav Zaher on 12/27/15. +// +// + +import Foundation + +import RxSwift +import XCTest + +class MainSchedulerTest : RxTest { + +} + +extension MainSchedulerTest { + func runRunLoop() { + for _ in 0 ..< 10 { + let currentRunLoop = NSRunLoop.currentRunLoop().getCFRunLoop() + + dispatch_async(dispatch_get_main_queue()) { + CFRunLoopStop(currentRunLoop) + } + + CFRunLoopWakeUp(currentRunLoop) + CFRunLoopRunInMode(NSDefaultRunLoopMode, 1, false) + XCTAssertTrue(currentRunLoop === CFRunLoopGetCurrent()) + } + } +} + +extension MainSchedulerTest { + func testMainScheduler_basicScenario() { + + var messages = [Int]() + var executedImmediatelly = false + _ = MainScheduler.instance.schedule(()) { s in + executedImmediatelly = true + messages.append(1) + MainScheduler.instance.schedule(()) { s in + messages.append(3) + MainScheduler.instance.schedule(()) { + messages.append(5) + return NopDisposable.instance + } + messages.append(4) + return NopDisposable.instance + } + messages.append(2) + return NopDisposable.instance + } + + XCTAssertTrue(executedImmediatelly) + + runRunLoop() + + XCTAssertEqual(messages, [1, 2, 3, 4, 5]) + } + + func testMainScheduler_disposing1() { + + var messages = [Int]() + _ = MainScheduler.instance.schedule(()) { s in + messages.append(1) + let disposable = MainScheduler.instance.schedule(()) { s in + messages.append(3) + let disposable = MainScheduler.instance.schedule(()) { + messages.append(5) + return NopDisposable.instance + } + disposable.dispose() + messages.append(4) + return disposable + } + messages.append(2) + return disposable + } + + runRunLoop() + + XCTAssertEqual(messages, [1, 2, 3, 4]) + } + + func testMainScheduler_disposing2() { + + var messages = [Int]() + _ = MainScheduler.instance.schedule(()) { s in + messages.append(1) + let disposable = MainScheduler.instance.schedule(()) { s in + messages.append(3) + let disposable = MainScheduler.instance.schedule(()) { + messages.append(5) + return NopDisposable.instance + } + messages.append(4) + return disposable + } + disposable.dispose() + messages.append(2) + return disposable + } + + runRunLoop() + + XCTAssertEqual(messages, [1, 2]) + } +} \ No newline at end of file diff --git a/Tests/RxSwiftTests/Tests/Observable+CreationTest.swift b/Tests/RxSwiftTests/Tests/Observable+CreationTest.swift index 4a17e32e..62bc7c96 100644 --- a/Tests/RxSwiftTests/Tests/Observable+CreationTest.swift +++ b/Tests/RxSwiftTests/Tests/Observable+CreationTest.swift @@ -82,7 +82,7 @@ extension ObservableCreationTests { } func testJust_DefaultScheduler() { - let res = try! Observable.just(42, scheduler: MainScheduler.sharedInstance) + let res = try! Observable.just(42, scheduler: MainScheduler.instance) .toBlocking() .toArray() diff --git a/Tests/Tests.xcodeproj/project.pbxproj b/Tests/Tests.xcodeproj/project.pbxproj index 7c59bf87..d6f62f4a 100644 --- a/Tests/Tests.xcodeproj/project.pbxproj +++ b/Tests/Tests.xcodeproj/project.pbxproj @@ -155,6 +155,12 @@ C8F6A1411BEFE04F007DF367 /* SubjectConcurrencyTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8F6A1401BEFE04F007DF367 /* SubjectConcurrencyTest.swift */; }; C8F6A1421BEFE04F007DF367 /* SubjectConcurrencyTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8F6A1401BEFE04F007DF367 /* SubjectConcurrencyTest.swift */; }; C8F6A1431BEFE04F007DF367 /* SubjectConcurrencyTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8F6A1401BEFE04F007DF367 /* SubjectConcurrencyTest.swift */; }; + C8FA890B1C302C5000CD3A17 /* CurrentThreadSchedulerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8FA890A1C302C5000CD3A17 /* CurrentThreadSchedulerTest.swift */; }; + C8FA890C1C302C5000CD3A17 /* CurrentThreadSchedulerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8FA890A1C302C5000CD3A17 /* CurrentThreadSchedulerTest.swift */; }; + C8FA890D1C302C5000CD3A17 /* CurrentThreadSchedulerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8FA890A1C302C5000CD3A17 /* CurrentThreadSchedulerTest.swift */; }; + C8FA890F1C302F0F00CD3A17 /* MainSchedulerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8FA890E1C302F0F00CD3A17 /* MainSchedulerTests.swift */; }; + C8FA89101C302F0F00CD3A17 /* MainSchedulerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8FA890E1C302F0F00CD3A17 /* MainSchedulerTests.swift */; }; + C8FA89111C302F0F00CD3A17 /* MainSchedulerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8FA890E1C302F0F00CD3A17 /* MainSchedulerTests.swift */; }; C8FDC5F81B2B5B7E0065F8D9 /* ElementIndexPair.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8FDC5F71B2B5B7E0065F8D9 /* ElementIndexPair.swift */; }; C8FDC5F91B2B5B7E0065F8D9 /* ElementIndexPair.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8FDC5F71B2B5B7E0065F8D9 /* ElementIndexPair.swift */; }; D203C4EB1BB9C22800D02D00 /* NSNotificationCenterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C811082B1AF50E2A001C13E4 /* NSNotificationCenterTests.swift */; }; @@ -271,6 +277,8 @@ C8E9D2C01BD4525B0079D0DB /* Control+RxTests+Cocoa.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Control+RxTests+Cocoa.swift"; sourceTree = ""; }; C8EA2D361BD02E1900FB22AC /* EquatableArray.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EquatableArray.swift; sourceTree = ""; }; C8F6A1401BEFE04F007DF367 /* SubjectConcurrencyTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SubjectConcurrencyTest.swift; sourceTree = ""; }; + C8FA890A1C302C5000CD3A17 /* CurrentThreadSchedulerTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CurrentThreadSchedulerTest.swift; sourceTree = ""; }; + C8FA890E1C302F0F00CD3A17 /* MainSchedulerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainSchedulerTests.swift; sourceTree = ""; }; C8FDC5F71B2B5B7E0065F8D9 /* ElementIndexPair.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ElementIndexPair.swift; sourceTree = ""; }; D2AF91961BD2EBB900A008C1 /* MockDisposable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockDisposable.swift; sourceTree = ""; }; D2EBEB491BB9B7AE003A27DC /* AllTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AllTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -462,6 +470,8 @@ C69B64FF1BA88FAC00A7FA73 /* ObserverTests.swift */, C89CDB951BCDA1F1002063D9 /* Observable+SubscriptionTest.swift */, C8F6A1401BEFE04F007DF367 /* SubjectConcurrencyTest.swift */, + C8FA890A1C302C5000CD3A17 /* CurrentThreadSchedulerTest.swift */, + C8FA890E1C302F0F00CD3A17 /* MainSchedulerTests.swift */, ); path = Tests; sourceTree = ""; @@ -676,7 +686,9 @@ C8B605EC1B6260A10044410E /* AnonymousObservable+Test.swift in Sources */, C88FA4F91C25BF6A00CCFEA4 /* RxMutableBox.swift in Sources */, C8EA2D371BD02E1900FB22AC /* EquatableArray.swift in Sources */, + C8FA890B1C302C5000CD3A17 /* CurrentThreadSchedulerTest.swift in Sources */, C811085D1AF50E2A001C13E4 /* AssumptionsTest.swift in Sources */, + C8FA890F1C302F0F00CD3A17 /* MainSchedulerTests.swift in Sources */, C810EEC81C2DE7CF000033CE /* TestErrors.swift in Sources */, C81108501AF50E2A001C13E4 /* TestConnectableObservable.swift in Sources */, C8C4B4D51C1772D700828BD5 /* RuntimeStateSnapshot.swift in Sources */, @@ -750,7 +762,9 @@ C8F6A1421BEFE04F007DF367 /* SubjectConcurrencyTest.swift in Sources */, C88FA4FA1C25BF6A00CCFEA4 /* RxMutableBox.swift in Sources */, C88BB8AC1B07E64B0064D411 /* AssumptionsTest.swift in Sources */, + C8FA890C1C302C5000CD3A17 /* CurrentThreadSchedulerTest.swift in Sources */, C88BB8AD1B07E64B0064D411 /* TestConnectableObservable.swift in Sources */, + C8FA89101C302F0F00CD3A17 /* MainSchedulerTests.swift in Sources */, C810EEC91C2DE7CF000033CE /* TestErrors.swift in Sources */, C8E3813A1B21B77E008CDC33 /* Observable+Extensions.swift in Sources */, C8C4B4D61C1772D700828BD5 /* RuntimeStateSnapshot.swift in Sources */, @@ -814,7 +828,9 @@ C8EA2D391BD02E1900FB22AC /* EquatableArray.swift in Sources */, C88FA4FB1C25BF6A00CCFEA4 /* RxMutableBox.swift in Sources */, D2EBEB531BB9B7CC003A27DC /* TestConnectableObservable.swift in Sources */, + C8FA890D1C302C5000CD3A17 /* CurrentThreadSchedulerTest.swift in Sources */, D2EBEB571BB9B7CC003A27DC /* Observable.Extensions.swift in Sources */, + C8FA89111C302F0F00CD3A17 /* MainSchedulerTests.swift in Sources */, C810EECA1C2DE7CF000033CE /* TestErrors.swift in Sources */, D2EBEB741BB9B7F9003A27DC /* Observable+StandardSequenceOperatorsTest.swift in Sources */, C8C4B4D71C1772D700828BD5 /* RuntimeStateSnapshot.swift in Sources */,