Skip to content

Commit edfe9d4

Browse files
committed
Make Polling into a function along the lines of Confirmation
Additionally, make PollingBehavior an implementation detail of polling, instead of exposed publicly Removes any timeouts involved for polling, as they become increasingly unreliable as the system runs more and more tests
1 parent 1d9ea96 commit edfe9d4

File tree

8 files changed

+382
-926
lines changed

8 files changed

+382
-926
lines changed

Sources/Testing/Expectations/Expectation+Macro.swift

Lines changed: 0 additions & 167 deletions
Original file line numberDiff line numberDiff line change
@@ -572,170 +572,3 @@ public macro require(
572572
sourceLocation: SourceLocation = #_sourceLocation,
573573
performing expression: @escaping @Sendable @convention(thin) () async throws -> Void
574574
) -> ExitTest.Result = #externalMacro(module: "TestingMacros", type: "ExitTestRequireMacro")
575-
576-
// MARK: - Polling Expectations
577-
578-
/// Continuously check an expression until it matches the given PollingBehavior
579-
///
580-
/// - Parameters:
581-
/// - until: The desired PollingBehavior to check for.
582-
/// - timeout: How long to run poll the expression until stopping.
583-
/// - comment: A comment describing the expectation.
584-
/// - sourceLocation: The source location to which the recorded expectations
585-
/// and issues should be attributed.
586-
/// - expression: The expression to be evaluated.
587-
///
588-
/// Use this overload of `#expect()` when you wish to poll whether a value
589-
/// changes as the result of activity in another task/queue/thread.
590-
@_spi(Experimental)
591-
@available(macOS 13, iOS 17, watchOS 9, tvOS 17, visionOS 1, *)
592-
@freestanding(expression) public macro expect(
593-
until pollingBehavior: PollingBehavior,
594-
timeout: Duration = .seconds(60),
595-
_ comment: @autoclosure () -> Comment? = nil,
596-
sourceLocation: SourceLocation = #_sourceLocation,
597-
expression: @Sendable () async throws -> Bool
598-
) = #externalMacro(module: "TestingMacros", type: "ExpectMacro")
599-
600-
/// Continuously check an expression until it matches the given PollingBehavior
601-
///
602-
/// - Parameters:
603-
/// - until: The desired PollingBehavior to check for.
604-
/// - throws: The error the expression should throw.
605-
/// - timeout: How long to run poll the expression until stopping.
606-
/// - comment: A comment describing the expectation.
607-
/// - sourceLocation: The source location to which the recorded expectations
608-
/// and issues should be attributed.
609-
/// - expression: The expression to be evaluated.
610-
///
611-
/// Use this overload of `#expect()` when you wish to poll whether a value
612-
/// changes as the result of activity in another task/queue/thread.
613-
@_spi(Experimental)
614-
@available(macOS 13, iOS 17, watchOS 9, tvOS 17, visionOS 1, *)
615-
@freestanding(expression) public macro expect<E>(
616-
until pollingBehavior: PollingBehavior,
617-
throws error: E,
618-
timeout: Duration = .seconds(60),
619-
_ comment: @autoclosure () -> Comment? = nil,
620-
sourceLocation: SourceLocation = #_sourceLocation,
621-
expression: @Sendable () async throws -> Bool
622-
) = #externalMacro(module: "TestingMacros", type: "ExpectMacro")
623-
where E: Error & Equatable
624-
625-
/// Continuously check an expression until it matches the given PollingBehavior
626-
///
627-
/// - Parameters:
628-
/// - until: The desired PollingBehavior to check for.
629-
/// - timeout: How long to run poll the expression until stopping.
630-
/// - comment: A comment describing the expectation.
631-
/// - sourceLocation: The source location to which the recorded expectations
632-
/// and issues should be attributed.
633-
/// - expression: The expression to be evaluated.
634-
/// - throws: A closure to confirm if the expression throws the expected error.
635-
///
636-
/// Use this overload of `#expect()` when you wish to poll whether a value
637-
/// changes as the result of activity in another task/queue/thread.
638-
@_spi(Experimental)
639-
@available(macOS 13, iOS 17, watchOS 9, tvOS 17, visionOS 1, *)
640-
@freestanding(expression) public macro expect(
641-
until pollingBehavior: PollingBehavior,
642-
timeout: Duration = .seconds(60),
643-
_ comment: @autoclosure () -> Comment? = nil,
644-
sourceLocation: SourceLocation = #_sourceLocation,
645-
performing: @Sendable () async throws -> Bool,
646-
throws errorMatcher: @Sendable (any Error) async throws -> Bool
647-
) = #externalMacro(module: "TestingMacros", type: "ExpectMacro")
648-
649-
/// Continuously check an expression until it matches the given PollingBehavior
650-
///
651-
/// - Parameters:
652-
/// - until: The desired PollingBehavior to check for.
653-
/// - timeout: How long to run poll the expression until stopping.
654-
/// - comment: A comment describing the expectation.
655-
/// - sourceLocation: The source location to which the recorded expectations
656-
/// and issues should be attributed.
657-
/// - expression: The expression to be evaluated.
658-
///
659-
/// Use this overload of `#require()` when you wish to poll whether a value
660-
/// changes as the result of activity in another task/queue/thread.
661-
@_spi(Experimental)
662-
@available(macOS 13, iOS 17, watchOS 9, tvOS 17, visionOS 1, *)
663-
@freestanding(expression) public macro require(
664-
until pollingBehavior: PollingBehavior,
665-
timeout: Duration = .seconds(60),
666-
_ comment: @autoclosure () -> Comment? = nil,
667-
sourceLocation: SourceLocation = #_sourceLocation,
668-
expression: @Sendable () async throws -> Bool
669-
) = #externalMacro(module: "TestingMacros", type: "RequireMacro")
670-
671-
/// Continuously check an expression until it matches the given PollingBehavior
672-
///
673-
/// - Parameters:
674-
/// - until: The desired PollingBehavior to check for.
675-
/// - timeout: How long to run poll the expression until stopping.
676-
/// - comment: A comment describing the expectation.
677-
/// - sourceLocation: The source location to which the recorded expectations
678-
/// and issues should be attributed.
679-
/// - expression: The expression to be evaluated.
680-
///
681-
/// Use this overload of `#require()` when you wish to poll whether a value
682-
/// changes as the result of activity in another task/queue/thread.
683-
@_spi(Experimental)
684-
@available(macOS 13, iOS 17, watchOS 9, tvOS 17, visionOS 1, *)
685-
@freestanding(expression) public macro require<R>(
686-
until pollingBehavior: PollingBehavior,
687-
timeout: Duration = .seconds(60),
688-
_ comment: @autoclosure () -> Comment? = nil,
689-
sourceLocation: SourceLocation = #_sourceLocation,
690-
expression: @Sendable () async throws -> R?
691-
) = #externalMacro(module: "TestingMacros", type: "RequireMacro")
692-
where R: Sendable
693-
694-
/// Continuously check an expression until it matches the given PollingBehavior
695-
///
696-
/// - Parameters:
697-
/// - until: The desired PollingBehavior to check for.
698-
/// - throws: The error the expression should throw
699-
/// - timeout: How long to run poll the expression until stopping.
700-
/// - comment: A comment describing the expectation.
701-
/// - sourceLocation: The source location to which the recorded expectations
702-
/// and issues should be attributed.
703-
/// - expression: The expression to be evaluated.
704-
///
705-
/// Use this overload of `#require()` when you wish to poll whether a value
706-
/// changes as the result of activity in another task/queue/thread.
707-
@_spi(Experimental)
708-
@available(macOS 13, iOS 17, watchOS 9, tvOS 17, visionOS 1, *)
709-
@freestanding(expression) public macro require<E>(
710-
until pollingBehavior: PollingBehavior,
711-
throws error: E,
712-
timeout: Duration = .seconds(60),
713-
_ comment: @autoclosure () -> Comment? = nil,
714-
sourceLocation: SourceLocation = #_sourceLocation,
715-
expression: @Sendable () async throws -> Bool
716-
) = #externalMacro(module: "TestingMacros", type: "RequireMacro")
717-
where E: Error & Equatable
718-
719-
/// Continuously check an expression until it matches the given PollingBehavior
720-
///
721-
/// - Parameters:
722-
/// - until: The desired PollingBehavior to check for.
723-
/// - timeout: How long to run poll the expression until stopping.
724-
/// - comment: A comment describing the expectation.
725-
/// - sourceLocation: The source location to which the recorded expectations
726-
/// and issues should be attributed.
727-
/// - expression: The expression to be evaluated.
728-
/// - throws: A closure to confirm if the expression throws the expected error.
729-
///
730-
/// Use this overload of `#require()` when you wish to poll whether a value
731-
/// changes as the result of activity in another task/queue/thread.
732-
@_spi(Experimental)
733-
@available(macOS 13, iOS 17, watchOS 9, tvOS 17, visionOS 1, *)
734-
@freestanding(expression) public macro require<E>(
735-
until pollingBehavior: PollingBehavior,
736-
timeout: Duration = .seconds(60),
737-
_ comment: @autoclosure () -> Comment? = nil,
738-
sourceLocation: SourceLocation = #_sourceLocation,
739-
expression: @Sendable () async throws -> Bool,
740-
throws errorMatcher: @Sendable (any Error) async throws -> Bool
741-
) = #externalMacro(module: "TestingMacros", type: "RequireMacro")

