Skip to content

Instantly share code, notes, and snippets.

@finalfantasia
Last active February 21, 2022 03:30
Show Gist options
  • Save finalfantasia/2673d431e76a6ac472a4b934e77a0302 to your computer and use it in GitHub Desktop.
Save finalfantasia/2673d431e76a6ac472a4b934e77a0302 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