Toggle a Todo Between Completed and Not Completed

Story: As a user, I want to be able to toggle a todo between completed and not completed statuses, so that I can keep track of it.

TodoMVC actions

It should create an action to toggle a todo between completed and not completed

Write a test.

diff --git a/tests/todomvc/actions.spec.js b/tests/todomvc/actions.spec.js
index fd31f8f..367d6ad 100644
--- a/tests/todomvc/actions.spec.js
+++ b/tests/todomvc/actions.spec.js
@@ -29,5 +29,13 @@ describe('TodoMVC actions', () => {
     };

     expect(todomvc.actions.deleteTodo('my_id')).to.deep.equal(expectedAction)
+  });
+
+  it('Should create an action to toggle a todo between completed and not completed', () => {
+    const expectedAction = {
+      type: todomvc.types.TOGGLE_COMPLETE_ONE, id: 'my_id'
+    };
+
+    expect(todomvc.actions.toggleCompleteOneTodo('my_id')).to.deep.equal(expectedAction)
   })
 });
(END)

Run the test and watch it fail.

  TodoMVC actions
    ✓ Should create an action to add a todo
    ✓ Should create an action to edit a todo
    ✓ Should create an action to delete a todo
    1) Should create an action to toggle a todo between completed and not completed

  Header component
    Should render correctly
      ✓ Should be a Header
      ✓ Should have a title
      ✓ Should have a TodoTextInput field
    Should behave correctly
      ✓ Should call addTodo() if length of text is greater than 0

  MainSection component
    Should render correctly
      ✓ Should be a MainSection component
      ✓ Should include a list of todos

  TodoApp component
    Should render correctly
      ✓ Should be a TodoApp
      ✓ Should have a header
      ✓ Should have a main section

  TodoItem component
    Should render correctly
      ✓ Should be an li
      ✓ Should have a label
      ✓ Should have a delete button
    Should behave correctly
      ✓ Should switch to edit mode when label onDoubleClick is fired
      ✓ Should call editTodo() when TodoTextInput onSave is called
      ✓ Should leave edit mode after TodoTextInput onSave
      ✓ Should call deleteTodo() when the delete button is clicked
      ✓ Should call deleteTodo() when TodoTextInput onSave is called with no text

  TodoTextInput component
    ✓ Should not call onSave() on blur if isNew
    Should render correctly
      ✓ Should be a TodoTextInput component
    Should behave correctly
      ✓ Should update value on change
      ✓ Should call onSave() on return key press
      ✓ Should reset state on return key press if isNew
      ✓ Should call onSave() on blur if not isNew

  TodoMVC reducer
    ✓ Should handle initial state
    ✓ Should handle ADD todo
    ✓ Should handle EDIT todo
    ✓ Should handle DELETE todo


  30 passing (85ms)
  1 failing

  1) TodoMVC actions Should create an action to toggle a todo between completed and not completed:
     TypeError: _todomvc2.default.actions.toggleCompleteOneTodo is not a function
      at Context.<anonymous> (tests/todomvc/actions.spec.js:39:28)

Write the code to make the test pass.

diff --git a/src/todomvc/ActionTypes.js b/src/todomvc/ActionTypes.js
index 040095a..6259983 100644
--- a/src/todomvc/ActionTypes.js
+++ b/src/todomvc/ActionTypes.js
@@ -3,3 +3,4 @@
 export const ADD = 'todomvc/ADD';
 export const EDIT = 'todomvc/EDIT';
 export const DELETE = 'todomvc/DELETE';