Sources/Testing/Expectations/ExpectationChecking+Macro.swift

Lines changed: 0 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,102 +1201,6 @@ public func __checkClosureCall<each T>(
12011201
}
12021202
#endif
12031203

1204-
// MARK: - Polling
1205-
1206-
@_spi(Experimental)
1207-
@available(macOS 13, iOS 17, watchOS 9, tvOS 17, visionOS 1, *)
1208-
public func __checkClosureCall(
1209-
until behavior: PollingBehavior,
1210-
timeout: Duration = .seconds(60),
1211-
performing closure: @escaping @Sendable () async throws -> Bool,
1212-
expression: __Expression,
1213-
comments: @autoclosure () -> [Comment],
1214-
isRequired: Bool,
1215-
sourceLocation: SourceLocation
1216-
) async -> Result<Void, any Error> {
1217-
await callPolling(
1218-
behavior: behavior,
1219-
timeout: timeout,
1220-
closure: closure,
1221-
expression: expression,
1222-
comments: comments(),
1223-
isRequired: isRequired,
1224-
sourceLocation: sourceLocation
1225-
)
1226-
}
1227-
1228-
@_spi(Experimental)
1229-
@available(macOS 13, iOS 17, watchOS 9, tvOS 17, visionOS 1, *)
1230-
public func __checkClosureCall<E>(
1231-
until behavior: PollingBehavior,
1232-
throws error: E,
1233-
timeout: Duration = .seconds(60),
1234-
performing closure: @escaping @Sendable () async throws -> Bool,
1235-
expression: __Expression,
1236-
comments: @autoclosure () -> [Comment],
1237-
isRequired: Bool,
1238-
sourceLocation: SourceLocation
1239-
) async -> Result<Void, any Error> where E: Error & Equatable {
1240-
await callPolling(
1241-
behavior: behavior,
1242-
throws: error,
1243-
timeout: timeout,
1244-
closure: closure,
1245-
expression: expression,
1246-
comments: comments(),
1247-
isRequired: isRequired,
1248-
sourceLocation: sourceLocation
1249-
)
1250-
}
1251-
1252-
@_spi(Experimental)
1253-
@available(macOS 13, iOS 17, watchOS 9, tvOS 17, visionOS 1, *)
1254-
public func __checkClosureCall(
1255-
until behavior: PollingBehavior,
1256-
timeout: Duration = .seconds(60),
1257-
performing closure: @escaping @Sendable () async throws -> Bool,
1258-
throws errorMatcher: @escaping @Sendable (any Error) async throws -> Bool,
1259-
expression: __Expression,
1260-
comments: @autoclosure () -> [Comment],
1261-
isRequired: Bool,
1262-
sourceLocation: SourceLocation
1263-
) async -> Result<Void, any Error> {
1264-
await callPolling(
1265-
behavior: behavior,
1266-
timeout: timeout,
1267-
closure: closure,
1268-
errorMatcher: errorMatcher,
1269-
expression: expression,
1270-
comments: comments(),
1271-
isRequired: isRequired,
1272-
sourceLocation: sourceLocation
1273-
)
1274-
}
1275-
1276-
@_spi(Experimental)
1277-
@available(macOS 13, iOS 17, watchOS 9, tvOS 17, visionOS 1, *)
1278-
public func __checkClosureCall<R>(
1279-
until behavior: PollingBehavior,
1280-
timeout: Duration = .seconds(60),
1281-
performing closure: @escaping @Sendable () async throws -> R,
1282-
throws errorMatcher: @escaping @Sendable (any Error) async throws -> Bool,
1283-
expression: __Expression,
1284-
comments: @autoclosure () -> [Comment],
1285-
isRequired: Bool,
1286-
sourceLocation: SourceLocation
1287-
) async -> Result<R, any Error> where R: Sendable {
1288-
await callPolling(
1289-
behavior: behavior,
1290-
timeout: timeout,
1291-
closure: closure,
1292-
errorMatcher: errorMatcher,
1293-
expression: expression,
1294-
comments: comments(),
1295-
isRequired: isRequired,
1296-
sourceLocation: sourceLocation
1297-
)
1298-
}
1299-
13001204
// MARK: -
13011205

