Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save danascheider/82eda70a4f7152841dca to your computer and use it in GitHub Desktop.
Save danascheider/82eda70a4f7152841dca to your computer and use it in GitHub Desktop.
Backbone, Require.js, Mocha, and Chai
<!DOCTYPE html>
<html>
<head>
<!-- All the same stuff you'd ordinarily have in your head -->
</head>
<body>
<script data-main='js/main' src='js/lib/require.js'></script>
</body>
</html>
This gist is an offshoot of the one by Michael Cox at https://gist.github.com/michaelcox/3800736.
I had been looking for a testing solution for a long time, and his code didn't quite work for me,
so I thought I'd share what finally did.
In all the files I'm showing here, there are additional lines of code that are omitted for brevity.
If you'd like to see the whole thing in action, you can find it at
`https://github.com/danascheider/canto`.
Relevant parts of my directory structure looked like this. The ./js/lib/chai and
./js/lib/mocha directories are the same directories that show up in your node_modules
folder when you run `npm install`, but for the sake of clarity, I'm only showing the files
I reference in this gist.
.
├── js/
| ├── lib/
| | ├── chai/
| | | ├── chai.js
| | ├── mocha/
| | | ├── mocha.js
| | ├── backbone.js
| | ├── chai-jquery.js
| | ├── css.min.js // Require.js plugin
| | ├── jquery-2.1.1.js
| | ├── require.js
| | ├── text.js // Require.js plugin
| | ├── underscore.js
| ├── spec/
| | ├── task-spec.js
| | ├── user-spec.js
| ├── models/
| | ├── task.js
| | ├── user.js
| | ├── presenter.js
| ├── collections/
| | ├── tasks.js
| ├── views/
| | ├── app/
| | | ├── dashboard.js
| | | ├── homepage.js
| | ├── spec/
| | | ├── spec.js
| ├── main.js
| ├── router.js
├── index.html
// File is /js/main.js
requirejs.config({
paths: {
jquery : './lib/jquery-2.1.1',
underscore : './lib/underscore',
backbone : './lib/backbone',
mocha : './lib/mocha/mocha',
chai : './lib/chai/chai',
text : './lib/text',
css : './lib/css.min',
'chai-jquery' : './lib/chai-jquery'
},
shim: {
backbone : {
deps : ['jquery', 'underscore'],
exports : 'Backbone'
},
'chai-jquery' : ['jquery', 'chai']
}
});
// In the Michael Cox's gist, the testing code goes here, but I put that code in the spec
// view and use this code to run the app.
require(['jquery', 'backbone, router, models/user'], function($, Backbone, Router, UserModel) {
$(function() {
this.router = new Router();
Backbone.history.start({root: '.'});
});
});
// File is /js/router.js
define([
'backbone',
'models/presenter',
'models/user',
'views/spec/spec'
], function(Backbone, Presenter, UserModel, SpecRunner) {
var AppRouter = Backbone.Router.extend({
// this.presenter handles most of the top level views for the app. I will probably refactor
// the code to either make it run specs too, or make a new presenter that handles the test suite.
routes : {
// Obviously there are other routes and handlers too
'spec(/)' : 'runSpec'
},
runSpec : function() {
this.presenter.removeAll(); // clean up views for garbage collection
// Setting the spec runner as a property of the router makes it easier
// to clean up when we are done with it.
this.specRunner = new SpecRunner({el: 'body'});
}
});
return AppRouter;
});
// File is /js/views/spec.js
define([
'underscore',
'backbone',
'css!lib/mocha/mocha.css'
], function(_, Backbone) {
var SpecRunner = Backbone.View.extend({
template : _.template("<div id='mocha'></div>"),
initialize: function() {
this.render();
},
render : function() {
this.runSpecs();
this.$el.html(this.template());
},
runSpecs : function() {
require(['require', 'chai', 'mocha', 'jquery', 'chai-jquery'], function(require, chai) {
var should = chai.should();
mocha.setup('bdd');
require(['spec/userSpec'], function(require) {
mocha.run();
});
});
}
});
return SpecRunner;
});
// File is /js/spec/user-spec.js
//
// I think this is fairly self-explanatory test code, so I'm not including the User model
// code in the gist because I don't think it's necessary. If you disagree, please let me
// know and I'll add it.
define(function(require) {
var User = require('models/user');
describe('User', function() {
it('has a default URL root of "/users"', function() {
var user = new User();
user.urlRoot.should.equal('/users');
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment