Glad You're Ready. Let's Get Started!

Let us know how we can contact you.

Thank you!

We'll respond shortly.

Using Jasmine to test CoffeeScript in a Rails 3.1 App

Lately I’ve had the opportunity to use Jasmine to test drive a whole bunch of Javascript and am loving it. If you haven’t had a chance to take Jasmine for a spin, I recommend you take some time to do so.

When I heard that Rails 3.1 was going to include CoffeeScript I decided to work to figure out how I could write both my production code as well as my specs in Coffeescript.

Using this gist as a guide, I came up with these detailed instructions:

Add Guard and Guard-Coffeescript to your Gemfile and run bundle.

Run guard init to create a Guardfile and edit it to contain the following:

guard 'coffeescript', :output => 'public/javascripts/compiled' do

guard 'coffeescript', :output => 'spec/javascripts/compiled' do

Edit your spec/javascripts/support/jasmine.yml to have at least the following entries:

src_dir: public/javascripts/compiled
  - **/*.js

spec_dir: spec/javascripts/compiled
  - **/*_spec.js

Start up the Jasmine server using rake jasmine and point your browser to http://localhost:8888. You should see 0 specs, 0 failures. Since you have changed the location that Jasmine looks for spec files, you aren’t picking up the example Jasmine specs any longer.

Create a new spec file in spec/javascripts/ with the following contents:

describe 'Math:', ->
  describe 'fib()', ->
    it 'should calculate the numbers correctly up to fib(16)', ->
      fib = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987]
      expect(Math.fib(i)).toEqual fib[i] for i in [0..16]

Refresh your browser, you should see one failing spec. Guard has compiled your .coffee file into a .js file that Jasmine will use.

Create a new implementation file in app/assets/javascripts/ with the following contents:

Math.fib = (n) ->
    s = 0
    return s if n == 0
    if n == 1
      s += 1
      Math.fib(n - 1) + Math.fib(n - 2)

Refresh your Jasmine browser window and you should see 1 passing spec. Again, Guard has compiled your implementation file and Jasmine uses it to satisfy the spec.

At some point, it would be nice to figure out a way to run Jasmine specs directly from the .coffee files and against the implementation .coffee files without having to use Guard to compile them. With the above steps, you still have to check in the compiled files into source control so your tests can be run in the CI environment. If you miss one of the compiled specs or one of the compiled implementation files, your CI environment may report improper results.

If anyone has any ideas, I’d love to hear them.

  1. grosser says:

    I like the idea of jasmine specs, makes them so much nicer / rspec-ish.

    create something like rake compile_all_coffee and run it on the ci before tests, so you do not have to check in the compiled source.
    Also you only need guard if you do something auto-test-ish, another idea wold be to have the compile step taking place in a task you perpend to jasmine

  2. Peter Lyons says:

    Switch to node.js and express! It can do .coffee compilation on the fly and serve up the corresponding .js code. Or in rails, you could add the equivalent logic to test the request path for .js, look at the filesystem for a matching .coffee and compile it on the fly. This could go in the rescue block where your 404 page might ultimately be rendered.

  3. Mike Gehard says:

    @grosser – Right before I went to bed I came up with the rake task idea for compiling coffeescript…stay tuned for an add on post about that.

    @peter – Using node is another great idea. I’ll poke around and see what I can figure out. Thanks!

  4. I’m currently using the rack-asset-compiler gem to compile jasmine specs and app code.

    The CoffeeScript compilation step is done inside of Rack middleware, so there’s no need to run a rake task or use a process to watch the CoffeeScript files for changes. The middleware uses the If-Modified-Since header to make sure CoffeeScript is only compiled when it changes.

    I have a sample jasmine_config.rb here:

  5. Hey Mike, nice post! I stumbled upon it when trying to figure out how to integrate jasmine into my node app :x

  6. alf says:

    I have one newbie question. Is there a way to test anything not global? In this example, it’s testing the global Math prototype. but if I create a new coffeescript class, I will have to attach it to the window. For example, class window.Picture….
    Is it the approach you are taking too? If not, what will you recommend? Thanks

  7. AlexT says:

    You can check jasminerice gem

  8. Mike Gehard says:

    @alf The approach I take is to set up a namespace for my application and attach that to window and then I have all of my code attach to that namespace:

    window.MyApp = {}

    class MyApp.MyClass
    foo: ->
    alert(“Foo called”)

    a = new MyApp.MyClass()

    Hope this helps.

  9. Mike Gehard says:

    Here is another option for running with Rails 3.1:

Post a Comment

Your Information (Name required. Email address will not be displayed with comment.)

* Copy This Password *

* Type Or Paste Password Here *