Skip to content

Commit 5d091ee

Browse files
Add tests everywhere
1 parent 0b5cff8 commit 5d091ee

Some content is hidden

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

92 files changed

+3581
-160
lines changed

step-2-done/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@
1313
"babel-preset-react": "6.5.0",
1414
"babel-register": "6.7.2",
1515
"chai": "3.5.0",
16-
"enzyme": "^2.2.0",
16+
"enzyme": "2.2.0",
1717
"eslint": "2.4.0",
1818
"eslint-plugin-react": "4.2.3",
1919
"jsdom": "8.1.0",
2020
"mocha": "2.4.5",
2121
"react-addons-test-utils": "0.14.7",
22-
"sinon": "^1.17.3",
22+
"sinon": "1.17.3",
2323
"webpack": "1.12.14",
2424
"webpack-dev-server": "1.14.1"
2525
},

step-2/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@
1515
"chai": "3.5.0",
1616
"eslint": "2.4.0",
1717
"eslint-plugin-react": "4.2.3",
18-
"enzyme": "^2.2.0",
18+
"enzyme": "2.2.0",
1919
"jsdom": "8.1.0",
2020
"mocha": "2.4.5",
2121
"react-addons-test-utils": "0.14.7",
22-
"sinon": "^1.17.3",
22+
"sinon": "1.17.3",
2323
"webpack": "1.12.14",
2424
"webpack-dev-server": "1.14.1"
2525
},

step-3-done/package.json

