Skip to content

Commit

Permalink
Implement tests coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
vodkabears committed Feb 14, 2016
1 parent 32ff6b4 commit 04d96cf
Show file tree
Hide file tree
Showing 19 changed files with 136 additions and 108 deletions.
3 changes: 3 additions & 0 deletions .babelrc
@@ -0,0 +1,3 @@
{
"presets": ["es2015", "stage-2", "react"]
}
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -3,4 +3,5 @@ npm-debug.log

.idea/
node_modules/
coverage/
build/
5 changes: 4 additions & 1 deletion package.json
Expand Up @@ -8,7 +8,8 @@
"clean-test": "rm -rf build/test/",
"lint": "eslint . --debug --ignore-path .gitignore && csscomb -l -v client/",
"fix": "eslint . --fix --ignore-path .gitignore && csscomb client/",
"unit": "npm-run-all clean-test build:test && mocha --recursive build/test/",
"unit": "NODE_PATH=. mocha --compilers js:babel-register --recursive",
"coverage": "NODE_PATH=. istanbul cover _mocha -- --compilers js:babel-register --reporter dot --recursive",
"test": "npm-run-all lint unit",
"copy-public": "mkdir -p build/ && cp -r client/public/ build/public/",
"build:test": "webpack --config webpack.test.config.js --progress",
Expand All @@ -31,6 +32,7 @@
"babel-preset-es2015": "^6.3.13",
"babel-preset-react": "^6.3.13",
"babel-preset-stage-2": "^6.3.13",
"babel-register": "^6.5.2",
"body-parser": "^1.14.2",
"chai": "^3.5.0",
"connect-redis": "^3.0.1",
Expand All @@ -48,6 +50,7 @@
"hiredis": "^0.4.1",
"history": "^1.17.0",
"image-webpack-loader": "^1.6.2",
"istanbul": "^v1.0.0-alpha",
"json-loader": "^0.5.4",
"mocha": "^2.4.5",
"mongodb": "^2.1.4",
Expand Down
9 changes: 7 additions & 2 deletions test/client/components/page/page-type-todos-example.test.js
Expand Up @@ -5,11 +5,16 @@ import ComponentMock from 'test/mocks/component';
import PageTypeTodosExampleModel from 'client/components/page/mods/type/todos-example/model';

let component = new ComponentMock();
let model = new PageTypeTodosExampleModel(component);
let sandbox = sinon.sandbox.create();
let model;

