Skip to content

Commit 4eb0b86

Browse files
committed
Polling Confirmations: Add requirePassesEventually and requireAlwaysPasses
1 parent 3df93b7 commit 4eb0b86

File tree

1 file changed

+87
-7
lines changed

1 file changed

+87
-7
lines changed

proposals/testing/NNNN-polling-confirmations.md

Lines changed: 87 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ await confirmPassesEventually {
6868

6969
### New confirmation functions
7070

71-
We will introduce 4 new members of the confirmation family of functions to the
71+
We will introduce 5 new members of the confirmation family of functions to the
7272
testing library:
7373

7474
```swift
@@ -111,6 +111,47 @@ public func confirmPassesEventually(
111111
_ body: @escaping () async throws -> Bool
112112
) async
113113

114+
/// Require that some expression eventually returns true
115+
///
116+
/// - Parameters:
117+
/// - comment: An optional comment to apply to any issues generated by this
118+
/// function.
119+
/// - maxPollingIterations: The maximum amount of times to attempt polling.
120+
/// If nil, this uses whatever value is specified under the last
121+
/// ``ConfirmPassesEventuallyConfigurationTrait`` added to the test or
122+
/// suite.
123+
/// If no ``ConfirmPassesEventuallyConfigurationTrait`` has been added, then
124+
/// polling will be attempted 1000 times before recording an issue.
125+
/// `maxPollingIterations` must be greater than 0.
126+
/// - pollingInterval: The minimum amount of time to wait between polling
127+
/// attempts.
128+
/// If nil, this uses whatever value is specified under the last
129+
/// ``ConfirmPassesEventuallyConfigurationTrait`` added to the test or suite.
130+
/// If no ``ConfirmPassesEventuallyConfigurationTrait`` has been added, then
131+
/// polling will wait at least 1 millisecond between polling attempts.
132+
/// `pollingInterval` must be greater than 0.
133+
/// - isolation: The actor to which `body` is isolated, if any.
134+
/// - sourceLocation: The source location to whych any recorded issues should
135+
/// be attributed.
136+
/// - body: The function to invoke.
137+
///
138+
/// - Throws: A `PollingFailedError` will be thrown if the expression never
139+
/// returns true.
140+
///
141+
/// Use polling confirmations to check that an event while a test is running in
142+
/// complex scenarios where other forms of confirmation are insufficient. For
143+
/// example, waiting on some state to change that cannot be easily confirmed
144+
/// through other forms of `confirmation`.
145+
@available(macOS 13, iOS 17, watchOS 9, tvOS 17, visionOS 1, *)
146+
public func requirePassesEventually(
147+
_ comment: Comment? = nil,
148+
maxPollingIterations: Int? = nil,
149+
pollingInterval: Duration? = nil,
150+
isolation: isolated (any Actor)? = #isolation,
151+
sourceLocation: SourceLocation = #_sourceLocation,
152+
_ body: @escaping () async throws -> Bool
153+
) async throws
154+
114155
/// Confirm that some expression eventually returns a non-nil value
115156
///
116157
/// - Parameters:
@@ -138,7 +179,7 @@ public func confirmPassesEventually(
138179
/// - Returns: The first non-nil value returned by `body`.
139180
///
140181
/// - Throws: A `PollingFailedError` will be thrown if `body` never returns a
141-
/// non-optional value
182+
/// non-optional value.
142183
///
143184
/// Use polling confirmations to check that an event while a test is running in
144185
/// complex scenarios where other forms of confirmation are insufficient. For
@@ -189,6 +230,45 @@ public func confirmAlwaysPasses(
189230
sourceLocation: SourceLocation = #_sourceLocation,
190231
_ body: @escaping () async throws -> Bool
191232
) async
233+
234+
/// Require that some expression always returns true
235+
///
236+
/// - Parameters:
237+
/// - comment: An optional comment to apply to any issues generated by this
238+
/// function.
239+
/// - maxPollingIterations: The maximum amount of times to attempt polling.
240+
/// If nil, this uses whatever value is specified under the last
241+
/// ``ConfirmAlwaysPassesConfigurationTrait`` added to the test or suite.
242+
/// If no ``ConfirmAlwaysPassesConfigurationTrait`` has been added, then
243+
/// polling will be attempted 1000 times before recording an issue.
244+
/// `maxPollingIterations` must be greater than 0.
245+
/// - pollingInterval: The minimum amount of time to wait between polling
246+
/// attempts.
247+
/// If nil, this uses whatever value is specified under the last
248+
/// ``ConfirmAlwaysPassesConfigurationTrait`` added to the test or suite.
249+
/// If no ``ConfirmAlwaysPassesConfigurationTrait`` has been added, then
250+
/// polling will wait at least 1 millisecond between polling attempts.
251+
/// `pollingInterval` must be greater than 0.
252+
/// - isolation: The actor to which `body` is isolated, if any.
253+
/// - sourceLocation: The source location to whych any recorded issues should
254+
/// be attributed.
255+
/// - body: The function to invoke.
256+
///
257+
/// - Throws: A `PollingFailedError` will be thrown if the expression ever
258+
/// returns false.
259+
///
260+
/// Use polling confirmations to check that an event while a test is running in
261+
/// complex scenarios where other forms of confirmation are insufficient. For
262+
/// example, confirming that some state does not change.
263+
@available(macOS 13, iOS 17, watchOS 9, tvOS 17, visionOS 1, *)
264+
public func requireAlwaysPasses(
265+
_ comment: Comment? = nil,
266+
maxPollingIterations: Int? = nil,
267+
pollingInterval: Duration? = nil,
268+
isolation: isolated (any Actor)? = #isolation,
269+
sourceLocation: SourceLocation = #_sourceLocation,
270+
_ body: @escaping () async throws -> Bool
271+
) async throws
192272
```
193273

194274
### New Error Type
@@ -197,16 +277,16 @@ A new error type, `PollingFailedError` to be thrown when polling doesn't return
197277
a non-nil value:
198278

199279
```swift
200-
/// A type describing an error thrown when polling fails to return a non-nil
201-
/// value
202-
public struct PollingFailedError: Error {}
280+
/// A type describing an error thrown when polling fails.
281+
public struct PollingFailedError: Error, Equatable {}
203282
```
204283

205284
### New Issue Kind
206285

207286
A new Issue.Kind, `confirmationPollingFailed` will be added to represent the
208-
case here confirmation polling fails. This issue kind will be recorded when
209-
polling fails.
287+
case where a polling confirmation failed. This issue kind will be recorded when
288+
`confirmPassesEventually` and `confirmAlwaysPasses` fail, but not when
289+
`requirePassesEventually` or `requireAlwaysPasses` fail.
210290

211291
### New Traits
212292

0 commit comments

Comments
 (0)