Jasmine with Rails 3.1
I have been writing a JavaScript intensive Rails 3.1 application recently and haven been using Jasmine to test my JavaScript. When I started this application I was using the RC version of Rails 3.1 and was generating my assets based on Jeff Dean’s post however with the release of 3.1 stable I found this method does not work any more. So I had to change the jasmine_config.rb to make it work again.
Also because Rails is out of beta now so I am no longer calling the rake task, instead I am. Using the API that the rake task uses.
So to keep things brief here is what my jasmine.rb looks like (located in spec/javascript/support)
1 module Jasmine
2 class Config
3
4 def js_files(spec_filter = nil)
5 generated_files_directory = File.expand_path("../../generated", __FILE__)
6 rm_rf generated_files_directory, :secure => true
7 precompile_app_assets
8 compile_jasmine_javascripts
9
10 # this is code from the original jasmine config js_files method - you could also just alias_method_chain it
11 spec_files_to_include = spec_filter.nil? ? spec_files : match_files(spec_dir, [spec_filter])
12 src_files.collect {|f| "/" + f } + helpers.collect {|f| File.join(spec_path, f) } + spec_files_to_include.collect {|f| File.join(spec_path, f) }
13 end
14
15 private
16
17 # this method compiles all the same javascript files your app will
18 def precompile_app_assets
19 puts "Precompiling assets..."
20
21 # make sure the Rails environment is loaded
22 require 'config/environment'
23 # ::Rake.application['environment'].invoke
24
25
26
27 config = Rails.application.config
28 env = Rails.application.assets
29 target = Rails.root.join("spec/javascripts/generated/assets")
30
31
32 config.assets.precompile.each do |path|
33 env.each_logical_path do |logical_path|
34 if path.is_a?(Regexp)
35 next unless path.match(logical_path)
36 elsif path.is_a?(Proc)
37 next unless path.call(logical_path)
38 else
39 next unless File.fnmatch(path.to_s, logical_path)
40 end
41
42 if asset = env.find_asset(logical_path)
43 asset_path = config.assets.digest ? asset.digest_path : logical_path
44 filename = target.join(asset_path)
45
46 mkdir_p filename.dirname
47 asset.write_to(filename)
48 asset.write_to("#{filename}.gz") if filename.to_s =~ /\.(css|js)$/
49 end
50 end
51 end
52 end
53
54 # this method compiles all of the spec files into js files that jasmine can run
55 def compile_jasmine_javascripts
56 puts "Compiling jasmine coffee scripts into javascript..."
57 root = File.expand_path("../../../../spec/javascripts/coffee", __FILE__)
58 destination_dir = File.expand_path("../../generated/specs", __FILE__)
59
60 glob = File.expand_path("**/*.js.coffee", root)
61
62 Dir.glob(glob).each do |srcfile|
63 srcfile = Pathname.new(srcfile)
64 destfile = srcfile.sub(root, destination_dir).sub(".coffee", "")
65 FileUtils.mkdir_p(destfile.dirname)
66 File.open(destfile, "w") {|f| f.write(CoffeeScript.compile(File.new(srcfile)))}
67 end
68 end
69
70 end
71 end
72
73
74 # Note - this is necessary for rspec2, which has removed the backtrace
75 module Jasmine
76 class SpecBuilder
77 def declare_spec(parent, spec)
78 me = self
79 example_name = spec["name"]
80 @spec_ids << spec["id"]
81 backtrace = @example_locations[parent.description + " " + example_name]
82 parent.it example_name, {} do
83 me.report_spec(spec["id"])
84 end
85 end
86 end
87 end
Here is an exert from jasmine.yml, also located in spec/javascript/support.
src_files:
- spec/javascripts/generated/assets/application*.js
With these changes I have not had any problems with my jasmine suite running correctly.