diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components | |
parent | Initial commit. (diff) | |
download | firefox-esr-upstream.tar.xz firefox-esr-upstream.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components')
10 files changed, 771 insertions, 0 deletions
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/Footer.js b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/Footer.js new file mode 100644 index 0000000000..e272c08a54 --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/Footer.js @@ -0,0 +1,71 @@ +import React, { PropTypes, Component } from 'react' +import classnames from 'classnames' +import { SHOW_ALL, SHOW_COMPLETED, SHOW_ACTIVE } from '../constants/TodoFilters' + +const FILTER_TITLES = { + [SHOW_ALL]: 'All', + [SHOW_ACTIVE]: 'Active', + [SHOW_COMPLETED]: 'Completed' +} + +export default class Footer extends Component { + static propTypes = { + completedCount: PropTypes.number.isRequired, + activeCount: PropTypes.number.isRequired, + filter: PropTypes.string.isRequired, + onClearCompleted: PropTypes.func.isRequired, + onShow: PropTypes.func.isRequired + } + + renderTodoCount() { + const { activeCount } = this.props + const itemWord = activeCount === 1 ? 'item' : 'items' + + return ( + <span className="todo-count"> + <strong>{activeCount || 'No'}</strong> {itemWord} left + </span> + ) + } + + renderFilterLink(filter) { + const title = FILTER_TITLES[filter] + const { filter: selectedFilter, onShow } = this.props + + return ( + <a className={classnames({ selected: filter === selectedFilter })} + style={{ cursor: 'pointer' }} + onClick={() => onShow(filter)}> + {title} + </a> + ) + } + + renderClearButton() { + const { completedCount, onClearCompleted } = this.props + if (completedCount > 0) { + return ( + <button className="clear-completed" + onClick={onClearCompleted} > + Clear completed + </button> + ) + } + } + + render() { + return ( + <footer className="footer"> + {this.renderTodoCount()} + <ul className="filters"> + {[ SHOW_ALL, SHOW_ACTIVE, SHOW_COMPLETED ].map(filter => + <li key={filter}> + {this.renderFilterLink(filter)} + </li> + )} + </ul> + {this.renderClearButton()} + </footer> + ) + } +} diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/Footer.spec.js b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/Footer.spec.js new file mode 100644 index 0000000000..a0fa830e4c --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/Footer.spec.js @@ -0,0 +1,102 @@ +import React from 'react' +import TestUtils from 'react-addons-test-utils' +import Footer from './Footer' +import { SHOW_ALL, SHOW_ACTIVE } from '../constants/TodoFilters' + +const setup = propOverrides => { + const props = Object.assign({ + completedCount: 0, + activeCount: 0, + filter: SHOW_ALL, + onClearCompleted: jest.fn(), + onShow: jest.fn() + }, propOverrides) + + const renderer = TestUtils.createRenderer() + renderer.render(<Footer {...props} />) + const output = renderer.getRenderOutput() + + return { + props: props, + output: output + } +} + +const getTextContent = elem => { + const children = Array.isArray(elem.props.children) ? + elem.props.children : [ elem.props.children ] + + return children.reduce((out, child) => + // Concatenate the text + // Children are either elements or text strings + out + (child.props ? getTextContent(child) : child) + , '') +} + +describe('components', () => { + describe('Footer', () => { + it('should render container', () => { + const { output } = setup() + expect(output.type).toBe('footer') + expect(output.props.className).toBe('footer') + }) + + it('should display active count when 0', () => { + const { output } = setup({ activeCount: 0 }) + const [ count ] = output.props.children + expect(getTextContent(count)).toBe('No items left') + }) + + it('should display active count when above 0', () => { + const { output } = setup({ activeCount: 1 }) + const [ count ] = output.props.children + expect(getTextContent(count)).toBe('1 item left') + }) + + it('should render filters', () => { + const { output } = setup() + const [ , filters ] = output.props.children + expect(filters.type).toBe('ul') + expect(filters.props.className).toBe('filters') + expect(filters.props.children.length).toBe(3) + filters.props.children.forEach(function checkFilter(filter, i) { + expect(filter.type).toBe('li') + const a = filter.props.children + expect(a.props.className).toBe(i === 0 ? 'selected' : '') + expect(a.props.children).toBe({ + 0: 'All', + 1: 'Active', + 2: 'Completed' + }[i]) + }) + }) + + it('should call onShow when a filter is clicked', () => { + const { output, props } = setup() + const [ , filters ] = output.props.children + const filterLink = filters.props.children[1].props.children + filterLink.props.onClick({}) + expect(props.onShow).toBeCalledWith(SHOW_ACTIVE) + }) + + it('shouldnt show clear button when no completed todos', () => { + const { output } = setup({ completedCount: 0 }) + const [ , , clear ] = output.props.children + expect(clear).toBe(undefined) + }) + + it('should render clear button when completed todos', () => { + const { output } = setup({ completedCount: 1 }) + const [ , , clear ] = output.props.children + expect(clear.type).toBe('button') + expect(clear.props.children).toBe('Clear completed') + }) + + it('should call onClearCompleted on clear button click', () => { + const { output, props } = setup({ completedCount: 1 }) + const [ , , clear ] = output.props.children + clear.props.onClick({}) + expect(props.onClearCompleted).toBeCalled() + }) + }) +}) diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/Header.js b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/Header.js new file mode 100644 index 0000000000..9f192399d9 --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/Header.js @@ -0,0 +1,25 @@ +import React, { PropTypes, Component } from 'react' +import TodoTextInput from './TodoTextInput' + +export default class Header extends Component { + static propTypes = { + addTodo: PropTypes.func.isRequired + } + + handleSave = text => { + if (text.length !== 0) { + this.props.addTodo(text) + } + } + + render() { + return ( + <header className="header"> + <h1>todos</h1> + <TodoTextInput newTodo + onSave={this.handleSave} + placeholder="What needs to be done?" /> + </header> + ) + } +} diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/Header.spec.js b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/Header.spec.js new file mode 100644 index 0000000000..6b63df2a34 --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/Header.spec.js @@ -0,0 +1,49 @@ +import React from 'react' +import TestUtils from 'react-addons-test-utils' +import Header from './Header' +import TodoTextInput from './TodoTextInput' + +const setup = () => { + const props = { + addTodo: jest.fn() + } + + const renderer = TestUtils.createRenderer() + renderer.render(<Header {...props} />) + const output = renderer.getRenderOutput() + + return { + props: props, + output: output, + renderer: renderer + } +} + +describe('components', () => { + describe('Header', () => { + it('should render correctly', () => { + const { output } = setup() + + expect(output.type).toBe('header') + expect(output.props.className).toBe('header') + + const [ h1, input ] = output.props.children + + expect(h1.type).toBe('h1') + expect(h1.props.children).toBe('todos') + + expect(input.type).toBe(TodoTextInput) + expect(input.props.newTodo).toBe(true) + expect(input.props.placeholder).toBe('What needs to be done?') + }) + + it('should call addTodo if length of text is greater than 0', () => { + const { output, props } = setup() + const input = output.props.children[1] + input.props.onSave('') + expect(props.addTodo).not.toBeCalled() + input.props.onSave('Use Redux') + expect(props.addTodo).toBeCalled() + }) + }) +}) diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/MainSection.js b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/MainSection.js new file mode 100644 index 0000000000..ec23b516b8 --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/MainSection.js @@ -0,0 +1,78 @@ +import React, { Component, PropTypes } from 'react' +import TodoItem from './TodoItem' +import Footer from './Footer' +import { SHOW_ALL, SHOW_COMPLETED, SHOW_ACTIVE } from '../constants/TodoFilters' + +const TODO_FILTERS = { + [SHOW_ALL]: () => true, + [SHOW_ACTIVE]: todo => !todo.completed, + [SHOW_COMPLETED]: todo => todo.completed +} + +export default class MainSection extends Component { + static propTypes = { + todos: PropTypes.array.isRequired, + actions: PropTypes.object.isRequired + } + + state = { filter: SHOW_ALL } + + handleClearCompleted = () => { + this.props.actions.clearCompleted() + } + + handleShow = filter => { + this.setState({ filter }) + } + + renderToggleAll(completedCount) { + const { todos, actions } = this.props + if (todos.length > 0) { + return ( + <input className="toggle-all" + type="checkbox" + checked={completedCount === todos.length} + onChange={actions.completeAll} /> + ) + } + } + + renderFooter(completedCount) { + const { todos } = this.props + const { filter } = this.state + const activeCount = todos.length - completedCount + + if (todos.length) { + return ( + <Footer completedCount={completedCount} + activeCount={activeCount} + filter={filter} + onClearCompleted={this.handleClearCompleted.bind(this)} + onShow={this.handleShow.bind(this)} /> + ) + } + } + + render() { + const { todos, actions } = this.props + const { filter } = this.state + + const filteredTodos = todos.filter(TODO_FILTERS[filter]) + const completedCount = todos.reduce((count, todo) => + todo.completed ? count + 1 : count, + 0 + ) + + return ( + <section className="main"> + {this.renderToggleAll(completedCount)} + <ul className="todo-list"> + {filteredTodos.map(todo => + <TodoItem key={todo.id} todo={todo} {...actions} /> + )} + </ul> + {this.renderFooter(completedCount)} + </section> + ) + } +} diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/MainSection.spec.js b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/MainSection.spec.js new file mode 100644 index 0000000000..f5924548bb --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/MainSection.spec.js @@ -0,0 +1,129 @@ +import React from 'react' +import TestUtils from 'react-addons-test-utils' +import MainSection from './MainSection' +import TodoItem from './TodoItem' +import Footer from './Footer' +import { SHOW_ALL, SHOW_COMPLETED } from '../constants/TodoFilters' + +const setup = propOverrides => { + const props = Object.assign({ + todos: [ + { + text: 'Use Redux', + completed: false, + id: 0 + }, { + text: 'Run the tests', + completed: true, + id: 1 + } + ], + actions: { + editTodo: jest.fn(), + deleteTodo: jest.fn(), + completeTodo: jest.fn(), + completeAll: jest.fn(), + clearCompleted: jest.fn() + } + }, propOverrides) + + const renderer = TestUtils.createRenderer() + renderer.render(<MainSection {...props} />) + const output = renderer.getRenderOutput() + + return { + props: props, + output: output, + renderer: renderer + } +} + +describe('components', () => { + describe('MainSection', () => { + it('should render container', () => { + const { output } = setup() + expect(output.type).toBe('section') + expect(output.props.className).toBe('main') + }) + + describe('toggle all input', () => { + it('should render', () => { + const { output } = setup() + const [ toggle ] = output.props.children + expect(toggle.type).toBe('input') + expect(toggle.props.type).toBe('checkbox') + expect(toggle.props.checked).toBe(false) + }) + + it('should be checked if all todos completed', () => { + const { output } = setup({ todos: [ + { + text: 'Use Redux', + completed: true, + id: 0 + } + ] + }) + const [ toggle ] = output.props.children + expect(toggle.props.checked).toBe(true) + }) + + it('should call completeAll on change', () => { + const { output, props } = setup() + const [ toggle ] = output.props.children + toggle.props.onChange({}) + expect(props.actions.completeAll).toBeCalled() + }) + }) + + describe('footer', () => { + it('should render', () => { + const { output } = setup() + const [ , , footer ] = output.props.children + expect(footer.type).toBe(Footer) + expect(footer.props.completedCount).toBe(1) + expect(footer.props.activeCount).toBe(1) + expect(footer.props.filter).toBe(SHOW_ALL) + }) + + it('onShow should set the filter', () => { + const { output, renderer } = setup() + const [ , , footer ] = output.props.children + footer.props.onShow(SHOW_COMPLETED) + const updated = renderer.getRenderOutput() + const [ , , updatedFooter ] = updated.props.children + expect(updatedFooter.props.filter).toBe(SHOW_COMPLETED) + }) + + it('onClearCompleted should call clearCompleted', () => { + const { output, props } = setup() + const [ , , footer ] = output.props.children + footer.props.onClearCompleted() + expect(props.actions.clearCompleted).toBeCalled() + }) + }) + + describe('todo list', () => { + it('should render', () => { + const { output, props } = setup() + const [ , list ] = output.props.children + expect(list.type).toBe('ul') + expect(list.props.children.length).toBe(2) + list.props.children.forEach((item, i) => { + expect(item.type).toBe(TodoItem) + expect(item.props.todo).toBe(props.todos[i]) + }) + }) + + it('should filter items', () => { + const { output, renderer, props } = setup() + const [ , , footer ] = output.props.children + footer.props.onShow(SHOW_COMPLETED) + const updated = renderer.getRenderOutput() + const [ , updatedList ] = updated.props.children + expect(updatedList.props.children.length).toBe(1) + expect(updatedList.props.children[0].props.todo).toBe(props.todos[1]) + }) + }) + }) +}) diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/TodoItem.js b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/TodoItem.js new file mode 100644 index 0000000000..490921d543 --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/TodoItem.js @@ -0,0 +1,65 @@ +import React, { Component, PropTypes } from 'react' +import classnames from 'classnames' +import TodoTextInput from './TodoTextInput' + +export default class TodoItem extends Component { + static propTypes = { + todo: PropTypes.object.isRequired, + editTodo: PropTypes.func.isRequired, + deleteTodo: PropTypes.func.isRequired, + completeTodo: PropTypes.func.isRequired + } + + state = { + editing: false + } + + handleDoubleClick = () => { + this.setState({ editing: true }) + } + + handleSave = (id, text) => { + if (text.length === 0) { + this.props.deleteTodo(id) + } else { + this.props.editTodo(id, text) + } + this.setState({ editing: false }) + } + + render() { + const { todo, completeTodo, deleteTodo } = this.props + + let element + if (this.state.editing) { + element = ( + <TodoTextInput text={todo.text} + editing={this.state.editing} + onSave={(text) => this.handleSave(todo.id, text)} /> + ) + } else { + element = ( + <div className="view"> + <input className="toggle" + type="checkbox" + checked={todo.completed} + onChange={() => completeTodo(todo.id)} /> + <label onDoubleClick={this.handleDoubleClick}> + {todo.text} + </label> + <button className="destroy" + onClick={() => deleteTodo(todo.id)} /> + </div> + ) + } + + return ( + <li className={classnames({ + completed: todo.completed, + editing: this.state.editing + })}> + {element} + </li> + ) + } +} diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/TodoItem.spec.js b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/TodoItem.spec.js new file mode 100644 index 0000000000..4c364f5b19 --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/TodoItem.spec.js @@ -0,0 +1,119 @@ +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('') + }) + }) +}) diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/TodoTextInput.js b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/TodoTextInput.js new file mode 100644 index 0000000000..cc09a3b0bb --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/TodoTextInput.js @@ -0,0 +1,53 @@ +import React, { Component, PropTypes } from 'react' +import classnames from 'classnames' + +export default class TodoTextInput extends Component { + static propTypes = { + onSave: PropTypes.func.isRequired, + text: PropTypes.string, + placeholder: PropTypes.string, + editing: PropTypes.bool, + newTodo: PropTypes.bool + } + + state = { + text: this.props.text || '' + } + + handleSubmit = e => { + const text = e.target.value.trim() + if (e.which === 13) { + this.props.onSave(text) + if (this.props.newTodo) { + this.setState({ text: '' }) + } + } + } + + handleChange = e => { + this.setState({ text: e.target.value }) + } + + handleBlur = e => { + if (!this.props.newTodo) { + this.props.onSave(e.target.value) + } + } + + render() { + return ( + <input className={ + classnames({ + edit: this.props.editing, + 'new-todo': this.props.newTodo + })} + type="text" + placeholder={this.props.placeholder} + autoFocus="true" + value={this.state.text} + onBlur={this.handleBlur} + onChange={this.handleChange} + onKeyDown={this.handleSubmit} /> + ) + } +} diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/TodoTextInput.spec.js b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/TodoTextInput.spec.js new file mode 100644 index 0000000000..efca79a908 --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/todomvc/architecture-examples/react-redux/src/components/TodoTextInput.spec.js @@ -0,0 +1,80 @@ +import React from 'react' +import TestUtils from 'react-addons-test-utils' +import TodoTextInput from './TodoTextInput' + +const setup = propOverrides => { + const props = Object.assign({ + onSave: jest.fn(), + text: 'Use Redux', + placeholder: 'What needs to be done?', + editing: false, + newTodo: false + }, propOverrides) + + const renderer = TestUtils.createRenderer() + + renderer.render( + <TodoTextInput {...props} /> + ) + + const output = renderer.getRenderOutput() + + return { + props: props, + output: output, + renderer: renderer + } +} + +describe('components', () => { + describe('TodoTextInput', () => { + it('should render correctly', () => { + const { output } = setup() + expect(output.props.placeholder).toEqual('What needs to be done?') + expect(output.props.value).toEqual('Use Redux') + expect(output.props.className).toEqual('') + }) + + it('should render correctly when editing=true', () => { + const { output } = setup({ editing: true }) + expect(output.props.className).toEqual('edit') + }) + + it('should render correctly when newTodo=true', () => { + const { output } = setup({ newTodo: true }) + expect(output.props.className).toEqual('new-todo') + }) + + it('should update value on change', () => { + const { output, renderer } = setup() + output.props.onChange({ target: { value: 'Use Radox' } }) + const updated = renderer.getRenderOutput() + expect(updated.props.value).toEqual('Use Radox') + }) + + it('should call onSave on return key press', () => { + const { output, props } = setup() + output.props.onKeyDown({ which: 13, target: { value: 'Use Redux' } }) + expect(props.onSave).toBeCalledWith('Use Redux') + }) + + it('should reset state on return key press if newTodo', () => { + const { output, renderer } = setup({ newTodo: true }) + output.props.onKeyDown({ which: 13, target: { value: 'Use Redux' } }) + const updated = renderer.getRenderOutput() + expect(updated.props.value).toEqual('') + }) + + it('should call onSave on blur', () => { + const { output, props } = setup() + output.props.onBlur({ target: { value: 'Use Redux' } }) + expect(props.onSave).toBeCalledWith('Use Redux') + }) + + it('shouldnt call onSave on blur if newTodo', () => { + const { output, props } = setup({ newTodo: true }) + output.props.onBlur({ target: { value: 'Use Redux' } }) + expect(props.onSave).not.toBeCalled() + }) + }) +}) |