forked from Thomvis/BrightFutures
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathInvalidationTokenTests.swift
129 lines (104 loc) · 4.08 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
//
// 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.error != nil, "future should have an error")
if let error = token.future.error?.nsError {
XCTAssertEqual(error.domain, BrightFuturesErrorDomain)
XCTAssertEqual(error.code, InvalidationTokenInvalid)
}
}
func testCompletionAfterInvalidation() {
let token = InvalidationToken()
let p = Promise<Int, NSError>()
p.future.onSuccess(token: token) { val in
XCTAssert(false, "onSuccess should not get called")
}.onFailure(token: token) { 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>.succeeded(3).onSuccess(token: token) { val in
XCTAssertEqual(val, 3)
e.fulfill()
}
self.waitForExpectationsWithTimeout(2, handler: nil)
}
func testNonInvalidatedSucceededFutureOnComplete() {
let token = InvalidationToken()
let e = self.expectation()
Future<Int, NoError>.succeeded(3).onComplete(token: token) { 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>.failed(TestError.JustAnError).onFailure(token: token) { err in
XCTAssertEqual(err, TestError.JustAnError)
e.fulfill()
}
self.waitForExpectationsWithTimeout(2, handler: nil)
}
func testStress() {
class Counter {
var i = 0
}
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(context: Queue.global.context, token: token) { _ in
XCTAssert(!token.isInvalid)
XCTAssertEqual(currentI, counter.i, "onSuccess should only get called if the counter did not increment")
}.onComplete(context: Queue.global.context) { _ in
NSThread.sleepForTimeInterval(0.0001);
e.fulfill()
}
NSThread.sleepForTimeInterval(0.0005)
token.context {
counter.i++
token.invalidate()
}
}
self.waitForExpectationsWithTimeout(5, handler: nil)
}
}