feat: Refactors / moves into individual files, wip.
This commit is contained in:
@@ -1,33 +1,66 @@
|
|||||||
import ComposableArchitecture
|
import ComposableArchitecture
|
||||||
import OSLog
|
import OSLog
|
||||||
|
|
||||||
extension Effect where Action: ReceiveAction {
|
extension Effect {
|
||||||
|
|
||||||
public static func receive(
|
@usableFromInline
|
||||||
_ operation: @escaping () async throws -> Action.ReceiveAction
|
static func receive<T>(
|
||||||
|
_ casePath: AnyCasePath<Action, TaskResult<T>>,
|
||||||
|
_ operation: @escaping @Sendable () async throws -> T
|
||||||
) -> Self {
|
) -> Self {
|
||||||
.run { send in
|
.run { send in
|
||||||
await send(.receive(
|
await send(casePath.embed(
|
||||||
TaskResult { try await operation() }
|
TaskResult { try await operation() }
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func receive<T>(
|
@usableFromInline
|
||||||
_ operation: @escaping () async throws -> T,
|
static func receive<T, V>(
|
||||||
transform: @escaping (T) -> Action.ReceiveAction
|
_ casePath: AnyCasePath<Action, TaskResult<V>>,
|
||||||
|
_ operation: @escaping @Sendable () async throws -> T,
|
||||||
|
_ transform: @escaping @Sendable (T) -> V
|
||||||
) -> Self {
|
) -> Self {
|
||||||
.run { send in
|
.run { send in
|
||||||
await send(.receive(
|
await send(casePath.embed(
|
||||||
TaskResult { try await operation() }
|
TaskResult { try await operation() }
|
||||||
.map(transform)
|
.map(transform)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@inlinable
|
||||||
|
public static func receive<T>(
|
||||||
|
action toResult: CaseKeyPath<Action, TaskResult<T>>,
|
||||||
|
operation: @escaping @Sendable () async throws -> T
|
||||||
|
) -> Self {
|
||||||
|
.receive(AnyCasePath(toResult), operation)
|
||||||
|
}
|
||||||
|
|
||||||
|
@inlinable
|
||||||
|
public static func receive<T, V>(
|
||||||
|
action toResult: CaseKeyPath<Action, TaskResult<V>>,
|
||||||
|
operation: @escaping @Sendable () async throws -> T,
|
||||||
|
transform: @escaping @Sendable (T) -> V
|
||||||
|
) -> Self {
|
||||||
|
.receive(AnyCasePath(toResult), operation, transform)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Effect where Action: ReceiveAction {
|
||||||
|
|
||||||
|
@inlinable
|
||||||
|
public static func receive<T>(
|
||||||
|
_ operation: @escaping @Sendable () async throws -> T,
|
||||||
|
transform: @escaping @Sendable (T) -> Action.ReceiveAction
|
||||||
|
) -> Self {
|
||||||
|
.receive(AnyCasePath(unsafe: Action.receive), operation, transform)
|
||||||
|
}
|
||||||
|
|
||||||
|
@inlinable
|
||||||
public static func receive<T>(
|
public static func receive<T>(
|
||||||
_ toReceiveAction: CaseKeyPath<Action.ReceiveAction, T>,
|
_ toReceiveAction: CaseKeyPath<Action.ReceiveAction, T>,
|
||||||
_ operation: @escaping () async throws -> T
|
_ operation: @escaping @Sendable () async throws -> T
|
||||||
) -> Self {
|
) -> Self {
|
||||||
return .receive(operation) {
|
return .receive(operation) {
|
||||||
AnyCasePath(toReceiveAction).embed($0)
|
AnyCasePath(toReceiveAction).embed($0)
|
||||||
|
|||||||
32
Sources/ComposableSubscriber/Internal/SetAction.swift
Normal file
32
Sources/ComposableSubscriber/Internal/SetAction.swift
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import ComposableArchitecture
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
@usableFromInline
|
||||||
|
enum SetAction<State, Action, Value> {
|
||||||
|
case operation(f: (inout State, Value) -> Effect<Action>)
|
||||||
|
case keyPath(WritableKeyPath<State, Value>, effect: Effect<Action>)
|
||||||
|
case optionalKeyPath(WritableKeyPath<State, Value?>, effect: Effect<Action>)
|
||||||
|
|
||||||
|
@usableFromInline
|
||||||
|
func callAsFunction(state: inout State, value: Value) -> Effect<Action> {
|
||||||
|
switch self {
|
||||||
|
case let .operation(f: f):
|
||||||
|
return f(&state, value)
|
||||||
|
case let .keyPath(keyPath, effect):
|
||||||
|
state[keyPath: keyPath] = value
|
||||||
|
return effect
|
||||||
|
case let .optionalKeyPath(keyPath, effect):
|
||||||
|
state[keyPath: keyPath] = value
|
||||||
|
return effect
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@usableFromInline
|
||||||
|
static func operation(_ f: @escaping (inout State, Value) -> Void) -> Self {
|
||||||
|
.operation(f: { state, value in
|
||||||
|
f(&state, value)
|
||||||
|
return .none
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -4,13 +4,7 @@ import OSLog
|
|||||||
|
|
||||||
public enum OnFailAction<State, Action> {
|
public enum OnFailAction<State, Action> {
|
||||||
case fail(prefix: String? = nil, log: ((String) -> Void)? = nil)
|
case fail(prefix: String? = nil, log: ((String) -> Void)? = nil)
|
||||||
case handle((inout State, Error) -> Void)
|
case operation((inout State, Error) -> Effect<Action>)
|
||||||
|
|
||||||
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
|
|
||||||
@inlinable
|
|
||||||
static func fail(prefix: String? = nil, logger: Logger) -> Self {
|
|
||||||
.fail(prefix: prefix, log: { logger.error("\($0)") })
|
|
||||||
}
|
|
||||||
|
|
||||||
@usableFromInline
|
@usableFromInline
|
||||||
func callAsFunction(state: inout State, error: Error) -> Effect<Action> {
|
func callAsFunction(state: inout State, error: Error) -> Effect<Action> {
|
||||||
@@ -21,10 +15,45 @@ public enum OnFailAction<State, Action> {
|
|||||||
} else {
|
} else {
|
||||||
return .fail(error: error, log: log)
|
return .fail(error: error, log: log)
|
||||||
}
|
}
|
||||||
case let .handle(handler):
|
case let .operation(handler):
|
||||||
handler(&state, error)
|
return handler(&state, error)
|
||||||
return .none
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *)
|
||||||
|
@inlinable
|
||||||
|
static func fail(prefix: String? = nil, logger: Logger) -> Self {
|
||||||
|
.fail(prefix: prefix, log: { logger.error("\($0)") })
|
||||||
|
}
|
||||||
|
|
||||||
|
@inlinable
|
||||||
|
public static func set(
|
||||||
|
_ operation: @escaping @Sendable (inout State, Error) -> Void
|
||||||
|
) -> Self {
|
||||||
|
.operation(
|
||||||
|
SetAction.operation(operation).callAsFunction(state:value:)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@inlinable
|
||||||
|
public static func set(
|
||||||
|
_ operation: @escaping @Sendable (inout State, Error) -> Effect<Action>
|
||||||
|
) -> Self {
|
||||||
|
.operation(
|
||||||
|
SetAction.operation(f: operation).callAsFunction(state:value:)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@inlinable
|
||||||
|
public static func set(
|
||||||
|
keyPath: WritableKeyPath<State, Error?>,
|
||||||
|
effect: Effect<Action> = .none
|
||||||
|
) -> Self {
|
||||||
|
.operation(
|
||||||
|
SetAction.optionalKeyPath(
|
||||||
|
keyPath,
|
||||||
|
effect: effect
|
||||||
|
).callAsFunction(state:value:)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ import OSLog
|
|||||||
|
|
||||||
extension Reducer {
|
extension Reducer {
|
||||||
|
|
||||||
@inlinable
|
@usableFromInline
|
||||||
public func onReceive<V>(
|
func onReceive<V>(
|
||||||
action toReceiveAction: CaseKeyPath<Action, V>,
|
action toReceiveAction: CaseKeyPath<Action, V>,
|
||||||
set setAction: @escaping (inout State, V) -> Effect<Action>
|
set setAction: SetAction<State, Action, V>
|
||||||
) -> _ReceiveReducer<Self, V> {
|
) -> _OnReceiveReducer<Self, V> {
|
||||||
.init(
|
.init(
|
||||||
parent: self,
|
parent: self,
|
||||||
receiveAction: { AnyCasePath(toReceiveAction).extract(from: $0) },
|
receiveAction: { AnyCasePath(toReceiveAction).extract(from: $0) },
|
||||||
@@ -18,40 +18,58 @@ extension Reducer {
|
|||||||
@inlinable
|
@inlinable
|
||||||
public func onReceive<V>(
|
public func onReceive<V>(
|
||||||
action toReceiveAction: CaseKeyPath<Action, V>,
|
action toReceiveAction: CaseKeyPath<Action, V>,
|
||||||
set setAction: @escaping (inout State, V) -> Void
|
set setAction: @escaping (inout State, V) -> Effect<Action>
|
||||||
) -> _ReceiveReducer<Self, V> {
|
) -> _OnReceiveReducer<Self, V> {
|
||||||
.init(
|
self.onReceive(
|
||||||
parent: self,
|
action: toReceiveAction,
|
||||||
receiveAction: { AnyCasePath(toReceiveAction).extract(from: $0) },
|
set: .operation(f: setAction)
|
||||||
setAction: { state, value in
|
|
||||||
setAction(&state, value)
|
|
||||||
return .none
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@inlinable
|
@inlinable
|
||||||
public func onReceive<V>(
|
public func onReceive<V>(
|
||||||
action toReceiveAction: CaseKeyPath<Action, V>,
|
action toReceiveAction: CaseKeyPath<Action, V>,
|
||||||
set toStateKeyPath: WritableKeyPath<State, V>
|
set setAction: @escaping (inout State, V) -> Void
|
||||||
) -> _ReceiveReducer<Self, V> {
|
) -> _OnReceiveReducer<Self, V> {
|
||||||
self.onReceive(action: toReceiveAction, set: toStateKeyPath.callAsFunction(root:value:))
|
self.onReceive(
|
||||||
|
action: toReceiveAction,
|
||||||
|
set: .operation(f: { state, value in
|
||||||
|
setAction(&state, value)
|
||||||
|
return .none
|
||||||
|
})
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@inlinable
|
@inlinable
|
||||||
public func onReceive<V>(
|
public func onReceive<V>(
|
||||||
action toReceiveAction: CaseKeyPath<Action, V>,
|
action toReceiveAction: CaseKeyPath<Action, V>,
|
||||||
set toStateKeyPath: WritableKeyPath<State, V?>
|
set toStateKeyPath: WritableKeyPath<State, V>,
|
||||||
) -> _ReceiveReducer<Self, V> {
|
effect: Effect<Action> = .none
|
||||||
self.onReceive(action: toReceiveAction, set: toStateKeyPath.callAsFunction(root:value:))
|
) -> _OnReceiveReducer<Self, V> {
|
||||||
|
self.onReceive(
|
||||||
|
action: toReceiveAction,
|
||||||
|
set: .keyPath(toStateKeyPath, effect: effect)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@inlinable
|
@inlinable
|
||||||
public func onReceive<V>(
|
public func onReceive<V>(
|
||||||
|
action toReceiveAction: CaseKeyPath<Action, V>,
|
||||||
|
set toStateKeyPath: WritableKeyPath<State, V?>,
|
||||||
|
effect: Effect<Action> = .none
|
||||||
|
) -> _OnReceiveReducer<Self, V> {
|
||||||
|
self.onReceive(
|
||||||
|
action: toReceiveAction,
|
||||||
|
set: .optionalKeyPath(toStateKeyPath, effect: effect)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@usableFromInline
|
||||||
|
func onReceive<V>(
|
||||||
action toReceiveAction: CaseKeyPath<Action, TaskResult<V>>,
|
action toReceiveAction: CaseKeyPath<Action, TaskResult<V>>,
|
||||||
onFail: OnFailAction<State, Action>? = nil,
|
onFail: OnFailAction<State, Action>? = nil,
|
||||||
onSuccess setAction: @escaping (inout State, V) -> Void
|
onSuccess setAction: SetAction<State, Action, V>
|
||||||
) -> _ReceiveReducer<Self, TaskResult<V>> {
|
) -> _OnReceiveReducer<Self, TaskResult<V>> {
|
||||||
self.onReceive(action: toReceiveAction) { state, result in
|
self.onReceive(action: toReceiveAction) { state, result in
|
||||||
switch result {
|
switch result {
|
||||||
case let .failure(error):
|
case let .failure(error):
|
||||||
@@ -60,50 +78,50 @@ extension Reducer {
|
|||||||
}
|
}
|
||||||
return .none
|
return .none
|
||||||
case let .success(value):
|
case let .success(value):
|
||||||
setAction(&state, value)
|
return setAction(state: &state, value: value)
|
||||||
return .none
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@inlinable
|
||||||
|
public func onReceive<V>(
|
||||||
|
action toReceiveAction: CaseKeyPath<Action, TaskResult<V>>,
|
||||||
|
onSuccess setAction: @escaping (inout State, V) -> Void,
|
||||||
|
onFail: OnFailAction<State, Action>? = nil
|
||||||
|
) -> _OnReceiveReducer<Self, TaskResult<V>> {
|
||||||
|
self.onReceive(
|
||||||
|
action: toReceiveAction,
|
||||||
|
onFail: onFail,
|
||||||
|
onSuccess: .operation(setAction)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@inlinable
|
@inlinable
|
||||||
public func onReceive<V>(
|
public func onReceive<V>(
|
||||||
action toReceiveAction: CaseKeyPath<Action, TaskResult<V>>,
|
action toReceiveAction: CaseKeyPath<Action, TaskResult<V>>,
|
||||||
set toStateKeyPath: WritableKeyPath<State, V>,
|
set toStateKeyPath: WritableKeyPath<State, V>,
|
||||||
onFail: OnFailAction<State, Action>? = nil
|
onFail: OnFailAction<State, Action>? = nil,
|
||||||
) -> _ReceiveReducer<Self, TaskResult<V>> {
|
effect: Effect<Action> = .none
|
||||||
self.onReceive(action: toReceiveAction) { state, result in
|
) -> _OnReceiveReducer<Self, TaskResult<V>> {
|
||||||
switch result {
|
self.onReceive(
|
||||||
case let .failure(error):
|
action: toReceiveAction,
|
||||||
if let onFail {
|
onFail: onFail,
|
||||||
return onFail(state: &state, error: error)
|
onSuccess: .keyPath(toStateKeyPath, effect: effect)
|
||||||
}
|
)
|
||||||
return .none
|
|
||||||
case let .success(value):
|
|
||||||
toStateKeyPath(root: &state, value: value)
|
|
||||||
return .none
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@inlinable
|
@inlinable
|
||||||
public func onReceive<V>(
|
public func onReceive<V>(
|
||||||
action toReceiveAction: CaseKeyPath<Action, TaskResult<V>>,
|
action toReceiveAction: CaseKeyPath<Action, TaskResult<V>>,
|
||||||
set toStateKeyPath: WritableKeyPath<State, V?>,
|
set toStateKeyPath: WritableKeyPath<State, V?>,
|
||||||
onFail: OnFailAction<State, Action>? = nil
|
onFail: OnFailAction<State, Action>? = nil,
|
||||||
) -> _ReceiveReducer<Self, TaskResult<V>> {
|
effect: Effect<Action> = .none
|
||||||
self.onReceive(action: toReceiveAction) { state, result in
|
) -> _OnReceiveReducer<Self, TaskResult<V>> {
|
||||||
switch result {
|
self.onReceive(
|
||||||
case let .failure(error):
|
action: toReceiveAction,
|
||||||
if let onFail {
|
onFail: onFail,
|
||||||
return onFail(state: &state, error: error)
|
onSuccess: .optionalKeyPath(toStateKeyPath, effect: effect)
|
||||||
}
|
)
|
||||||
return .none
|
|
||||||
case let .success(value):
|
|
||||||
toStateKeyPath(root: &state, value: value)
|
|
||||||
return .none
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@inlinable
|
@inlinable
|
||||||
@@ -126,7 +144,7 @@ extension Reducer where Action: ReceiveAction {
|
|||||||
@inlinable
|
@inlinable
|
||||||
public func receive<TriggerAction, Value>(
|
public func receive<TriggerAction, Value>(
|
||||||
on triggerAction: CaseKeyPath<Action, TriggerAction>,
|
on triggerAction: CaseKeyPath<Action, TriggerAction>,
|
||||||
with embedCasePath: CaseKeyPath<Action.ReceiveAction, Value>,
|
case embedCasePath: CaseKeyPath<Action.ReceiveAction, Value>,
|
||||||
result resultHandler: @escaping @Sendable () async throws -> Value
|
result resultHandler: @escaping @Sendable () async throws -> Value
|
||||||
) -> _ReceiveOnTriggerReducer<Self, TriggerAction, Action.ReceiveAction> {
|
) -> _ReceiveOnTriggerReducer<Self, TriggerAction, Action.ReceiveAction> {
|
||||||
.init(
|
.init(
|
||||||
@@ -142,16 +160,7 @@ extension Reducer where Action: ReceiveAction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension WritableKeyPath {
|
public struct _OnReceiveReducer<Parent: Reducer, Value>: Reducer {
|
||||||
|
|
||||||
@usableFromInline
|
|
||||||
func callAsFunction(root: inout Root, value: Value) {
|
|
||||||
root[keyPath: self] = value
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct _ReceiveReducer<Parent: Reducer, Value>: Reducer {
|
|
||||||
|
|
||||||
@usableFromInline
|
@usableFromInline
|
||||||
let parent: Parent
|
let parent: Parent
|
||||||
@@ -160,13 +169,13 @@ public struct _ReceiveReducer<Parent: Reducer, Value>: Reducer {
|
|||||||
let receiveAction: (Parent.Action) -> Value?
|
let receiveAction: (Parent.Action) -> Value?
|
||||||
|
|
||||||
@usableFromInline
|
@usableFromInline
|
||||||
let setAction: (inout Parent.State, Value) -> Effect<Parent.Action>
|
let setAction: SetAction<Parent.State, Parent.Action, Value>
|
||||||
|
|
||||||
@usableFromInline
|
@usableFromInline
|
||||||
init(
|
init(
|
||||||
parent: Parent,
|
parent: Parent,
|
||||||
receiveAction: @escaping (Parent.Action) -> Value?,
|
receiveAction: @escaping (Parent.Action) -> Value?,
|
||||||
setAction: @escaping (inout Parent.State, Value) -> Effect<Parent.Action>
|
setAction: SetAction<Parent.State, Parent.Action, Value>
|
||||||
) {
|
) {
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.receiveAction = receiveAction
|
self.receiveAction = receiveAction
|
||||||
@@ -182,7 +191,7 @@ public struct _ReceiveReducer<Parent: Reducer, Value>: Reducer {
|
|||||||
var setEffects = Effect<Action>.none
|
var setEffects = Effect<Action>.none
|
||||||
|
|
||||||
if let value = receiveAction(action) {
|
if let value = receiveAction(action) {
|
||||||
setEffects = setAction(&state, value)
|
setEffects = setAction(state: &state, value: value)
|
||||||
}
|
}
|
||||||
|
|
||||||
return .merge(baseEffects, setEffects)
|
return .merge(baseEffects, setEffects)
|
||||||
@@ -286,9 +286,14 @@ extension Reducer {
|
|||||||
/// return .none
|
/// return .none
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// .subscribe(using: \.number, to: numberFactStream, on: \.task, with: \.receive) { numberFact in
|
/// .subscribe(
|
||||||
/// "\(numberFact) Appended with my custom transformation."
|
/// to: numberFactStream,
|
||||||
/// }
|
/// using: \.number,
|
||||||
|
/// on: \.task,
|
||||||
|
/// with: \.receiveNumberFact
|
||||||
|
/// ) { numberFact in
|
||||||
|
/// "\(numberFact) Appended with my custom transformation."
|
||||||
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
@@ -513,6 +518,7 @@ public struct _SubscribeReducer<Parent: Reducer, TriggerAction, StreamElement, V
|
|||||||
@usableFromInline
|
@usableFromInline
|
||||||
let transform: (StreamElement) -> Value
|
let transform: (StreamElement) -> Value
|
||||||
|
|
||||||
|
@usableFromInline
|
||||||
init(
|
init(
|
||||||
parent: Parent,
|
parent: Parent,
|
||||||
on triggerAction: CaseKeyPath<Parent.Action, TriggerAction>,
|
on triggerAction: CaseKeyPath<Parent.Action, TriggerAction>,
|
||||||
@@ -127,29 +127,16 @@ struct ReducerWithReceiveAction {
|
|||||||
return .none
|
return .none
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.receive(on: \.task, with: \.currentNumber) {
|
.receive(on: \.task, case: \.currentNumber) {
|
||||||
try await numberClient.currentNumber()
|
try await numberClient.currentNumber()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reduce<State, Action> { state, action in
|
|
||||||
// switch action {
|
|
||||||
//
|
|
||||||
// case .receive:
|
|
||||||
// return .none
|
|
||||||
//
|
|
||||||
// case .task:
|
|
||||||
// return .receive(\.currentNumber) {
|
|
||||||
// try await numberClient.currentNumber()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@MainActor
|
|
||||||
final class TCAExtrasTests: XCTestCase {
|
final class TCAExtrasTests: XCTestCase {
|
||||||
|
|
||||||
|
@MainActor
|
||||||
func testSubscribeWithArg() async throws {
|
func testSubscribeWithArg() async throws {
|
||||||
let store = TestStore(
|
let store = TestStore(
|
||||||
initialState: ReducerWithArg.State(number: 19),
|
initialState: ReducerWithArg.State(number: 19),
|
||||||
@@ -167,6 +154,7 @@ final class TCAExtrasTests: XCTestCase {
|
|||||||
await store.finish()
|
await store.finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@MainActor
|
||||||
func testSubscribeWithArgAndTransform() async throws {
|
func testSubscribeWithArgAndTransform() async throws {
|
||||||
let store = TestStore(
|
let store = TestStore(
|
||||||
initialState: ReducerWithTransform.State(number: 10),
|
initialState: ReducerWithTransform.State(number: 10),
|
||||||
@@ -184,6 +172,7 @@ final class TCAExtrasTests: XCTestCase {
|
|||||||
await store.finish()
|
await store.finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@MainActor
|
||||||
func testReceiveAction() async throws {
|
func testReceiveAction() async throws {
|
||||||
let store = TestStore(
|
let store = TestStore(
|
||||||
initialState: ReducerWithReceiveAction.State(number: 19),
|
initialState: ReducerWithReceiveAction.State(number: 19),
|
||||||
@@ -193,7 +182,7 @@ final class TCAExtrasTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let task = await store.send(.task)
|
let task = await store.send(.task)
|
||||||
await store.receive(\.receive) {
|
await store.receive(\.receive.success.currentNumber) {
|
||||||
$0.currentNumber = 69420
|
$0.currentNumber = 69420
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user