I’m working with Rails 4, and though I like the new version of the framework, I miss such handy things as Spork running with it out of the box (yes, you can tweak and patch, but…). So, I turned to other tools out there for speeding up my development/testing environment. And obviously the first thing that came to my attention was Zeus. There is a great post devoted to adding it to your project: http://robots.thoughtbot.com/post/40193452558/improving-rails-boot-time-with-zeus. And it’s pretty simple anyways, so no need to repeat the basic steps here.
Since I use RSpec, don’t use Cucumber, use Pow for starting the Rails server, and I don’t mind to wait for a few extra seconds when I occasionally run rails db
(I just do it too infrequently to care), my zeus.json looks a bit simpler that the default:
{ "command": "ruby -rubygems -r./custom_plan -eZeus.go", "plan": { "boot": { "default_bundle": { "development_environment": { "prerake": {"rake": []}, "console": ["c"], "generate": ["g"] }, "test_environment": { "test_helper": {"test": ["rspec"]} } } } } }
And it works. However, there is one thing that annoys me about the setup. Instead of doing just zeus rspec
to run tests, you have to do zeus rspec spec/spec_helper.rb
, otherwise you get this:
$ zeus rspec ~/.rvm/gems/ruby-2.0.0-p0/gems/zeus-0.13.3/lib/zeus/rails.rb:214:in `spec_file?': undefined method `match' for nil:NilClass (NoMethodError)
and then a bunch of stack trace lines.
The problem is in how the test
method is defined in Zeus code (see https://github.com/burke/zeus/blob/master/rubygem/lib/zeus/rails.rb):
def test(argv=ARGV) if spec_file?(argv) && defined?(RSpec) # disable autorun in case the user left it in spec_helper.rb RSpec::Core::Runner.disable_autorun! exit RSpec::Core::Runner.run(argv) else Zeus::M.run(argv) end end
It first attempts to check if we meant RSpec, and only if detects the spec file, proceeds to executing it. Since in my case I know I always mean RSpec, I can avoid that spec_file?
check. Fortunately, there is an easy way to do that. Just define your custom method in custom_plan.rb
and use it inside your zeus.json
instead of the original test
method. Like this (note the test
-> spec
change):
# in custom_plan.rb: def spec(argv=ARGV) # disable autorun in case the user left it in spec_helper.rb RSpec::Core::Runner.disable_autorun! exit RSpec::Core::Runner.run(argv) end # in zeus.json: "test_helper": {"spec": ["rspec"]}
And now it runs smoothly. Just run zeus rspec
, and you’ll have your specs run as if you called rspec
.
As usual, here is the gist with complete Zeus config files (https://gist.github.com/moonfly/5326451):
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'zeus/rails' | |
class CustomPlan < Zeus::Rails | |
def spec(argv=ARGV) | |
# disable autorun in case the user left it in spec_helper.rb | |
RSpec::Core::Runner.disable_autorun! | |
exit RSpec::Core::Runner.run(argv) | |
end | |
end | |
Zeus.plan = CustomPlan.new |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"command": "ruby -rubygems -r./custom_plan -eZeus.go", | |
"plan": { | |
"boot": { | |
"default_bundle": { | |
"development_environment": { | |
"prerake": {"rake": []}, | |
"console": ["c"], | |
"generate": ["g"] | |
}, | |
"test_environment": { | |
"test_helper": {"spec": ["rspec"]} | |
} | |
} | |
} | |
} | |
} |