Skip to content

Commit

Permalink
Use Rails 3.2+ class reloading when available
Browse files Browse the repository at this point in the history
Additional custom_reloaders can also be passed in via options to support
other frameworks like Rails 2.x or custom class reloaders.

Closes #29
  • Loading branch information
nilbus committed May 30, 2013
1 parent c48a52f commit e500a3f
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 5 deletions.
25 changes: 22 additions & 3 deletions lib/guard/jruby-rspec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require 'guard'
require 'guard/guard'
require 'guard/rspec'
require 'guard/jruby-rspec/reloaders'

module Guard
class JRubyRSpec < ::Guard::RSpec
Expand All @@ -15,7 +16,8 @@ def initialize(watchers = [], options = {})
:spec_paths => ["spec"],
:spec_file_suffix => "_spec.rb",
:run_all => {},
:monitor_file => ".guard-jruby-rspec"
:monitor_file => ".guard-jruby-rspec",
:custom_reloaders => []
}.merge(options)
@last_failed = false
@failed_paths = []
Expand All @@ -41,7 +43,7 @@ def initialize(watchers = [], options = {})

@inspector = Inspector.new(@options)
@runner = Runner.new(@options)

@reloaders = set_up_reloaders(@options)
end

# Call once when guard starts
Expand All @@ -52,7 +54,7 @@ def start

def run_on_changes(raw_paths)
unload_previous_examples
reload_paths(raw_paths)
@reloaders.reload(raw_paths)

unless @custom_watchers.nil? or @custom_watchers.empty?
paths = []
Expand All @@ -70,6 +72,13 @@ def run_on_changes(raw_paths)
# Guard 1.1 renamed run_on_change to run_on_changes
alias_method :run_on_change, :run_on_changes

def reload_rails(*)
if defined? ::ActionDispatch::Reloader
ActionDispatch::Reloader.cleanup!
ActionDispatch::Reloader.prepare!
end
end

def reload_paths(paths)
paths.reject {|p| p.end_with?(@options[:spec_file_suffix])}.each do |p|
if File.exists?(p)
Expand All @@ -96,6 +105,16 @@ def reload_paths(paths)

private

def set_up_reloaders(options)
reloaders = Reloaders.new
reloader_methods = [:reload_rails, :reload_paths]
reloader_procs = reloader_methods.map { |name| method(name) }
reloader_procs += options[:custom_reloaders]
reloader_procs.each { |reloader| reloaders.register &reloader }

reloaders
end

def unload_previous_examples
::RSpec.configuration.reset
::RSpec.world.reset
Expand Down
20 changes: 20 additions & 0 deletions lib/guard/jruby-rspec/reloaders.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
class Reloaders
def initialize
@reloaders = []
end

# Add a reloader to be called on reload
def register(options = {}, &block)
if options[:prepend]
@reloaders.unshift block
else
@reloaders << block
end
end

def reload(paths = [])
@reloaders.each do |reloader|
reloader.call(paths)
end
end
end
45 changes: 45 additions & 0 deletions spec/guard/jruby-rspec/reloaders_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
require 'spec_helper'

describe Reloaders do
subject(:reloaders) { described_class.new }

describe 'storing blocks to be executed at reload time' do
it 'passes the paths to be reloaded to the reloaders' do
reloaders.register do |paths|
paths.should == ['/path/to/file']
end
reloaders.reload ['/path/to/file']
end

describe 'the order in which reloaders are executed' do
before :each do
@a = @b = @counter = 0
reloaders.register do
@counter += 1
@a = @counter
end
reloaders.register(:prepend => prepend) do
@counter += 1
@b = @counter
end
reloaders.reload
end

context 'in normal order' do
let(:prepend) { false }
it 'reloads in the same order as reloaders registered' do
@a.should == 1
@b.should == 2
end
end

context 'with the 2nd reloader prepended' do
let(:prepend) { true }
it 'reloads in the same order as reloaders registered' do
@a.should == 2
@b.should == 1
end
end
end
end
end
13 changes: 11 additions & 2 deletions spec/guard/jruby-rspec_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
:spec_paths => ['spec'],
:spec_file_suffix => "_spec.rb",
:run_all => {},
:monitor_file=> ".guard-jruby-rspec"
:monitor_file => ".guard-jruby-rspec",
:custom_reloaders => []
}
end

Expand Down Expand Up @@ -108,8 +109,16 @@
it_should_behave_like 'clear failed paths'
end

describe '#reload_paths' do
describe '#reload_rails' do
it 'continues silently if the supported Rails 3.2+ version of Rails reloading is not supported' do
defined?(::ActionDispatch::Reloader).should be_false
expect {
subject.reload_rails
}.not_to raise_exception
end
end

describe '#reload_paths' do
it 'should reload files other than spec files' do
lib_file = 'lib/myapp/greeter.rb'
spec_file = 'specs/myapp/greeter_spec.rb'
Expand Down

0 comments on commit e500a3f

Please sign in to comment.