+export const TOGGLE_COMPLETE_ONE = 'todomvc/TOGGLE_COMPLETE_ONE';
(END)
diff --git a/src/todomvc/actions.js b/src/todomvc/actions.js
index 0f1e307..7778446 100644
--- a/src/todomvc/actions.js
+++ b/src/todomvc/actions.js
@@ -13,3 +13,7 @@ export function editTodo(id, text) {
 export function deleteTodo(id) {
   return {type: types.DELETE, id: id}
 }
+
+export function toggleCompleteOneTodo(id) {
+  return {type: types.TOGGLE_COMPLETE_ONE, id: id}
+}
(END)

Run the test and watch it pass.

  TodoMVC actions
    ✓ Should create an action to add a todo
    ✓ Should create an action to edit a todo
    ✓ Should create an action to delete a todo
    ✓ Should create an action to toggle a todo between completed and not completed

  Header component
    Should render correctly
      ✓ Should be a Header
      ✓ Should have a title
      ✓ Should have a TodoTextInput field
    Should behave correctly
      ✓ Should call addTodo() if length of text is greater than 0

  MainSection component
    Should render correctly
      ✓ Should be a MainSection component
      ✓ Should include a list of todos

  TodoApp component
    Should render correctly
      ✓ Should be a TodoApp
      ✓ Should have a header
      ✓ Should have a main section

  TodoItem component
    Should render correctly
      ✓ Should be an li
      ✓ Should have a label
      ✓ Should have a delete button
    Should behave correctly
      ✓ Should switch to edit mode when label onDoubleClick is fired
      ✓ Should call editTodo() when TodoTextInput onSave is called
      ✓ Should leave edit mode after TodoTextInput onSave
      ✓ Should call deleteTodo() when the delete button is clicked
      ✓ Should call deleteTodo() when TodoTextInput onSave is called with no text

  TodoTextInput component
    ✓ Should not call onSave() on blur if isNew
    Should render correctly
      ✓ Should be a TodoTextInput component
    Should behave correctly
      ✓ Should update value on change
      ✓ Should call onSave() on return key press
      ✓ Should reset state on return key press if isNew
      ✓ Should call onSave() on blur if not isNew

  TodoMVC reducer
    ✓ Should handle initial state
    ✓ Should handle ADD todo
    ✓ Should handle EDIT todo
    ✓ Should handle DELETE todo


  31 passing (98ms)

Commit changes.

$ git add .
$ git commit -m 'created an action to toggle a todo'

TodoMVC reducer

It should handle TOGGLE_COMPLETE_ONE todo

Write the test.

diff --git a/tests/todomvc/reducer.spec.js b/tests/todomvc/reducer.spec.js
index dd79807..c7cd472 100644
--- a/tests/todomvc/reducer.spec.js
+++ b/tests/todomvc/reducer.spec.js
@@ -54,5 +54,16 @@ describe('TodoMVC reducer', () => {

     expect(new_state.size).to.equal(1);
     expect(new_state.get(0)).to.equal(state.get(0))
+  });
+
+  it('Should handle TOGGLE_COMPLETE_ONE todo', () => {
+    const state = List([
+      Map({id: uuid.v4(), description: 'My todo', completed: false})
+    ]);
+    const new_state = todomvc.reducer(state, {
+      type: todomvc.types.TOGGLE_COMPLETE_ONE, id: state.get(0).get('id')
+    });
+
+    expect(new_state.get(0).get('completed')).to.equal(!state.get(0).get('completed'))
   })
 });
(END)

Run the test and watch it fail.

  TodoMVC actions
    ✓ Should create an action to add a todo
    ✓ Should create an action to edit a todo
    ✓ Should create an action to delete a todo
    ✓ Should create an action to toggle a todo between completed and not completed

  Header component
    Should render correctly
      ✓ Should be a Header
      ✓ Should have a title
      ✓ Should have a TodoTextInput field
    Should behave correctly
      ✓ Should call addTodo() if length of text is greater than 0

  MainSection component
    Should render correctly
      ✓ Should be a MainSection component
      ✓ Should include a list of todos

  TodoApp component
    Should render correctly
      ✓ Should be a TodoApp
      ✓ Should have a header
      ✓ Should have a main section

  TodoItem component
    Should render correctly
      ✓ Should be an li
      ✓ Should have a label
      ✓ Should have a delete button
    Should behave correctly
      ✓ Should switch to edit mode when label onDoubleClick is fired
      ✓ Should call editTodo() when TodoTextInput onSave is called
      ✓ Should leave edit mode after TodoTextInput onSave
      ✓ Should call deleteTodo() when the delete button is clicked
      ✓ Should call deleteTodo() when TodoTextInput onSave is called with no text

  TodoTextInput component
    ✓ Should not call onSave() on blur if isNew
    Should render correctly
      ✓ Should be a TodoTextInput component
    Should behave correctly
      ✓ Should update value on change
      ✓ Should call onSave() on return key press
      ✓ Should reset state on return key press if isNew
      ✓ Should call onSave() on blur if not isNew

  TodoMVC reducer
    ✓ Should handle initial state
    ✓ Should handle ADD todo
    ✓ Should handle EDIT todo
    ✓ Should handle DELETE todo
    1) Should handle TOGGLE_COMPLETE_ONE todo


  31 passing (110ms)
  1 failing

  1) TodoMVC reducer Should handle TOGGLE_COMPLETE_ONE todo:

      AssertionError: expected false to equal true
      + expected - actual

      -false
      +true

      at Context.<anonymous> (tests/todomvc/reducer.spec.js:67:50)

