Skip to content

Commit ebc6ec2

Browse files
committed
created TimerCreator which allows to inject a mock timer into ImperativeGestureReactor for testability
1 parent 7e737c2 commit ebc6ec2

File tree

4 files changed

+50
-4
lines changed

4 files changed

+50
-4
lines changed

functional-reactive-intuition/Project/RFP.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
1FD5DC431C69D4B60050B3D9 /* ImperativeGestureReactor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD5DC421C69D4B60050B3D9 /* ImperativeGestureReactor.swift */; };
2121
1FD5DC451C69D60C0050B3D9 /* GestureReactor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD5DC441C69D60C0050B3D9 /* GestureReactor.swift */; };
2222
1FD5DC471C69D7EE0050B3D9 /* ReactiveGestureReactor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD5DC461C69D7EE0050B3D9 /* ReactiveGestureReactor.swift */; };
23+
1FE3E4351C6C782F00804CA2 /* TimerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FE3E4341C6C782F00804CA2 /* TimerProtocol.swift */; };
2324
B48DEEE7DD9FCD9E8F77A13B /* Pods.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AA3577BA56804CC07EC782AF /* Pods.framework */; };
2425
/* End PBXBuildFile section */
2526

@@ -52,6 +53,7 @@
5253
1FD5DC421C69D4B60050B3D9 /* ImperativeGestureReactor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImperativeGestureReactor.swift; sourceTree = "<group>"; };
5354
1FD5DC441C69D60C0050B3D9 /* GestureReactor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GestureReactor.swift; sourceTree = "<group>"; };
5455
1FD5DC461C69D7EE0050B3D9 /* ReactiveGestureReactor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReactiveGestureReactor.swift; sourceTree = "<group>"; };
56+
1FE3E4341C6C782F00804CA2 /* TimerProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TimerProtocol.swift; sourceTree = "<group>"; };
5557
350C6FD680F3FD2ADAEA261D /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = "<group>"; };
5658
AA3577BA56804CC07EC782AF /* Pods.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods.framework; sourceTree = BUILT_PRODUCTS_DIR; };
5759
/* End PBXFileReference section */
@@ -111,6 +113,7 @@
111113
1FD5DC441C69D60C0050B3D9 /* GestureReactor.swift */,
112114
1FD5DC461C69D7EE0050B3D9 /* ReactiveGestureReactor.swift */,
113115
1FB180CB1C6C72EF008BC2D1 /* UIGestureRecognizerProtocol.swift */,
116+
1FE3E4341C6C782F00804CA2 /* TimerProtocol.swift */,
114117
);
115118
path = RFP;
116119
sourceTree = "<group>";
@@ -300,6 +303,7 @@
300303
0C153D611C4F001300CBD947 /* Observable+Extension.swift in Sources */,
301304
0CDDAB481C56C21C00D5DA3D /* ReactiveShortViewController.swift in Sources */,
302305
1FD5DC451C69D60C0050B3D9 /* GestureReactor.swift in Sources */,
306+
1FE3E4351C6C782F00804CA2 /* TimerProtocol.swift in Sources */,
303307
0C9FFB351C46625F00FD6C05 /* ReactiveViewController.swift in Sources */,
304308
1FB180CC1C6C72EF008BC2D1 /* UIGestureRecognizerProtocol.swift in Sources */,
305309
);

functional-reactive-intuition/Project/RFP/ImperativeGestureReactor.swift

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,18 @@ import UIKit
66

77
var delegate: GestureReactorDelegate?
88

9+
var timerCreator: TimerCreator
10+
911
var panPresent = false
1012
var pinchPresent = false
11-
var gestureTimer: NSTimer?
13+
var gestureTimer: TimerType?
1214
var secondsLeft = 3
1315

16+
init(timerCreator: TimerCreator) {
17+
self.timerCreator = timerCreator
18+
super.init()
19+
}
20+
1421
func handlePan(panGesture: UIPanGestureRecognizerType) {
1522
if panGesture.state == .Began && self.panPresent == false {
1623
self.panPresent = true
@@ -34,7 +41,9 @@ import UIKit
3441
func checkIfBothGesturesPresent() {
3542
if self.pinchPresent == true && self.panPresent == true && self.gestureTimer == nil {
3643
self.secondsLeft = 3
37-
self.gestureTimer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "tick:", userInfo: nil, repeats: true)
44+
self.gestureTimer = timerCreator(interval: 1, repeats: true, onTick: { [weak self] sender in
45+
self?.tick(sender)
46+
})
3847
delegate?.didStart()
3948
}
4049
}
@@ -47,7 +56,7 @@ import UIKit
4756
}
4857
}
4958

50-
func tick(timer: NSTimer) {
59+
func tick(timer: TimerType) {
5160
if self.secondsLeft <= 0 {
5261
self.stopTimerIfNeeded()
5362
return

functional-reactive-intuition/Project/RFP/ImperativeViewController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import UIKit
1010

1111
class ImperativeViewController: UIViewController, UIGestureRecognizerDelegate, GestureReactorDelegate {
1212

13-
var gestureReactor: GestureReactor = ImperativeGestureReactor()
13+
var gestureReactor: GestureReactor = ImperativeGestureReactor(timerCreator: { interval, repeats, onTick in Timer(interval: interval, repeats: repeats, onTick: onTick) })
1414

1515
override func viewDidLoad() {
1616
super.viewDidLoad()
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import Foundation
2+
3+
4+
typealias TimerCreator = (interval: NSTimeInterval, repeats: Bool, onTick: TimerTicker) -> TimerType
5+
typealias TimerTicker = (sender: TimerType) -> Void
6+
7+
8+
protocol TimerType {
9+
10+
func invalidate()
11+
12+
}
13+
14+
@objc class Timer: NSObject, TimerType {
15+
16+
private var timer: NSTimer?
17+
private let onTick: TimerTicker
18+
19+
init(interval: NSTimeInterval, repeats: Bool, onTick: TimerTicker) {
20+
self.onTick = onTick
21+
super.init()
22+
timer = NSTimer.scheduledTimerWithTimeInterval(interval, target: self, selector: "tick", userInfo: nil, repeats: repeats)
23+
}
24+
25+
func tick() {
26+
onTick(sender: self)
27+
}
28+
29+
func invalidate() {
30+
timer?.invalidate()
31+
}
32+
33+
}

0 commit comments

Comments
 (0)