Skip to content

Commit 916db53

Browse files
committed
added proper tests and coverage
1 parent af836e1 commit 916db53

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+67952
-69664
lines changed

.babelrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"presets": ["react", "es2015", "es2017", "stage-0"]
3+
}

.circleci/config.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Javascript Node CircleCI 2.0 configuration file
2+
#
3+
# Check https://circleci.com/docs/2.0/language-javascript/ for more details
4+
#
5+
version: 2
6+
jobs:
7+
build:
8+
docker:
9+
# specify the version you desire here
10+
- image: circleci/node:7.10
11+
12+
# Specify service dependencies here if necessary
13+
# CircleCI maintains a library of pre-built images
14+
# documented at https://circleci.com/docs/2.0/circleci-images/
15+
# - image: circleci/mongo:3.4.4
16+
17+
steps:
18+
- checkout
19+
- run: npm install
20+
- run: npm test

__mocks__/react-easy-state.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from '../src'

__tests__/Clock.test.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import React from 'react'
2+
import { mount } from 'enzyme'
3+
import toJSON from 'enzyme-to-json'
4+
import sinon from 'sinon'
5+
import App from '../examples/clock/App'
6+
7+
describe('Clock App', () => {
8+
const clock = sinon.useFakeTimers()
9+
const app = mount(<App/>)
10+
const clearIntervalSpy = sinon.spy(global, 'clearInterval')
11+
12+
afterAll(() => {
13+
clock.restore()
14+
clearIntervalSpy.restore()
15+
})
16+
17+
test('should update to display the current time every second', async () => {
18+
expect(toJSON(app)).toMatchSnapshot('01. Initial state')
19+
20+
clock.tick(2000)
21+
await Promise.resolve()
22+
expect(toJSON(app)).toMatchSnapshot('02. After 2 seconds')
23+
24+
clock.tick(8500)
25+
await Promise.resolve()
26+
expect(toJSON(app)).toMatchSnapshot('03. After 10.5 seconds')
27+
})
28+
29+
test('should clean up the interval timer when the component is unmounted', () => {
30+
app.unmount()
31+
expect(clearIntervalSpy.callCount).toBe(1)
32+
})
33+
})

