Skip to content

Commit d950991

Browse files
committed
[chore]: improt Swift Testing support in test utilities
1 parent 20d3025 commit d950991

File tree

9 files changed

+103
-24
lines changed

9 files changed

+103
-24
lines changed

WorkflowCombine/Testing/WorkerTesting.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
#if DEBUG
18+
import IssueReporting
1819
import Workflow
1920
import WorkflowTesting
2021
import XCTest
@@ -62,9 +63,9 @@ extension RenderTester {
6263
guard !workflow.worker.isEquivalent(to: expectedWorker) else {
6364
return
6465
}
65-
XCTFail(
66+
reportIssue(
6667
"Workers of type \(ExpectedWorkerType.self) not equivalent. Expected: \(expectedWorker). Got: \(workflow.worker)",
67-
file: file,
68+
filePath: file,
6869
line: line
6970
)
7071
}

WorkflowConcurrency/Testing/WorkerTesting.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
#if DEBUG
18+
import IssueReporting
1819
import Workflow
1920
import WorkflowTesting
2021
import XCTest
@@ -62,9 +63,9 @@ extension RenderTester {
6263
guard !workflow.worker.isEquivalent(to: worker) else {
6364
return
6465
}
65-
XCTFail(
66+
reportIssue(
6667
"Workers of type \(ExpectedWorkerType.self) not equivalent. Expected: \(worker). Got: \(workflow.worker)",
67-
file: file,
68+
filePath: file,
6869
line: line
6970
)
7071
}

WorkflowReactiveSwift/Testing/WorkerTesting.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
#if DEBUG
18+
import IssueReporting
1819
import Workflow
1920
import WorkflowTesting
2021
import XCTest
@@ -62,9 +63,9 @@ extension RenderTester {
6263
guard !workflow.worker.isEquivalent(to: expectedWorker) else {
6364
return
6465
}
65-
XCTFail(
66+
reportIssue(
6667
"Workers of type \(ExpectedWorkerType.self) not equivalent. Expected: \(expectedWorker). Got: \(workflow.worker)",
67-
file: file,
68+
filePath: file,
6869
line: line
6970
)
7071
}

WorkflowRxSwift/Testing/WorkerTesting.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
#if DEBUG
18+
import IssueReporting
1819
import Workflow
1920
import WorkflowTesting
2021
import XCTest
@@ -62,9 +63,9 @@ extension RenderTester {
6263
guard !workflow.worker.isEquivalent(to: expectedWorker) else {
6364
return
6465
}
65-
XCTFail(
66+
reportIssue(
6667
"Workers of type \(ExpectedWorkerType.self) not equivalent. Expected: \(expectedWorker). Got: \(workflow.worker)",
67-
file: file,
68+
filePath: file,
6869
line: line
6970
)
7071
}

WorkflowTesting/Sources/Internal/AppliedAction.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17+
import IssueReporting
1718
import Workflow
1819
import XCTest
1920

@@ -26,7 +27,7 @@ struct AppliedAction<WorkflowType: Workflow> {
2627

2728
func assert<ActionType: WorkflowAction>(type: ActionType.Type = ActionType.self, file: StaticString, line: UInt, assertions: (ActionType) throws -> Void) rethrows where ActionType.WorkflowType == WorkflowType {
2829
guard let action = erasedAction as? ActionType else {
29-
XCTFail("Expected action of type \(ActionType.self), got \(erasedAction)", file: file, line: line)
30+
reportIssue("Expected action of type \(ActionType.self), got \(erasedAction)", filePath: file, line: line)
3031
return
3132
}
3233
try assertions(action)

WorkflowTesting/Sources/Internal/RenderTester+TestContext.swift

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616

1717
#if DEBUG
1818

19+
import IssueReporting
1920
import XCTest
21+
2022
@testable import Workflow
2123

2224
extension RenderTester {
@@ -65,7 +67,7 @@ extension RenderTester {
6567
"""
6668
}
6769
let failureMessage = "Attempted to render unexpected Workflow of type \(Child.self) with key \"\(key)\". \(diagnosticMessage)"
68-
XCTFail(failureMessage, file: file, line: line)
70+
reportIssue(failureMessage, filePath: file, line: line)
6971

7072
// We can “recover” from missing Void-rendering workflows since there’s only one possible value to return
7173
if Child.Rendering.self == Void.self {
@@ -76,7 +78,7 @@ extension RenderTester {
7678
}
7779
let (inserted, _) = usedWorkflowKeys.insert(WorkflowKey(type: ObjectIdentifier(Child.self), key: key))
7880
if !inserted {
79-
XCTFail("Multiple Workflows of type \(Child.self) with key \"\(key)\" used in the same render call. Use a unique key to render multiple Workflows of the same type.", file: file, line: line)
81+
reportIssue("Multiple Workflows of type \(Child.self) with key \"\(key)\" used in the same render call. Use a unique key to render multiple Workflows of the same type.", filePath: file, line: line)
8082
}
8183

8284
expectedWorkflows.removeAll(where: { $0 === expectedWorkflow })
@@ -96,7 +98,7 @@ extension RenderTester {
9698

9799
func runSideEffect(key: AnyHashable, action: (Lifetime) -> Void) {
98100
guard let sideEffect = expectedSideEffects.removeValue(forKey: key) else {
99-
XCTFail("Unexpected side-effect with key \"\(key)\"", file: file, line: line)
101+
reportIssue("Unexpected side-effect with key \"\(key)\"", filePath: file, line: line)
100102
return
101103
}
102104

@@ -106,21 +108,25 @@ extension RenderTester {
106108
/// Validate the expectations were fulfilled, or fail if not.
107109
func assertNoLeftOverExpectations() {
108110
for expectedWorkflow in expectedWorkflows {
109-
XCTFail("Expected child workflow of type: \(expectedWorkflow.workflowType), key: \"\(expectedWorkflow.key)\"", file: file, line: expectedWorkflow.line)
111+
reportIssue("Expected child workflow of type: \(expectedWorkflow.workflowType), key: \"\(expectedWorkflow.key)\"", filePath: file, line: expectedWorkflow.line)
110112
}
111113

112114
for (key, expectedSideEffect) in expectedSideEffects {
113-
XCTFail("Expected side-effect with key: \"\(key)\"", file: expectedSideEffect.file, line: expectedSideEffect.line)
115+
reportIssue("Expected side-effect with key: \"\(key)\"", filePath: expectedSideEffect.file, line: expectedSideEffect.line)
114116
}
115117
}
116118

117119
private func apply<ActionType: WorkflowAction>(action: ActionType) where ActionType.WorkflowType == WorkflowType {
118-
XCTAssertNil(appliedAction, "Received multiple actions in a single render test", file: file, line: line)
120+
if appliedAction != nil {
121+
reportIssue("Received multiple actions in a single render test", filePath: file, line: line)
122+
}
119123
appliedAction = AppliedAction(action)
120124
let output = action.apply(toState: &state)
121125

122126
if let output {
123-
XCTAssertNil(producedOutput, "Received multiple outputs in a single render test", file: file, line: line)
127+
if producedOutput != nil {
128+
reportIssue("Received multiple outputs in a single render test", filePath: file, line: line)
129+
}
124130
producedOutput = output
125131
}
126132
}

WorkflowTesting/Sources/RenderTesterResult.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
import CustomDump
18+
import IssueReporting
1819
import Workflow
1920
import XCTest
2021

@@ -56,7 +57,7 @@ public struct RenderTesterResult<WorkflowType: Workflow> {
5657
line: UInt = #line
5758
) -> RenderTesterResult<WorkflowType> {
5859
if let appliedAction {
59-
XCTFail("Expected no action, but got \(appliedAction.erasedAction).", file: file, line: line)
60+
reportIssue("Expected no action, but got \(appliedAction.erasedAction).", filePath: file, line: line)
6061
}
6162
return self
6263
}
@@ -70,7 +71,7 @@ public struct RenderTesterResult<WorkflowType: Workflow> {
7071
assertions: (ActionType) throws -> Void
7172
) rethrows -> RenderTesterResult<WorkflowType> where ActionType.WorkflowType == WorkflowType {
7273
guard let appliedAction else {
73-
XCTFail("No action was produced", file: file, line: line)
74+
reportIssue("No action was produced", filePath: file, line: line)
7475
return self
7576
}
7677
try appliedAction.assert(file: file, line: line, assertions: assertions)
@@ -106,7 +107,7 @@ public struct RenderTesterResult<WorkflowType: Workflow> {
106107
line: UInt = #line
107108
) -> RenderTesterResult<WorkflowType> {
108109
if let output {
109-
XCTFail("Expected no output, but got \(output).", file: file, line: line)
110+
reportIssue("Expected no output, but got \(output).", filePath: file, line: line)
110111
}
111112
return self
112113
}
@@ -119,7 +120,7 @@ public struct RenderTesterResult<WorkflowType: Workflow> {
119120
assertions: (WorkflowType.Output) throws -> Void
120121
) rethrows -> RenderTesterResult<WorkflowType> {
121122
guard let output else {
122-
XCTFail("No output was produced", file: file, line: line)
123+
reportIssue("No output was produced", filePath: file, line: line)
123124
return self
124125
}
125126
try assertions(output)

WorkflowTesting/Sources/WorkflowActionTester.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
* limitations under the License.
1515
*/
1616

17+
import CustomDump
18+
import IssueReporting
1719
import Workflow
1820
import XCTest
1921

@@ -91,7 +93,7 @@ public struct WorkflowActionTester<WorkflowType, Action: WorkflowAction> where A
9193
line: UInt = #line
9294
) -> WorkflowActionTester<WorkflowType, Action> {
9395
if let output {
94-
XCTFail("Expected no output, but got \(output).", file: file, line: line)
96+
reportIssue("Expected no output, but got \(output).", filePath: file, line: line)
9597
}
9698
return self
9799
}
@@ -109,7 +111,7 @@ public struct WorkflowActionTester<WorkflowType, Action: WorkflowAction> where A
109111
_ assertions: (WorkflowType.Output) throws -> Void
110112
) rethrows -> WorkflowActionTester<WorkflowType, Action> {
111113
guard let output else {
112-
XCTFail("No output was produced", file: file, line: line)
114+
reportIssue("No output was produced", filePath: file, line: line)
113115
return self
114116
}
115117
try assertions(output)
@@ -143,7 +145,7 @@ extension WorkflowActionTester where WorkflowType.State: Equatable {
143145
@discardableResult
144146
public func assert(state expectedState: WorkflowType.State, file: StaticString = #file, line: UInt = #line) -> WorkflowActionTester<WorkflowType, Action> {
145147
verifyState { actualState in
146-
XCTAssertEqual(actualState, expectedState, file: file, line: line)
148+
expectNoDifference(actualState, expectedState, filePath: file, line: line)
147149
}
148150
}
149151
}
@@ -157,7 +159,7 @@ extension WorkflowActionTester where WorkflowType.Output: Equatable {
157159
@discardableResult
158160
public func assert(output expectedOutput: WorkflowType.Output, file: StaticString = #file, line: UInt = #line) -> WorkflowActionTester<WorkflowType, Action> {
159161
verifyOutput { actualOutput in
160-
XCTAssertEqual(actualOutput, expectedOutput, file: file, line: line)
162+
expectNoDifference(actualOutput, expectedOutput, filePath: file, line: line)
161163
}
162164
}
163165
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright Square Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import Testing
18+
import Workflow
19+
import XCTest
20+
21+
@testable import WorkflowTesting
22+
23+
struct SwiftTestingCompatibilityTests {
24+
@Test
25+
func testInternalFailureRecordsExpectationFailure_swiftTesting() {
26+
withKnownIssue {
27+
TestAction
28+
.tester(withState: false)
29+
.send(action: .change(true))
30+
.assertNoOutput() // should fail the test
31+
}
32+
}
33+
}
34+
35+
final class XCTestCompatibilityTests: XCTestCase {
36+
func testInternalFailureRecordsExpectationFailure_xctest() {
37+
XCTExpectFailure {
38+
_ = TestAction
39+
.tester(withState: false)
40+
.send(action: .change(true))
41+
.assertNoOutput() // should fail the test
42+
}
43+
}
44+
}
45+
46+
private enum TestAction: WorkflowAction {
47+
typealias WorkflowType = TestWorkflow
48+
49+
case change(Bool)
50+
51+
func apply(toState state: inout Bool) -> TestWorkflow.Output? {
52+
if case .change(let newState) = self {
53+
state = newState
54+
}
55+
return 42
56+
}
57+
}
58+
59+
private struct TestWorkflow: Workflow {
60+
typealias Rendering = Void
61+
typealias Output = Int
62+
63+
func makeInitialState() -> Bool { true }
64+
func render(state: Bool, context: RenderContext<TestWorkflow>) {}
65+
}

0 commit comments

Comments
 (0)