@@ -100,3 +100,92 @@ public func AssertNoThrow<T>(
100
100
XCTFail ( " \( message ( ) ) : \( String ( describing: error) ) " , file: file, line: line)
101
101
}
102
102
}
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