Skip to content

Commit 44c9777

Browse files
committed
Add missing compile checks for XCTExpectFailure in Linux
1 parent fd1a2f9 commit 44c9777

File tree

5 files changed

+235
-219
lines changed

5 files changed

+235
-219
lines changed

Tests/ComposableArchitectureTests/EffectFailureTests.swift

Lines changed: 45 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,51 +3,54 @@ import XCTest
33

44
@testable import ComposableArchitecture
55

6-
@MainActor
7-
final class EffectFailureTests: XCTestCase {
8-
func testTaskUnexpectedThrows() {
9-
XCTExpectFailure {
10-
Effect<Void, Never>.task {
11-
struct Unexpected: Error {}
12-
throw Unexpected()
6+
// `XCTExpectFailure` is not supported on Linux
7+
#if !os(Linux)
8+
@MainActor
9+
final class EffectFailureTests: XCTestCase {
10+
func testTaskUnexpectedThrows() {
11+
XCTExpectFailure {
12+
Effect<Void, Never>.task {
13+
struct Unexpected: Error {}
14+
throw Unexpected()
15+
}
16+
.producer
17+
.start()
18+
19+
_ = XCTWaiter.wait(for: [.init()], timeout: 0.1)
20+
} issueMatcher: {
21+
$0.compactDescription == """
22+
An 'Effect.task' returned from "ComposableArchitectureTests/EffectFailureTests.swift:10" \
23+
threw an unhandled error. …
24+
25+
EffectFailureTests.Unexpected()
26+
27+
All non-cancellation errors must be explicitly handled via the 'catch' parameter on \
28+
'Effect.task', or via a 'do' block.
29+
"""
1330
}
14-
.producer
15-
.start()
16-
17-
_ = XCTWaiter.wait(for: [.init()], timeout: 0.1)
18-
} issueMatcher: {
19-
$0.compactDescription == """
20-
An 'Effect.task' returned from "ComposableArchitectureTests/EffectFailureTests.swift:10" \
21-
threw an unhandled error. …
22-
23-
EffectFailureTests.Unexpected()
24-
25-
All non-cancellation errors must be explicitly handled via the 'catch' parameter on \
26-
'Effect.task', or via a 'do' block.
27-
"""
2831
}
29-
}
3032

31-
func testRunUnexpectedThrows() {
32-
XCTExpectFailure {
33-
Effect<Void, Never>.run { _ in
34-
struct Unexpected: Error {}
35-
throw Unexpected()
33+
func testRunUnexpectedThrows() {
34+
XCTExpectFailure {
35+
Effect<Void, Never>.run { _ in
36+
struct Unexpected: Error {}
37+
throw Unexpected()
38+
}
39+
.producer
40+
.start()
41+
42+
_ = XCTWaiter.wait(for: [.init()], timeout: 0.1)
43+
} issueMatcher: {
44+
$0.compactDescription == """
45+
An 'Effect.run' returned from "ComposableArchitectureTests/EffectFailureTests.swift:33" \
46+
threw an unhandled error. …
47+
48+
EffectFailureTests.Unexpected()
49+
50+
All non-cancellation errors must be explicitly handled via the 'catch' parameter on \
51+
'Effect.run', or via a 'do' block.
52+
"""
3653
}
37-
.producer
38-
.start()
39-
40-
_ = XCTWaiter.wait(for: [.init()], timeout: 0.1)
41-
} issueMatcher: {
42-
$0.compactDescription == """
43-
An 'Effect.run' returned from "ComposableArchitectureTests/EffectFailureTests.swift:33" \
44-
threw an unhandled error. …
45-
46-
EffectFailureTests.Unexpected()
47-
48-
All non-cancellation errors must be explicitly handled via the 'catch' parameter on \
49-
'Effect.run', or via a 'do' block.
50-
"""
5154
}
5255
}
53-
}
56+
#endif

Tests/ComposableArchitectureTests/EffectRunTests.swift

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -45,35 +45,38 @@ final class EffectRunTests: XCTestCase {
4545
await store.receive(.response)
4646
}
4747

48-
func testRunUnhandledFailure() async {
49-
XCTExpectFailure(nil, enabled: nil, strict: nil) {
50-
$0.compactDescription == """
51-
An 'Effect.run' returned from "ComposableArchitectureTests/EffectRunTests.swift:62" threw \
52-
an unhandled error. …
48+
// `XCTExpectFailure` is not supported on Linux
49+
#if !os(Linux)
50+
func testRunUnhandledFailure() async {
51+
XCTExpectFailure(nil, enabled: nil, strict: nil) {
52+
$0.compactDescription == """
53+
An 'Effect.run' returned from "ComposableArchitectureTests/EffectRunTests.swift:62" threw \
54+
an unhandled error. …
5355
54-
EffectRunTests.Failure()
56+
EffectRunTests.Failure()
5557
56-
All non-cancellation errors must be explicitly handled via the 'catch' parameter on \
57-
'Effect.run', or via a 'do' block.
58-
"""
59-
}
60-
struct State: Equatable {}
61-
enum Action: Equatable { case tapped, response }
62-
let reducer = Reducer<State, Action, Void> { state, action, _ in
63-
switch action {
64-
case .tapped:
65-
return .run { send in
66-
struct Failure: Error {}
67-
throw Failure()
58+
All non-cancellation errors must be explicitly handled via the 'catch' parameter on \
59+
'Effect.run', or via a 'do' block.
60+
"""
61+
}
62+
struct State: Equatable {}
63+
enum Action: Equatable { case tapped, response }
64+
let reducer = Reducer<State, Action, Void> { state, action, _ in
65+
switch action {
66+
case .tapped:
67+
return .run { send in
68+
struct Failure: Error {}
69+
throw Failure()
70+
}
71+
case .response:
72+
return .none
6873
}
69-
case .response:
70-
return .none
7174
}
75+
let store = TestStore(initialState: State(), reducer: reducer, environment: ())
76+
// NB: We wait a long time here because XCTest failures take a long time to generate
77+
await store.send(.tapped).finish(timeout: 5 * NSEC_PER_SEC)
7278
}
73-
let store = TestStore(initialState: State(), reducer: reducer, environment: ())
74-
// NB: We wait a long time here because XCTest failures take a long time to generate
75-
await store.send(.tapped).finish(timeout: 5 * NSEC_PER_SEC)
76-
}
79+
#endif
7780

7881
func testRunCancellation() async {
7982
enum CancelID {}

Tests/ComposableArchitectureTests/EffectTaskTests.swift

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -45,35 +45,38 @@ final class EffectTaskTests: XCTestCase {
4545
await store.receive(.response)
4646
}
4747

48-
func testTaskUnhandledFailure() async {
49-
XCTExpectFailure(nil, enabled: nil, strict: nil) {
50-
$0.compactDescription == """
51-
An 'Effect.task' returned from "ComposableArchitectureTests/EffectTaskTests.swift:62" \
52-
threw an unhandled error. …
48+
// `XCTExpectFailure` is not supported on Linux
49+
#if !os(Linux)
50+
func testTaskUnhandledFailure() async {
51+
XCTExpectFailure(nil, enabled: nil, strict: nil) {
52+
$0.compactDescription == """
53+
An 'Effect.task' returned from "ComposableArchitectureTests/EffectTaskTests.swift:62" \
54+
threw an unhandled error. …
5355
54-
EffectTaskTests.Failure()
56+
EffectTaskTests.Failure()
5557
56-
All non-cancellation errors must be explicitly handled via the 'catch' parameter on \
57-
'Effect.task', or via a 'do' block.
58-
"""
59-
}
60-
struct State: Equatable {}
61-
enum Action: Equatable { case tapped, response }
62-
let reducer = Reducer<State, Action, Void> { state, action, _ in
63-
switch action {
64-
case .tapped:
65-
return .task {
66-
struct Failure: Error {}
67-
throw Failure()
58+
All non-cancellation errors must be explicitly handled via the 'catch' parameter on \
59+
'Effect.task', or via a 'do' block.
60+
"""
61+
}
62+
struct State: Equatable {}
63+
enum Action: Equatable { case tapped, response }
64+
let reducer = Reducer<State, Action, Void> { state, action, _ in
65+
switch action {
66+
case .tapped:
67+
return .task {
68+
struct Failure: Error {}
69+
throw Failure()
70+
}
71+
case .response:
72+
return .none
6873
}
69-
case .response:
70-
return .none
7174
}
75+
let store = TestStore(initialState: State(), reducer: reducer, environment: ())
76+
// NB: We wait a long time here because XCTest failures take a long time to generate
77+
await store.send(.tapped).finish(timeout: 5 * NSEC_PER_SEC)
7278
}
73-
let store = TestStore(initialState: State(), reducer: reducer, environment: ())
74-
// NB: We wait a long time here because XCTest failures take a long time to generate
75-
await store.send(.tapped).finish(timeout: 5 * NSEC_PER_SEC)
76-
}
79+
#endif
7780

7881
func testTaskCancellation() async {
7982
enum CancelID {}

Tests/ComposableArchitectureTests/TaskResultTests.swift

Lines changed: 63 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2,75 +2,79 @@ import ComposableArchitecture
22
import XCTest
33

44
class TaskResultTests: XCTestCase {
5-
func testEqualityNonEquatableError() {
6-
struct Failure: Error {
7-
let message: String
8-
}
9-
10-
XCTExpectFailure {
11-
XCTAssertNotEqual(
12-
TaskResult<Never>.failure(Failure(message: "Something went wrong")),
13-
TaskResult<Never>.failure(Failure(message: "Something went wrong"))
14-
)
15-
} issueMatcher: {
16-
$0.compactDescription == """
17-
'Failure' is not equatable. …
18-
19-
To test two values of this type, it must conform to the 'Equatable' protocol. For example:
205

21-
extension Failure: Equatable {}
22-
23-
See the documentation of 'TaskResult' for more information.
24-
"""
6+
// `XCTExpectFailure` is not supported on Linux
7+
#if !os(Linux)
8+
func testEqualityNonEquatableError() {
9+
struct Failure: Error {
10+
let message: String
11+
}
12+
13+
XCTExpectFailure {
14+
XCTAssertNotEqual(
15+
TaskResult<Never>.failure(Failure(message: "Something went wrong")),
16+
TaskResult<Never>.failure(Failure(message: "Something went wrong"))
17+
)
18+
} issueMatcher: {
19+
$0.compactDescription == """
20+
'Failure' is not equatable. …
21+
22+
To test two values of this type, it must conform to the 'Equatable' protocol. For example:
23+
24+
extension Failure: Equatable {}
25+
26+
See the documentation of 'TaskResult' for more information.
27+
"""
28+
}
2529
}
26-
}
2730

28-
func testEqualityMismatchingError() {
29-
struct Failure1: Error {
30-
let message: String
31-
}
32-
struct Failure2: Error {
33-
let message: String
31+
func testEqualityMismatchingError() {
32+
struct Failure1: Error {
33+
let message: String
34+
}
35+
struct Failure2: Error {
36+
let message: String
37+
}
38+
39+
XCTExpectFailure {
40+
XCTAssertNoDifference(
41+
TaskResult<Never>.failure(Failure1(message: "Something went wrong")),
42+
TaskResult<Never>.failure(Failure2(message: "Something went wrong"))
43+
)
44+
} issueMatcher: {
45+
$0.compactDescription == """
46+
XCTAssertNoDifference failed: …
47+
48+
  TaskResult.failure(
49+
− TaskResultTests.Failure1(message: "Something went wrong")
50+
+ TaskResultTests.Failure2(message: "Something went wrong")
51+
  )
52+
53+
(First: −, Second: +)
54+
"""
55+
}
3456
}
3557

36-
XCTExpectFailure {
37-
XCTAssertNoDifference(
38-
TaskResult<Never>.failure(Failure1(message: "Something went wrong")),
39-
TaskResult<Never>.failure(Failure2(message: "Something went wrong"))
40-
)
41-
} issueMatcher: {
42-
$0.compactDescription == """
43-
XCTAssertNoDifference failed: …
44-
45-
  TaskResult.failure(
46-
− TaskResultTests.Failure1(message: "Something went wrong")
47-
+ TaskResultTests.Failure2(message: "Something went wrong")
48-
  )
49-
50-
(First: −, Second: +)
51-
"""
52-
}
53-
}
58+
func testHashabilityNonHashableError() {
59+
struct Failure: Error {
60+
let message: String
61+
}
5462

55-
func testHashabilityNonHashableError() {
56-
struct Failure: Error {
57-
let message: String
58-
}
63+
XCTExpectFailure {
64+
_ = TaskResult<Never>.failure(Failure(message: "Something went wrong")).hashValue
65+
} issueMatcher: {
66+
$0.compactDescription == """
67+
'Failure' is not hashable. …
5968
60-
XCTExpectFailure {
61-
_ = TaskResult<Never>.failure(Failure(message: "Something went wrong")).hashValue
62-
} issueMatcher: {
63-
$0.compactDescription == """
64-
'Failure' is not hashable. …
69+
To hash a value of this type, it must conform to the 'Hashable' protocol. For example:
6570
66-
To hash a value of this type, it must conform to the 'Hashable' protocol. For example:
71+
extension Failure: Hashable {}
6772
68-
extension Failure: Hashable {}
69-
70-
See the documentation of 'TaskResult' for more information.
71-
"""
73+
See the documentation of 'TaskResult' for more information.
74+
"""
75+
}
7276
}
73-
}
77+
#endif
7478

7579
func testEquality_EquatableError() {
7680
enum Failure: Error, Equatable {

0 commit comments

Comments
 (0)