Over the last few days, I have made good progress converting my Backbone.js application to require.js. During that time, I have not paid the slightest bit of attention to my jasmine specs.
Tonight that changes:
Ugh.
Well, the first error—the
"ReferenceError: Cal is not defined"
error—likely has much to do with the remaining errors. Prior to the require.js switch, I had been including the monolithic version of my Backbone application in my SpecRunner.html
thusly: <!-- include source files here... -->
<script type="text/javascript" src="../public/javascripts/calendar.js"></script>
Now that I have switched to require.js, my web page is including the Backbone application like so:<script data-main="javascripts/main" src="javascripts/require.js"></script>I cannot simply re-use that line in my Jasmine tests because the
javascripts/main
file (referenced by the data-main
attribute) initializes the calendar application:require.config({ paths: { 'jquery': 'jquery.min', 'jquery-ui': 'jquery-ui.min' } }); require(['calendar'], function(Calendar){ var calendar = new Calendar($('#calendar')); });Most of my specs do that in a
beforeEach()
setup block. It will not do to already have instantiated my application.Instead, I think I can leverage require.js loading to replace the standard on-page-load Jasmine initializer. For that, in my
SpecRunner.html
file, I start by loading in requirejs, then do a little configuration: <script type="text/javascript" src="../public/javascripts/require.js"></script>
<script type="text/javascript">
require.config({
baseUrl: '../public/javascripts',
paths: {
'jquery': 'jquery.min',
'jquery-ui': 'jquery-ui.min'
}
});
require(['calendar', 'backbone'], function(Calendar, Backbone){
// ...
});
</script>
The paths
attribute to require.config
comes directly from my application code—it tells require.js how to find jquery and jquery-ui (i.e. to use the minified versions of each). The baseUrl
attribute is special to my spec setup. It tells require.js to look in the public/javascripts
directory for the javascript files instead of the same directory as SpecRunner.html
.As for the actual running of the jasmine environment, I do a normal require.js
require()
. In there, I need to assign Backbone
and Cal
(my Backbone application) to global variables so that my specs can access them: <script type="text/javascript" src="../public/javascripts/require.js"></script>
<script type="text/javascript">
require.config({ /* ... */ });
require(['calendar', 'backbone'], function(Calendar, Backbone){
window.Cal = Calendar;
window.Backbone = Backbone;
var jasmineEnv = jasmine.getEnv();
jasmineEnv.updateInterval = 1000;
var trivialReporter = new jasmine.TrivialReporter();
jasmineEnv.addReporter(trivialReporter);
jasmineEnv.specFilter = function(spec) {
return trivialReporter.specFilter(spec);
};
jasmineEnv.execute();
});
</script>
The rest of that is just normal Jasmine initialization code¸although I do remove some onload trickery. The require.js machinations ensure that the code will not run except on page load.And it works!
Well, almost. But 6 failing specs is much improved. I call it a night here and will fix the remaining three tomorrow.
Day #231
Thank you for the post!
ReplyDeleteIn the "require(['calendar', 'backbone'], function(Calendar, Backbone){" the backbone and calendar are in your path?