Merge branch 'hook' of git://github.com/monocle/guard
This commit is contained in:
commit
d47aebd424
@ -8,6 +8,7 @@ module Guard
|
||||
autoload :Listener, 'guard/listener'
|
||||
autoload :Watcher, 'guard/watcher'
|
||||
autoload :Notifier, 'guard/notifier'
|
||||
autoload :Hook, 'guard/hook'
|
||||
|
||||
class << self
|
||||
attr_accessor :options, :guards, :listener
|
||||
@ -60,7 +61,10 @@ module Guard
|
||||
# Let a guard execute its task but
|
||||
# fire it if his work leads to a system failure
|
||||
def supervised_task(guard, task_to_supervise, *args)
|
||||
guard.send(task_to_supervise, *args)
|
||||
guard.hook "#{task_to_supervise.to_s}_begin"
|
||||
result = guard.send(task_to_supervise, *args)
|
||||
guard.hook "#{task_to_supervise.to_s}_end"
|
||||
result
|
||||
rescue Exception
|
||||
UI.error("#{guard.class.name} guard failed to achieve its <#{task_to_supervise.to_s}> command: #{$!}")
|
||||
::Guard.guards.delete guard
|
||||
|
@ -1,5 +1,7 @@
|
||||
module Guard
|
||||
class Guard
|
||||
include Hook
|
||||
|
||||
attr_accessor :watchers, :options
|
||||
|
||||
def initialize(watchers = [], options = {})
|
||||
|
53
lib/guard/hook.rb
Normal file
53
lib/guard/hook.rb
Normal file
@ -0,0 +1,53 @@
|
||||
module Guard
|
||||
module Hook
|
||||
def self.included(base)
|
||||
base.send :include, InstanceMethods
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
|
||||
# When passed a sybmol, #hook will generate a hook name
|
||||
# from the symbol and calling method name. When passed
|
||||
# a string, #hook will turn the string into a symbol
|
||||
# directly.
|
||||
def hook(event)
|
||||
if event.class == Symbol
|
||||
calling_method = caller[0][/`([^']*)'/, 1]
|
||||
hook_name = "#{calling_method}_#{event}".to_sym
|
||||
else
|
||||
hook_name = event.to_sym
|
||||
end
|
||||
|
||||
UI.info "\nHook :#{hook_name} executed for #{self.class}"
|
||||
Hook.notify(self.class, hook_name)
|
||||
end
|
||||
end
|
||||
|
||||
class << self
|
||||
def callbacks
|
||||
@callbacks ||= Hash.new { |hash, key| hash[key] = [] }
|
||||
end
|
||||
|
||||
def add(listener, guard_class, events)
|
||||
_events = events.class == Array ? events : [events]
|
||||
_events.each do |event|
|
||||
callbacks[[guard_class, event]] << listener
|
||||
end
|
||||
end
|
||||
|
||||
def has_callback?(listener, guard_class, event)
|
||||
callbacks[[guard_class, event]].include? listener
|
||||
end
|
||||
|
||||
def notify(guard_class, event)
|
||||
callbacks[[guard_class, event]].each do |listener|
|
||||
listener.call(guard_class, event)
|
||||
end
|
||||
end
|
||||
|
||||
def reset!
|
||||
@callbacks = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
82
spec/guard/hook_spec.rb
Normal file
82
spec/guard/hook_spec.rb
Normal file
@ -0,0 +1,82 @@
|
||||
require "spec_helper"
|
||||
require 'guard/guard'
|
||||
require "guard/hook"
|
||||
|
||||
describe Guard::Hook do
|
||||
class Guard::Dummy < Guard::Guard
|
||||
include Guard::Hook
|
||||
|
||||
def run_all
|
||||
hook :begin
|
||||
hook :end
|
||||
end
|
||||
end
|
||||
|
||||
let(:guard_class) { ::Guard::Dummy }
|
||||
let(:listener) { double('listener').as_null_object }
|
||||
|
||||
context "--module methods--" do
|
||||
before { subject.add(listener, guard_class, :start_begin) }
|
||||
|
||||
after { subject.reset! }
|
||||
|
||||
describe ".add " do
|
||||
it "can add a single callback" do
|
||||
subject.has_callback?(listener, guard_class, :start_begin).should be_true
|
||||
end
|
||||
|
||||
it "can add multiple callbacks" do
|
||||
subject.add(listener, guard_class, [:event1, :event2])
|
||||
subject.has_callback?(listener, guard_class, :event1).should be_true
|
||||
subject.has_callback?(listener, guard_class, :event2).should be_true
|
||||
end
|
||||
end
|
||||
|
||||
describe ".notify " do
|
||||
it "sends :call to the given Guard class's callbacks" do
|
||||
listener.should_receive(:call).with(guard_class, :start_begin)
|
||||
subject.notify(guard_class, :start_begin)
|
||||
end
|
||||
|
||||
it "doesn't run callbacks of different types" do
|
||||
listener2 = double('listener2')
|
||||
subject.add(listener2, guard_class, :start_end)
|
||||
listener2.should_not_receive(:call).with(guard_class, :start_end)
|
||||
subject.notify(guard_class, :start_begin)
|
||||
end
|
||||
|
||||
it "doesn't run callbacks of the wrong class" do
|
||||
guard2_class = double('Guard::Dummy2').class
|
||||
subject.add(listener, guard2_class, :start_begin)
|
||||
listener.should_not_receive(:call).with(guard2_class, :start_begin)
|
||||
subject.notify(guard_class, :start_begin)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#hook " do
|
||||
it "calls Guard::Hook.notify" do
|
||||
guard = guard_class.new
|
||||
Guard::Hook.should_receive(:notify).
|
||||
with(guard_class, :run_all_begin)
|
||||
|
||||
Guard::Hook.should_receive(:notify).
|
||||
with(guard_class, :run_all_end)
|
||||
|
||||
guard.run_all
|
||||
end
|
||||
|
||||
it "if passed a string parameter, will use that for the hook name" do
|
||||
guard_class.class_eval do
|
||||
def start
|
||||
hook "my_hook"
|
||||
end
|
||||
end
|
||||
|
||||
guard = guard_class.new
|
||||
Guard::Hook.should_receive(:notify).
|
||||
with(guard_class, :my_hook)
|
||||
guard.start
|
||||
end
|
||||
end
|
||||
end
|
@ -54,7 +54,7 @@ describe Guard do
|
||||
describe ".supervised_task" do
|
||||
subject { ::Guard.setup }
|
||||
before(:each) do
|
||||
@g = mock(Guard::Guard)
|
||||
@g = mock(Guard::Guard).as_null_object
|
||||
subject.guards.push(@g)
|
||||
end
|
||||
|
||||
@ -92,6 +92,8 @@ describe Guard do
|
||||
failing_result.message.should == 'I break your system'
|
||||
end
|
||||
end
|
||||
|
||||
it "calls the default hooks"
|
||||
end
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user