Compare commits

...

3 Commits

4 changed files with 284 additions and 3 deletions

View File

@ -39,7 +39,13 @@ module Guard
end
UI.info "Guard is now watching at '#{Dir.pwd}'"
guards.each { |g| supervised_task(g, :start) }
guards.each do |guard|
if supervised_task(guard, :start)
%w[reload run_all].each do |m|
guard.send(m) if guard.respond_to?(:"#{m}_at_start?") && guard.send(:"#{m}_at_start?")
end
end
end
listener.start
end
end
@ -63,7 +69,11 @@ module Guard
# Let a guard execute his task but
# fire it if his work lead to system failure
def supervised_task(guard, task_to_supervise, *args)
guard.send(task_to_supervise, *args)
if !guard.respond_to(:"#{task_to_supervise}?") || guard.send(:"#{task_to_supervise}?")
guard.send(task_to_supervise, *args)
else
false
end
rescue Exception
UI.error("#{guard.class.name} guard failed to achieve its <#{task_to_supervise.to_s}> command: #{$!}")
::Guard.guards.delete guard

View File

@ -1,9 +1,14 @@
module Guard
class Guard
attr_accessor :watchers, :options
DEFAULT_OPTIONS = {
:reload => {:at_start => false, :disable => false},
:run_all => {:at_start => false, :disable => false}
}.freeze
def initialize(watchers = [], options = {})
@watchers, @options = watchers, options
@watchers, @options = watchers, DEFAULT_OPTIONS.merge(options)
end
# Guardfile template needed inside guard gem
@ -41,11 +46,31 @@ module Guard
def reload
true
end
# disable reload method if return true. When is overwriten, must return false if `super' return false
def reload?
options[:reload] == true || (options[:reload].is_a?(Hash) && !options[:reload][:disable])
end
# enable call of reload method after start method if return true. When is overwriten, must return false if `super' return false
def reload_at_start?
options[:reload].is_a?(Hash) && !!options[:reload][:at_start]
end
# Should be principally used for long action like running all specs/tests/...
def run_all
true
end
# disable run_all method if return true. When is overwriten, must return false if `super' return false
def run_all?
options[:run_all] == true || (options[:run_all].is_a?(Hash) && !options[:run_all][:disable])
end
# enable call of run_all method after start method if return true. When is overwriten, must return false if `super' return false
def run_all_at_start?
options[:run_all].is_a?(Hash) && !!options[:run_all][:at_start]
end
def run_on_change(paths)
true

152
spec/guard/guard_spec.rb Normal file
View File

@ -0,0 +1,152 @@
require 'spec_helper'
require 'guard/guard'
describe Guard::Guard do
subject { Guard::Guard }
it "should be initialized with watchers" do
watcher = mock(Guard::Watcher)
guard = subject.new([watcher])
guard.watchers.should == [watcher]
end
it "should be initialized with options" do
watcher = mock(Guard::Watcher)
guard = subject.new([], {:test => true})
guard.options[:test].should be_true
guard.options[:fake].should be_nil
end
context "#reload?" do
it "should return true by default" do
subject.new.reload?.should be_true
end
it "should return true with option `:reload => {:disable => false}'" do
guard = subject.new([], :reload => {:disable => false})
guard.reload?.should be_true
end
it "should return true with option `:reload => {}'" do
guard = subject.new([], :reload => {})
guard.reload?.should be_true
end
it "should return true with option `:reload => true'" do
guard = subject.new([], :reload => true)
guard.reload?.should be_true
end
it "should return false with option `:reload => {:disable => true}'" do
guard = subject.new([], :reload => {:disable => true})
guard.reload?.should be_false
end
it "should return false with option `:reload => false'" do
guard = subject.new([], :reload => false)
guard.reload?.should be_false
end
end
context "#reload_at_start?" do
it "should return false by default" do
subject.new.reload_at_start?.should be_false
end
it "should return false with option `:reload => {:at_start => false}'" do
guard = subject.new([], :reload => {:at_start => false})
guard.reload_at_start?.should be_false
end
it "should return false with option `:reload => {}'" do
guard = subject.new([], :reload => {})
guard.reload_at_start?.should be_false
end
it "should return false with option `:reload => true'" do
guard = subject.new([], :reload => true)
guard.reload_at_start?.should be_false
end
it "should return false with option `:reload => false'" do
guard = subject.new([], :reload => false)
guard.reload_at_start?.should be_false
end
it "should return true with option `:reload => {:at_start => true}'" do
guard = subject.new([], :reload => {:at_start => true})
guard.reload_at_start?.should be_true
end
end
context "#run_all?" do
it "should return true by default" do
subject.new.run_all?.should be_true
end
it "should return true with option `:reload => {:disable => false}'" do
guard = subject.new([], :run_all => {:disable => false})
guard.run_all?.should be_true
end
it "should return true with option `:reload => {}'" do
guard = subject.new([], :run_all => {})
guard.run_all?.should be_true
end
it "should return true with option `:reload => true'" do
guard = subject.new([], :run_all => true)
guard.run_all?.should be_true
end
it "should return false with option `:reload => {:disable => true}'" do
guard = subject.new([], :run_all => {:disable => true})
guard.run_all?.should be_false
end
it "should return false with option `:reload => false'" do
guard = subject.new([], :run_all => false)
guard.run_all?.should be_false
end
end
context "#run_all_at_start?" do
it "should return false by default" do
subject.new.run_all_at_start?.should be_false
end
it "should return false with option `:reload => {:at_start => false}'" do
guard = subject.new([], :run_all => {:at_start => false})
guard.run_all_at_start?.should be_false
end
it "should return false with option `:reload => {}'" do
guard = subject.new([], :run_all => {})
guard.run_all_at_start?.should be_false
end
it "should return false with option `:reload => true'" do
guard = subject.new([], :run_all => true)
guard.run_all_at_start?.should be_false
end
it "should return false with option `:reload => false'" do
guard = subject.new([], :run_all => false)
guard.run_all_at_start?.should be_false
end
it "should return true with option `:reload => {:at_start => true}'" do
guard = subject.new([], :run_all => {:at_start => true})
guard.run_all_at_start?.should be_true
end
end
end

