Skip to content

Commit

Permalink
Update README and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
denizcoskun committed Apr 5, 2021
1 parent 4af2a29 commit 8676fe6
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 83 deletions.
62 changes: 32 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,17 @@ class AppStore: RxStore {
}

// Define actions
enum CounterAction: RxStore.Action {
case Increment
case Decrement
enum CounterAction {
struct Increment: RxStore.Action {}
struct Decrement: RxStore.Action {}
}

// Create a reducer
let reducer : RxStore.Reducer<Int> = {state, action in
switch action {
case CounterAction.Increment:
case _ as CounterAction.Increment:
return state + 1
case CounterAction.Decrement:
case _ as CounterAction.Decrement:
return state - 1
default:
return state
Expand Down Expand Up @@ -63,23 +63,23 @@ class AppStore: RxStore {
}

// Define actions
enum CounterAction: RxStore.Action {
case Increment
case Decrement
enum CounterAction {
struct Increment: RxStoreAction {}
struct Decrement: RxStoreAction {}
}

enum LoadingAction: RxStore.Action {
case Loading
case Loaded
enum LoadingAction {
struct Loading: RxStoreAction {}
struct Loaded: RxStoreAction {}
}


// Reducer for counter state
let counterReducer : RxStore.Reducer<Int> = {state, action in
switch action {
case CounterAction.Increment:
case _ as CounterAction.Increment:
return state + 1
case CounterAction.Decrement:
case _ as CounterAction.Decrement:
return state - 1
default:
return state
Expand All @@ -89,9 +89,9 @@ let counterReducer : RxStore.Reducer<Int> = {state, action in
// Reducer for loading state
let loadingReducer: RxStore.Reducer<Bool> = {state, action in
switch action {
case LoadingAction.Loading:
case _ as LoadingAction.Loading:
return true
case LoadingAction.Loaded:
case _ as LoadingAction.Loaded:
return false
default:
return state
Expand All @@ -115,8 +115,8 @@ let cancellable2 = appStore
.loadingState
.sink(receiveValue: {print($0)}) // false, true

appStore.dispatch(action: CounterAction.Increment)
appStore.dispatch(action: LoadingAction.Loaded)
appStore.dispatch(action: CounterAction.Increment())
appStore.dispatch(action: LoadingAction.Loaded())

```

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

enum Action: RxStore.Action {
case LoadTodos, LoadTodosSuccess([Todo]), LoadTodosFailure
enum Action: {
struct LoadTodos: RxStoreAction {}
struct LoadTodosSuccess: RxStoreAction {
let payload: [Todo]
}
struct LoadTodosFailure: RxStoreAction {
let error: Error
}
}

let todoReducer: RxStore.Reducer = {state, action -> TodosState in
switch action {
case Action.LoadTodosSuccess(let todos):
case let action as Action.LoadTodosSuccess:
var newState = state
todos.forEach {
action.payload.forEach {
newState[$0.id] = $0
}
return newState
Expand All @@ -154,15 +160,11 @@ let todoReducer: RxStore.Reducer = {state, action -> TodosState in
}
}

let loadTodosEffect: RxStore.Effect = {state, action in
action.flatMap {action -> RxStore.ActionObservable in
if case Action.LoadTodos = action {
return mockGetTodosFromServer().map {
Action.LoadTodosSuccess($0)
}.eraseToAnyPublisher()
}
return Empty().eraseToAnyPublisher()
}.eraseToAnyPublisher()
let loadTodosEffect = AppStore.createEffect(Action.LoadTodos.self) { store, action in
mockGetTodosFromServer()
.map { Action.LoadTodosSuccess($0) }
.catch {Just(Action.LoadTodosFailure(error: $0))}
.eraseToAnyPublisher()
}


Expand Down
8 changes: 0 additions & 8 deletions Sources/RxStore/RxStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,10 @@ public protocol RxStoreProtocol : AnyObject {
}


public enum RxStoreActions: RxStoreAction {
case Empty
}



extension RxStoreProtocol {
public typealias ActionObservable = AnyPublisher<RxStoreAction, Never>
// public typealias Effect = (Self, ActionObservable) -> ActionObservable
// public typealias Effect<:T: RxStoreAction> = Effects<T>

}


Expand Down Expand Up @@ -112,7 +105,6 @@ extension RxStoreProtocol {
.eraseToAnyPublisher()
return self
}

}

extension RxStoreProtocol {
Expand Down
82 changes: 37 additions & 45 deletions Tests/RxStoreTests/RxStoreTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@ import Combine

import RxStore

enum CounterAction: RxStore.Action {
case Increment
case Decrement
case Dummy
enum CounterAction {
struct Increment: RxStoreAction {}
struct Decrement: RxStoreAction {}

}

final class RxStoreTests: XCTestCase {
var subscriptions = Set<AnyCancellable>()

override func tearDown() {
subscriptions = []
}
func testExampleWithCounter() {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct
Expand All @@ -23,9 +28,9 @@ final class RxStoreTests: XCTestCase {

let reducer : AppStore.Reducer<Int> = {state, action in
switch action {
case CounterAction.Increment:
case _ as CounterAction.Increment:
return state + 1
case CounterAction.Decrement:
case _ as CounterAction.Decrement:
return state - 1
default:
return state
Expand All @@ -35,35 +40,14 @@ final class RxStoreTests: XCTestCase {
let store = AppStore().registerReducer(for: \.counterState, reducer)
.initialize()

store.dispatch(action: CounterAction.Increment)
store.dispatch(action: CounterAction.Increment())
let _ = store.counterState.sink(receiveValue: { value in
XCTAssertEqual(value, 1)
})


}

func testEmptyActionsIgnored() {
class TestStore: RxStore {
let emptyState = RxStore.State(false)
}

let store = TestStore().registerReducer(for: \.emptyState, {state, action in
if case RxStoreActions.Empty = action {
return true
}
return false
}).initialize()

enum Action: RxStore.Action {
case first
}
let _ = store.emptyState.sink(receiveValue: {state in
XCTAssertEqual(state, false)
})
store.dispatch(action: RxStoreActions.Empty)
store.dispatch(action: Action.first)
}

func testEffects() {
struct Todo: Codable, Equatable {
Expand Down Expand Up @@ -115,12 +99,9 @@ final class RxStoreTests: XCTestCase {
}



let loadTodosEffect = AppStore.createEffect(Action.LoadTodos.self) { store, action in
mockGetTodosFromServer()
.map {
Action.LoadTodosSuccess($0)
}
.map { Action.LoadTodosSuccess($0) }
.replaceError(with: Action.LoadTodosFailure())
.eraseToAnyPublisher()
}
Expand All @@ -129,12 +110,20 @@ final class RxStoreTests: XCTestCase {
.registerReducer(for: \.todosState, todoReducer)
.registerEffects([loadTodosEffect])
.initialize()

var actions: [RxStoreAction] = []
store.stream.prefix(2).sink(receiveCompletion: {_ in
XCTAssertTrue(actions[0] is Action.LoadTodos)
XCTAssertTrue(actions[1] is Action.LoadTodosSuccess)
}, receiveValue: {action in
actions.append(action)
}).store(in: &subscriptions)

store.dispatch(action: Action.LoadTodos())

let _ = store.todosState.sink(receiveValue: {state in
XCTAssertEqual(state, [mockTodo.id: mockTodo])
})

}

func testSelector() {
Expand All @@ -143,15 +132,17 @@ final class RxStoreTests: XCTestCase {
var userTodoIds = RxStore.State<Dictionary<Int, [Int]>>([userId:[mockTodo.id], userId2: [mockTodo2.id]])
var counter = RxStore.State(0)
}
enum Action: RxStore.Action {
case AddTodo(Todo)
enum Action {
struct AddTodo: RxStoreAction {
let todo: Todo
}
}

func counterReducer(_ state: Int, action: RxStore.Action) -> Int {
switch action {
case CounterAction.Increment:
case _ as CounterAction.Increment:
return state + 1
case CounterAction.Decrement:
case _ as CounterAction.Decrement:
return state - 1
default:
return state
Expand All @@ -160,9 +151,9 @@ final class RxStoreTests: XCTestCase {

let store = AppStore()
.registerReducer(for: \.todos, {state, action in
if case Action.AddTodo(let todo) = action {
if let action = action as? Action.AddTodo {
var newState = state
newState.append(todo)
newState.append(action.todo)
return newState
}
return state
Expand All @@ -177,12 +168,13 @@ final class RxStoreTests: XCTestCase {
return userTodos
}
}

store.dispatch(action: Action.AddTodo(mockTodo2))
let _ = store.select(getTodosForSelectedUser(userId2)).sink { userTodos in
XCTAssertEqual(userTodos, [mockTodo2])
}

let _ = store.select(getTodosForSelectedUser(userId2)).prefix(2).collect()
.sink {todos in
XCTAssert(todos == [[], [mockTodo2]] as [[Todo]], "failed")
}.store(in: &subscriptions)

store.dispatch(action: Action.AddTodo(todo: mockTodo2))
}

static var allTests = [
Expand Down

0 comments on commit 8676fe6

Please sign in to comment.