netzpirat / guard-rspectacle

Experimental embedded RSpec runner.
MIT License
37 stars 5 forks source link

Guard::RSpectacle Build Status

Guard::RSpectacle automatically tests your application with [RSpec]() when files are modified.

Tested on MRI Ruby 1.8.7, 1.9.2, 1.9.3, REE and the latest versions of JRuby & Rubinius.

If you have any questions please join us on our Google group or on #guard (irc.freenode.net).

How it works

The idea is that Guard starts the Rails environment, reloads changed Ruby files and starts the RSpec runner embedded in the current process. Please be sure to understand the limitation of this approach.

If you want to use a safer approach to run your specs, try guard-rspec.

Install

Guard and Guard::RSpectacle

Please be sure to have Guard installed.

Add it to your Gemfile:

group :development
  gem 'guard-rspectacle'
end

and install it by running Bundler:

$ bundle

Add the guard definition to your Guardfile by running this command:

$ guard init rspectacle

Usage

Please read the Guard usage documentation for information about Guard.

Guardfile

Guard::RSpectacle can be adapted to all kind of projects. Please read the Guard documentation for more information about the Guardfile DSL.

guard :rspectacle do
  watch('spec/spec_helper.rb')                        { %w(spec/spec_helper spec) }
  watch('config/routes.rb')                           { %w(config/routes.rb spec/routing) }
  watch('app/controllers/application_controller.rb')  { 'spec/controllers' }

  watch(%r{^spec/.+_spec\.rb$})

  watch(%r{^app/(.+)\.rb$})                           { |m| ["app/#{m[1]}.rb", "spec/#{m[1]}_spec.rb"] }
  watch(%r{^lib/(.+)\.rb$})                           { |m| ["lib/#{m[1]}.rb", "spec/lib/#{m[1]}_spec.rb"] }
  watch(%r{^app/controllers/(.+)_controller\.rb$})    { |m| [
    "app/controllers/#{m[1]}_controller.rb",
    "spec/controllers/#{m[1]}_spec.rb",
    "spec/routing/#{m[1]}_routing_spec.rb",
    "spec/acceptance/#{m[1]}_spec.rb"
  ]}
end

NOTE: When using watch with a block, you must return all files that should be reloaded.

Options

There are many options that can customize Guard::RSpectacle to your needs. Options are simply supplied as hash when defining the Guard in your Guardfile:

guard :rspectacle, :cli => '--format Fuubar --backtrace --tag @focus', :all_on_start => false do
  ...
end

General options

The general options configures the environment that is needed to run Guard::RSpectacle and RSpec:

:cli => '--tag @focus'         # RSpec CLI options
                               # default: ''

Spork is not needed (and supported), thus the --drb flag will be removed from the :cli options.

Spec runner options

The spec runner options configures the behavior driven development (or BDD) cycle:

:all_on_start => false         # Run all specs on start.
                               # default: true

:keep_failed => false          # Keep failed examples and add them to the next run again.
                               # default: true

:all_after_pass => false       # Run all specs after all examples have passed again after failing.
                               # default: true

System notifications options

These options affects what system notifications (growl, libnotify or notifu) are shown after a spec run:

:notifications => false        # Show success and error notifications.
                               # default: true

:hide_success => true          # Disable successful spec run notification.
                               # default: false

Important note on reloading

The ability to run specs immediately comes at a cost:

  1. In your Guardfile, you have to specify which files should be reloaded (apart from specs to be executed). But don't worry, the default template takes care of it.
  2. When a file is changed, it is reloaded the Ruby code with Kernel#load, which only re-interprets the file.

This, for example, means that a method already defined on a class (including initialize) will not be removed simply by deleting that method from the source code:

class Dinner
  def initialize
    raise "Too early"
  end
end

The spec that uses this class will fail for the obvious reason. So your first thought may be to just remove initialize method. But that will not work and you should rewrite the class above:

class Dinner
  def initialize
    super
  end
end

When you are done testing, restart guard to load the file afresh. Unfortunately this inconvenience can't be fixed easily (suggest if you know how?). So just keep in mind: you are monkey-patching within a single guard session.

Alternatives

Please have a look at the rock solid guard-rspec. Guard::RSpectacle uses it for continuous testing.

Shameless self promotion

Developed by Michael Kessler, sponsored by mksoft.ch.

If you like Guard::RSpectacle, you can watch the repository at GitHub and follow @netzpirat on Twitter for project updates.

Issues

You can report issues and feature requests to GitHub Issues. Try to figure out where the issue belongs to: Is it an issue with Guard itself or with Guard::RSpectacle? Please don't ask question in the issue tracker, instead join us in our Google group or on #guard (irc.freenode.net).

When you file an issue, please try to follow to these simple rules if applicable:

Development

Pull requests are very welcome! Please try to follow these simple rules if applicable:

For questions please join us in our Google group or on #guard (irc.freenode.net).

Contributors

Acknowledgment

License

(The MIT License)

Copyright (c) 2011 - 2012 Michael Kessler

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.