Skip to content
This repository has been archived by the owner on Sep 15, 2023. It is now read-only.

Add JS testing framework: Karma w/ Mocha, Chai and Sinon #88

Merged
merged 6 commits into from
Feb 10, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 25 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,12 @@ alias gulp='node_modules/.bin/gulp'
Now, running `gulp` in the project directory will use the version specified and installed from the `package.json` file.

### Run gulp and be amazed.
The first time you run the app, you'll also need to generate the iconFont, since this is not something we want to run every time with our `default` task.
```
gulp iconFont
```

After that, just run the `default` gulp task with:
```
gulp
```
Expand All @@ -59,6 +64,11 @@ This will run the `default` gulp task defined in `gulp/tasks/default.js`, which
- `markup` doesn't do anything but copy an html file over from src to build, but here is where you could do additional templating work.
- `watch` has `watchify` as a dependency, which will run the browserifyTask with a `devMode` flag that enables sourcemaps and watchify, a browserify add-on that enables caching for super fast recompiling. The task itself starts watching source files and will re-run the appropriate tasks when those files change.

### Configuration
All paths and plugin settings have been abstracted into a centralized config object in `gulp/config.js`. Adapt the paths and settings to the structure and needs of your project.

### Additional Features and Tasks

#### Icon Fonts

```
Expand All @@ -81,12 +91,23 @@ or
<span class="icon -twitter"></span>
```

#### gulp production
#### Production files

There is also a `production` task you can run with `gulp production`, which will re-build optimized, compressed css and js files to the build folder, as well as output their file sizes to the console. It's a shortcut for running the following tasks: `['images', 'minifyCss', 'uglifyJs']`.
There is also a `production` task you can run:
```
gulp production
```
This will run JavaScript tests, then re-build optimized, compressed css and js files to the build folder, as well as output their file sizes to the console. It's a shortcut for running the following tasks: `karma`, `images`, `iconFont` `minifyCss`, `uglifyJs`.

### Configuration
All paths and plugin settings have been abstracted into a centralized config object in `gulp/config.js`. Adapt the paths and settings to the structure and needs of your project.
#### JavaScript Tests with Karma
This repo includes a basic js testing setup with the following: [Karma](http://karma-runner.github.io/0.12/index.html), [Mocha](http://mochajs.org/), [Chai](http://chaijs.com/), and [Sinon](http://sinonjs.org/). There is `karma` gulp task, which the `production` task uses to run the tests before compiling. If any tests fail, the `production` task will abort.

To run the tests and start monitoring files:
```
./node_modules/karma/bin/karma start
```

Want to just run `karma start`? Either add `alias karma="./node_modules/karma/bin/karma"` to your shell config or install the karma command line interface globally with `npm install -g karma-cli`.


--
Expand Down
14 changes: 7 additions & 7 deletions gulp/tasks/browserify.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ var browserifyTask = function(callback, devMode) {

if(devMode) {
// Add watchify args and debug (sourcemaps) option
_.extend(bundleConfig, watchify.args, { debug: true })
_.extend(bundleConfig, watchify.args, { debug: true });
// A watchify require/external bug that prevents proper recompiling,
// so (for now) we'll ignore these options during development
bundleConfig = _.omit(bundleConfig, ['external', 'require'])
bundleConfig = _.omit(bundleConfig, ['external', 'require']);
}

var b = browserify(bundleConfig);
Expand Down Expand Up @@ -57,19 +57,19 @@ var browserifyTask = function(callback, devMode) {
b = watchify(b);
// Rebundle on update
b.on('update', bundle);
bundleLogger.watch(bundleConfig.outputName)
bundleLogger.watch(bundleConfig.outputName);
} else {
// Sort out shared dependencies.
// b.require exposes modules externally
if(bundleConfig.require) b.require(bundleConfig.require)
if(bundleConfig.require) b.require(bundleConfig.require);
// b.external excludes modules from the bundle, and expects
// they'll be available externally
if(bundleConfig.external) b.external(bundleConfig.external)
if(bundleConfig.external) b.external(bundleConfig.external);
}

var reportFinished = function() {
// Log when bundling completes
bundleLogger.end(bundleConfig.outputName)
bundleLogger.end(bundleConfig.outputName);

if(bundleQueue) {
bundleQueue--;
Expand All @@ -91,4 +91,4 @@ var browserifyTask = function(callback, devMode) {
gulp.task('browserify', browserifyTask);

// Exporting the task so we can call it directly in our watch task, with the 'devMode' option
module.exports = browserifyTask
module.exports = browserifyTask;
13 changes: 13 additions & 0 deletions gulp/tasks/karma.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
var gulp = require('gulp');
var karma = require('karma');

var karmaTask = function(done) {
karma.server.start({
configFile: process.cwd() + '/karma.conf.js',
singleRun: true
}, done);
};

gulp.task('karma', karmaTask);

module.exports = karmaTask;
2 changes: 1 addition & 1 deletion gulp/tasks/markup.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
var gulp = require('gulp');
var config = require('../config').markup
var config = require('../config').markup;
var browserSync = require('browser-sync');

gulp.task('markup', function() {
Expand Down
5 changes: 4 additions & 1 deletion gulp/tasks/production.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
var gulp = require('gulp');

// Run this to compress all the things!
gulp.task('production', ['markup', 'images', 'iconFont', 'minifyCss', 'uglifyJs']);
gulp.task('production', ['karma'], function(){
// This runs only if the karma tests pass
gulp.start(['markup', 'images', 'iconFont', 'minifyCss', 'uglifyJs'])
});
2 changes: 1 addition & 1 deletion gulp/tasks/watchify.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
var gulp = require('gulp');
var browserifyTask = require('./browserify')
var browserifyTask = require('./browserify');

gulp.task('watchify', function(callback) {
// Start browserify task with devMode === true
Expand Down
60 changes: 60 additions & 0 deletions karma.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Karma configuration
// Generated on Fri Jan 23 2015 17:22:58 GMT-0500 (EST)

module.exports = function(config) {
config.set({

// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',

// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['mocha', 'sinon-chai', 'browserify'],

// list of files / patterns to load in the browser
files: [
'src/javascript/**/__tests__/*'
],

// list of files to exclude
exclude: [
],

// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'src/javascript/**/__tests__/*': ['browserify']
},

browserify: {
debug: true,
extensions: ['.js', '.coffee', '.hbs']
},

// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['nyan'],

// web server port
port: 9876,

// enable / disable colors in the output (reporters and logs)
colors: true,

// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,

// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,

// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['Chrome'],

// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false
});
};
7 changes: 7 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@
"gulp-util": "^3.0.0",
"handlebars": "^1.3.0",
"hbsfy": "~2.0.0",
"karma": "^0.12.31",
"karma-browserify": "^3.0.0",
"karma-chrome-launcher": "^0.1.7",
"karma-coffee-preprocessor": "^0.2.1",
"karma-mocha": "^0.1.10",
"karma-nyan-reporter": "0.0.50",
"karma-sinon-chai": "^0.3.0",
"lodash": "^2.4.1",
"pretty-hrtime": "~0.2.1",
"require-dir": "^0.1.0",
Expand Down
7 changes: 7 additions & 0 deletions src/javascript/__tests__/page-test.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
require '../page'
$ = require 'jquery'

describe 'page.js', ->
it 'contains a love letter', ->
loveLetter = $('.love-letter').length
loveLetter.should.equal 1
2 changes: 1 addition & 1 deletion src/javascript/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ var _ = require('underscore');
// This combination lets this file use the jquery module bundled with
// global.js, instead including it twice!

var messageTemplate = _.template("<p>Made with <%= feels %> at <a href='<%= url %>'><%= bestCompanyEvar %>!</a></p>");
var messageTemplate = _.template("<p class='love-letter'>Made with <%= feels %> at <a href='<%= url %>'><%= bestCompanyEvar %>!</a></p>");

var message = messageTemplate({
bestCompanyEvar: 'Viget',
Expand Down