Skip to content

Commit 8676fe6

Browse files
committed
Update README and tests
1 parent 4af2a29 commit 8676fe6

File tree

3 files changed

+69
-83
lines changed

3 files changed

+69
-83
lines changed

README.md

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,17 @@ class AppStore: RxStore {
1717
}
1818

1919
// Define actions
20-
enum CounterAction: RxStore.Action {
21-
case Increment
22-
case Decrement
20+
enum CounterAction {
21+
struct Increment: RxStore.Action {}
22+
struct Decrement: RxStore.Action {}
2323
}
2424

2525
// Create a reducer
2626
let reducer : RxStore.Reducer<Int> = {state, action in
2727
switch action {
28-
case CounterAction.Increment:
28+
case _ as CounterAction.Increment:
2929
return state + 1
30-
case CounterAction.Decrement:
30+
case _ as CounterAction.Decrement:
3131
return state - 1
3232
default:
3333
return state
@@ -63,23 +63,23 @@ class AppStore: RxStore {
6363
}
6464

6565
// Define actions
66-
enum CounterAction: RxStore.Action {
67-
case Increment
68-
case Decrement
66+
enum CounterAction {
67+
struct Increment: RxStoreAction {}
68+
struct Decrement: RxStoreAction {}
6969
}
7070

71-
enum LoadingAction: RxStore.Action {
72-
case Loading
73-
case Loaded
71+
enum LoadingAction {
72+
struct Loading: RxStoreAction {}
73+
struct Loaded: RxStoreAction {}
7474
}
7575

7676

7777
// Reducer for counter state
7878
let counterReducer : RxStore.Reducer<Int> = {state, action in
7979
switch action {
80-
case CounterAction.Increment:
80+
case _ as CounterAction.Increment:
8181
return state + 1
82-
case CounterAction.Decrement:
82+
case _ as CounterAction.Decrement:
8383
return state - 1
8484
default:
8585
return state
@@ -89,9 +89,9 @@ let counterReducer : RxStore.Reducer<Int> = {state, action in
8989
// Reducer for loading state
9090
let loadingReducer: RxStore.Reducer<Bool> = {state, action in
9191
switch action {
92-
case LoadingAction.Loading:
92+
case _ as LoadingAction.Loading:
9393
return true
94-
case LoadingAction.Loaded:
94+
case _ as LoadingAction.Loaded:
9595
return false
9696
default:
9797
return state
@@ -115,8 +115,8 @@ let cancellable2 = appStore
115115
.loadingState
116116
.sink(receiveValue: {print($0)}) // false, true
117117

118-
appStore.dispatch(action: CounterAction.Increment)
119-
appStore.dispatch(action: LoadingAction.Loaded)
118+
appStore.dispatch(action: CounterAction.Increment())
119+
appStore.dispatch(action: LoadingAction.Loaded())
120120

121121
```
122122

@@ -137,15 +137,21 @@ class AppStore: RxStore {
137137
var loadingState = RxStore.State(false)
138138
}
139139

140-
enum Action: RxStore.Action {
141-
case LoadTodos, LoadTodosSuccess([Todo]), LoadTodosFailure
140+
enum Action: {
141+
struct LoadTodos: RxStoreAction {}
142+
struct LoadTodosSuccess: RxStoreAction {
143+
let payload: [Todo]
144+
}
145+
struct LoadTodosFailure: RxStoreAction {
146+
let error: Error
147+
}
142148
}
143149

144150
let todoReducer: RxStore.Reducer = {state, action -> TodosState in
145151
switch action {
146-
case Action.LoadTodosSuccess(let todos):
152+
case let action as Action.LoadTodosSuccess:
147153
var newState = state
148-
todos.forEach {
154+
action.payload.forEach {
149155
newState[$0.id] = $0
150156
}
151157
return newState
@@ -154,15 +160,11 @@ let todoReducer: RxStore.Reducer = {state, action -> TodosState in
154160
}
155161
}
156162

157-
let loadTodosEffect: RxStore.Effect = {state, action in
158-
action.flatMap {action -> RxStore.ActionObservable in
159-
if case Action.LoadTodos = action {
160-
return mockGetTodosFromServer().map {
161-
Action.LoadTodosSuccess($0)
162-
}.eraseToAnyPublisher()
163-
}
164-
return Empty().eraseToAnyPublisher()
165-
}.eraseToAnyPublisher()
163+
let loadTodosEffect = AppStore.createEffect(Action.LoadTodos.self) { store, action in
164+
mockGetTodosFromServer()
165+
.map { Action.LoadTodosSuccess($0) }
166+
.catch {Just(Action.LoadTodosFailure(error: $0))}
167+
.eraseToAnyPublisher()
166168
}
167169

168170

Sources/RxStore/RxStore.swift

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,17 +57,10 @@ public protocol RxStoreProtocol : AnyObject {
5757
}
5858

5959

60-
public enum RxStoreActions: RxStoreAction {
61-
case Empty
62-
}
63-
6460

6561

6662
extension RxStoreProtocol {
6763
public typealias ActionObservable = AnyPublisher<RxStoreAction, Never>
68-
// public typealias Effect = (Self, ActionObservable) -> ActionObservable
69-
// public typealias Effect<:T: RxStoreAction> = Effects<T>
70-
7164
}
7265

7366

@@ -112,7 +105,6 @@ extension RxStoreProtocol {
112105
.eraseToAnyPublisher()
113106
return self
114107
}
115-
116108
}
117109

118110
extension RxStoreProtocol {

Tests/RxStoreTests/RxStoreTests.swift

Lines changed: 37 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,18 @@ import Combine
33

44
import RxStore
55

6-
enum CounterAction: RxStore.Action {
7-
case Increment
8-
case Decrement
9-
case Dummy
6+
enum CounterAction {
7+
struct Increment: RxStoreAction {}
8+
struct Decrement: RxStoreAction {}
9+
1010
}
1111

1212
final class RxStoreTests: XCTestCase {
13+
var subscriptions = Set<AnyCancellable>()
14+
15+
override func tearDown() {
16+
subscriptions = []
17+
}
1318
func testExampleWithCounter() {
1419
// This is an example of a functional test case.
1520
// Use XCTAssert and related functions to verify your tests produce the correct
@@ -23,9 +28,9 @@ final class RxStoreTests: XCTestCase {
2328

2429
let reducer : AppStore.Reducer<Int> = {state, action in
2530
switch action {
26-
case CounterAction.Increment:
31+
case _ as CounterAction.Increment:
2732
return state + 1
28-
case CounterAction.Decrement:
33+
case _ as CounterAction.Decrement:
2934
return state - 1
3035
default:
3136
return state
@@ -35,35 +40,14 @@ final class RxStoreTests: XCTestCase {
3540
let store = AppStore().registerReducer(for: \.counterState, reducer)
3641
.initialize()
3742

38-
store.dispatch(action: CounterAction.Increment)
43+
store.dispatch(action: CounterAction.Increment())
3944
let _ = store.counterState.sink(receiveValue: { value in
4045
XCTAssertEqual(value, 1)
4146
})
4247

4348

4449
}
4550

46-
func testEmptyActionsIgnored() {
47-
class TestStore: RxStore {
48-
let emptyState = RxStore.State(false)
49-
}
50-
51-
let store = TestStore().registerReducer(for: \.emptyState, {state, action in
52-
if case RxStoreActions.Empty = action {
53-
return true
54-
}
55-
return false
56-
}).initialize()
57-
58-
enum Action: RxStore.Action {
59-
case first
60-
}
61-
let _ = store.emptyState.sink(receiveValue: {state in
62-
XCTAssertEqual(state, false)
63-
})
64-
store.dispatch(action: RxStoreActions.Empty)
65-
store.dispatch(action: Action.first)
66-
}
6751

6852
func testEffects() {
6953
struct Todo: Codable, Equatable {
@@ -115,12 +99,9 @@ final class RxStoreTests: XCTestCase {
11599
}
116100

117101

118-
119102
let loadTodosEffect = AppStore.createEffect(Action.LoadTodos.self) { store, action in
120103
mockGetTodosFromServer()
121-
.map {
122-
Action.LoadTodosSuccess($0)
123-
}
104+
.map { Action.LoadTodosSuccess($0) }
124105
.replaceError(with: Action.LoadTodosFailure())
125106
.eraseToAnyPublisher()
126107
}
@@ -129,12 +110,20 @@ final class RxStoreTests: XCTestCase {
129110
.registerReducer(for: \.todosState, todoReducer)
130111
.registerEffects([loadTodosEffect])
131112
.initialize()
132-
113+
var actions: [RxStoreAction] = []
114+
store.stream.prefix(2).sink(receiveCompletion: {_ in
115+
XCTAssertTrue(actions[0] is Action.LoadTodos)
116+
XCTAssertTrue(actions[1] is Action.LoadTodosSuccess)
117+
}, receiveValue: {action in
118+
actions.append(action)
119+
}).store(in: &subscriptions)
120+
133121
store.dispatch(action: Action.LoadTodos())
122+
134123
let _ = store.todosState.sink(receiveValue: {state in
135124
XCTAssertEqual(state, [mockTodo.id: mockTodo])
136125
})
137-
126+
138127
}
139128

140129
func testSelector() {
@@ -143,15 +132,17 @@ final class RxStoreTests: XCTestCase {
143132
var userTodoIds = RxStore.State<Dictionary<Int, [Int]>>([userId:[mockTodo.id], userId2: [mockTodo2.id]])
144133
var counter = RxStore.State(0)
145134
}
146-
enum Action: RxStore.Action {
147-
case AddTodo(Todo)
135+
enum Action {
136+
struct AddTodo: RxStoreAction {
137+
let todo: Todo
138+
}
148139
}
149140

150141
func counterReducer(_ state: Int, action: RxStore.Action) -> Int {
151142
switch action {
152-
case CounterAction.Increment:
143+
case _ as CounterAction.Increment:
153144
return state + 1
154-
case CounterAction.Decrement:
145+
case _ as CounterAction.Decrement:
155146
return state - 1
156147
default:
157148
return state
@@ -160,9 +151,9 @@ final class RxStoreTests: XCTestCase {
160151

161152
let store = AppStore()
162153
.registerReducer(for: \.todos, {state, action in
163-
if case Action.AddTodo(let todo) = action {
154+
if let action = action as? Action.AddTodo {
164155
var newState = state
165-
newState.append(todo)
156+
newState.append(action.todo)
166157
return newState
167158
}
168159
return state
@@ -177,12 +168,13 @@ final class RxStoreTests: XCTestCase {
177168
return userTodos
178169
}
179170
}
180-
181-
store.dispatch(action: Action.AddTodo(mockTodo2))
182-
let _ = store.select(getTodosForSelectedUser(userId2)).sink { userTodos in
183-
XCTAssertEqual(userTodos, [mockTodo2])
184-
}
185171

172+
let _ = store.select(getTodosForSelectedUser(userId2)).prefix(2).collect()
173+
.sink {todos in
174+
XCTAssert(todos == [[], [mockTodo2]] as [[Todo]], "failed")
175+
}.store(in: &subscriptions)
176+
177+
store.dispatch(action: Action.AddTodo(todo: mockTodo2))
186178
}
187179

188180
static var allTests = [

0 commit comments

Comments
 (0)