diff --git a/lib/guard/watcher.rb b/lib/guard/watcher.rb index 8384f97..2c354af 100644 --- a/lib/guard/watcher.rb +++ b/lib/guard/watcher.rb @@ -38,7 +38,7 @@ module Guard # # @param [Guard::Guard] guard the guard which watchers are used # @param [Array] files the changed files - # @return [Array] the matched files + # @return [Array] the matched watcher response # def self.match_files(guard, files) guard.watchers.inject([]) do |paths, watcher| @@ -46,14 +46,18 @@ module Guard if matches = watcher.match_file?(file) if watcher.action result = watcher.call_action(matches) - paths << Array(result) if result.respond_to?(:empty?) && !result.empty? + if guard.options[:any_return] + paths << result + elsif result.respond_to?(:empty?) && !result.empty? + paths << Array(result) + end else paths << matches[0] end end end - - paths.flatten.map { |p| p.to_s } + + guard.options[:any_return] ? paths : paths.flatten.map { |p| p.to_s } end end diff --git a/spec/guard/watcher_spec.rb b/spec/guard/watcher_spec.rb index ff1775f..0e9eb95 100644 --- a/spec/guard/watcher_spec.rb +++ b/spec/guard/watcher_spec.rb @@ -46,7 +46,11 @@ describe Guard::Watcher do end describe ".match_files" do - before(:all) { @guard = Guard::Guard.new } + before(:all) do + @guard = Guard::Guard.new + @guard_any_return = Guard::Guard.new + @guard_any_return.options[:any_return] = true + end context "with a watcher without action" do context "that is a regex pattern" do @@ -65,8 +69,8 @@ describe Guard::Watcher do end end end - - context "with a watcher action without parameter" do + + context "with a watcher action without parameter for a watcher that matches file strings" do before(:all) do @guard.watchers = [ described_class.new('spec_helper.rb', lambda { 'spec' }), @@ -103,56 +107,132 @@ describe Guard::Watcher do end end - context "with a watcher action that takes a parameter" do + context 'with a watcher action without parameter for a watcher that matches information objects' do before(:all) do - @guard.watchers = [ + @guard_any_return.watchers = [ + described_class.new('spec_helper.rb', lambda { 'spec' }), + described_class.new('addition.rb', lambda { 1 + 1 }), + described_class.new('hash.rb', lambda { Hash[:foo, 'bar'] }), + described_class.new('array.rb', lambda { ['foo', 'bar'] }), + described_class.new('blank.rb', lambda { '' }), + described_class.new(/^uptime\.rb/, lambda { `uptime > /dev/null` }) + ] + end + + it "returns a single file specified within the action" do + described_class.match_files(@guard_any_return, ['spec_helper.rb']).class.should == Array + described_class.match_files(@guard_any_return, ['spec_helper.rb']).empty?.should == false + end + + it "returns multiple files specified within the action" do + described_class.match_files(@guard_any_return, ['hash.rb']).should == [{:foo => 'bar'}] + end + + it "returns multiple files by combining the results of different actions" do + described_class.match_files(@guard_any_return, ['spec_helper.rb', 'array.rb']).should == ['spec', ['foo', 'bar']] + end + + it "returns the evaluated addition argument in an array" do + described_class.match_files(@guard_any_return, ['addition.rb']).class.should == Array + described_class.match_files(@guard_any_return, ['addition.rb'])[0].should == 2 + end + + it "returns nothing if the action response is empty string" do + described_class.match_files(@guard_any_return, ['blank.rb']).should == [''] + end + + it "returns nothing if the action returns empty string" do + described_class.match_files(@guard_any_return, ['uptime.rb']).should == [''] + end + end + + context "with a watcher action that takes a parameter for a watcher that matches file strings" do + before(:all) do + @guard.watchers = [ + described_class.new(%r{lib/(.*)\.rb}, lambda { |m| "spec/#{m[1]}_spec.rb" }), + described_class.new(/addition(.*)\.rb/, lambda { |m| 1 + 1 }), + described_class.new('hash.rb', lambda { |m| Hash[:foo, 'bar'] }), + described_class.new(/array(.*)\.rb/, lambda { |m| ['foo', 'bar'] }), + described_class.new(/blank(.*)\.rb/, lambda { |m| '' }), + described_class.new(/uptime(.*)\.rb/, lambda { |m| `uptime > /dev/null` }) + ] + end + + it "returns a substituted single file specified within the action" do + described_class.match_files(@guard, ['lib/my_wonderful_lib.rb']).should == ['spec/my_wonderful_lib_spec.rb'] + end + + it "returns multiple files specified within the action" do + described_class.match_files(@guard, ['hash.rb']).should == ['foo', 'bar'] + end + + it "returns multiple files by combining the results of different actions" do + described_class.match_files(@guard, ['lib/my_wonderful_lib.rb', 'array.rb']).should == ['spec/my_wonderful_lib_spec.rb', 'foo', 'bar'] + end + + it "returns nothing if the action returns something other than a string or an array of strings" do + described_class.match_files(@guard, ['addition.rb']).should == [] + end + + it "returns nothing if the action response is empty" do + described_class.match_files(@guard, ['blank.rb']).should == [] + end + + it "returns nothing if the action returns nothing" do + described_class.match_files(@guard, ['uptime.rb']).should == [] + end + end + + context "with a watcher action that takes a parameter for a watcher that matches information objects" do + before(:all) do + @guard_any_return.watchers = [ described_class.new(%r{lib/(.*)\.rb}, lambda { |m| "spec/#{m[1]}_spec.rb" }), - described_class.new(/addition(.*)\.rb/, lambda { |m| 1 + 1 }), - described_class.new('hash.rb', lambda { Hash[:foo, 'bar'] }), - described_class.new(/array(.*)\.rb/, lambda { |m| ['foo', 'bar'] }), + described_class.new(/addition(.*)\.rb/, lambda { |m| (1 + 1).to_s + m[0] }), + described_class.new('hash.rb', lambda { |m| Hash[:foo, 'bar', :file_name, m[0]] }), + described_class.new(/array(.*)\.rb/, lambda { |m| ['foo', 'bar', m[0]] }), described_class.new(/blank(.*)\.rb/, lambda { |m| '' }), described_class.new(/uptime(.*)\.rb/, lambda { |m| `uptime > /dev/null` }) ] end it "returns a substituted single file specified within the action" do - described_class.match_files(@guard, ['lib/my_wonderful_lib.rb']).should == ['spec/my_wonderful_lib_spec.rb'] + described_class.match_files(@guard_any_return, ['lib/my_wonderful_lib.rb']).should == ['spec/my_wonderful_lib_spec.rb'] end - it "returns multiple files specified within the action" do - described_class.match_files(@guard, ['hash.rb']).should == ['foo', 'bar'] + it "returns a hash specified within the action" do + described_class.match_files(@guard_any_return, ['hash.rb']).should == [{:foo => 'bar', :file_name => 'hash.rb'}] end it "returns multiple files by combining the results of different actions" do - described_class.match_files(@guard, ['lib/my_wonderful_lib.rb', 'array.rb']).should == ['spec/my_wonderful_lib_spec.rb', 'foo', 'bar'] + described_class.match_files(@guard_any_return, ['lib/my_wonderful_lib.rb', 'array.rb']).should == ['spec/my_wonderful_lib_spec.rb', ['foo', 'bar', "array.rb"]] end - it "returns nothing if the action returns something other than a string or an array of strings" do - described_class.match_files(@guard, ['addition.rb']).should == [] + it "returns the evaluated addition argument + the path" do + described_class.match_files(@guard_any_return, ['addition.rb']).should == ["2addition.rb"] end - it "returns nothing if the action response is empty" do - described_class.match_files(@guard, ['blank.rb']).should == [] + it "returns nothing if the action response is empty string" do + described_class.match_files(@guard_any_return, ['blank.rb']).should == [''] end - it "returns nothing if the action returns nothing" do - described_class.match_files(@guard, ['uptime.rb']).should == [] + it "returns nothing if the action returns empty string" do + described_class.match_files(@guard_any_return, ['uptime.rb']).should == [''] end end context "with an exception that is raised" do - before(:all) { @guard.watchers = [described_class.new('evil.rb', lambda { raise "EVIL" })] } + before(:all) { @guard.watchers = [described_class.new('evil.rb', lambda { raise "EVIL" })] } - it "displays the error and backtrace" do - Guard::UI.should_receive(:error) { |msg| - msg.should include("Problem with watch action!") - msg.should include("EVIL") - } + it "displays the error and backtrace" do + Guard::UI.should_receive(:error) do |msg| + msg.should include("Problem with watch action!") + msg.should include("EVIL") + end - described_class.match_files(@guard, ['evil.rb']) - end - end - end + described_class.match_files(@guard, ['evil.rb']) + end + end + end describe ".match_files?" do before(:all) do