Skip to content

Commit 1325404

Browse files
stephencelisp4checo
authored andcommitted
Run swift-format
(cherry picked from commit 26da32710dfb7f3a322230d5c9bd1bf671817d9b) # Conflicts: # Tests/ComposableArchitectureTests/EffectTests.swift # Tests/ComposableArchitectureTests/ReducerTests.swift
1 parent a4b9750 commit 1325404

File tree

10 files changed

+1491
-1491
lines changed

10 files changed

+1491
-1491
lines changed

Sources/Dependencies/Dependencies/MainQueue.swift

Lines changed: 85 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,98 @@
1-
import Foundation
1+
import Foundation
22
import ReactiveSwift
33
import XCTestDynamicOverlay
44

5-
extension DependencyValues {
6-
/// The "main" queue.
7-
///
8-
/// Introduce controllable timing to your features by using the ``Dependency`` property wrapper
5+
extension DependencyValues {
6+
/// The "main" queue.
7+
///
8+
/// Introduce controllable timing to your features by using the ``Dependency`` property wrapper
99
/// with a key path to this property. The wrapped value is a ReactiveSwift scheduler with the time
10-
/// type and options of a dispatch queue. By default, `DispatchQueue.main` will be provided,
11-
/// with the exception of XCTest cases, in which an "unimplemented" scheduler will be provided.
12-
///
13-
/// For example, you could introduce controllable timing to a Composable Architecture reducer
14-
/// that counts the number of seconds it's onscreen:
15-
///
16-
/// ```
17-
/// struct TimerReducer: ReducerProtocol {
18-
/// struct State {
19-
/// var elapsed = 0
20-
/// }
21-
///
22-
/// enum Action {
23-
/// case task
24-
/// case timerTicked
25-
/// }
26-
///
27-
/// @Dependency(\.mainQueue) var mainQueue
28-
///
29-
/// func reduce(into state: inout State, action: Action) -> EffectTask<Action> {
30-
/// switch action {
31-
/// case .task:
32-
/// return .run { send in
33-
/// for await _ in self.mainQueue.timer(interval: .seconds(1)) {
34-
/// send(.timerTicked)
35-
/// }
36-
/// }
37-
///
38-
/// case .timerTicked:
39-
/// state.elapsed += 1
40-
/// return .none
41-
/// }
42-
/// }
43-
/// }
44-
/// ```
45-
///
46-
/// And you could test this reducer by overriding its main queue with a test scheduler:
47-
///
48-
/// ```
10+
/// type and options of a dispatch queue. By default, `DispatchQueue.main` will be provided,
11+
/// with the exception of XCTest cases, in which an "unimplemented" scheduler will be provided.
12+
///
13+
/// For example, you could introduce controllable timing to a Composable Architecture reducer
14+
/// that counts the number of seconds it's onscreen:
15+
///
16+
/// ```
17+
/// struct TimerReducer: ReducerProtocol {
18+
/// struct State {
19+
/// var elapsed = 0
20+
/// }
21+
///
22+
/// enum Action {
23+
/// case task
24+
/// case timerTicked
25+
/// }
26+
///
27+
/// @Dependency(\.mainQueue) var mainQueue
28+
///
29+
/// func reduce(into state: inout State, action: Action) -> EffectTask<Action> {
30+
/// switch action {
31+
/// case .task:
32+
/// return .run { send in
33+
/// for await _ in self.mainQueue.timer(interval: .seconds(1)) {
34+
/// send(.timerTicked)
35+
/// }
36+
/// }
37+
///
38+
/// case .timerTicked:
39+
/// state.elapsed += 1
40+
/// return .none
41+
/// }
42+
/// }
43+
/// }
44+
/// ```
45+
///
46+
/// And you could test this reducer by overriding its main queue with a test scheduler:
47+
///
48+
/// ```
4949
/// let mainQueue = TestScheduler()
50-
///
51-
/// let store = TestStore(
52-
/// initialState: TimerReducer.State()
53-
/// reducer: TimerReducer()
50+
///
51+
/// let store = TestStore(
52+
/// initialState: TimerReducer.State()
53+
/// reducer: TimerReducer()
5454
/// .dependency(\.mainQueue, mainQueue)
55-
/// )
56-
///
57-
/// let task = store.send(.task)
58-
///
59-
/// mainQueue.advance(by: .seconds(1)
60-
/// await store.receive(.timerTicked) {
61-
/// $0.elapsed = 1
62-
/// }
63-
/// mainQueue.advance(by: .seconds(1)
64-
/// await store.receive(.timerTicked) {
65-
/// $0.elapsed = 2
66-
/// }
67-
/// await task.cancel()
68-
/// ```
69-
@available(
70-
iOS, deprecated: 9999.0, message: "Use '\\.continuousClock' or '\\.suspendingClock' instead."
71-
)
72-
@available(
73-
macOS, deprecated: 9999.0,
74-
message: "Use '\\.continuousClock' or '\\.suspendingClock' instead."
75-
)
76-
@available(
77-
tvOS,
78-
deprecated: 9999.0,
79-
message: "Use '\\.continuousClock' or '\\.suspendingClock' instead."
80-
)
81-
@available(
82-
watchOS,
83-
deprecated: 9999.0,
84-
message: "Use '\\.continuousClock' or '\\.suspendingClock' instead."
85-
)
86-
public var mainQueue: DateScheduler {
87-
get { self[MainQueueKey.self] }
88-
set { self[MainQueueKey.self] = newValue }
89-
}
55+
/// )
56+
///
57+
/// let task = store.send(.task)
58+
///
59+
/// mainQueue.advance(by: .seconds(1)
60+
/// await store.receive(.timerTicked) {
61+
/// $0.elapsed = 1
62+
/// }
63+
/// mainQueue.advance(by: .seconds(1)
64+
/// await store.receive(.timerTicked) {
65+
/// $0.elapsed = 2
66+
/// }
67+
/// await task.cancel()
68+
/// ```
69+
@available(
70+
iOS, deprecated: 9999.0, message: "Use '\\.continuousClock' or '\\.suspendingClock' instead."
71+
)
72+
@available(
73+
macOS, deprecated: 9999.0,
74+
message: "Use '\\.continuousClock' or '\\.suspendingClock' instead."
75+
)
76+
@available(
77+
tvOS,
78+
deprecated: 9999.0,
79+
message: "Use '\\.continuousClock' or '\\.suspendingClock' instead."
80+
)
81+
@available(
82+
watchOS,
83+
deprecated: 9999.0,
84+
message: "Use '\\.continuousClock' or '\\.suspendingClock' instead."
85+
)
86+
public var mainQueue: DateScheduler {
87+
get { self[MainQueueKey.self] }
88+
set { self[MainQueueKey.self] = newValue }
89+
}
9090

91-
private enum MainQueueKey: DependencyKey {
91+
private enum MainQueueKey: DependencyKey {
9292
static let liveValue = QueueScheduler.main as DateScheduler
9393
static let testValue = UnimplementedScheduler() as DateScheduler
94-
}
9594
}
95+
}
9696

9797
public final class UnimplementedScheduler: DateScheduler {
9898

Tests/ComposableArchitectureTests/CompatibilityTests.swift

Lines changed: 93 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -4,122 +4,122 @@ import XCTest
44

55
// `@MainActor` introduces issues gathering tests on Linux
66
#if !os(Linux)
7-
@MainActor
8-
final class CompatibilityTests: XCTestCase {
9-
// Actions can be re-entrantly sent into the store if an action is sent that holds an object
10-
// which sends an action on deinit. In order to prevent a simultaneous access exception for this
11-
// case we need to use `withExtendedLifetime` on the buffered actions when clearing them out.
12-
func testCaseStudy_ActionReentranceFromClearedBufferCausingDeinitAction() {
13-
let cancelID = UUID()
14-
15-
struct State: Equatable {}
16-
enum Action: Equatable {
17-
case start
18-
case kickOffAction
19-
case actionSender(OnDeinit)
20-
case stop
21-
22-
var description: String {
23-
switch self {
24-
case .start:
25-
return "start"
26-
case .kickOffAction:
27-
return "kickOffAction"
28-
case .actionSender:
29-
return "actionSender"
30-
case .stop:
31-
return "stop"
7+
@MainActor
8+
final class CompatibilityTests: XCTestCase {
9+
// Actions can be re-entrantly sent into the store if an action is sent that holds an object
10+
// which sends an action on deinit. In order to prevent a simultaneous access exception for this
11+
// case we need to use `withExtendedLifetime` on the buffered actions when clearing them out.
12+
func testCaseStudy_ActionReentranceFromClearedBufferCausingDeinitAction() {
13+
let cancelID = UUID()
14+
15+
struct State: Equatable {}
16+
enum Action: Equatable {
17+
case start
18+
case kickOffAction
19+
case actionSender(OnDeinit)
20+
case stop
21+
22+
var description: String {
23+
switch self {
24+
case .start:
25+
return "start"
26+
case .kickOffAction:
27+
return "kickOffAction"
28+
case .actionSender:
29+
return "actionSender"
30+
case .stop:
31+
return "stop"
32+
}
3233
}
3334
}
34-
}
3535
let (signal, observer) = Signal<Action, Never>.pipe()
3636

37-
var handledActions: [String] = []
37+
var handledActions: [String] = []
3838

39-
let reducer = Reducer<State, Action, Void> { state, action, env in
40-
handledActions.append(action.description)
39+
let reducer = Reducer<State, Action, Void> { state, action, env in
40+
handledActions.append(action.description)
4141

42-
switch action {
43-
case .start:
42+
switch action {
43+
case .start:
4444
return signal.producer
45-
.eraseToEffect()
46-
.cancellable(id: cancelID)
45+
.eraseToEffect()
46+
.cancellable(id: cancelID)
4747

48-
case .kickOffAction:
48+
case .kickOffAction:
4949
return EffectTask(value: .actionSender(OnDeinit { observer.send(value: .stop) }))
5050

51-
case .actionSender:
52-
return .none
51+
case .actionSender:
52+
return .none
5353

54-
case .stop:
55-
return .cancel(id: cancelID)
54+
case .stop:
55+
return .cancel(id: cancelID)
56+
}
5657
}
57-
}
5858

59-
let store = Store(
60-
initialState: .init(),
61-
reducer: reducer,
62-
environment: ()
63-
)
64-
65-
let viewStore = ViewStore(store)
66-
67-
viewStore.send(.start)
68-
viewStore.send(.kickOffAction)
69-
70-
XCTAssertEqual(
71-
handledActions,
72-
[
73-
"start",
74-
"kickOffAction",
75-
"actionSender",
76-
"stop",
77-
]
78-
)
79-
}
59+
let store = Store(
60+
initialState: .init(),
61+
reducer: reducer,
62+
environment: ()
63+
)
64+
65+
let viewStore = ViewStore(store)
66+
67+
viewStore.send(.start)
68+
viewStore.send(.kickOffAction)
69+
70+
XCTAssertEqual(
71+
handledActions,
72+
[
73+
"start",
74+
"kickOffAction",
75+
"actionSender",
76+
"stop",
77+
]
78+
)
79+
}
8080

81-
// Actions can be re-entrantly sent into the store while observing changes to the store's state.
82-
// In such cases we need to take special care that those re-entrant actions are handled _after_
83-
// the original action.
84-
//
85-
// In particular, this means that in the implementation of `Store.send` we need to flip
86-
// `isSending` to false _after_ the store's state mutation is made so that re-entrant actions
87-
// are buffered rather than immediately handled.
88-
func testCaseStudy_ActionReentranceFromStateObservation() {
89-
let store = Store<Int, Int>(
90-
initialState: 0,
91-
reducer: .init { state, action, _ in
92-
state = action
93-
return .none
94-
},
95-
environment: ()
96-
)
97-
98-
let viewStore = ViewStore(store)
81+
// Actions can be re-entrantly sent into the store while observing changes to the store's state.
82+
// In such cases we need to take special care that those re-entrant actions are handled _after_
83+
// the original action.
84+
//
85+
// In particular, this means that in the implementation of `Store.send` we need to flip
86+
// `isSending` to false _after_ the store's state mutation is made so that re-entrant actions
87+
// are buffered rather than immediately handled.
88+
func testCaseStudy_ActionReentranceFromStateObservation() {
89+
let store = Store<Int, Int>(
90+
initialState: 0,
91+
reducer: .init { state, action, _ in
92+
state = action
93+
return .none
94+
},
95+
environment: ()
96+
)
97+
98+
let viewStore = ViewStore(store)
9999

100100
viewStore.produced.producer
101101
.startWithValues { value in
102-
if value == 1 {
103-
viewStore.send(0)
102+
if value == 1 {
103+
viewStore.send(0)
104+
}
104105
}
105-
}
106106

107-
var stateChanges: [Int] = []
107+
var stateChanges: [Int] = []
108108
viewStore.produced.producer
109109
.startWithValues { stateChanges.append($0) }
110110

111-
XCTAssertEqual(stateChanges, [0])
112-
viewStore.send(1)
113-
XCTAssertEqual(stateChanges, [0, 1, 0])
111+
XCTAssertEqual(stateChanges, [0])
112+
viewStore.send(1)
113+
XCTAssertEqual(stateChanges, [0, 1, 0])
114+
}
114115
}
115-
}
116116

117-
private final class OnDeinit: Equatable {
118-
private let onDeinit: () -> Void
119-
init(onDeinit: @escaping () -> Void) {
120-
self.onDeinit = onDeinit
117+
private final class OnDeinit: Equatable {
118+
private let onDeinit: () -> Void
119+
init(onDeinit: @escaping () -> Void) {
120+
self.onDeinit = onDeinit
121+
}
122+
deinit { self.onDeinit() }
123+
static func == (lhs: OnDeinit, rhs: OnDeinit) -> Bool { true }
121124
}
122-
deinit { self.onDeinit() }
123-
static func == (lhs: OnDeinit, rhs: OnDeinit) -> Bool { true }
124-
}
125125
#endif

0 commit comments

Comments
 (0)