Skip to content

Commit 1e8799d

Browse files
authored
Add AssertEqualEventually() and AssertTrueEventually test assertions (#2)
1 parent 4859a53 commit 1e8799d

File tree

2 files changed

+91
-0
lines changed

2 files changed

+91
-0
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ The AsyncExtensions package also inlcudes the AsyncTestExtensions target, which
1111
## AsyncTestExtensions includes
1212

1313
- `AssertEqual()`
14+
- `AssertEqualEventually()`
1415
- `AssertTrue()`
16+
- `AssertTrueEventually()`
1517
- `AssertFalse()`
1618
- `AssertNil()`
1719
- `AssertNotNil()`

Sources/AsyncTestExtensions/Assertions.swift

+89
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,92 @@ public func AssertNoThrow<T>(
100100
XCTFail("\(message()): \(String(describing: error))", file: file, line: line)
101101
}
102102
}
103+
104+
public func AssertEqualEventually<T: Equatable>(
105+
_ expression1: @escaping @autoclosure () async throws -> T,
106+
_ expression2: @escaping @autoclosure () async throws -> T,
107+
_ timeout: TimeInterval = 5,
108+
_ message: @escaping @autoclosure () -> String = "",
109+
file: StaticString = #filePath,
110+
line: UInt = #line
111+
) async {
112+
do {
113+
try await withThrowingTaskGroup(
114+
of: Void.self
115+
) { (group: inout ThrowingTaskGroup<Void, Error>) in
116+
_ = group.addTaskUnlessCancelled {
117+
try await Task.sleep(nanoseconds: UInt64(timeout * Double(NSEC_PER_SEC)))
118+
throw CancellationError()
119+
}
120+
121+
_ = group.addTaskUnlessCancelled {
122+
var expr1 = try await expression1()
123+
var expr2 = try await expression2()
124+
125+
while expr1 != expr2 {
126+
try await Task.sleep(nanoseconds: 10 * NSEC_PER_MSEC)
127+
128+
expr1 = try await expression1()
129+
expr2 = try await expression2()
130+
}
131+
132+
XCTAssertEqual(expr1, expr2, message(), file: file, line: line)
133+
}
134+
135+
_ = try await group.next()
136+
group.cancelAll()
137+
}
138+
} catch is CancellationError {
139+
do {
140+
let expr1 = try await expression1()
141+
let expr2 = try await expression2()
142+
XCTAssertEqual(expr1, expr2, message(), file: file, line: line)
143+
} catch {
144+
XCTFail("\(message()): \(String(describing: error))", file: file, line: line)
145+
}
146+
} catch {
147+
XCTFail("\(message()): \(String(describing: error))", file: file, line: line)
148+
}
149+
}
150+
151+
public func AssertTrueEventually(
152+
_ expression1: @escaping @autoclosure () async throws -> Bool,
153+
_ timeout: TimeInterval = 5,
154+
_ message: @escaping @autoclosure () -> String = "",
155+
file: StaticString = #filePath,
156+
line: UInt = #line
157+
) async {
158+
do {
159+
try await withThrowingTaskGroup(
160+
of: Void.self
161+
) { (group: inout ThrowingTaskGroup<Void, Error>) in
162+
_ = group.addTaskUnlessCancelled {
163+
try await Task.sleep(nanoseconds: UInt64(timeout * Double(NSEC_PER_SEC)))
164+
throw CancellationError()
165+
}
166+
167+
_ = group.addTaskUnlessCancelled {
168+
var expr1 = try await expression1()
169+
170+
while !expr1 {
171+
try await Task.sleep(nanoseconds: 10 * NSEC_PER_MSEC)
172+
expr1 = try await expression1()
173+
}
174+
175+
XCTAssertTrue(expr1, message(), file: file, line: line)
176+
}
177+
178+
_ = try await group.next()
179+
group.cancelAll()
180+
}
181+
} catch is CancellationError {
182+
do {
183+
let expr1 = try await expression1()
184+
XCTAssertTrue(expr1, message(), file: file, line: line)
185+
} catch {
186+
XCTFail("\(message()): \(String(describing: error))", file: file, line: line)
187+
}
188+
} catch {
189+
XCTFail("\(message()): \(String(describing: error))", file: file, line: line)
190+
}
191+
}

0 commit comments

Comments
 (0)