forked from Thomvis/BrightFutures
-
Notifications
You must be signed in to change notification settings - Fork 0
/
InvalidationTokenTests.swift
130 lines (104 loc) · 4.07 KB
/
InvalidationTokenTests.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//
// InvalidationTokenTests.swift
// BrightFutures
//
// Created by Thomas Visser on 19/01/15.
// Copyright (c) 2015 Thomas Visser. All rights reserved.
//
import XCTest
import BrightFutures
class InvalidationTokenTests: XCTestCase {
func testInvalidationTokenInit() {
let token = InvalidationToken()
XCTAssert(!token.isInvalid, "a token is valid by default")
}
func testInvalidateToken() {
let token = InvalidationToken()
token.invalidate()
XCTAssert(token.isInvalid, "a token should become invalid after invalidating")
}
func testInvalidationTokenFuture() {
let token = InvalidationToken()
XCTAssertNotNil(token.future, "token should have a future")
XCTAssert(!token.future.isCompleted, "token should have a future and not be complete")
token.invalidate()
XCTAssert(token.future.result?.error != nil, "future should have an error")
if let error = token.future.result?.error {
XCTAssert(error == BrightFuturesError<NoError>.InvalidationTokenInvalidated)
}
}
func testCompletionAfterInvalidation() {
let token = InvalidationToken()
let p = Promise<Int, NSError>()
p.future.onSuccess(token.validContext) { val in
XCTAssert(false, "onSuccess should not get called")
}.onFailure(token.validContext) { error in
XCTAssert(false, "onSuccess should not get called")
}
let e = self.expectation()
Queue.global.async {
token.invalidate()
p.success(2)
NSThread.sleepForTimeInterval(0.2); // make sure onSuccess is not called
e.fulfill()
}
self.waitForExpectationsWithTimeout(2, handler: nil)
}
func testNonInvalidatedSucceededFutureOnSuccess() {
let token = InvalidationToken()
let e = self.expectation()
Future<Int, NoError>(value: 3).onSuccess(token.validContext) { val in
XCTAssertEqual(val, 3)
e.fulfill()
}
self.waitForExpectationsWithTimeout(2, handler: nil)
}
func testNonInvalidatedSucceededFutureOnComplete() {
let token = InvalidationToken()
let e = self.expectation()
Future<Int, NoError>(value: 3).onComplete(token.validContext) { res in
XCTAssertEqual(res.value!, 3)
e.fulfill()
}
self.waitForExpectationsWithTimeout(2, handler: nil)
}
func testNonInvalidatedFailedFutureOnFailure() {
let token = InvalidationToken()
let e = self.expectation()
Future<Int, TestError>(error: TestError.JustAnError).onFailure(token.validContext) { err in
XCTAssertEqual(err, TestError.JustAnError)
e.fulfill()
}
self.waitForExpectationsWithTimeout(2, handler: nil)
}
func testStress() {
class Counter {
var i = 0
}
let q = Queue()
var token: InvalidationToken!
let counter = Counter()
for _ in 1...100 {
token = InvalidationToken()
let currentI = counter.i
let e = self.expectation()
future { () -> Bool in
let sleep: NSTimeInterval = NSTimeInterval(arc4random() % 100) / 100000.0
NSThread.sleepForTimeInterval(sleep)
return true
}.onSuccess(token.validContext(q.context)) { _ in
XCTAssert(!token.isInvalid)
XCTAssertEqual(currentI, counter.i, "onSuccess should only get called if the counter did not increment")
}.onComplete(Queue.global.context) { _ in
NSThread.sleepForTimeInterval(0.0001);
e.fulfill()
}
NSThread.sleepForTimeInterval(0.0005)
q.sync {
token.invalidate()
counter.i++
}
}
self.waitForExpectationsWithTimeout(5, handler: nil)
}
}