+3
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,19 @@
1414
"babel-preset-react": "6.5.0",
1515
"babel-register": "6.7.2",
1616
"chai": "3.5.0",
17+
"enzyme": "2.2.0",
1718
"eslint": "2.4.0",
1819
"eslint-plugin-react": "4.2.3",
1920
"jsdom": "8.1.0",
2021
"mocha": "2.4.5",
2122
"react-addons-test-utils": "0.14.7",
23+
"sinon": "1.17.3",
2224
"webpack": "1.12.14",
2325
"webpack-dev-server": "1.14.1"
2426
},
2527
"scripts": {
2628
"lint": "eslint src",
29+
"test": "mocha --compilers js:babel-register tests/index.js",
2730
"bundle": "webpack -p --colors --progress",
2831
"start": "webpack-dev-server -d --colors --inline --content-base public",
2932
"build": "npm run lint && npm run bundle"

step-3-done/src/app.js

+19-13
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22

33
import 'whatwg-fetch';
44

5-
import React from 'react';
6-
import ReactDOM from 'react-dom';
5+
import React, { PropTypes } from 'react';
76

87
import WineApp from './components/wine-app';
98
import { RegionsPage } from './components/regions';
@@ -13,14 +12,21 @@ import { NotFound } from './components/not-found';
1312

1413
import { Router, Route, browserHistory, IndexRoute } from 'react-router';
1514

16-
ReactDOM.render(
17-
<Router history={browserHistory}>
18-
<Route path="/" component={WineApp}>
19-
<IndexRoute component={RegionsPage} />
20-
<Route path="regions/:regionId" component={WineListPage} />
21-
<Route path="regions/:regionId/wines/:wineId" component={WinePage} />
22-
<Route path="*" component={NotFound} />
23-
</Route>
24-
</Router>
25-
, document.getElementById('main')
26-
);
15+
export const App = React.createClass({
16+
propTypes: {
17+
history: PropTypes.object, // eslint-disable-line
18+
},
19+
render() {
20+
const history = this.props.history || browserHistory;
21+
return (
22+
<Router history={history}>
23+
<Route path="/" component={WineApp}>
24+
<IndexRoute component={RegionsPage} />
25+
<Route path="regions/:regionId" component={WineListPage} />
26+
<Route path="regions/:regionId/wines/:wineId" component={WinePage} />
27+
<Route path="*" component={NotFound} />
28+
</Route>
29+
</Router>
30+
);
31+
}
32+
});

step-3-done/src/index.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import 'whatwg-fetch';
2+
3+
import React from 'react';
4+
import ReactDOM from 'react-dom';
5+
6+
import { App } from './app';
7+
8+
ReactDOM.render(<App />, document.getElementById('main'));

step-3-done/tests/bootstrap.js

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/* eslint no-console: 0 */
2+
3+
import jsdom from 'jsdom';
4+
5+
export function bootstrapEnv(body = '') {
6+
const doc = jsdom.jsdom(`<!doctype html><html><body>${body}</body></html>`);
7+
const win = doc.defaultView;
8+
function propagateToGlobal(window) {
9+
for (const key in window) {
10+
if (!window.hasOwnProperty(key)) continue;
11+
if (key in global) continue;
12+
global[key] = window[key];
13+
}
14+
}
15+
global.document = doc;
16+
global.window = win;
17+
propagateToGlobal(win);
18+
// console.log('\nENV setup is done !!!');
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/* eslint no-undef:0, no-unused-vars:0, react/jsx-closing-bracket-location: 0, react/jsx-max-props-per-line: 0 */
2+
3+
import React from 'react';
4+
import { expect } from 'chai';
5+
import { shallow } from 'enzyme';
6+
import sinon from 'sinon';
7+
8+
import { Regions } from '../../src/components/regions';
9+
10+
describe('<Regions />', () => {
11+
it('doit afficher des régions', () => {
12+
const regions = ['region 1', 'region 2', 'region 3'];
13+
const wrapper = shallow(
14+
<Regions regions={regions} />
15+
);
16+
const children = wrapper.get(0).props.children;
17+
expect(wrapper.equals(
18+
<div>
19+
<div {...children[0].props}>region 1</div>
20+
<div {...children[1].props}>region 2</div>
21+
<div {...children[2].props}>region 3</div>
22+
</div>
23+
)).to.equal(true);
24+
});
25+
it('doit gérer le click sur une région', () => {
26+
const regions = ['region 1', 'region 2', 'region 3'];
27+
const onRegionChange = sinon.spy();
28+
const wrapper = shallow(
29+
<Regions
30+
regions={regions}
31+
onRegionChange={onRegionChange} />
32+
);
33+
const children = wrapper.get(0).props.children;
34+
expect(wrapper.equals(
35+
<div>
36+
<div {...children[0].props}>region 1</div>
37+
<div {...children[1].props}>region 2</div>
38+
<div {...children[2].props}>region 3</div>
39+
</div>
40+
)).to.equal(true);
41+
wrapper.find('div').at(3).simulate('click', { target: { textContent: '...' }});
42+
expect(onRegionChange.calledOnce).to.equal(true);
43+
});
44+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
/* eslint no-undef:0, no-unused-vars:1, react/jsx-closing-bracket-location: 0, react/jsx-max-props-per-line: 0 */
2+
3+
import React from 'react';
4+
import { expect } from 'chai';
5+
import { mount } from 'enzyme';
6+
import { createMemoryHistory } from 'react-router';
7+
8+
import { App } from '../../src/app';
9+
10+
const regions = ['Bordeaux', 'Bourgogne'];
11+
12+
const wines1 = [
13+
{
14+
"id": "chevrol-bel-air",
15+
"name": "Château Chevrol Bel Air",
16+
"type": "Rouge",
17+
"appellation": {"name": "Lalande-de-Pomerol", "region": "Bordeaux"},
18+
"grapes": ["Cabernet Sauvignon", "Merlot", "Cabernet Franc"]
19+
},
20+
{
21+
"id": "bel-air",
22+
"name": "Château Bel-Air",
23+
"type": "Rouge",
24+
"appellation": {"name": "Lussac-Saint-Emilion", "region": "Bordeaux"},
25+
"grapes": ["Cabernet Sauvignon", "Merlot", "Cabernet Franc"]
26+
}
27+
];
28+
29+
const wines2 = [
30+
{
31+
"id": "clarendelle",
32+
"name": "Clarendelle",
33+
"type": "Blanc",
34+
"appellation": {"name": "Bordeaux", "region": "Bordeaux"},
35+
"grapes": ["Sauvignon", "Sémillon", "Muscadelle"]
36+
},
37+
{
38+
"id": "les-hauts-de-tour-prignac",
39+
"name": "Les Hauts de Tour Prignac",
40+
"type": "Rouge",
41+
"appellation": {"name": "Médoc", "region": "Bordeaux"},
42+
"grapes": ["Cabernet Sauvignon", "Merlot"]
43+
}
44+
];
45+
46+
function promise(data) {
47+
return {
48+
then(func) {
49+
return promise(func(data));
50+
},
51+
catch() {}
52+
};
53+
}
54+
55+
window.fetch = (url) => {
56+
if (url.startsWith('/api/regions')) {
57+
return promise({ json: () => regions });
58+
}
59+
if (url.startsWith(`/api/wines?region=${regions[0]}`)) {
60+
return promise({ json: () => wines1 });
61+
}
62+
if (url.startsWith(`/api/wines?region=${regions[1]}`)) {
63+
return promise({ json: () => wines2 });
64+
}
65+
if (url.startsWith(`/api/wines/${wines1[0].id}`)) {
66+
return promise({ json: () => wines1[0] });
67+
}
68+
if (url.startsWith(`/api/wines/${wines1[1].id}`)) {
69+
return promise({ json: () => wines1[1] });
70+
}
71+
if (url.startsWith(`/api/wines/${wines2[0].id}`)) {
72+
return promise({ json: () => wines2[0] });
73+
}
74+
if (url.startsWith(`/api/wines/${wines2[1].id}`)) {
75+
return promise({ json: () => wines2[1] });
76+
}
77+
throw new Error(`Unknown URL : ${url}`);
78+
};
79+
global.fetch = window.fetch;
80+
81+
describe('<App />', () => {
82+
it('doit afficher des régions', () => {
83+
const history = createMemoryHistory(window.location);
84+
const wrapper = mount(
85+
<App history={history} />
86+
);
87+
const foundRegions = wrapper.find('Regions').find('div').filterWhere(n => regions.indexOf(n.get(0).innerHTML) > -1);
88+
expect(foundRegions.length).to.equal(2);
89+
});
90+
91+
it('doit afficher des vins après avoir sélectionné une région', () => {
92+
const history = createMemoryHistory(window.location);
93+
const wrapper = mount(
94+
<App history={history} />
95+
);
96+
97+
{
98+
const foundRegions = wrapper.find('Regions').find('div').filterWhere(n => regions.indexOf(n.get(0).innerHTML) > -1);
99+
expect(foundRegions.length).to.equal(2);
100+
}
101+
102+
const region2 = wrapper.find('Regions').find('div').filterWhere(n => n.get(0).innerHTML === regions[1]);
103+
region2.simulate('click');
104+
105+
{
106+
const wineNames1 = Object.keys(wines1).map(k => wines1[k].name);
107+
const foundWines1 = wrapper.find('WineList').find('div').filterWhere(n => wineNames1.indexOf(n.get(0).innerHTML) > -1);
108+
expect(foundWines1.length).to.equal(0);
109+
110+
const wineNames2 = Object.keys(wines2).map(k => wines2[k].name);
111+
const foundWines2 = wrapper.find('WineList').find('div').filterWhere(n => wineNames2.indexOf(n.get(0).innerHTML) > -1);
112+
expect(foundWines2.length).to.equal(2);
113+
}
114+
115+
history.goBack();
116+
117+
const region1 = wrapper.find('Regions').find('div').filterWhere(n => n.get(0).innerHTML === regions[0]);
118+
region1.simulate('click');
119+
120+
{
121+
const wineNames1 = Object.keys(wines1).map(k => wines1[k].name);
122+
const foundWines1 = wrapper.find('WineList').find('div').filterWhere(n => wineNames1.indexOf(n.get(0).innerHTML) > -1);
123+
expect(foundWines1.length).to.equal(2);
124+
125+
const wineNames2 = Object.keys(wines2).map(k => wines2[k].name);
126+
const foundWines2 = wrapper.find('WineList').find('div').filterWhere(n => wineNames2.indexOf(n.get(0).innerHTML) > -1);
127+
expect(foundWines2.length).to.equal(0);
128+
}
129+
130+
});
131+
132+
it('doit afficher un vin après avoir sélectionné un nouveau vin', () => {
133+
const history = createMemoryHistory(window.location);
134+
const wrapper = mount(
135+
<App history={history} />
136+
);
137+
138+
const region1 = wrapper.find('Regions').find('div').filterWhere(n => n.get(0).innerHTML === regions[0]);
139+
region1.simulate('click');
140+
141+
const wine1 = wrapper.find('WineList').find('div').filterWhere(n => n.get(0).innerHTML === wines1[0].name);
142+
wine1.simulate('click');
143+
144+
{
145+
const firstWine = wines1[0];
146+
const Wine = wrapper.find('Wine').at(0).first();
147+
const foundName = Wine.find('div').filterWhere(n => n.get(0).innerHTML.indexOf(firstWine.name) > -1);
148+
const foundType = Wine.find('div').filterWhere(n => n.get(0).innerHTML.indexOf(firstWine.type) > -1);
149+
const foundRegion = Wine.find('div').filterWhere(n => n.get(0).innerHTML.indexOf(firstWine.appellation.region) > -1);
150+
const foundAppellation = Wine.find('div').filterWhere(n => n.get(0).innerHTML.indexOf(firstWine.appellation.name) > -1);
151+
const foundGrapes = Wine.find('div').filterWhere(n => n.get(0).innerHTML.indexOf(firstWine.grapes.join(', ')) > -1);
152+
153+
expect(foundName.length).to.equal(2); // because of root div
154+
expect(foundType.length).to.equal(2);
155+
expect(foundAppellation.length).to.equal(2);
156+
expect(foundRegion.length).to.equal(2);
157+
expect(foundGrapes.length).to.equal(2);
158+
}
159+
160+
history.goBack();
161+
162+
const wine2 = wrapper.find('WineList').find('div').filterWhere(n => n.get(0).innerHTML === wines1[1].name);
163+
wine2.simulate('click');
164+
165+
{
166+
const firstWine = wines1[1];
167+
const Wine = wrapper.find('Wine').at(0).first();
168+
const foundName = Wine.find('div').filterWhere(n => n.get(0).innerHTML.indexOf(firstWine.name) > -1);
169+
const foundType = Wine.find('div').filterWhere(n => n.get(0).innerHTML.indexOf(firstWine.type) > -1);
170+
const foundRegion = Wine.find('div').filterWhere(n => n.get(0).innerHTML.indexOf(firstWine.appellation.region) > -1);
171+
const foundAppellation = Wine.find('div').filterWhere(n => n.get(0).innerHTML.indexOf(firstWine.appellation.name) > -1);
172+
const foundGrapes = Wine.find('div').filterWhere(n => n.get(0).innerHTML.indexOf(firstWine.grapes.join(', ')) > -1);
173+
174+
expect(foundName.length).to.equal(2); // because of root div
175+
expect(foundType.length).to.equal(2);
176+
expect(foundAppellation.length).to.equal(2);
177+
expect(foundRegion.length).to.equal(2);
178+
expect(foundGrapes.length).to.equal(2);
179+
}
180+
});
181+
});

0 commit comments

Comments
 (0)