| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289 |
- //
- // SchedulerSpec.swift
- // ReactiveCocoa
- //
- // Created by Justin Spahr-Summers on 2014-07-13.
- // Copyright (c) 2014 GitHub. All rights reserved.
- //
- import Foundation
- import Nimble
- import Quick
- @testable
- import ReactiveCocoa
- class SchedulerSpec: QuickSpec {
- override func spec() {
- describe("ImmediateScheduler") {
- it("should run enqueued actions immediately") {
- var didRun = false
- ImmediateScheduler().schedule {
- didRun = true
- }
- expect(didRun) == true
- }
- }
- describe("UIScheduler") {
- func dispatchSyncInBackground(action: () -> Void) {
- let group = dispatch_group_create()
- dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), action)
- dispatch_group_wait(group, DISPATCH_TIME_FOREVER)
- }
- it("should run actions immediately when on the main thread") {
- let scheduler = UIScheduler()
- var values: [Int] = []
- expect(NSThread.isMainThread()) == true
- scheduler.schedule {
- values.append(0)
- }
- expect(values) == [ 0 ]
- scheduler.schedule {
- values.append(1)
- }
- scheduler.schedule {
- values.append(2)
- }
- expect(values) == [ 0, 1, 2 ]
- }
- it("should enqueue actions scheduled from the background") {
- let scheduler = UIScheduler()
- var values: [Int] = []
- dispatchSyncInBackground {
- scheduler.schedule {
- expect(NSThread.isMainThread()) == true
- values.append(0)
- }
- return
- }
- expect(values) == []
- expect(values).toEventually(equal([ 0 ]))
- dispatchSyncInBackground {
- scheduler.schedule {
- expect(NSThread.isMainThread()) == true
- values.append(1)
- }
- scheduler.schedule {
- expect(NSThread.isMainThread()) == true
- values.append(2)
- }
- return
- }
- expect(values) == [ 0 ]
- expect(values).toEventually(equal([ 0, 1, 2 ]))
- }
- it("should run actions enqueued from the main thread after those from the background") {
- let scheduler = UIScheduler()
- var values: [Int] = []
- dispatchSyncInBackground {
- scheduler.schedule {
- expect(NSThread.isMainThread()) == true
- values.append(0)
- }
- return
- }
- scheduler.schedule {
- expect(NSThread.isMainThread()) == true
- values.append(1)
- }
- scheduler.schedule {
- expect(NSThread.isMainThread()) == true
- values.append(2)
- }
- expect(values) == []
- expect(values).toEventually(equal([ 0, 1, 2 ]))
- }
- }
- describe("QueueScheduler") {
- it("should run enqueued actions on a global queue") {
- var didRun = false
- let scheduler: QueueScheduler
- if #available(OSX 10.10, *) {
- scheduler = QueueScheduler(qos: QOS_CLASS_DEFAULT)
- } else {
- scheduler = QueueScheduler(queue: dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0))
- }
- scheduler.schedule {
- didRun = true
- expect(NSThread.isMainThread()) == false
- }
- expect{didRun}.toEventually(beTruthy())
- }
- describe("on a given queue") {
- var scheduler: QueueScheduler!
- beforeEach {
- if #available(OSX 10.10, *) {
- scheduler = QueueScheduler(qos: QOS_CLASS_DEFAULT)
- } else {
- scheduler = QueueScheduler(queue: dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0))
- }
- dispatch_suspend(scheduler.queue)
- }
- it("should run enqueued actions serially on the given queue") {
- var value = 0
- for _ in 0..<5 {
- scheduler.schedule {
- expect(NSThread.isMainThread()) == false
- value += 1
- }
- }
- expect(value) == 0
- dispatch_resume(scheduler.queue)
- expect{value}.toEventually(equal(5))
- }
- it("should run enqueued actions after a given date") {
- var didRun = false
- scheduler.scheduleAfter(NSDate()) {
- didRun = true
- expect(NSThread.isMainThread()) == false
- }
- expect(didRun) == false
- dispatch_resume(scheduler.queue)
- expect{didRun}.toEventually(beTruthy())
- }
- it("should repeatedly run actions after a given date") {
- let disposable = SerialDisposable()
- var count = 0
- let timesToRun = 3
- disposable.innerDisposable = scheduler.scheduleAfter(NSDate(), repeatingEvery: 0.01, withLeeway: 0) {
- expect(NSThread.isMainThread()) == false
- count += 1
- if count == timesToRun {
- disposable.dispose()
- }
- }
- expect(count) == 0
- dispatch_resume(scheduler.queue)
- expect{count}.toEventually(equal(timesToRun))
- }
- }
- }
- describe("TestScheduler") {
- var scheduler: TestScheduler!
- var startDate: NSDate!
- // How much dates are allowed to differ when they should be "equal."
- let dateComparisonDelta = 0.00001
- beforeEach {
- startDate = NSDate()
- scheduler = TestScheduler(startDate: startDate)
- expect(scheduler.currentDate) == startDate
- }
- it("should run immediately enqueued actions upon advancement") {
- var string = ""
- scheduler.schedule {
- string += "foo"
- expect(NSThread.isMainThread()) == true
- }
- scheduler.schedule {
- string += "bar"
- expect(NSThread.isMainThread()) == true
- }
- expect(string) == ""
- scheduler.advance()
- expect(scheduler.currentDate).to(beCloseTo(startDate))
- expect(string) == "foobar"
- }
- it("should run actions when advanced past the target date") {
- var string = ""
- scheduler.scheduleAfter(15) { [weak scheduler] in
- string += "bar"
- expect(NSThread.isMainThread()) == true
- expect(scheduler?.currentDate).to(beCloseTo(startDate.dateByAddingTimeInterval(15), within: dateComparisonDelta))
- }
- scheduler.scheduleAfter(5) { [weak scheduler] in
- string += "foo"
- expect(NSThread.isMainThread()) == true
- expect(scheduler?.currentDate).to(beCloseTo(startDate.dateByAddingTimeInterval(5), within: dateComparisonDelta))
- }
- expect(string) == ""
- scheduler.advanceByInterval(10)
- expect(scheduler.currentDate).to(beCloseTo(startDate.dateByAddingTimeInterval(10), within: dateComparisonDelta))
- expect(string) == "foo"
- scheduler.advanceByInterval(10)
- expect(scheduler.currentDate).to(beCloseTo(startDate.dateByAddingTimeInterval(20), within: dateComparisonDelta))
- expect(string) == "foobar"
- }
- it("should run all remaining actions in order") {
- var string = ""
- scheduler.scheduleAfter(15) {
- string += "bar"
- expect(NSThread.isMainThread()) == true
- }
- scheduler.scheduleAfter(5) {
- string += "foo"
- expect(NSThread.isMainThread()) == true
- }
- scheduler.schedule {
- string += "fuzzbuzz"
- expect(NSThread.isMainThread()) == true
- }
- expect(string) == ""
- scheduler.run()
- expect(scheduler.currentDate) == NSDate.distantFuture()
- expect(string) == "fuzzbuzzfoobar"
- }
- }
- }
- }
|