Add a Todo
Story: As a user, I want to add a todo to my todos list
Since this is our first story, we'll need to create some scaffolding to complete it. It will probably be our largest single story, creating basic React/Redux structures like Actions, Action Types, the Reducer, and the Component hierarchy, all the way up to the top-level Container. In a real project team, we might choose to split this story into several sub-stories or sub-tasks that can each be completed by a separate engineer, in parallel.
TodoMVC actions
It should create an action to add a todo
Write the test.
// tests/todomvc/actions.spec.js
'use strict';
import {expect} from 'chai'
import todomvc from '../../src/todomvc'
describe('TodoMVC actions', () => {
it('Should create an action to add a todo', () => {
const description = 'My todo';
const expectedAction = {
type: 'todomvc/ADD', description: description, completed: false
};
expect(todomvc.actions.addTodo(description)).to.deep.equal(expectedAction)
})
});Run the test and watch it fail.
Write the code to make the test pass. In this case, the test failed because we haven't yet written any production code, so we couldn't find the todomvc module.
We will also need to a place to define our action type constants:
Finally, we will need to create an index file to export modules from our application:
Run the test and watch it pass.
Commit changes.
TodoMVC reducer
It should handle initial state
Write the test.
Run the test and watch it fail.
Write the code to make the test pass.
And export the new reducer from the application.
Run the test and watch it pass.
Commit changes.
It should handle ADD todo
Write the test.
Run the test and watch it fail.
Write the code to make the test pass.
Run the test and watch it pass.
Commit changes.
TodoTextInput component
It should render correctly
It should be a TodoTextInput component
Write the test.
Run the test and watch it fail.
Write the code to make the test pass.
Run the test and watch it pass.
Commit changes.
Should behave correctly
It should update value on change
Write the test.
Run the test and watch it fail.
Write the code to make the test pass.
Run the test and watch it pass.
Commit changes.
It should call onSave() on return key press
Write the test. We need to import sinon to spy on the onSave
Run the test and watch it fail.
Write the code to make the test pass.
Run the test and watch it pass.
Commit changes.
It should reset state on return key press if isNew
Write the test.
Run the test and watch it fail.
Write the code to make the test pass.
Run the test and watch it pass.
Commit changes.
It should call onSave() on blur if not isNew
Write the test.
Run the test and watch it fail.
Write the code to make the test pass.
Run the test and watch it pass.
Commit changes.
It should not call onSave() on blur if isNew
Write the test.
Run the test and watch it fail.
Write the code to make the test pass.
Run the test and watch it pass.
Commit changes.
Header component
Should render correctly
It should be a Header component
Write the test.
Run the test and watch it fail.
Write the code to make the test pass.
Run the test and watch it pass.
Commit changes.
It should have a title
Write the test.
Run the test and watch it fail.
Write the code to make the test pass.
Run the test and watch it pass.
Commit changes.
It should have a TodoTextInput field
Write the test.
Run the test and watch it fail.
Write the code to make the test pass.
Run the test and watch it pass. Note the warning, below. We'll implement onSave in the next test.
Commit changes.
Should behave correctly
It should call addTodo() if length of text is greater than 0
Write the test.
Run the test and watch it fail.
Write the code to make the test pass.
Run the test and watch it pass.
Commit changes.
TodoApp component
This is the top-level container component of our application. To render it, we'll need a Redux store. However, we don't want to pull the whole application template into these tests. Instead, we'll just create our own, simple Redux store using our existing reducer.
Interestingly, there is not a lot to test in this component, since it's mostly just responsible for rendering its child components and passing them the mapped store and actions.
Should render correctly
It should have a Header
Write the test.
Run the test and watch it fail.
Write the code to make the test pass.
Run the test and watch it pass.
Commit changes.
Tie everything together
Commit changes.
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 what happens. Then enter "World" You can watch state update with each action in the Redux Dev Tools window on the right, like this:

Last updated
Was this helpful?