View File

@ -54,16 +54,97 @@ describe Guard do
::Guard.listener.should be_kind_of(Guard::Listener)
end
end
describe "start" do
before(:each) do
@guard = mock(::Guard::Guard)
@guard.stub!(:reload_at_start?).and_return(false)
@guard.stub!(:run_all_at_start?).and_return(false)
@guard.stub!(:respond_to?)
@listener = mock(::Guard::Polling)
@listener.stub!(:on_change)
@listener.stub!(:start).and_return(true)
::Guard::Listener.stub!(:init).and_return(@listener)
::Guard::Dsl.stub!(:evaluate_guardfile)
::Guard::Interactor.stub!(:init_signal_traps)
subject.stub!(:guards).and_return([@guard])
subject.stub!(:supervised_task).with(anything(), :start).and_return(true)
end
it 'should evaluate Guardfile' do
::Guard::Dsl.should_receive(:evaluate_guardfile)
subject.start
end
it 'should init signal traps' do
::Guard::Interactor.should_receive(:init_signal_traps)
subject.start
end
it 'should define listener on_change' do
@listener.should_receive(:on_change)
subject.start
end
it 'should start guards' do
subject.should_receive(:supervised_task).with(@guard, :start).and_return(true)
subject.start
end
it 'should call reload at start if needed' do
@guard.should_receive(:respond_to?).with(:reload_at_start?).and_return(true)
@guard.should_receive(:reload_at_start?).and_return(true)
@guard.should_receive(:reload).and_return(true)
subject.start
end
it 'should call run_all at start if needed' do
@guard.should_receive(:respond_to?).with(:run_all_at_start?).and_return(true)
@guard.should_receive(:run_all_at_start?).and_return(true)
@guard.should_receive(:run_all).and_return(true)
subject.start
end
it 'should not call reload and run_all at start if not needed' do
@guard.should_receive(:respond_to?).with(:reload_at_start?).and_return(true)
@guard.should_receive(:reload_at_start?).and_return(false)
@guard.should_not_receive(:reload)
@guard.should_receive(:respond_to?).with(:run_all_at_start?).and_return(true)
@guard.should_receive(:run_all_at_start?).and_return(false)
@guard.should_not_receive(:run_all)
subject.start
end
it 'should start listener' do
@listener.should_receive(:start)
subject.start
end
end
describe "supervised_task" do
subject { ::Guard.init }
before :each do
@g = mock(Guard::Guard)
@g.stub!(:respond_to).and_return { false }
@g.stub!(:regular).and_return { true }
@g.stub!(:spy).and_return { raise "I break your system" }
@g.stub!(:pirate).and_raise Exception.new("I blow your system up")
@g.stub!(:regular_arg).with("given_path").and_return { "given_path" }
@g.stub!(:enable_method).and_return { true }
@g.stub!(:enable_method?).and_return { true }
@g.stub!(:respond_to).with(:enable_method?).and_return { true }
@g.stub!(:disable_method).and_return { true }
@g.stub!(:disable_method?).and_return { false }
@g.stub!(:respond_to).with(:disable_method?).and_return { true }
subject.guards.push @g
end
@ -92,6 +173,19 @@ describe Guard do
subject.guards.should be_include(@g)
::Guard.supervised_task(@g, :regular_arg, "given_path").should == "given_path"
end
it 'should let it go when method is enable by guard options' do
subject.guards.should be_include(@g)
subject.supervised_task(@g, :enable_method).should be_true
subject.guards.should be_include(@g)
end
it 'should not let it go when method is disable by guard options' do
subject.guards.should be_include(@g)
subject.supervised_task(@g, :disable_method).should be_false
subject.guards.should be_include(@g)
end
end
end