Question

Guard-RSpec mentions in the README that one could run specs using spring by specifying a cusom cmd:

guard :rspec, cmd: 'spring rspec' do
  # ...
end

This used to work fine, until I did a spring binstub --all which changed my bin/spring from...

#!/usr/bin/env ruby
#
# This file was generated by Bundler.
#
# The application 'spring' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'pathname'
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
  Pathname.new(__FILE__).realpath)

require 'rubygems'
require 'bundler/setup'

load Gem.bin_path('spring', 'spring')

...to...

#!/usr/bin/env ruby

# This file loads spring without using Bundler, in order to be fast
# It gets overwritten when you run the `spring binstub` command

unless defined?(Spring)
  require "rubygems"
  require "bundler"

  if match = Bundler.default_lockfile.read.match(/^GEM$.*?^    spring \((.*?)\)$.*?^$/m)
    ENV["GEM_PATH"] = ([Bundler.bundle_path.to_s] + Gem.path).join(File::PATH_SEPARATOR)
    ENV["GEM_HOME"] = ""
    Gem.paths = ENV

    gem "spring", match[1]
    require "spring/binstub"
  end
end

Now when running guard and hitting enter, it simply tells me this:

[2] guard(main)>                     <<<<< pressing enter
14:35:35 - INFO - Run all
14:35:35 - INFO - Running all specs

And a notification like "RSpec results - Failed" appears.

When changing my Guardfile and removing spring from the RSpec's cmd like this...

guard :rspec, cmd: 'rspec' do

...the specs are run again, but apparently not using spring?

I also have to mention that when running spring from the OSX terminal, nothing seems to happen:

$ spring
$ 

So: how must I configure Guard and RSpec to use Spring?

Update

At the moment, I have reverted my bin/spring executable to the version before "binstubbing" it:

#!/usr/bin/env ruby
#
# This file was generated by Bundler.
#
# The application 'spring' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'pathname'
ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
  Pathname.new(__FILE__).realpath)

require 'rubygems'
require 'bundler/setup'

load Gem.bin_path('spring', 'spring')

And the Guardfile looks like this:

guard :rspec, cmd: 'spring rspec' do ... end

This works, but I don't think it's faster than running bare rspec.

So I'm absolutely unsure now how to correctly run RSpec with Spring - using spring rspec or just rspec?

Was it helpful?

Solution

I was looking into this very issue earlier.

Binstubs are wrapper scripts around executables. In Rails they live inside bin/. If you run spring binstub --all, your binstubs will be using Spring.

http://makandracards.com/makandra/26083-3-ways-to-run-spring-the-rails-app-preloader-and-how-to-disable-it

Given this fact, you should be able to do something like this to use Rspec with Spring

guard :rspec, cmd: "bin/rspec" do

A little test to verify. Make sure that you have binstubbed rspec already.

bundle binstubs 'rspec-core'

Verify that Spring hasn't been bootstrapped in bin/rspec. The following block should not appear.

[bin/rspec]

begin
  load File.expand_path("../spring", __FILE__)
rescue LoadError
end

Shut down Spring. Run bin/rspec and verify that Spring wasn't triggered.

spring stop
spring status
bin/rspec
spring status

If Spring wasn't triggered, you should see this

Spring is not running.

Now bootstrap your binstubs with Spring. Make sure that you have already bundle installed the necessary gems.

[Gemfile]

group :development, :test do
  gem "rspec-rails", "~> 3.0"
  gem 'spring-commands-rspec'
  ...
end

[terminal]

bundle install

Update binstubs to use Spring

spring binstub --all

Verify that Spring has been bootstrapped in bin/rspec. The following block should now appear.

[bin/rspec]

begin
  load File.expand_path("../spring", __FILE__)
rescue LoadError
end

Shut down Spring. Run bin/rspec and verify that Spring was triggered.

spring stop
spring status
bin/rspec
spring status

Now check to see if the tests run faster after spring has loaded the environment for the tests.

spring stop
time bin/rspec

[output]

real    0m4.981s
user    0m0.144s
sys 0m0.032s

Spring should be running now. Let's see if it's doing its job.

time bin/rspec

[output]

real    0m0.831s
user    0m0.140s
sys 0m0.034s

Yep.

Bottom line, if your binstubs have been bootstrapped with Spring, calling the binstubs will include Spring. And, of course, only commands that have been registered with Spring can use Spring, which is why spring-commands-rspec was included in the Gemfile earlier to support Rspec.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top