describe('PageTypeTodosExample', () => {
afterEach(() => sandbox.restore());
beforeEach(() => model = new PageTypeTodosExampleModel(component));

afterEach(() => {
model.destroy();
sandbox.restore();
});

describe('#load()', () => {
it('should set correct state after loading', () => {
Expand Down
9 changes: 7 additions & 2 deletions test/client/components/page/page-type-welcome.test.js
Expand Up @@ -5,11 +5,16 @@ import ComponentMock from 'test/mocks/component';
import PageTypeWelcomeModel from 'client/components/page/mods/type/welcome/model';

let component = new ComponentMock();
let model = new PageTypeWelcomeModel(component);
let sandbox = sinon.sandbox.create();
let model;

describe('PageTypeWelcome', () => {
afterEach(() => sandbox.restore());
beforeEach(() => model = new PageTypeWelcomeModel(component));

afterEach(() => {
model.destroy();
sandbox.restore();
});

describe('#load()', () => {
it('should set correct state after loading', () => {
Expand Down
6 changes: 5 additions & 1 deletion test/client/components/todos/todos-footer.test.js
Expand Up @@ -5,9 +5,13 @@ import ComponentMock from 'test/mocks/component';
import TodosFooterModel from 'client/components/todos/elems/footer/model';

let component = new ComponentMock();
let model = new TodosFooterModel(component);
let model;

describe('TodosFooter', () => {
beforeEach(() => model = new TodosFooterModel(component));

afterEach(() => model.destroy());

describe('on "TodosUpdatedList" event', () => {
it('should calculate the number of uncompleted todos', () => {
Dispatcher.emit(EVENTS.TodosUpdatedList, {
Expand Down
6 changes: 5 additions & 1 deletion test/client/components/todos/todos-header.test.js
Expand Up @@ -5,9 +5,13 @@ import ComponentMock from 'test/mocks/component';
import TodosHeaderModel from 'client/components/todos/elems/header/model';

let component = new ComponentMock();
let model = new TodosHeaderModel(component);
let model;

describe('TodosHeader', () => {
beforeEach(() => model = new TodosHeaderModel(component));

afterEach(() => model.destroy());

describe('on "TodosUpdatedList" event', () => {
it('should have the checked checkbox, if all todos are completed', () => {
Dispatcher.emit(EVENTS.TodosUpdatedList, {
Expand Down
6 changes: 5 additions & 1 deletion test/client/components/todos/todos-item.test.js
Expand Up @@ -5,9 +5,13 @@ import ComponentMock from 'test/mocks/component';
import TodosItemModel from 'client/components/todos/elems/item/model';

let component = new ComponentMock({ id: 1, text: 'test' });
let model = new TodosItemModel(component);
let model;

describe('TodosItem', () => {
beforeEach(() => model = new TodosItemModel(component));

afterEach(() => model.destroy());

describe('#toggle(makeCompleted)', () => {
it('should emit the "TodosToggleItem" event', done => {
Dispatcher.once(EVENTS.TodosToggleItem, data => {
Expand Down
21 changes: 18 additions & 3 deletions test/client/components/todos/todos-list.test.js
Expand Up @@ -7,13 +7,19 @@ import ComponentMock from 'test/mocks/component';
import TodosListModel from 'client/components/todos/elems/list/model';

let component = new ComponentMock();
let model = new TodosListModel(component);
let sandbox = sinon.sandbox.create();
let model;

describe('TodosList', () => {
beforeEach(() => component.state = { todos: [] });
beforeEach(() => {
component.state = { todos: [] };
model = new TodosListModel(component);
});

afterEach(() => sandbox.restore());
afterEach(() => {
model.destroy();
sandbox.restore();
});

it('should call #addTodo(text) on the "TodosCreateItem" event', () => {
let spy = sandbox.spy(model, 'addTodo');
Expand Down Expand Up @@ -238,6 +244,15 @@ describe('TodosList', () => {
});

describe('#deleteCompleted()', () => {
it('should not toggle todos if todos are undefined', () => {
let spy = sandbox.spy(API, 'remove');

component.state = {};
model.deleteCompleted();

expect(spy.called).to.be.false;
});

it('should call the "/api/components/Todos" gate', () => {
sandbox.stub(API, 'remove', gate => {
expect(gate).to.be.equal('/api/components/Todos');
Expand Down
16 changes: 13 additions & 3 deletions test/lib/api.test.js
@@ -1,15 +1,25 @@
import 'expose?FormData!form-data';
import 'expose?fetch!node-fetch';
import { expect } from 'chai';
import nock from 'nock';
import fetch from 'node-fetch';
import FormData from 'form-data';
import API from 'lib/api';

const HOST = 'http://test';
const PATH = '/api/component';
const GATE = HOST + PATH;

describe('API', () => {
afterEach(() => nock.cleanAll());
beforeEach(() => {
global.FormData = FormData;
global.fetch = fetch;
});

afterEach(() => {
delete global.FormData;
delete global.fetch;

nock.cleanAll();
});

describe('.getQueryString(path, query)', () => {
it('should return a correct path if query params are undefined', () => {
Expand Down
10 changes: 7 additions & 3 deletions test/lib/component-model.test.js
Expand Up @@ -5,17 +5,21 @@ import ComponentModel from 'lib/component-model';
import ComponentMock from 'test/mocks/component';

let component = new ComponentMock();
let model = new ComponentModel(component);
let sandbox = sinon.sandbox.create();
let model;

describe('ComponentModel', () => {
afterEach(() => sandbox.restore());

beforeEach(() => {
model = new ComponentModel(component);
component.props = { text: 'props' };
component.state = { text: 'state' };
});

afterEach(() => {
model.destroy();
sandbox.restore();
});

describe('#props', () => {
it('should return component props', () => {
expect(model.props).to.be.deep.equal(component.props);
Expand Down
39 changes: 20 additions & 19 deletions test/lib/dispatcher.test.js
Expand Up @@ -3,66 +3,67 @@ import { expect } from 'chai';
import sinon from 'sinon';
import Dispatcher from 'lib/dispatcher';

let sandbox = sinon.sandbox.create();
let EVENT = 'event';
let spy;

describe('Dispatcher', () => {
afterEach(() => sandbox.restore());
afterEach(() => Dispatcher.off(EVENT, spy));

describe('.emit(event, data)', () => {
it('should emit an event', () => {
let spy = sandbox.spy(EventEmitter.prototype, 'emit');
spy = sinon.spy(EventEmitter.prototype, 'emit');

Dispatcher.emit('event', 'data');
Dispatcher.emit(EVENT, 'data');

expect(spy.calledWithExactly('event', 'data')).to.be.true;
expect(spy.calledWithExactly(EVENT, 'data')).to.be.true;
});
});

describe('.on(event, listener)', () => {
it('should handle multiple events', () => {
let spy = sandbox.spy();
spy = sinon.spy();

Dispatcher.on('event', spy);
Dispatcher.emit('event');
Dispatcher.emit('event');
Dispatcher.on(EVENT, spy);
Dispatcher.emit(EVENT);
Dispatcher.emit(EVENT);

expect(spy.callCount).to.be.equal(2);
});

it('should pass data to the handler', () => {
let spy = sandbox.spy();
spy = sinon.spy();

Dispatcher.on('event', spy).emit('event', 'data');
Dispatcher.on(EVENT, spy).emit(EVENT, 'data');

expect(spy.calledWithExactly('data')).to.be.true;
});
});

describe('.once(event, listener)', () => {
it('should handle an event once', () => {
let spy = sandbox.spy();
spy = sinon.spy();

Dispatcher.once('event', spy);
Dispatcher.emit('event');
Dispatcher.emit('event');
Dispatcher.once(EVENT, spy);
Dispatcher.emit(EVENT);
Dispatcher.emit(EVENT);

expect(spy.callCount).to.be.equal(1);
});

it('should pass data to the handler', () => {
let spy = sandbox.spy();
spy = sinon.spy();

Dispatcher.once('event', spy).emit('event', 'data');
Dispatcher.once(EVENT, spy).emit(EVENT, 'data');

expect(spy.calledWithExactly('data')).to.be.true;
});
});

describe('.off(event, listener)', () => {
it('should remove an event listener', () => {
let spy = sandbox.spy();
spy = sinon.spy();

Dispatcher.on('event', spy).off('event', spy).emit('event');
Dispatcher.on(EVENT, spy).off(EVENT, spy).emit(EVENT);

expect(spy.called).to.be.false;
});
Expand Down
24 changes: 18 additions & 6 deletions test/server/models/todos.test.js
Expand Up @@ -186,23 +186,35 @@ describe('Todos model', () => {
expect(mongodb.argumentsStack[1][0]._id).to.be.equal(SESSION_ID);
});

it('should toggle todos and save them', () => {
it('should toggle selected todos and save them', () => {
mongodb.data = [{
items: [
{
id: '56b8a6a8fd0b51ae4bf72887',
text: 'test',
isCompleted: false
},
{
id: '56b8a6a8fd0b51ae4bf72888',
text: 'test',
isCompleted: false
}
]
}];

return Model.toggle({ db: mongodb }, true, '56b8a6a8fd0b51ae4bf72887')
.then(items => expect(items).to.be.deep.equal([{
id: '56b8a6a8fd0b51ae4bf72887',
text: 'test',
isCompleted: true
}]));
.then(items => expect(items).to.be.deep.equal([
{
id: '56b8a6a8fd0b51ae4bf72887',
text: 'test',
isCompleted: true
},
{
id: '56b8a6a8fd0b51ae4bf72888',
text: 'test',
isCompleted: false
}
]));
});

it('should build the right update query', () => {
Expand Down
7 changes: 7 additions & 0 deletions test/server/providers/page-type-todos-example.test.js
Expand Up @@ -20,4 +20,11 @@ describe('PageTypeTodosExample provider', () => {
}
}));
});

it('should not fetch data if it is already defined', () => {
let prevData = { PageTypeTodosExample: {} };

return provider(null, prevData)
.then(data => expect(data.PageTypeTodosExample).to.be.equal(prevData.PageTypeTodosExample));
});
});
7 changes: 7 additions & 0 deletions test/server/providers/page-type-welcome.test.js
Expand Up @@ -11,4 +11,11 @@ describe('PageTypeWelcome provider', () => {
}
}));
});

it('should not fetch data if it is already defined', () => {
let prevData = { PageTypeWelcome: {} };

return provider(null, prevData)
.then(data => expect(data.PageTypeWelcome).to.be.equal(prevData.PageTypeWelcome));
});
});
7 changes: 7 additions & 0 deletions test/server/providers/todos.test.js
Expand Up @@ -14,4 +14,11 @@ describe('Todos provider', () => {
return provider()
.then(data => expect(data.Todos).to.be.deep.equal({ items: [] }));
});

it('should not fetch data if it is already defined', () => {
let prevData = { Todos: {} };

return provider(null, prevData)
.then(data => expect(data.Todos).to.be.equal(prevData.Todos));
});
});
5 changes: 1 addition & 4 deletions webpack.client.config.js
Expand Up @@ -55,10 +55,7 @@ module.exports = {
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['es2015', 'stage-2', 'react']
}
loader: 'babel'
},
{
test: /\.css$/,
Expand Down

0 comments on commit 04d96cf

Please sign in to comment.