Permalink
Browse files

Switched to karma + jasmine + sinon for tests

Jest was really easy to setup, but for this project it had some downsides:
- Slow tests (32 - 1min) now it is (32 - 9 sec)
- Uses jsdom, which doesn't have classList support
- Only run in node 10.x versions
- Doesn't work with almost any npm plugins, i tried nock, sinon, vcr, sepia
  • Loading branch information...
tegon committed Jul 22, 2015
1 parent a23d996 commit a80deab24ff0c2c60001b64fd6a8a5e053499975
2 .nvmrc
@@ -1 +1 @@
v0.10.40
v0.12.0
@@ -1,4 +1,6 @@
language: node_js
node_js:
- "0.10"
- "0.11"
- "0.12"
script: "npm test"

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.
@@ -0,0 +1,40 @@
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['browserify', 'jasmine'],
files: [
'node_modules/phantomjs-polyfill/bind-polyfill.js',
'tests/test-helper.js',
'tests/**/*.js'
],
exclude: [
],
preprocessors: {
'tests/**/*.js': ['browserify']
},
reporters: ['dots'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: ['Chrome', 'PhantomJS'],
browserify: {
debug: true,
transform: ['reactify']
},
singleRun: true
});
};
@@ -12,38 +12,35 @@
},
"devDependencies": {
"browserify": "10.2.4",
"grunt": "0.4.5",
"grunt-karma": "0.12.0",
"gulp": "3.9.0",
"gulp-autoprefixer": "2.3.1",
"gulp-concat": "2.6.0",
"gulp-exit": "0.0.2",
"gulp-if": "1.2.5",
"gulp-minify-css": "1.2.0",
"gulp-uglify": "1.2.0",
"gulp-zip": "^3.0.2",
"jest-cli": "0.4.15",
"gulp-zip": "3.0.2",
"karma-browserify": "4.2.1",
"karma-chrome-launcher": "0.2.0",
"karma-jasmine": "0.3.6",
"karma-phantomjs-launcher": "0.2.0",
"minimist": "1.1.1",
"phantomjs-polyfill": "0.0.1",
"react-tools": "0.13.3",
"reactify": "1.1.1",
"sinon": "1.15.4",
"vinyl-buffer": "1.0.0",
"vinyl-source-stream": "1.1.0",
"watchify": "3.2.3"
},
"engines": {
"node": "0.10.40"
"node": "0.12.0"
},
"scripts": {
"start": "./node_modules/gulp/bin/gulp.js --env development",
"build": "./node_modules/gulp/bin/gulp.js build --env production",
"test": "jest"
},
"jest": {
"scriptPreprocessor": "<rootDir>/preprocessor.js",
"unmockedModulePathPatterns": [
"<rootDir>/node_modules/react"
],
"testPathIgnorePatterns": [
"/node_modules/",
"<rootDir>/__tests__/test-helper.js"
]
"start": "gulp --env development",
"build": "gulp build --env production",
"test": "karma start"
}
}
@@ -0,0 +1,24 @@
var Analytics = require('../../app/scripts/src/background/analytics');
describe('Analytics', function() {
it('sets the tracker', function() {
var tracker = {
sendAppView: sinon.stub(),
sendEvent: sinon.stub()
};
Analytics.setTracker(tracker);
expect(Analytics.tracker).toBe(tracker);
});
it('sends app view', function() {
Analytics.sendAppView('Foo');
expect(Analytics.tracker.sendAppView.callCount).toBe(1);
expect(Analytics.tracker.sendAppView.getCall(0).args).toEqual(['Foo']);
});
it('sends event', function() {
Analytics.sendEvent('Foozin', 'Bar');
expect(Analytics.tracker.sendEvent.callCount).toBe(1);
expect(Analytics.tracker.sendEvent.getCall(0).args).toEqual(['Foozin', 'Bar']);
});
});
@@ -1,5 +1,3 @@
jest.dontMock('../../app/scripts/src/content/item');
var Item = require('../../app/scripts/src/content/item');
var rocky = new Item({
title: 'Rocky', type: 'movie', scrubber: { style: { width: '25.22222%' } }
@@ -0,0 +1,66 @@
var Scrobble = require('../../app/scripts/src/content/scrobble');
var Settings = require('../../app/scripts/src/settings.js');
describe('Scrobble', function() {
beforeEach(function() {
this.xhr = sinon.useFakeXMLHttpRequest();
var requests = this.requests = [];
this.xhr.onCreate = function (xhr) {
requests.push(xhr);
};
});
afterEach(function() {
this.xhr.restore();
});
it('sets properties in constructor', function() {
var scrubber = sinon.stub().returns(10.1);
var success = sinon.stub();
var error = sinon.stub();
var scrobble = new Scrobble({
type: 'show',
response: { foo: 'bar' },
scrubber: scrubber,
success: success,
error: error
});
expect(scrobble.item).toEqual({ episode: { foo: 'bar' } });
expect(scrobble.scrubber).toBe(scrubber);
expect(scrobble.success).toBe(success);
expect(scrobble.error).toBe(error);
expect(scrobble.url).toBe(Settings.apiUri + '/scrobble');
});
it('when type is show, item is wrapped inside episode', function() {
var scrobble = new Scrobble({ type: 'show', response: { foo: 'bar' } });
expect(scrobble.item).toEqual({ episode: { foo: 'bar' } });
});
it('when type is movie, item is wrapped inside movie', function() {
var scrobble = new Scrobble({
type: 'movie',
response: {
movie: { foo: 'bar' }
}
});
expect(scrobble.item).toEqual({ movie: { foo: 'bar' } });
});
it('start scrobble calls success', function() {
var scrubber = sinon.stub().returns(10.1);
var success = sinon.spy();
var error = sinon.spy();
var scrobble = new Scrobble({
type: 'show',
response: { foo: 'bar' },
scrubber: scrubber,
success: success,
error: error
});
scrobble.start();
expect(this.requests.length).toBe(1);
this.requests[0].respond(200, { 'Content-Type': 'application/json' }, '');
expect(success.callCount).toBe(1);
});
});
@@ -1,12 +1,13 @@
jest.dontMock('../../../app/scripts/src/popup/components/button');
var React = require('react/addons');
var Button = require('../../../app/scripts/src/popup/components/button');
var helper = require('../../test-helper.js');
var TestUtils = React.addons.TestUtils;
var button = TestUtils.renderIntoDocument(<Button text={'Test'} url={'http://foo.bar'} />);
describe('Button', function() {
beforeEach(function() {
chrome.tabs.create.reset();
});
it('Text content equals props.text', function() {
expect('Test').toEqual(button.getDOMNode().textContent);
});
@@ -17,7 +18,7 @@ describe('Button', function() {
it('Creates a tab with props.url when clicked', function() {
React.addons.TestUtils.Simulate.click(button.getDOMNode());
expect(chrome.tabs.create.mock.calls.length).toEqual(1);
expect(chrome.tabs.create.mock.calls[0]).toEqual([{ url: 'http://foo.bar', active: true }])
expect(chrome.tabs.create.callCount).toEqual(1);
expect(chrome.tabs.create.getCall(0).args).toEqual([{ url: 'http://foo.bar', active: true }])
});
});
@@ -1,11 +1,9 @@
jest.dontMock('../../../app/scripts/src/popup/components/header');
var React = require('react/addons');
var Header = require('../../../app/scripts/src/popup/components/header');
var TestUtils = React.addons.TestUtils;
var items = [{ name: 'Foo', show: true }, { name: 'Bar', show: false }];
var clickMock = jest.genMockFunction();
var header = TestUtils.renderIntoDocument(<Header items={items} onItemClicked={clickMock} />);
var click = sinon.stub();
var header = TestUtils.renderIntoDocument(<Header items={items} onItemClicked={click} />);
var nav = TestUtils.findRenderedDOMComponentWithTag(header, 'nav');
describe('Header', function() {
@@ -27,7 +25,7 @@ describe('Header', function() {
it('Calls on click function', function() {
React.addons.TestUtils.Simulate.click(nav.getDOMNode().children[0]);
expect(clickMock.mock.calls.length).toEqual(1);
expect(click.callCount).toEqual(1);
});
it('has the correct html classes', function() {
@@ -1,13 +1,14 @@
jest.dontMock('../../../app/scripts/src/popup/components/info');
var React = require('react/addons');
var Info = require('../../../app/scripts/src/popup/components/info');
var helper = require('../../test-helper.js');
var TestUtils = React.addons.TestUtils;
var messages = ['Info Message', 'About Message'];
var info = TestUtils.renderIntoDocument(<Info messages={messages} />);
describe('Info', function() {
beforeEach(function() {
chrome.runtime.sendMessage.reset();
});
it('Returns random message', function() {
var h4 = TestUtils.findRenderedDOMComponentWithTag(info, 'h4');
expect(messages).toContain(h4.getDOMNode().textContent);
@@ -21,9 +22,10 @@ describe('Info', function() {
});
it('Sends analytics appView', function() {
var info = TestUtils.renderIntoDocument(<Info messages={messages} />);
var h4 = TestUtils.findRenderedDOMComponentWithTag(info, 'h4');
expect(chrome.runtime.sendMessage.mock.calls.length).toEqual(1);
expect(chrome.runtime.sendMessage.mock.calls[0]).toEqual([{
expect(chrome.runtime.sendMessage.callCount).toEqual(1);
expect(chrome.runtime.sendMessage.getCall(0).args).toEqual([{
type: 'sendAppView', view: 'Info ' + h4.getDOMNode().textContent
}]);
});
Oops, something went wrong.

0 comments on commit a80deab

Please sign in to comment.