13021206
/// Generate a description of an error that includes its type name if not

Sources/Testing/Issues/Issue.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ public struct Issue: Sendable {
3838
/// confirmed too few or too many times.
3939
indirect case confirmationMiscounted(actual: Int, expected: any RangeExpression & Sendable)
4040

41+
@_spi(Experimental)
42+
case confirmationPollingFailed
43+
4144
/// An issue due to an `Error` being thrown by a test function and caught by
4245
/// the testing library.
4346
///
@@ -286,6 +289,8 @@ extension Issue.Kind: CustomStringConvertible {
286289
}
287290
}
288291
return "Confirmation was confirmed \(actual.counting("time")), but expected to be confirmed \(String(describingForTest: expected)) time(s)"
292+
case .confirmationPollingFailed:
293+
return "Confirmation polling failed"
289294
case let .errorCaught(error):
290295
return "Caught error: \(error)"
291296
case let .timeLimitExceeded(timeLimitComponents: timeLimitComponents):
@@ -465,6 +470,8 @@ extension Issue.Kind {
465470
.expectationFailed(Expectation.Snapshot(snapshotting: expectation))
466471
case .confirmationMiscounted:
467472
.unconditional
473+
case .confirmationPollingFailed:
474+
.unconditional
468475
case let .errorCaught(error), let .valueAttachmentFailed(error):
469476
.errorCaught(ErrorSnapshot(snapshotting: error))
470477
case let .timeLimitExceeded(timeLimitComponents: timeLimitComponents):

0 commit comments

Comments
 (0)