I can't quite tear myself away from Backbone.js (and really, why would I want to?). So tonight I am going to try to get a Backbone application built with require.js to run under the jasmine server (part of the jasmine ruby gem). Ultimately, I hope to parlay this into something that can be run under PhantomJS, but first things first.
The main problem with the jasmine server, with respect to require.js code, is that the jasmine server explicitly slurps in a bunch of Javascript files. It does this by checking the
spec/javascripts/support/jasmine.yml file for the src_files entry. Back before require.js, that entry looked like:src_files:
- public/scripts/jquery.min.js
- public/scripts/jquery-ui.min.js
- public/scripts/underscore.js
- public/scripts/backbone.js
- public/scripts/**/*.jsInserting those into the server's HTML is just going to cause require.js related trouble, so I empty out that entry.But how do I get require.js into the server spec runner and, more importantly, how do I also add the
data-main attribute? For now, I manually copy the run.html.erb file from the Ruby gem into my application's home directory. In there, I can manually add the require.js <script> tag:<script data-main="/public/scripts/main" src="/public/scripts/require.js"></script>I was already able to get standalone jasmine to work with require.js the other night, so I can copy the same configuration into
run.html.erb now:<script data-main="/public/scripts/main" src="/public/scripts/require.js"></script>
<script type="text/javascript">
require.config({
baseUrl: '../public/scripts',
paths: {
'jquery': 'jquery.min',
'jquery-ui': 'jquery-ui.min'
}
});
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>That is a combination of the usual Jasmine initialization and require.js configuration.At this point, I have my spec runner ready to go, but the jasmine gem's server is still going to look for
run.html.erb inside the library instead of using my new require.js copy. To get around that, I edit the Rakefile, to pull in a specialized jasmine server:begin
require 'jasmine'
require './jasmine_server'
load 'jasmine/tasks/jasmine.rake'
rescue LoadError
task :jasmine do
abort "Jasmine is not available. In order to run jasmine, you must: (sudo) gem install jasmine"
end
endIn the jasmine_server.rb file, I make use of Ruby's open classes to modify the server's run method:module Jasmine
class RunAdapter
def run(focused_suite = nil)
jasmine_files = @jasmine_files
css_files = @jasmine_stylesheets + (@config.css_files || [])
js_files = @config.js_files(focused_suite)
body = ERB.new(File.read(File.join(File.dirname(__FILE__), "run.html.erb"))).result(binding)
[
200,
{ 'Content-Type' => 'text/html' },
[body]
]
end
end
endWith that, I have my require.js jasmine server running my specs. Tomorrow, I will go through the exercise of fixing them:The switch to the node-dirty data store broke those—not the switch to the jasmine server. For now, this is a good stopping point.
Day #236

Great documentation - thanks so much for posting this!
ReplyDeleteSince this posting, the jasmine gem has changed slightly (1.2.1) and instead of modifying RunAdapter, I modified ::Jasmine.runner_template. Might be helpful to the next person who runs across this.
Again, thank you!