| import React from 'react' |
| import TestUtils from 'react-addons-test-utils' |
| import TodoItem from './TodoItem' |
| import TodoTextInput from './TodoTextInput' |
| |
| const setup = ( editing = false ) => { |
| const props = { |
| todo: { |
| id: 0, |
| text: 'Use Redux', |
| completed: false |
| }, |
| editTodo: jest.fn(), |
| deleteTodo: jest.fn(), |
| completeTodo: jest.fn() |
| } |
| |
| const renderer = TestUtils.createRenderer() |
| |
| renderer.render( |
| <TodoItem {...props} /> |
| ) |
| |
| let output = renderer.getRenderOutput() |
| |
| if (editing) { |
| const label = output.props.children.props.children[1] |
| label.props.onDoubleClick({}) |
| output = renderer.getRenderOutput() |
| } |
| |
| return { |
| props: props, |
| output: output, |
| renderer: renderer |
| } |
| } |
| |
| describe('components', () => { |
| describe('TodoItem', () => { |
| it('initial render', () => { |
| const { output } = setup() |
| |
| expect(output.type).toBe('li') |
| expect(output.props.className).toBe('') |
| |
| const div = output.props.children |
| |
| expect(div.type).toBe('div') |
| expect(div.props.className).toBe('view') |
| |
| const [ input, label, button ] = div.props.children |
| |
| expect(input.type).toBe('input') |
| expect(input.props.checked).toBe(false) |
| |
| expect(label.type).toBe('label') |
| expect(label.props.children).toBe('Use Redux') |
| |
| expect(button.type).toBe('button') |
| expect(button.props.className).toBe('destroy') |
| }) |
| |
| it('input onChange should call completeTodo', () => { |
| const { output, props } = setup() |
| const input = output.props.children.props.children[0] |
| input.props.onChange({}) |
| expect(props.completeTodo).toBeCalledWith(0) |
| }) |
| |
| it('button onClick should call deleteTodo', () => { |
| const { output, props } = setup() |
| const button = output.props.children.props.children[2] |
| button.props.onClick({}) |
| expect(props.deleteTodo).toBeCalledWith(0) |
| }) |
| |
| it('label onDoubleClick should put component in edit state', () => { |
| const { output, renderer } = setup() |
| const label = output.props.children.props.children[1] |
| label.props.onDoubleClick({}) |
| const updated = renderer.getRenderOutput() |
| expect(updated.type).toBe('li') |
| expect(updated.props.className).toBe('editing') |
| }) |
| |
| it('edit state render', () => { |
| const { output } = setup(true) |
| |
| expect(output.type).toBe('li') |
| expect(output.props.className).toBe('editing') |
| |
| const input = output.props.children |
| expect(input.type).toBe(TodoTextInput) |
| expect(input.props.text).toBe('Use Redux') |
| expect(input.props.editing).toBe(true) |
| }) |
| |
| it('TodoTextInput onSave should call editTodo', () => { |
| const { output, props } = setup(true) |
| output.props.children.props.onSave('Use Redux') |
| expect(props.editTodo).toBeCalledWith(0, 'Use Redux') |
| }) |
| |
| it('TodoTextInput onSave should call deleteTodo if text is empty', () => { |
| const { output, props } = setup(true) |
| output.props.children.props.onSave('') |
| expect(props.deleteTodo).toBeCalledWith(0) |
| }) |
| |
| it('TodoTextInput onSave should exit component from edit state', () => { |
| const { output, renderer } = setup(true) |
| output.props.children.props.onSave('Use Redux') |
| const updated = renderer.getRenderOutput() |
| expect(updated.type).toBe('li') |
| expect(updated.props.className).toBe('') |
| }) |
| }) |
| }) |