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!