Write the code to make the test pass.

diff --git a/src/todomvc/reducer.js b/src/todomvc/reducer.js
index 5f9a53c..58f9a29 100644
--- a/src/todomvc/reducer.js
+++ b/src/todomvc/reducer.js
@@ -13,6 +13,8 @@ export default function reducer(state = List([]), action) {
       return (state.map(todo => todo.get('id') === action.id ? todo.set('description', action.description) : todo));
     case types.DELETE:
       return state.filter(todo => todo.get('id') !== action.id);
+    case types.TOGGLE_COMPLETE_ONE:
+      return (state.map(todo => todo.get('id') === action.id ? todo.set('completed', !todo.get('completed')) : todo));
     default:
       // just return the same state
       return (state)
(END)

Run the test and watch it pass.

  TodoMVC actions
    ✓ Should create an action to add a todo
    ✓ Should create an action to edit a todo
    ✓ Should create an action to delete a todo
    ✓ Should create an action to toggle a todo between completed and not completed

  Header component
    Should render correctly
      ✓ Should be a Header
      ✓ Should have a title
      ✓ Should have a TodoTextInput field
    Should behave correctly
      ✓ Should call addTodo() if length of text is greater than 0

  MainSection component
    Should render correctly
      ✓ Should be a MainSection component
      ✓ Should include a list of todos

  TodoApp component
    Should render correctly
      ✓ Should be a TodoApp
      ✓ Should have a header
      ✓ Should have a main section

  TodoItem component
    Should render correctly
      ✓ Should be an li
      ✓ Should have a label
      ✓ Should have a delete button
    Should behave correctly
      ✓ Should switch to edit mode when label onDoubleClick is fired
      ✓ Should call editTodo() when TodoTextInput onSave is called
      ✓ Should leave edit mode after TodoTextInput onSave
      ✓ Should call deleteTodo() when the delete button is clicked
      ✓ Should call deleteTodo() when TodoTextInput onSave is called with no text

  TodoTextInput component
    ✓ Should not call onSave() on blur if isNew
    Should render correctly
      ✓ Should be a TodoTextInput component
    Should behave correctly
      ✓ Should update value on change
      ✓ Should call onSave() on return key press
      ✓ Should reset state on return key press if isNew
      ✓ Should call onSave() on blur if not isNew

  TodoMVC reducer
    ✓ Should handle initial state
    ✓ Should handle ADD todo
    ✓ Should handle EDIT todo
    ✓ Should handle DELETE todo
    ✓ Should handle TOGGLE_COMPLETE_ONE todo


  32 passing (104ms)

Commit changes.

$ git add .
$ git commit -m 'handle TOGGLE_COMPLETE_ONE todo'

TodoItem component

It Should render correctly

It should have a toggle complete status checkbox

Write the test.

diff --git a/tests/todomvc/components/TodoItem.spec.js b/tests/todomvc/components/TodoItem.spec.js
index 9792ed2..67241e8 100644
--- a/tests/todomvc/components/TodoItem.spec.js
+++ b/tests/todomvc/components/TodoItem.spec.js
@@ -47,6 +47,15 @@ describe('TodoItem component', () => {

       expect(button).to.have.length(1);
       expect(button.children().text()).to.equal('delete todo')
+    });
+
+    it('Should have a toggle complete status checkbox', () => {
+      const {component} = setup();
+      const checkbox = component.children('input');
+
+      expect(checkbox).to.have.length(1);
+      expect(checkbox.props().type).to.equal('checkbox');
+      expect(checkbox.props().name).to.equal('completed')
     })
   });

(END)

Run the test and watch it fail.

  TodoMVC actions
    ✓ Should create an action to add a todo
    ✓ Should create an action to edit a todo
    ✓ Should create an action to delete a todo
    ✓ Should create an action to toggle a todo between completed and not completed

  Header component
    Should render correctly
      ✓ Should be a Header
      ✓ Should have a title
      ✓ Should have a TodoTextInput field
    Should behave correctly
      ✓ Should call addTodo() if length of text is greater than 0

  MainSection component
    Should render correctly
      ✓ Should be a MainSection component
      ✓ Should include a list of todos

  TodoApp component
    Should render correctly
      ✓ Should be a TodoApp
      ✓ Should have a header
      ✓ Should have a main section

  TodoItem component
    Should render correctly
      ✓ Should be an li
      ✓ Should have a label
      ✓ Should have a delete button
      1) Should have a toggle complete status checkbox
    Should behave correctly
      ✓ Should switch to edit mode when label onDoubleClick is fired
      ✓ Should call editTodo() when TodoTextInput onSave is called
      ✓ Should leave edit mode after TodoTextInput onSave
      ✓ Should call deleteTodo() when the delete button is clicked
      ✓ Should call deleteTodo() when TodoTextInput onSave is called with no text

  TodoTextInput component
    ✓ Should not call onSave() on blur if isNew
    Should render correctly
      ✓ Should be a TodoTextInput component
    Should behave correctly
      ✓ Should update value on change
      ✓ Should call onSave() on return key press
      ✓ Should reset state on return key press if isNew
      ✓ Should call onSave() on blur if not isNew

  TodoMVC reducer
    ✓ Should handle initial state
    ✓ Should handle ADD todo
    ✓ Should handle EDIT todo
    ✓ Should handle DELETE todo
    ✓ Should handle TOGGLE_COMPLETE_ONE todo


  32 passing (103ms)
  1 failing

  1) TodoItem component Should render correctly Should have a toggle complete status checkbox:

      AssertionError: expected { Object (root, unrendered, ...) } to have a length of 1 but got 0
      + expected - actual

      -0
      +1

      at Context.<anonymous> (tests/todomvc/components/TodoItem.spec.js:56:32)

Write the code to make the test pass.

diff --git a/src/todomvc/components/TodoItem.js b/src/todomvc/components/TodoItem.js
index 384570d..3eea02e 100644
--- a/src/todomvc/components/TodoItem.js
+++ b/src/todomvc/components/TodoItem.js
@@ -35,7 +35,8 @@ export default class TodoItem extends Component {
         <label onDoubleClick={this.handleDoubleClick.bind(this)}>
           {todo.get('description')}
         </label>
         <input type="checkbox" name="completed"/>completed
+        <button onClick={() => deleteTodo(todo.get('id'))}>delete todo</button>
       </li>
     )
   }
@@ -46,7 +47,8 @@ export default class TodoItem extends Component {
     return (
       <li>
         <TodoTextInput text={todo.get('description')} onSave={(text) => this.handleSave(todo.get('id'), text)}/>
         <input type="checkbox" name="completed"/>completed
+        <button onClick={() => deleteTodo(todo.get('id'))}>delete todo</button>
       </li>
     )
   }
(END)

Run the test and watch it pass.

  TodoMVC actions
    ✓ Should create an action to add a todo
    ✓ Should create an action to edit a todo
    ✓ Should create an action to delete a todo
    ✓ Should create an action to toggle a todo between completed and not completed

  Header component
    Should render correctly
      ✓ Should be a Header
      ✓ Should have a title
      ✓ Should have a TodoTextInput field
    Should behave correctly
      ✓ Should call addTodo() if length of text is greater than 0

  MainSection component
    Should render correctly
      ✓ Should be a MainSection component
      ✓ Should include a list of todos

  TodoApp component
    Should render correctly
      ✓ Should be a TodoApp
      ✓ Should have a header
      ✓ Should have a main section

  TodoItem component
    Should render correctly
      ✓ Should be an li
      ✓ Should have a label
      ✓ Should have a delete button
      ✓ Should have a toggle complete status checkbox
    Should behave correctly
      ✓ Should switch to edit mode when label onDoubleClick is fired
      ✓ Should call editTodo() when TodoTextInput onSave is called
      ✓ Should leave edit mode after TodoTextInput onSave
      ✓ Should call deleteTodo() when the delete button is clicked
      ✓ Should call deleteTodo() when TodoTextInput onSave is called with no text

  TodoTextInput component
    ✓ Should not call onSave() on blur if isNew
    Should render correctly
      ✓ Should be a TodoTextInput component
    Should behave correctly
      ✓ Should update value on change
      ✓ Should call onSave() on return key press
      ✓ Should reset state on return key press if isNew
      ✓ Should call onSave() on blur if not isNew

  TodoMVC reducer
    ✓ Should handle initial state
    ✓ Should handle ADD todo
    ✓ Should handle EDIT todo
    ✓ Should handle DELETE todo
    ✓ Should handle TOGGLE_COMPLETE_ONE todo


  33 passing (101ms)

Commit changes.

$ git add .
$ git commit -m 'have a toggle complete status checkbox'

It should behave correctly

It should call toggleCompleteOneTodo() when the complete status checkbox is changed

Write the test.

diff --git a/tests/todomvc/components/TodoItem.spec.js b/tests/todomvc/components/TodoItem.spec.js
index 67241e8..fcfc6e0 100644
--- a/tests/todomvc/components/TodoItem.spec.js
+++ b/tests/todomvc/components/TodoItem.spec.js
@@ -13,7 +13,8 @@ function setup() {
   const props = {
     todo: Map({id: uuid.v4(), description: 'Use Redux', completed: false}),
     editTodo: sinon.spy(),
-    deleteTodo: sinon.spy()
+    deleteTodo: sinon.spy(),
+    toggleCompleteOneTodo: sinon.spy()
   };
   const component = shallow(
     <TodoItem {...props} />
@@ -102,6 +103,14 @@ describe('TodoItem component', () => {
       component.children('label').simulate('doubleclick'); // switch to edit mode
       component.find('TodoTextInput').props().onSave('');
       expect(props.deleteTodo.called).to.be.true
+    });
+
+    it('Should call toggleCompleteOneTodo() when the complete status checkbox is changed', () => {
+      const {component, props} = setup();
+      const input = component.find('input');
+
+      input.simulate('change');
+      expect(props.toggleCompleteOneTodo.called).to.be.true
     })
   })
 });
(END)

Run the test and watch it fail.

  TodoMVC actions
    ✓ Should create an action to add a todo
    ✓ Should create an action to edit a todo
    ✓ Should create an action to delete a todo
    ✓ Should create an action to toggle a todo between completed and not completed

  Header component
    Should render correctly
      ✓ Should be a Header
      ✓ Should have a title
      ✓ Should have a TodoTextInput field
    Should behave correctly
      ✓ Should call addTodo() if length of text is greater than 0

  MainSection component
    Should render correctly
      ✓ Should be a MainSection component
      ✓ Should include a list of todos

  TodoApp component
    Should render correctly
      ✓ Should be a TodoApp
      ✓ Should have a header
      ✓ Should have a main section

  TodoItem component
    Should render correctly
      ✓ Should be an li
      ✓ Should have a label
      ✓ Should have a delete button
      ✓ Should have a toggle complete status checkbox
    Should behave correctly
      ✓ Should switch to edit mode when label onDoubleClick is fired
      ✓ Should call editTodo() when TodoTextInput onSave is called
      ✓ Should leave edit mode after TodoTextInput onSave
      ✓ Should call deleteTodo() when the delete button is clicked
      ✓ Should call deleteTodo() when TodoTextInput onSave is called with no text
      1) Should call toggleCompleteOneTodo() when the complete status checkbox is changed

  TodoTextInput component
    ✓ Should not call onSave() on blur if isNew
    Should render correctly
      ✓ Should be a TodoTextInput component
    Should behave correctly
      ✓ Should update value on change
      ✓ Should call onSave() on return key press
      ✓ Should reset state on return key press if isNew
      ✓ Should call onSave() on blur if not isNew

  TodoMVC reducer
    ✓ Should handle initial state
    ✓ Should handle ADD todo
    ✓ Should handle EDIT todo
    ✓ Should handle DELETE todo
    ✓ Should handle TOGGLE_COMPLETE_ONE todo


  33 passing (94ms)
  1 failing

  1) TodoItem component Should behave correctly Should call toggleCompleteOneTodo() when the complete status checkbox is changed:

      AssertionError: expected false to be true
      + expected - actual

      -false
      +true

      at Context.<anonymous> (tests/todomvc/components/TodoItem.spec.js:113:7)

Write the code to make the test pass, but also let's immediately work on the required prop warning regression.

diff --git a/src/todomvc/components/TodoItem.js b/src/todomvc/components/TodoItem.js
index 9532d03..bb30c72 100644
--- a/src/todomvc/components/TodoItem.js
+++ b/src/todomvc/components/TodoItem.js
@@ -8,7 +8,8 @@ export default class TodoItem extends Component {
   static propTypes = {
     todo: PropTypes.object.isRequired,
     editTodo: PropTypes.func.isRequired,
-    deleteTodo: PropTypes.func.isRequired
+    deleteTodo: PropTypes.func.isRequired,
+    toggleCompleteOneTodo: PropTypes.func.isRequired
   };

   constructor(props, context) {
@@ -28,26 +29,28 @@ export default class TodoItem extends Component {
   }

   renderTodoListItem() {
-    const {todo, deleteTodo} = this.props;
+    const {todo, deleteTodo, toggleCompleteOneTodo} = this.props;

     return (
       <li>
         <label onDoubleClick={ this.handleDoubleClick.bind(this) }>
           { todo.get('description') }
         </label>
-        <input type="checkbox" name="completed" />completed
+        <input type="checkbox" name="completed" checked={todo.get('completed')}
+               onChange={ () => toggleCompleteOneTodo(todo.get('id')) }/>completed
         <button onClick={ () => deleteTodo(todo.get('id')) }>delete todo</button>
       </li>
     )
   }

   renderTodoTextInput() {
-    const {todo, deleteTodo} = this.props;
+    const {todo, deleteTodo, toggleCompleteOneTodo} = this.props;

     return (
       <li>
         <TodoTextInput text={ todo.get('description') } onSave={ (text) => this.handleSave(todo.get('id'), text) }/>
-        <input type="checkbox" name="completed" />completed
+        <input type="checkbox" name="completed" checked={todo.get('completed')}
+               onChange={ () => toggleCompleteOneTodo(todo.get('id')) }/>completed
         <button onClick={ () => deleteTodo(todo.get('id')) }>delete todo</button>
       </li>
     )
diff --git a/tests/todomvc/components/MainSection.spec.js b/tests/todomvc/components/MainSection.spec.js
index badf84c..dd90ed1 100644
--- a/tests/todomvc/components/MainSection.spec.js
+++ b/tests/todomvc/components/MainSection.spec.js
@@ -18,7 +18,8 @@ function setup() {
     ]),
     actions: {
       editTodo: sinon.spy(),
-      deleteTodo: sinon.spy()
+      deleteTodo: sinon.spy(),
+      toggleCompleteOneTodo: sinon.spy()
     }
   };

(END)

Run the test and watch it pass.

  TodoMVC actions
    ✓ Should create an action to add a todo
    ✓ Should create an action to edit a todo
    ✓ Should create an action to delete a todo
    ✓ Should create an action to toggle a todo between completed and not completed

  Header component
    Should render correctly
      ✓ Should be a Header
      ✓ Should have a title
      ✓ Should have a TodoTextInput field
    Should behave correctly
      ✓ Should call addTodo() if length of text is greater than 0

  MainSection component
    Should render correctly
      ✓ Should be a MainSection component
      ✓ Should include a list of todos

  TodoApp component
    Should render correctly
      ✓ Should be a TodoApp
      ✓ Should have a header
      ✓ Should have a main section

  TodoItem component
    Should render correctly
      ✓ Should be an li
      ✓ Should have a label
      ✓ Should have a delete button
      ✓ Should have a toggle complete status checkbox
    Should behave correctly
      ✓ Should switch to edit mode when label onDoubleClick is fired
      ✓ Should call editTodo() when TodoTextInput onSave is called
      ✓ Should leave edit mode after TodoTextInput onSave
      ✓ Should call deleteTodo() when the delete button is clicked
      ✓ Should call deleteTodo() when TodoTextInput onSave is called with no text
      ✓ Should call toggleCompleteOneTodo() when the complete status checkbox is changed

  TodoTextInput component
    ✓ Should not call onSave() on blur if isNew
    Should render correctly
      ✓ Should be a TodoTextInput component
    Should behave correctly
      ✓ Should update value on change
      ✓ Should call onSave() on return key press
      ✓ Should reset state on return key press if isNew
      ✓ Should call onSave() on blur if not isNew

  TodoMVC reducer
    ✓ Should handle initial state
    ✓ Should handle ADD todo
    ✓ Should handle EDIT todo
    ✓ Should handle DELETE todo
    ✓ Should handle TOGGLE_COMPLETE_ONE todo


  34 passing (103ms)

Commit changes.

$ git add .
$ git commit -m 'call toggleCompleteOneTodo() when the complete status checkbox is changed'

Run It!

Now let's see what this looks like.

Open http://localhost:4000 in your web browser.

Type "Hello" into the text input box and see a new complete status checkbox appear.

Last updated

Was this helpful?