Sample iOS code that accompanies this blog post: https://brent.is/writing/nysc-tests
-
-
Save brenthargrave/ebd6324dcfc3a02f6bdfaf4e6aaf3699 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@testable import App | |
import KIF | |
import SwiftDate | |
class ExampleTest: KIFTestCase { | |
func testClassReservation() { | |
// ...login, etc. | |
let tooLateToReserve = klass.reservationsEndAt + 15.minutes | |
timeTravel(to: tooLateToReserve) | |
// ...verify time-sensitive view state using KIF | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
protocol TimeTravel {} | |
extension XCTestCase: TimeTravel { | |
func timeTravel(to time: NSDate) { | |
NotificationCenter.post(.TimeTravel, ["to": time]) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import RxSwift | |
class NotificationCenter { | |
enum NotificationType: String { | |
case TimeTravel | |
} | |
typealias NotificationInfo = [NSObject: AnyObject]? | |
class func post(type: NotificationType, _ info: NotificationInfo = [:]) { | |
NSNotificationCenter.defaultCenter() | |
.postNotificationName(type.rawValue, object: nil, userInfo: info) | |
} | |
class func observe(type: NotificationType) -> Observable<NSNotification> { | |
return | |
NSNotificationCenter.defaultCenter() | |
.rx_notification(type.rawValue) | |
} | |
} | |
class NotificationClosureWrapper<T>: AnyObject { | |
let closure: T | |
init(closure: T) { | |
self.closure = closure | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import RxSwift | |
import SwiftDate | |
struct Time { | |
static var time$: Observable<NSDate> { | |
let mutableTime$: Observable<NSDate> = | |
NotificationCenter.observe(.TimeTravel) | |
.map({ note -> NSDate? in | |
let to: NSDate? = note.userInfo?["to"] as? NSDate | |
return to | |
}) | |
.filterNil() | |
let systemTime$ = | |
Observable<Int>.interval(1.minute, scheduler: MainScheduler.instance) | |
.map { _ in NSDate() } | |
.startWith(NSDate()) | |
let overridableTime$ = | |
systemTime$ | |
.takeUntil(mutableTime$) | |
let time$ = | |
[mutableTime$, overridableTime$] | |
.toObservable() | |
.merge() | |
.shareReplayLatestWhileConnected() | |
return time$ | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class AppDelegate: UIResponder, UIApplicationDelegate { | |
func application( | |
application: UIApplication, | |
didFinishLaunchingWithOptions | |
launchOptions: [NSObject: AnyObject]?) -> Bool { | |
let time$ = Time.time$ | |
let vc = ExampleKlassViewController(time$: time$) | |
self.window = UIWindow(frame: UIScreen.mainScreen().bounds) | |
self.window?.rootViewController = vc | |
self.window?.makeKeyAndVisible() | |
return true | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class KlassDetailViewController: UIViewController { | |
let klass: Klass | |
let time$: Observable<NSDate> | |
init(time$: Observable<NSDate>) { | |
self.time$ = time$ | |
super.init(nibName: nil, bundle: nil) | |
} | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
guard let view = self.view as? KlassDetailView else { return } | |
let klass = // ... | |
let klassDeadline$ = klass.reservationsEndAt$ | |
Observable | |
.combineLatest(klassDeadline$, time$) { ($0, $1) } | |
.subscribeNext { [unowned self] (deadline, time) in | |
view.render(deadline, time) | |
} | |
.addDisposableTo(rx_disposeBag) | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment