With the upcoming release of Rails3, it’s important to maintain gem/plugins compatibility with both Rails 2.x series and the new Rails 3.x series.
That’s why I wanted to implement specs supporting both versions for one of my plugin.
With a simple rake task, I wanted to run spec for a specific Rails version.
By default, Rspec create this kind of Rakefile :
require 'rubygems'
require 'rake'
require 'spec/rake/spectask'
spec_files = Rake::FileList["spec/**/*_spec.rb"]
desc "Run specs"
Spec::Rake::SpecTask.new do |t|
t.spec_files = spec_files
t.spec_opts = ["-c"]
end
task :default => :spec
Here we have the default Rake task : “spec” wich will run specs for our code.
Custom our Rakefile to specify the Rails version
At this point, we need to pass an extra option to spec script in order to specify wich rails version we want to use in our tests.
The way I found to do this is to tricks spec_opts (which is command line options for spec) by assigning to it, a Proc, like this :
t.spec_opts = lambda do
@rails_version ? ["-c -- rails_version=#{@rails_version}"] : ["-c"]
end
Then add two tasks to your Rakefile :
desc "Run Rails 2.x specs"
task :rails2_spec do
@rails_version = 2
Rake::Task['spec'].invoke
end
desc "Run Rails 3.x specs"
task :rails3_spec do
@rails_version = 3
Rake::Task['spec'].invoke
end
Ok, now we have our three tasks passing Rails version to our spec tests !
kwi@ ~/Projects/i18n_routing$ rake -T
(in /Users/kwi/Projects/i18n_routing)
rake rails2_spec # Run Rails 2.x specs
rake rails3_spec # Run Rails 3.x specs
rake spec # Run specs for current Rails version
Retrieve the Rails version parameter
Then in your spec_helper.rb file, where you include your dependencies, you just need to retrieve the rails version with this (dirty) piece of code :
rails_version = ARGV.find { |e| e =~ /rails_version=.*/ }
rails_version = rails_version.split('=').last.to_i rescue 2
Now we have the correct rails version we want for running our tests, so we need to include our dependencies depending on the Rails’ version we want to load.
For this, there is a tricky things with gem method for specify wich version of gem you want to use :
gem 'actionpack', (rails_version < 3 ? '< 2.9' : '> 2.9')
require 'action_controller'
(Example for loading action_controller only, here I use 2.9 version number in order to support Rails3beta)
Here we are, now we can run our tests on both Rails version just with a simple rake task :
rake rails2_spec
# Or
rake rails3_spec