Fares
Fares

Reputation: 241

Loading jQuery on Jasmine on Rails 3.1 plugin before source files

I'm working Jasmine on a Rails plugin that would be included in a Rails app that loads jQuery from a CDN. However, I'm running into issues running Jasmine tests in my plugin. I need to load jQuery before my source javascript files in app/assets/javascripts, but if I include jQuery in my jasmine.yml it doesn't get loaded before the source files:

jasmine.yml contents:

src_dir: "app/assets/javascripts"
src_files:
 - "my_rails_plugin_source_includer.js"
spec_dir: spec/javascripts
asset_paths:
- "vendor/assets/javascripts"

my_rails_plugin_source_includer.js requires my source javascripts:

//= require my_jquery_dependent_script.js
//= require my_other_jquery_dependent_script.js

I'm using

bundle exec jasmine-headless-webkit --color --keep ./spec/javascripts/specs.js

to run my tests. I get an error message like

ReferenceError: Can't find variable: jQuery
ReferenceError: Can't find variable: jQuery
Test ordering seed: --seed 1629

My tests pass if I explicitly require a jQuery javascript file (e.g., jquery-1.9.1-min.js) in my_rails_plugin_source_includer.js. However, I don't want to do that, as I want the actual Rails app, rather than this plugin. Any suggestions on how to require jQuery before my source files? Requiring it in my specs or my helpers doesn't work, as Jasmine seems to always load the source files first (which of course makes sense).

Upvotes: 3

Views: 1730

Answers (2)

jefflunt
jefflunt

Reputation: 33954

Thanks for your answer, Fares, it gave me the insight into what's happening with the jasmine config file.

There's a predictable order to how files are included in your jasmine page's <head> tag.

First, my setup deatils:

rails 4.0.1
jasmine 1.3.2
jquery-rails 3.0.4 (which provides jquery-1.10.2)


Here's my spec/javascripts/support/jasmine.yml. I have no helpers, I don't need css files to test my particular app, and I removed all the comments.

src_files:
  - spec/javascripts/lib/jquery-1.10.2.js
  - app/assets/javascripts/tools/dependency-parser.js

spec_dir: spec/javascripts
spec_files:
  - '**/*[sS]pec.js'


The <head> of my jasmine page contains the following, in order:

jasmine core  <link rel="shortcut icon" type="image/png" href="/__JASMINE_ROOT__/images/jasmine_favicon.png">
              <link rel="stylesheet" href="/__jasmine__/jasmine.css" type="text/css" media="screen">
              <script src="/__jasmine__/jasmine.js" type="text/javascript"></script>
              <script src="/__jasmine__/jasmine-html.js" type="text/javascript"></script>
              <script src="/__jasmine__/json2.js" type="text/javascript"></script>

   src_files  <script src="/spec/javascripts/lib/jquery-1.10.2.js" type="text/javascript"></script>
              <script src="/app/assets/javascripts/tools/dependency-parser.js" type="text/javascript"></script>

helper_files  <!-- I didn't have anything here -->

  spec_files  <script src="/__spec__/dependency-parser_spec.js" type="text/javascript"></script>

jasmine boot  <script src="/__boot__/boot.js" type="text/javascript"></script>


My app uses the asset pipeline, and the jquery-rails gem, along with the typical includes in app/assets/application.js:

//=require jquery
//=require jquery-ujs
//=require tree .

Because I am using the jquery-rails gem, that means I don't actually have the jQuery JavaScript files anywhere to load directly - they should come from the asset pipeline if they come from anywhere. It also seemed that I couldn't include the app/assets/javascripts/application.js file for some reason. This turned out to be okay; I just want to test my custom JavaScript, which depends upon jQuery.

So, I simply downloaded the version of jQuery that my app is using (1.10.2), and put it in:

spec/javascripts/lib/   <= I created this folder

After that everything worked perfectly, because I could predictably load my .js files in the order in which I needed them. It's not perfect. I now manually have keep my jQuery version the same in my specs as whatever version of jquery-rails I use, but that's a rather minor thing for now...though it begs the question, "Why the hell do people package javascript file into a gem?" No other web framework does this kind of wacky stuff.

I also tried using the jasmine 2.0.0.rc5 gem (the current version as of this writing), because it was supposed to take care of asset pipeline issues like this, but it didn't work for me.

I also tried jumping to something more complex like using the jasmine-jquery or jasminerice gems, but found both of their implementations to be more complicated versions of what I did above. Once I understood how the config file was generating the contents of the <head> tag in my particular case, it was a relatively easy fix.

I may move to jasmine 2.0.0 when it's released, if I feel it's necessary (it supposedly has better Rails 4 support), but I'm pretty sure this solution is going to work out just fine.

Upvotes: 0

Fares
Fares

Reputation: 241

I was able to solve this issue by doing the following:

  1. Downloading jquery-1.9.1.min.js from the official jQuery source and storing it in my spec/javascripts/support/helpers folder.
  2. Creating a source.js file in my spec/javascripts/support/fixtures folder (can be an arbitrary folder) that has the following contents:

    //= require ../helpers/jquery-1.9.1.min
    //= require ../../../../app/assets/javascripts/application
    

    where app/assets/javascripts/application.js is the manifest for my plugin's JavaScripts.

  3. Editing my jasmine.yml file to use the following sources:

    src_dir: "spec/javascripts/support/fixtures"
    src_files:
     - "source.js"
    

As a result, the jQuery-dependent source JavaScripts have jQuery preloaded only for Jasmine testing.

Upvotes: 3

Related Questions