@@ -47,7 +47,7 @@ and would improve code coverage for existing test targets that adopt them.
4747
4848## Proposed solution
4949
50- This proposal introduces a new variant of the ` #expect() ` and ` #require() `
50+ This proposal introduces new overloads of the ` #expect() ` and ` #require() `
5151macros that take, as an argument, a closure to be executed in a child process.
5252When called, these macros spawn a new process using the relevant
5353platform-specific interface (` posix_spawn() ` , ` CreateProcessW() ` , etc.), call
@@ -57,7 +57,76 @@ value passed to the macro, allowing the test to pass or fail as appropriate.
5757
5858## Detailed design
5959
60- We will introduce the following new interfaces to the testing library:
60+ ### New expectations
61+
62+ We will introduce the following new overloads of ` #expect() ` and ` #require() ` to
63+ the testing library:
64+
65+ ``` swift
66+ /// Check that an expression causes the process to terminate in a given fashion.
67+ ///
68+ /// - Parameters:
69+ /// - exitCondition: The expected exit condition.
70+ /// - comment: A comment describing the expectation.
71+ /// - sourceLocation: The source location to which recorded expectations and
72+ /// issues should be attributed.
73+ /// - expression: The expression to be evaluated.
74+ ///
75+ /// Use this overload of `#expect()` when an expression will cause the current
76+ /// process to terminate and the nature of that termination will determine if
77+ /// the test passes or fails.
78+ #if SWT_NO_EXIT_TESTS
79+ @available (* , unavailable , message : " Exit tests are not available on this platform." )
80+ #endif
81+ @freestanding (expression) public macro expect (
82+ exitsWith exitCondition : ExitCondition,
83+ _ comment : @autoclosure () -> Comment? = nil ,
84+ sourceLocation : SourceLocation = SourceLocation (),
85+ performing expression : @convention (thin) () async -> Void
86+ )
87+
88+ /// Check that an expression causes the process to terminate in a given fashion.
89+ ///
90+ /// - Parameters:
91+ /// - exitCondition: The expected exit condition.
92+ /// - comment: A comment describing the expectation.
93+ /// - sourceLocation: The source location to which recorded expectations and
94+ /// issues should be attributed.
95+ /// - expression: The expression to be evaluated.
96+ ///
97+ /// Use this overload of `#require()` when an expression will cause the current
98+ /// process to terminate and the nature of that termination will determine if
99+ /// the test passes or fails.
100+ #if SWT_NO_EXIT_TESTS
101+ @available (* , unavailable , message : " Exit tests are not available on this platform." )
102+ #endif
103+ @freestanding (expression) public macro require (
104+ exitsWith exitCondition : ExitCondition,
105+ _ comment : @autoclosure () -> Comment? = nil ,
106+ sourceLocation : SourceLocation = SourceLocation (),
107+ performing expression : @convention (thin) () async -> Void
108+ )
109+ ```
110+
111+ > [ !NOTE]
112+ > ` SWT_NO_EXIT_TESTS ` is defined by the testing library when building for
113+ > platforms that do not have the ability to spawn child processes (including
114+ > iOS, watchOS, tvOS, visionOS, and WASI.) In other words, these interfaces are
115+ > available on ** macOS** , ** Linux** , and ** Windows** . ` SWT_NO_EXIT_TESTS ` is not
116+ > defined during test target builds.
117+
118+ ### Exit conditions
119+
120+ These macros take an argument of the new enumeration ` ExitCondition ` . This type
121+ describes how the child process is expected to have exited:
122+
123+ - With a specific exit code (as passed to the C standard function ` exit() ` or a
124+ platform equivalent;
125+ - With a specific signal (on POSIX-like platforms that support signal handling;
126+ - With any successful status; or
127+ - With any failure status.
128+
129+ The enumeration is declared as:
61130
62131``` swift
63132/// An enumeration describing possible conditions under which an exit test will
@@ -67,6 +136,10 @@ We will introduce the following new interfaces to the testing library:
67136/// ``expect(exitsWith:_:sourceLocation:performing:)`` or
68137/// ``require(exitsWith:_:sourceLocation:performing:)`` to configure which exit
69138/// statuses should be considered successful.
139+ ///
140+ /// Two instances of this type can be compared; if either instance is equal to
141+ /// ``failure``, it will compare equal to any instance except ``success``. To
142+ /// check if two instances are exactly equal, use the `===` operator:
70143#if SWT_NO_EXIT_TESTS
71144@available (* , unavailable , message : " Exit tests are not available on this platform." )
72145#endif
@@ -122,57 +195,16 @@ public enum ExitCondition: Sendable {
122195 case signal (_ signal : CInt )
123196}
124197
125- /// Check that an expression causes the process to terminate in a given fashion.
126- ///
127- /// - Parameters:
128- /// - exitCondition: The expected exit condition.
129- /// - comment: A comment describing the expectation.
130- /// - sourceLocation: The source location to which recorded expectations and
131- /// issues should be attributed.
132- /// - expression: The expression to be evaluated.
133- ///
134- /// Use this overload of `#expect()` when an expression will cause the current
135- /// process to terminate and the nature of that termination will determine if
136- /// the test passes or fails.
137- #if SWT_NO_EXIT_TESTS
138- @available (* , unavailable , message : " Exit tests are not available on this platform." )
139- #endif
140- @freestanding (expression) public macro expect (
141- exitsWith exitCondition : ExitCondition,
142- _ comment : @autoclosure () -> Comment? = nil ,
143- sourceLocation : SourceLocation = SourceLocation (),
144- performing expression : @convention (thin) () async -> Void
145- )
198+ extension ExitCondition : Equatable {
199+ public static func === (lhs : Self , rhs : Self ) -> Bool
200+ public static func !== (lhs : Self , rhs : Self ) -> Bool
201+ }
146202
147- /// Check that an expression causes the process to terminate in a given fashion.
148- ///
149- /// - Parameters:
150- /// - exitCondition: The expected exit condition.
151- /// - comment: A comment describing the expectation.
152- /// - sourceLocation: The source location to which recorded expectations and
153- /// issues should be attributed.
154- /// - expression: The expression to be evaluated.
155- ///
156- /// Use this overload of `#require()` when an expression will cause the current
157- /// process to terminate and the nature of that termination will determine if
158- /// the test passes or fails.
159- #if SWT_NO_EXIT_TESTS
160- @available (* , unavailable , message : " Exit tests are not available on this platform." )
161- #endif
162- @freestanding (expression) public macro require (
163- exitsWith exitCondition : ExitCondition,
164- _ comment : @autoclosure () -> Comment? = nil ,
165- sourceLocation : SourceLocation = SourceLocation (),
166- performing expression : @convention (thin) () async -> Void
167- )
203+ @available (* , unavailable , message : " ExitCondition does not conform to Hashable." )
204+ extension ExitCondition : Hashable {}
168205```
169206
170- > [ !NOTE]
171- > ` SWT_NO_EXIT_TESTS ` is defined by the testing library when building for
172- > platforms that do not have the ability to spawn child processes (including
173- > iOS, watchOS, tvOS, visionOS, and WASI.) In other words, these interfaces are
174- > available on ** macOS** , ** Linux** , and ** Windows** . ` SWT_NO_EXIT_TESTS ` is not
175- > defined during test target builds.
207+ ### Usage
176208
177209These macros can be used within a test function:
178210
@@ -447,3 +479,4 @@ can expand upon in the future if it proves to be important to exit test authors.
447479## Acknowledgments
448480
449481Many thanks to the XCTest and swift-testing team.
482+
0 commit comments