__tests__/Contacts.test.js

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import React from 'react'
2+
import { mount } from 'enzyme'
3+
import toJSON from 'enzyme-to-json'
4+
import App from '../examples/contacts/App'
5+
6+
describe('Contacts App', () => {
7+
const app = mount(<App/>)
8+
9+
test('should add new contacts', async () => {
10+
expect(toJSON(app)).toMatchSnapshot('01. Initial state')
11+
12+
const creator = app.find('.contact-creator')
13+
const nameField = creator.find('input[name="name"]')
14+
const emailField = creator.find('input[name="email"]')
15+
const createButton = creator.find('button')
16+
17+
nameField.simulate('change', {
18+
target: { name: 'name', value: 'Test Contact' }
19+
})
20+
await Promise.resolve()
21+
expect(toJSON(app)).toMatchSnapshot('02. Create Test Contact name')
22+
23+
emailField.simulate('change', {
24+
target: { name: 'email', value: 'test.contact@gmail.com' }
25+
})
26+
await Promise.resolve()
27+
expect(toJSON(app)).toMatchSnapshot('03. Create Test Contact email')
28+
29+
createButton.simulate('click')
30+
await Promise.resolve()
31+
expect(toJSON(app)).toMatchSnapshot('04. Add Test Contact')
32+
33+
nameField.simulate('change', {
34+
target: { name: 'name', value: 'Other Contact' }
35+
})
36+
emailField.simulate('change', {
37+
target: { name: 'email', value: 'other.contact@gmail.com' }
38+
})
39+
createButton.simulate('click')
40+
await Promise.resolve()
41+
expect(toJSON(app)).toMatchSnapshot('05. Add Other Contact')
42+
})
43+
44+
test('should edit contact', async () => {
45+
let display, editor, editButton, cancelButton, saveButton, nameField, emailField
46+
47+
display = app.find('.contact-display').at(0)
48+
editButton = display.find('.zmdi-edit')
49+
50+
editButton.simulate('click')
51+
await Promise.resolve()
52+
expect(toJSON(app)).toMatchSnapshot('06. Switch Test Contact to Edit Mode')
53+
54+
editor = app.find('.contact-editor').at(0)
55+
nameField = editor.find('input[name="name"]')
56+
cancelButton = editor.find('.zmdi-close')
57+
58+
nameField.simulate('change', {
59+
target: { name: 'name', value: 'Edited Test Contact' }
60+
})
61+
await Promise.resolve()
62+
expect(toJSON(app)).toMatchSnapshot('07. Edit Test Contact name')
63+
64+
cancelButton.simulate('click')
65+
await Promise.resolve()
66+
expect(toJSON(app)).toMatchSnapshot('08. Cancel Test Contact edit')
67+
68+
display = app.find('.contact-display').at(0)
69+
editButton = display.find('.zmdi-edit')
70+
71+
editButton.simulate('click')
72+
await Promise.resolve()
73+
expect(toJSON(app)).toMatchSnapshot('09. Switch Test Contact to edit Mode')
74+
75+
editor = app.find('.contact-editor').at(0)
76+
emailField = editor.find('input[name="email"]')
77+
saveButton = editor.find('.zmdi-save')
78+
79+
emailField.simulate('change', {
80+
target: { name: 'email', value: 'test.contact.edited@gmail.com' }
81+
})
82+
await Promise.resolve()
83+
expect(toJSON(app)).toMatchSnapshot('10. Edit Test Contact email')
84+
85+
saveButton.simulate('click')
86+
await Promise.resolve()
87+
expect(toJSON(app)).toMatchSnapshot('11. Save Test Contact edit')
88+
})
89+
90+
test('should delete contact', async () => {
91+
let deleteButton = app.find('.contact-display .zmdi-delete').at(1)
92+
93+
deleteButton.simulate('click')
94+
await Promise.resolve()
95+
expect(toJSON(app)).toMatchSnapshot('12. Delete Other Contact')
96+
97+
deleteButton = app.find('.contact-display .zmdi-delete').at(0)
98+
99+
deleteButton.simulate('click')
100+
await Promise.resolve()
101+
expect(toJSON(app)).toMatchSnapshot('13. Delete Test Contact')
102+
})
103+
})

