Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save mfrancois3k/2c8c01221bb98988cd8e429a5904234a to your computer and use it in GitHub Desktop.
Save mfrancois3k/2c8c01221bb98988cd8e429a5904234a to your computer and use it in GitHub Desktop.
Todo List Redux Reducer
// <script src="https://cdnjs.cloudflare.com/ajax/libs/expect/1.20.2/expect.min.js"></script>
// redux api
const combineReducers = reducers =>
(state = {}, action) =>
Object.keys (reducers).
reduce ((accumulator, key) => Object.assign ({}, accumulator, {[key]: reducers [key] (state [key], action)}), {})
// redux reducers
const todo = (state = {}, {type, id, text}) => {
switch (type) {
case 'ADD_TODO': return {
id: id,
text: text,
done: false
}
case 'TOGGLE_TODO':
return Object.assign ({}, state, {done: !state.done})
default: return state
}
}
const todos = (state = [], action) => {
const {type, id, text} = action
switch (type) {
case 'ADD_TODO': return [
...state,
todo ({}, action)
]
case 'TOGGLE_TODO':
return state.map (t => t.id === id ? todo (t, {type: type}) : t)
default: return state
}
}
const visibility = (state = '', {type, visibility}) => {
switch (type) {
case 'SET_VISIBILITY': return visibility
default: return state
}
}
// const todoAppReducer = (state = {}, action) => ({
// todos: todoListReducer (state.todos, action),
// visibility: visibilityReducer (state.visibility, action)
// })
const todoApp = combineReducers ({todos, visibility})
// tests
const testAddTodo = () => {
// GIVEN
const stateBefore = []
const action = {
type: 'ADD_TODO',
id: 0,
text: 'Learn Redux'
}
const stateAfter = [{
id: 0,
text: 'Learn Redux',
done: false
}]
Object.freeze (stateBefore)
Object.freeze (action)
// WHEN
const actual = todos (stateBefore, action)
// THEN
expect (actual).toEqual (stateAfter)
}
const testToggleTodo = () => {
// GIVEN
const stateBefore = [{
id: 0,
text: 'Learn Redux',
done: false
}, {
id: 1,
text: 'Go home',
done: false
}]
const action = {
type: 'TOGGLE_TODO',
id: 1
}
const stateAfter = [{
id: 0,
text: 'Learn Redux',
done: false
}, {
id: 1,
text: 'Go home',
done: true
}]
Object.freeze (stateBefore)
Object.freeze (action)
// WHEN
const actual = todos (stateBefore, action)
// THEN
expect (actual).toEqual (stateAfter)
}
const testTodoVisibility = () => {
// GIVEN
const stateBefore = 'SHOW_ALL'
const action = {
type: 'SET_VISIBILITY',
visibility: 'SHOW_DONE_ONLY'
}
const stateAfter = 'SHOW_DONE_ONLY'
Object.freeze (stateBefore)
Object.freeze (action)
// WHEN
const actual = visibility (stateBefore, action)
// THEN
expect (actual).toEqual (stateAfter)
}
const testTodoApp = () => {
// GIVEN
const stateBefore = {
todos: [{
id: 0,
text: 'Learn Redux',
done: false
}, {
id: 1,
text: 'Go home',
done: false
}],
visibility: 'SHOW_ALL'
}
const actionToggleTodo = {
type: 'TOGGLE_TODO',
id: 1
}
const actionSetVisibility = {
type: 'SET_VISIBILITY',
visibility: 'SHOW_DONE_ONLY'
}
const stateAfter = {
todos: [{
id: 0,
text: 'Learn Redux',
done: false
}, {
id: 1,
text: 'Go home',
done: true
}],
visibility: 'SHOW_DONE_ONLY'
}
Object.freeze (stateBefore)
Object.freeze (actionToggleTodo)
Object.freeze (actionSetVisibility)
// WHEN
const stateIntermediate = todoApp (stateBefore, actionToggleTodo)
const actual = todoApp (stateIntermediate, actionSetVisibility)
// THEN
expect (actual).toEqual (stateAfter)
}
// test runners
testAddTodo ()
testToggleTodo ()
testTodoVisibility ()
testTodoApp ()
console.log ('All tests passed.')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment