1
1
// Inspired by https://github.com/groue/CombineExpectations
2
2
import XCTest
3
3
4
- #if canImport(Darwin) // needed for XCTIssue
5
4
/// A XCTestCase subclass that can test its own failures.
6
5
class FailureTestCase : XCTestCase {
7
6
private struct Failure : Hashable {
7
+ #if canImport(Darwin)
8
8
let issue : XCTIssue
9
-
9
+
10
10
func issue( prefix: String = " " ) -> XCTIssue {
11
11
if prefix. isEmpty {
12
12
return issue
@@ -20,24 +20,28 @@ class FailureTestCase: XCTestCase {
20
20
attachments: issue. attachments)
21
21
}
22
22
}
23
-
23
+
24
24
private var description : String {
25
25
return issue. compactDescription
26
26
}
27
-
27
+
28
28
func hash( into hasher: inout Hasher ) {
29
29
hasher. combine ( 0 )
30
30
}
31
31
32
32
static func == ( lhs: Failure , rhs: Failure ) -> Bool {
33
33
lhs. description. hasPrefix ( rhs. description) || rhs. description. hasPrefix ( lhs. description)
34
34
}
35
+ #endif
35
36
}
36
37
37
38
private var recordedFailures : [ Failure ] = [ ]
38
39
private var isRecordingFailures = false
39
40
40
- func assertFailure( _ prefixes: String ... , file: StaticString = #file, line: UInt = #line, _ execute: ( ) throws -> Void ) rethrows {
41
+ func assertFailure( _ prefixes: String ... , file: StaticString = #file, line: UInt = #line, _ execute: ( ) throws -> Void ) throws {
42
+ #if !canImport(Darwin)
43
+ throw XCTSkip ( " XCTIssue unavailable on non-Darwin platforms " )
44
+ #else
41
45
let recordedFailures = try recordingFailures ( execute)
42
46
if prefixes. isEmpty {
43
47
if recordedFailures. isEmpty {
@@ -69,22 +73,24 @@ class FailureTestCase: XCTestCase {
69
73
recordedFailures: recordedFailures,
70
74
expectedFailures: expectedFailures)
71
75
}
76
+ #endif
72
77
}
73
78
74
79
override func setUp( ) {
75
80
super. setUp ( )
76
81
isRecordingFailures = false
77
82
recordedFailures = [ ]
78
83
}
79
-
84
+
85
+ #if canImport(Darwin)
80
86
override func record( _ issue: XCTIssue ) {
81
87
if isRecordingFailures {
82
88
recordedFailures. append ( Failure ( issue: issue) )
83
89
} else {
84
90
super. record ( issue)
85
91
}
86
92
}
87
-
93
+
88
94
private func recordingFailures( _ execute: ( ) throws -> Void ) rethrows -> [ Failure ] {
89
95
let oldRecordingFailures = isRecordingFailures
90
96
let oldRecordedFailures = recordedFailures
@@ -121,6 +127,7 @@ class FailureTestCase: XCTestCase {
121
127
}
122
128
}
123
129
}
130
+ #endif
124
131
}
125
132
126
133
// MARK: - Tests
@@ -129,83 +136,82 @@ class FailureTestCaseTests: FailureTestCase {
129
136
func testEmptyTest( ) {
130
137
}
131
138
132
- func testExpectedAnyFailure( ) {
133
- assertFailure {
139
+ func testExpectedAnyFailure( ) throws {
140
+ try assertFailure {
134
141
XCTFail ( " foo " )
135
142
}
136
- assertFailure {
143
+ try assertFailure {
137
144
XCTFail ( " foo " )
138
145
XCTFail ( " bar " )
139
146
}
140
147
}
141
148
142
- func testMissingAnyFailure( ) {
143
- assertFailure ( " No failure did happen " ) {
144
- assertFailure {
149
+ func testMissingAnyFailure( ) throws {
150
+ try assertFailure ( " No failure did happen " ) {
151
+ try assertFailure {
145
152
}
146
153
}
147
154
}
148
155
149
- func testExpectedFailure( ) {
150
- assertFailure ( " failed - foo " ) {
156
+ func testExpectedFailure( ) throws {
157
+ try assertFailure ( " failed - foo " ) {
151
158
XCTFail ( " foo " )
152
159
}
153
160
}
154
161
155
- func testExpectedFailureMatchesOnPrefix( ) {
156
- assertFailure ( " failed - foo " ) {
162
+ func testExpectedFailureMatchesOnPrefix( ) throws {
163
+ try assertFailure ( " failed - foo " ) {
157
164
XCTFail ( " foobarbaz " )
158
165
}
159
166
}
160
167
161
- func testOrderOfExpectedFailureIsIgnored( ) {
162
- assertFailure ( " failed - foo " , " failed - bar " ) {
168
+ func testOrderOfExpectedFailureIsIgnored( ) throws {
169
+ try assertFailure ( " failed - foo " , " failed - bar " ) {
163
170
XCTFail ( " foo " )
164
171
XCTFail ( " bar " )
165
172
}
166
- assertFailure ( " failed - bar " , " failed - foo " ) {
173
+ try assertFailure ( " failed - bar " , " failed - foo " ) {
167
174
XCTFail ( " foo " )
168
175
XCTFail ( " bar " )
169
176
}
170
177
}
171
178
172
- func testExpectedFailureCanBeRepeated( ) {
173
- assertFailure ( " failed - foo " , " failed - foo " , " failed - bar " ) {
179
+ func testExpectedFailureCanBeRepeated( ) throws {
180
+ try assertFailure ( " failed - foo " , " failed - foo " , " failed - bar " ) {
174
181
XCTFail ( " foo " )
175
182
XCTFail ( " bar " )
176
183
XCTFail ( " foo " )
177
184
}
178
185
}
179
186
180
- func testExactNumberOfRepetitionIsRequired( ) {
181
- assertFailure ( " Failure did not happen: failed - foo " ) {
182
- assertFailure ( " failed - foo " , " failed - foo " ) {
187
+ func testExactNumberOfRepetitionIsRequired( ) throws {
188
+ try assertFailure ( " Failure did not happen: failed - foo " ) {
189
+ try assertFailure ( " failed - foo " , " failed - foo " ) {
183
190
XCTFail ( " foo " )
184
191
}
185
192
}
186
- assertFailure ( " failed - foo " ) {
187
- assertFailure ( " failed - foo " , " failed - foo " ) {
193
+ try assertFailure ( " failed - foo " ) {
194
+ try assertFailure ( " failed - foo " , " failed - foo " ) {
188
195
XCTFail ( " foo " )
189
196
XCTFail ( " foo " )
190
197
XCTFail ( " foo " )
191
198
}
192
199
}
193
200
}
194
201
195
- func testUnexpectedFailure( ) {
196
- assertFailure ( " Failure did not happen: failed - foo " ) {
197
- assertFailure ( " failed - foo " ) {
202
+ func testUnexpectedFailure( ) throws {
203
+ try assertFailure ( " Failure did not happen: failed - foo " ) {
204
+ try assertFailure ( " failed - foo " ) {
198
205
}
199
206
}
200
207
}
201
208
202
- func testMissedFailure( ) {
203
- assertFailure ( " failed - bar " ) {
204
- assertFailure ( " failed - foo " ) {
209
+ func testMissedFailure( ) throws {
210
+ try assertFailure ( " failed - bar " ) {
211
+ try assertFailure ( " failed - foo " ) {
205
212
XCTFail ( " foo " )
206
213
XCTFail ( " bar " )
207
214
}
208
215
}
209
216
}
210
217
}
211
- #endif
0 commit comments