__tests__/TodoMVC.test.js

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import React from 'react'
2+
import { mount } from 'enzyme'
3+
import toJSON from 'enzyme-to-json'
4+
import App from '../examples/todoMVC/App'
5+
6+
describe('TodoMVC App', () => {
7+
const app = mount(<App/>)
8+
9+
test('should add todos', async () => {
10+
expect(toJSON(app)).toMatchSnapshot('01. Initial state')
11+
12+
const input = app.find('.new-todo')
13+
14+
input.simulate('keyUp', {
15+
keyCode: 13,
16+
target: { value: 'Test Todo' }
17+
})
18+
await Promise.resolve()
19+
expect(toJSON(app)).toMatchSnapshot('02. Add Test Todo')
20+
21+
input.simulate('keyUp', {
22+
keyCode: 13,
23+
target: { value: 'Other Todo' }
24+
})
25+
await Promise.resolve()
26+
expect(toJSON(app)).toMatchSnapshot('03. Add Other Todo')
27+
28+
input.simulate('keyUp', {
29+
keyCode: 13,
30+
target: { value: 'Final Todo' }
31+
})
32+
await Promise.resolve()
33+
expect(toJSON(app)).toMatchSnapshot('04. Add Final Todo')
34+
})
35+
36+
test('should toggle todo status', async () => {
37+
const toggles = app.find('.todo-list .toggle')
38+
39+
toggles.at(0).simulate('change')
40+
await Promise.resolve()
41+
expect(toJSON(app)).toMatchSnapshot('05. Toggle Test Todo to completed')
42+
43+
toggles.at(1).simulate('change')
44+
await Promise.resolve()
45+
expect(toJSON(app)).toMatchSnapshot('06. Toggle Other Todo to completed')
46+
47+
toggles.at(0).simulate('change')
48+
await Promise.resolve()
49+
expect(toJSON(app)).toMatchSnapshot('07. Toggle Test Todo to active')
50+
})
51+
52+
test('should filter todos', async () => {
53+
const completedFilter = app.find('button[value="completed"]')
54+
const activeFilter = app.find('button[value="active"]')
55+
const allFilter = app.find('button[value="todos"]')
56+
57+
completedFilter.simulate('click')
58+
await Promise.resolve()
59+
expect(toJSON(app)).toMatchSnapshot('08. Filter completed')
60+
61+
activeFilter.simulate('click')
62+
await Promise.resolve()
63+
expect(toJSON(app)).toMatchSnapshot('09. Filter active')
64+
65+
allFilter.simulate('click')
66+
await Promise.resolve()
67+
expect(toJSON(app)).toMatchSnapshot('10. Filter all')
68+
})
69+
70+
test('should clear completed', async () => {
71+
const clearCompleted = app.find('.clear-completed')
72+
73+
clearCompleted.simulate('click')
74+
await Promise.resolve()
75+
expect(toJSON(app)).toMatchSnapshot('11. Clear completed')
76+
})
77+
78+
test('should toggle all todo state at once', async () => {
79+
const toggleAll = app.find('.toggle-all')
80+
81+
toggleAll.simulate('change')
82+
await Promise.resolve()
83+
expect(toJSON(app)).toMatchSnapshot('12. Toggle all to completed')
84+
85+
toggleAll.simulate('change')
86+
await Promise.resolve()
87+
expect(toJSON(app)).toMatchSnapshot('13. Toggle all to active')
88+
})
89+
90+
test('should delete todo', async () => {
91+
const deleters = app.find('.todo-list .destroy')
92+
93+
deleters.at(0).simulate('click')
94+
await Promise.resolve()
95+
expect(toJSON(app)).toMatchSnapshot('14. Delete Test Todo')
96+
})
97+
})

examples/clock/style.css renamed to __tests__/__snapshots__/Clock.test.js.css

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@import url('https://fonts.googleapis.com/css?family=Orbitron');
2+
13
body {
24
font: 50px 'Orbitron', sans-serif;
35
text-align: center;
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`01. Initial state 1`] = `
4+
<EasyStateWrapper>
5+
<div>
6+
01:00:00 AM
7+
</div>
8+
</EasyStateWrapper>
9+
------------HTML PREVIEW---------------
10+
<EasyStateWrapper>
11+
<div>
12+
01:00:00 AM
13+
</div>
14+
</EasyStateWrapper>
15+
`;
16+
17+
exports[`02. After 2 seconds 1`] = `
18+
<EasyStateWrapper>
19+
<div>
20+
01:00:02 AM
21+
</div>
22+
</EasyStateWrapper>
23+
------------HTML PREVIEW---------------
24+
<EasyStateWrapper>
25+
<div>
26+
01:00:02 AM
27+
</div>
28+
</EasyStateWrapper>
29+
`;
30+
31+
exports[`03. After 10.5 seconds 1`] = `
32+
<EasyStateWrapper>
33+
<div>
34+
01:00:10 AM
35+
</div>
36+
</EasyStateWrapper>
37+
------------HTML PREVIEW---------------
38+
<EasyStateWrapper>
39+
<div>
40+
01:00:10 AM
41+
</div>
42+
</EasyStateWrapper>
43+
`;

examples/contacts/style.css renamed to __tests__/__snapshots__/Contacts.test.js.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
@import url('https://cdnjs.cloudflare.com/ajax/libs/material-design-iconic-font/2.2.0/css/material-design-iconic-font.min.css');
2+
@import url('https://fonts.googleapis.com/css?family=Raleway');
3+
14
* {
25
font: 16px "Open Sans", sans-serif;
36
color: #2c3e50;

0 commit comments

Comments
 (0)