diff --git a/CHANGELOG.rdoc b/CHANGELOG.rdoc index 676fc87..e22ec01 100644 --- a/CHANGELOG.rdoc +++ b/CHANGELOG.rdoc @@ -1,13 +1,23 @@ +== 0.3.3 (Avril 18, 2011) + +Bugs fixes: +- Fixed new_modified_files rerun conditions on Guard.run_on_change_for_all_guards + +== 0.3.2 (Avril 17, 2011) + +Bugs fixes: +- Fixed "guard init" command (@brainopia) + == 0.3.1 (Avril 14, 2011) Features: - - Added a command line option (-n false) to disable notifications (growl/libnotify) +- Added a command line option (-n false) to disable notifications (growl/libnotify) Bugs fixes: - - Return unique filenames from Linux listener (Marian Schubert) - - Guard.get_guard_class return wrong class when loaded nested class. (koshigoe) - - Fixed open-gem/gem_open dependency problem by using `gem which` to locate guards gem path - - Fixed an invalid ANSI escape code in UI.reset_line (gix) +- Return unique filenames from Linux listener (Marian Schubert) +- Guard.get_guard_class return wrong class when loaded nested class. (@koshigoe) +- Fixed open-gem/gem_open dependency problem by using `gem which` to locate guards gem path +- Fixed an invalid ANSI escape code in UI.reset_line (@gix) == 0.3.0 (Jan 19, 2011) diff --git a/Gemfile b/Gemfile index a7126b6..32f6d47 100644 --- a/Gemfile +++ b/Gemfile @@ -4,11 +4,10 @@ gemspec require 'rbconfig' -if Config::CONFIG['target_os'] =~ /darwin/i +if Config::CONFIG['host_os'] =~ /darwin/i gem 'rb-fsevent', '>= 0.3.9' - gem 'growl', '~> 1.0.3' -end -if Config::CONFIG['target_os'] =~ /linux/i + gem 'growl', '~> 1.0' +elsif Config::CONFIG['host_os'] =~ /linux/i gem 'rb-inotify', '>= 0.5.1' - gem 'libnotify', '~> 0.1.3' + gem 'libnotify', '~> 0.1' end diff --git a/Guardfile b/Guardfile index c7303d5..117d61c 100644 --- a/Guardfile +++ b/Guardfile @@ -1,5 +1,7 @@ +ENV["GUARD_ENV"] = 'development' + guard('rspec', :cli => '-f doc', :version => 2) do watch(%r{^spec/(.*)_spec\.rb}) watch(%r{^lib/(.*)\.rb}) { |m| "spec/#{m[1]}_spec.rb" } watch('spec/spec_helper.rb') { "spec" } -end \ No newline at end of file +end diff --git a/README.markdown b/README.markdown new file mode 100644 index 0000000..edd2dc8 --- /dev/null +++ b/README.markdown @@ -0,0 +1,269 @@ +Guard +===== + +Guard is a command line tool that easily handle events on files modifications. + +Features +-------- + +* [FSEvent](http://en.wikipedia.org/wiki/FSEvents) support on Mac OS X 10.5+ (without RubyCocoa!, [rb-fsevent gem, >= 0.3.5](https://rubygems.org/gems/rb-fsevent) required). +* [Inotify](http://en.wikipedia.org/wiki/Inotify) support on Linux ([rb-inotify gem, >= 0.5.1](https://rubygems.org/gems/rb-inotify) required). +* Polling on the other operating systems (help us to support more OS). +* Automatic & Super fast (when polling is not used) files modifications detection (even new files are detected). +* Growl notifications ([growlnotify](http://growl.info/documentation/growlnotify.php) & [growl gem](https://rubygems.org/gems/growl) required). +* Libnotify notifications ([libnotify gem](https://rubygems.org/gems/libnotify) required). +* Tested on Ruby 1.8.6, 1.8.7 & 1.9.2. + +Install +------- + +Install the gem: + + $ gem install guard + +Add it to your Gemfile (inside the test group): + +``` ruby +gem 'guard' +``` + +Generate an empty Guardfile with: + + $ guard init + +Add the guards you need to your Guardfile (see the existing guards below). + +### On Mac OS X + +Install the rb-fsevent gem for [FSEvent](http://en.wikipedia.org/wiki/FSEvents) support: + + $ gem install rb-fsevent + +Install the Growl gem if you want notification support: + + $ gem install growl + +And add it to you Gemfile: + +``` ruby +gem 'growl' +``` + +### On Linux + +Install the rb-inotify gem for [inotify](http://en.wikipedia.org/wiki/Inotify) support: + + $ gem install rb-inotify + +Install the Libnotify gem if you want notification support: + + $ gem install libnotify + +And add it to you Gemfile: + +``` ruby +gem 'libnotify' +``` + +Usage +----- + +Just launch Guard inside your Ruby / Rails project with: + + $ guard [start] + +or if you use Bundler, to run the Guard executable specific to your bundle: + + $ bundle exec guard + +Command line options +-------------------- + +Shell can be cleared after each change with: + + $ guard --clear + $ guard -c # shortcut + +Notifications (growl/libnotify) can be disabled with: + + $ guard --notify false + $ guard -n false # shortcut + +The guards to start can be specified by group (see the Guardfile DSL below) specifying the --group (or -g) option: + + $ guard --group group_name another_group_name + $ guard -g group_name another_group_name # shortcut + +Options list is available with: + + $ guard help [TASK] + +Signal handlers +--------------- + +Signal handlers are used to interact with Guard: + +* Ctrl-C - Calls each guard's stop method, in the same order they are declared in the Guardfile, and then quits Guard itself. +* Ctrl-\\ - Calls each guard's run_all method, in the same order they are declared in the Guardfile. +* Ctrl-Z - Calls each guard's reload method, in the same order they are declared in the Guardfile. + +Available Guards +---------------- + +[Available Guards list](https://github.com/guard/guard/wiki/List-of-available-Guards) (on the wiki now) + +### Add a guard to your Guardfile + +Add it to your Gemfile (inside the test group): + +``` ruby +gem '' +``` + +Insert default guard's definition to your Guardfile by running this command: + + $ guard init + +You are good to go! + +Guardfile DSL +------------- + +The Guardfile DSL consists of just three simple methods: guard, watch & group. + +Required: +* The guard method allows you to add a guard with an optional hash of options. +* The watch method allows you to define which files are supervised by this guard. An optional block can be added to overwrite the paths sent to the run_on_change guard method or to launch any arbitrary command. + +Optional: +* The group method allows you to group several guards together. Groups to be run can be specified with the Guard DSL option --group (or -g). This comes in handy especially when you have a huge Guardfile and want to focus your development on a certain part. + +Example: + +``` ruby +group 'backend' do + guard 'bundler' do + watch('Gemfile') + end + + guard 'rspec', :cli => '--color --format doc' do + # Regexp watch patterns are matched with Regexp#match + watch(%r{^spec/.+_spec\.rb}) + watch(%r{^lib/(.+)\.rb}) { |m| "spec/lib/#{m[1]}_spec.rb" } + watch(%r{^spec/models/.+\.rb}) { ["spec/models", "spec/acceptance"] } + watch(%r{^spec/.+\.rb}) { `say hello` } + + # String watch patterns are matched with simple '==' + watch('spec/spec_helper.rb') { "spec" } + end +end + +group 'frontend' do + guard 'coffeescript', :output => 'public/javascripts/compiled' do + watch(%r{^app/coffeescripts/.+\.coffee}) + end + + guard 'livereload' do + watch(%r{^app/.+\.(erb|haml)}) + end +end +``` + +Create a new guard +------------------ + +Creating a new guard is very easy, just create a new gem (bundle gem if you use Bundler) with this basic structure: + + lib/ + guard/ + guard-name/ + templates/ + Guardfile (needed for guard init ) + guard-name.rb + +Guard::GuardName (in lib/guard/guard-name.rb) must inherit from Guard::Guard and should overwrite at least one of the five basic Guard::Guard instance methods. Example: + +``` ruby +require 'guard' +require 'guard/guard' + +module Guard + class GuardName < Guard + + def initialize(watchers=[], options={}) + super + # init stuff here, thx! + end + + # ================= + # = Guard methods = + # ================= + + # If one of those methods raise an exception, the Guard::GuardName instance + # will be removed from the active guards. + + # Called once when Guard starts + # Please override initialize method to init stuff + def start + true + end + + # Called on Ctrl-C signal (when Guard quits) + def stop + true + end + + # Called on Ctrl-Z signal + # This method should be mainly used for "reload" (really!) actions like reloading passenger/spork/bundler/... + def reload + true + end + + # Called on Ctrl-/ signal + # This method should be principally used for long action like running all specs/tests/... + def run_all + true + end + + # Called on file(s) modifications + def run_on_change(paths) + true + end + + end +end +``` + +Please take a look at the existing guards' source code (see the list above) for more concrete example. + +Alternatively, a new guard can be added inline to a Guardfile with this basic structure: + +``` ruby +require 'guard/guard' + +module ::Guard + class Example < ::Guard::Guard + def run_all + true + end + + def run_on_change(paths) + true + end + end +end +``` + +Development +----------- + +* Source hosted at [GitHub](https://github.com/guard/guard). +* Report Issues/Questions/Feature requests on [GitHub Issues](https://github.com/guard/guard/issues). + +Pull requests are very welcome! Make sure your patches are well tested. Please create a topic branch for every separate change +you make. + +Author +------ + +[Thibaud Guillaume-Gentil](https://github.com/thibaudgg) diff --git a/README.rdoc b/README.rdoc deleted file mode 100644 index dfeee74..0000000 --- a/README.rdoc +++ /dev/null @@ -1,228 +0,0 @@ -= Guard - -Guard is a command line tool that easily handle events on files modifications. - -== Features - -- {FSEvent}[http://en.wikipedia.org/wiki/FSEvents] support on Mac OS X 10.5+ (without RubyCocoa!, {rb-fsevent gem, >= 0.3.5}[https://rubygems.org/gems/rb-fsevent] required). -- {Inotify}[http://en.wikipedia.org/wiki/Inotify] support on Linux ({rb-inotify gem, >= 0.5.1}[https://rubygems.org/gems/rb-inotify] required). -- Polling on the other operating systems (help us to support more OS). -- Automatic & Super fast (when polling is not used) files modifications detection (even new files are detected). -- Growl notifications ({growlnotify}[http://growl.info/documentation/growlnotify.php] & {growl gem}[https://rubygems.org/gems/growl] required). -- Libnotify notifications ({libnotify gem}[https://rubygems.org/gems/libnotify] required). -- Tested on Ruby 1.8.6, 1.8.7 & 1.9.2. - -== Install - -Install the gem: - - $ gem install guard - -Add it to your Gemfile (inside the test group): - - gem 'guard' - -Generate an empty Guardfile with: - - $ guard init - -Add the guards you need to your Guardfile (see the existing guards below). - -=== On Mac OS X - -Install the rb-fsevent gem for {FSEvent}[http://en.wikipedia.org/wiki/FSEvents] support: - - $ gem install rb-fsevent - -Install the Growl gem if you want notification support: - - $ gem install growl - -And add it to you Gemfile: - - gem 'growl' - -=== On Linux - -Install the rb-inotify gem for {inotify}[http://en.wikipedia.org/wiki/Inotify] support: - - $ gem install rb-inotify - -Install the Libnotify gem if you want notification support: - - $ gem install libnotify - -And add it to you Gemfile: - - gem 'libnotify' - -== Usage - -Just launch Guard inside your Ruby / Rails project with: - - $ guard [start] - -or if you use Bundler, to run the Guard executable specific to your bundle: - - $ bundle exec guard - -== Command line options - -Shell can be cleared after each change with: - - $ guard --clear - $ guard -c # shortcut - -Notifications (growl/libnotify) can be disabled with: - - $ guard --notify false - $ guard -n false # shortcut - -The guards to start can be specified by group (see the Guardfile DSL below) specifying the --group (or -g) option: - - $ guard --group group_name another_group_name - $ guard -g group_name another_group_name # shortcut - -Options list is available with: - - $ guard help [TASK] - -== Signal handlers - -Signal handlers are used to interact with Guard: - -- Ctrl-C - Calls each guard's stop method, in the same order they are declared in the Guardfile, and then quits Guard itself. -- Ctrl-\\ - Calls each guard's run_all method, in the same order they are declared in the Guardfile. -- Ctrl-Z - Calls each guard's reload method, in the same order they are declared in the Guardfile. - -== Available Guards - -{Available Guards list}[https://github.com/guard/guard/wiki/List-of-available-Guards] (on the wiki now) - -=== Add a guard to your Guardfile - -Add it to your Gemfile (inside the test group): - - gem '' - -Insert default guard's definition to your Guardfile by running this command: - - $ guard init - -You are good to go! - -== Guardfile DSL - -The Guardfile DSL consists of just three simple methods: guard, watch & group. - -Required: -- The guard method allows you to add a guard with an optional hash of options. -- The watch method allows you to define which files are supervised by this guard. An optional block can be added to overwrite the paths sent to the run_on_change guard method or to launch any arbitrary command. - -Optional: -- The group method allows you to group several guards together. Groups to be run can be specified with the Guard DSL option --group (or -g). This comes in handy especially when you have a huge Guardfile and want to focus your development on a certain part. - -Example: - - group 'backend' do - guard 'bundler' do - watch('Gemfile') - end - - guard 'rspec', :cli => '--color --format doc' do - # Regexp watch patterns are matched with Regexp#match - watch(%r{^spec/.+_spec\.rb}) - watch(%r{^lib/(.+)\.rb}) { |m| "spec/lib/#{m[1]}_spec.rb" } - watch(%r{^spec/models/.+\.rb}) { ["spec/models", "spec/acceptance"] } - watch(%r{^spec/.+\.rb}) { `say hello` } - - # String watch patterns are matched with simple '==' - watch('spec/spec_helper.rb') { "spec" } - end - end - - group 'frontend' do - guard 'coffeescript', :output => 'public/javascripts/compiled' do - watch(%r{^app/coffeescripts/.+\.coffee}) - end - - guard 'livereload' do - watch(%r{^app/.+\.(erb|haml)}) - end - end - -== Create a new guard - -Creating a new guard is very easy, just create a new gem (bundle gem if you use Bundler) with this basic structure: - - lib/ - guard/ - guard-name/ - templates/ - Guardfile (needed for guard init ) - guard-name.rb - -Guard::GuardName (in lib/guard/guard-name.rb) must inherit from Guard::Guard and should overwrite at least one of the five basic Guard::Guard instance methods. Example: - - require 'guard' - require 'guard/guard' - - module Guard - class GuardName < Guard - - def initialize(watchers=[], options={}) - super - # init stuff here, thx! - end - - # ================= - # = Guard methods = - # ================= - - # If one of those methods raise an exception, the Guard::GuardName instance - # will be removed from the active guards. - - # Called once when Guard starts - # Please override initialize method to init stuff - def start - true - end - - # Called on Ctrl-C signal (when Guard quits) - def stop - true - end - - # Called on Ctrl-Z signal - # This method should be mainly used for "reload" (really!) actions like reloading passenger/spork/bundler/... - def reload - true - end - - # Called on Ctrl-/ signal - # This method should be principally used for long action like running all specs/tests/... - def run_all - true - end - - # Called on file(s) modifications - def run_on_change(paths) - true - end - - end - end - -Please take a look at the existing guards' source code (see the list above) for more concrete example. - -== Development - -- Source hosted at {GitHub}[https://github.com/guard/guard]. -- Report Issues/Questions/Feature requests on {GitHub Issues}[https://github.com/guard/guard/issues]. - -Pull requests are very welcome! Make sure your patches are well tested. Please create a topic branch for every separate change -you make. - -== Authors - -{Thibaud Guillaume-Gentil}[https://github.com/thibaudgg] \ No newline at end of file diff --git a/Rakefile b/Rakefile index 4541498..04717e7 100644 --- a/Rakefile +++ b/Rakefile @@ -8,14 +8,14 @@ task :default => :spec namespace(:spec) do desc "Run all specs on multiple ruby versions (requires rvm)" task(:portability) do - %w[1.8.6 1.8.7 1.9.2].each do |version| + %w[1.8.6 1.8.7 1.9.2 ree].each do |version| system <<-BASH bash -c 'source ~/.rvm/scripts/rvm; rvm #{version}; echo "--------- version #{version} ----------\n"; bundle install; - rake spec' + rake spec;' BASH end end -end \ No newline at end of file +end diff --git a/guard.gemspec b/guard.gemspec index 045de79..b24b9bb 100644 --- a/guard.gemspec +++ b/guard.gemspec @@ -21,7 +21,7 @@ Gem::Specification.new do |s| s.add_dependency 'thor', '~> 0.14.6' - s.files = Dir.glob('{bin,images,lib}/**/*') + %w[LICENSE README.rdoc] + s.files = Dir.glob('{bin,images,lib}/**/*') + %w[LICENSE README.markdown] s.executable = 'guard' s.require_path = 'lib' end \ No newline at end of file diff --git a/lib/guard.rb b/lib/guard.rb index 322441e..423dcf8 100644 --- a/lib/guard.rb +++ b/lib/guard.rb @@ -1,5 +1,3 @@ -require 'bundler' - module Guard autoload :UI, 'guard/ui' @@ -52,8 +50,8 @@ module Guard # Reparse the whole directory to catch new files modified during the guards run new_modified_files = listener.modified_files([Dir.pwd + '/'], :all => true) listener.update_last_event - unless new_modified_files.empty? - run { run_on_change_for_all_guards(new_modified_files) } if Watcher.match_files?(guards, files) + if !new_modified_files.empty? && Watcher.match_files?(guards, new_modified_files) + run { run_on_change_for_all_guards(new_modified_files) } end end @@ -89,10 +87,15 @@ module Guard end def get_guard_class(name) - require "guard/#{name.downcase}" + try_to_load_gem name self.const_get(self.constants.find{|klass_name| klass_name.to_s.downcase == name.downcase }) + rescue TypeError + UI.error "Could not find load find gem 'guard-#{name}' or find class Guard::#{name}" + end + + def try_to_load_gem(name) + require "guard/#{name.downcase}" rescue LoadError - UI.error "Could not find gem 'guard-#{name}', please add it in your Gemfile." end def locate_guard(name) diff --git a/lib/guard/cli.rb b/lib/guard/cli.rb index c3e4526..a80211d 100644 --- a/lib/guard/cli.rb +++ b/lib/guard/cli.rb @@ -38,4 +38,4 @@ module Guard end end -end \ No newline at end of file +end diff --git a/lib/guard/dsl.rb b/lib/guard/dsl.rb index aee322d..dd1251d 100644 --- a/lib/guard/dsl.rb +++ b/lib/guard/dsl.rb @@ -43,11 +43,7 @@ module Guard end def callback(*args, &listener) - listener, events = if args.size > 1 - args - else - [listener, args[0]] - end + listener, events = args.size > 1 ? args : [listener, args[0]] @callbacks << { :events => events, :listener => listener } end diff --git a/lib/guard/guard.rb b/lib/guard/guard.rb index e952fe3..0b52f62 100644 --- a/lib/guard/guard.rb +++ b/lib/guard/guard.rb @@ -54,4 +54,4 @@ module Guard end end -end \ No newline at end of file +end diff --git a/lib/guard/hook.rb b/lib/guard/hook.rb index 950e7f5..4537f7a 100644 --- a/lib/guard/hook.rb +++ b/lib/guard/hook.rb @@ -1,14 +1,32 @@ 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. + # When +event+ is a Symbol, #hook will generate a hook name + # by concatenating the method name from where #hook is called + # with the given Symbol. + # Example: + # def run_all + # hook :foo + # end + # Here, when #run_all is called, #hook will notify callbacks + # registered for the "run_all_foo" event. + # + # When +event+ is a String, #hook will directly turn the String + # into a Symbol. + # Example: + # def run_all + # hook "foo_bar" + # end + # Here, when #run_all is called, #hook will notify callbacks + # registered for the "foo_bar" event. + # + # +args+ parameter is passed as is to the callbacks registered + # for the given event. def hook(event, *args) hook_name = if event.is_a? Symbol calling_method = caller[0][/`([^']*)'/, 1] @@ -51,5 +69,6 @@ module Guard @callbacks = nil end end + end end diff --git a/lib/guard/interactor.rb b/lib/guard/interactor.rb index f5247eb..e65346c 100644 --- a/lib/guard/interactor.rb +++ b/lib/guard/interactor.rb @@ -1,6 +1,6 @@ module Guard module Interactor - + def self.init_signal_traps # Run all (Ctrl-\) Signal.trap('QUIT') do @@ -8,7 +8,7 @@ module Guard ::Guard.guards.each { |guard| ::Guard.supervised_task(guard, :run_all) } end end - + # Stop (Ctrl-C) Signal.trap('INT') do UI.info "Bye bye...", :reset => true @@ -16,7 +16,7 @@ module Guard ::Guard.guards.each { |guard| ::Guard.supervised_task(guard, :stop) } abort("\n") end - + # Reload (Ctrl-Z) Signal.trap('TSTP') do ::Guard.run do @@ -24,6 +24,6 @@ module Guard end end end - + end -end \ No newline at end of file +end diff --git a/lib/guard/listener.rb b/lib/guard/listener.rb index 3675489..5289be9 100644 --- a/lib/guard/listener.rb +++ b/lib/guard/listener.rb @@ -121,4 +121,4 @@ end # end # # end -# end \ No newline at end of file +# end diff --git a/lib/guard/notifier.rb b/lib/guard/notifier.rb index d250a22..cabb857 100644 --- a/lib/guard/notifier.rb +++ b/lib/guard/notifier.rb @@ -63,4 +63,4 @@ module Guard end end -end \ No newline at end of file +end diff --git a/lib/guard/ui.rb b/lib/guard/ui.rb index 94953db..d71ee8d 100644 --- a/lib/guard/ui.rb +++ b/lib/guard/ui.rb @@ -2,21 +2,21 @@ module Guard module UI class << self - def info(message, options = {}) + def info(message, options={}) unless ENV["GUARD_ENV"] == "test" reset_line if options[:reset] puts reset_color(message) if message != '' end end - def error(message, options = {}) + def error(message, options={}) unless ENV["GUARD_ENV"] == "test" reset_line if options[:reset] puts "ERROR: #{message}" end end - def debug(message, options = {}) + def debug(message, options={}) unless ENV["GUARD_ENV"] == "test" reset_line if options[:reset] puts "DEBUG: #{message}" if ::Guard.options && ::Guard.options[:debug] diff --git a/lib/guard/version.rb b/lib/guard/version.rb index 2e9b5fb..1db0eec 100644 --- a/lib/guard/version.rb +++ b/lib/guard/version.rb @@ -1,3 +1,3 @@ module Guard - VERSION = "0.3.1" -end \ No newline at end of file + VERSION = "0.3.4" +end diff --git a/lib/guard/watcher.rb b/lib/guard/watcher.rb index fc16b23..a4292a0 100644 --- a/lib/guard/watcher.rb +++ b/lib/guard/watcher.rb @@ -1,11 +1,11 @@ module Guard class Watcher attr_accessor :pattern, :action - + def initialize(pattern, action = nil) @pattern, @action = pattern, action @@warning_printed ||= false - + # deprecation warning if @pattern.is_a?(String) && @pattern =~ /(^(\^))|(>?(\\\.)|(\.\*))|(\(.*\))|(\[.*\])|(\$$)/ unless @@warning_printed @@ -17,7 +17,7 @@ module Guard @pattern = Regexp.new(@pattern) end end - + def self.match_files(guard, files) guard.watchers.inject([]) do |paths, watcher| files.each do |file| @@ -33,7 +33,7 @@ module Guard paths.flatten.map { |p| p.to_s } end end - + def self.match_files?(guards, files) guards.any? do |guard| guard.watchers.any? do |watcher| @@ -41,7 +41,7 @@ module Guard end end end - + def match_file?(file) if @pattern.is_a?(Regexp) file.match(@pattern) @@ -49,7 +49,7 @@ module Guard file == @pattern ? [file] : nil end end - + def call_action(matches) begin @action.arity > 0 ? @action.call(matches) : @action.call @@ -57,6 +57,6 @@ module Guard UI.error "Problem with watch action!" end end - + end -end \ No newline at end of file +end diff --git a/spec/guard/dsl_spec.rb b/spec/guard/dsl_spec.rb index 625b037..ba626f4 100644 --- a/spec/guard/dsl_spec.rb +++ b/spec/guard/dsl_spec.rb @@ -1,8 +1,11 @@ require 'spec_helper' +require 'guard/guard' describe Guard::Dsl do subject { Guard::Dsl } + class Guard::Dummy < Guard::Guard; end + before(:each) do ::Guard.stub!(:add_guard) end @@ -114,20 +117,23 @@ describe Guard::Dsl do describe "#callback" do it "creates callbacks for the guard" do class MyCustomCallback + def self.call(guard_class, event, args) + # do nothing + end end - mock_guardfile_content(" - guard 'test' do - callback(:start_end) { 'Guard::Test started!' } + mock_guardfile_content(' + guard :dummy do + callback(:start_end) { |guard_class, event, args| "#{guard_class} executed \'#{event}\' hook with #{args}!" } callback(MyCustomCallback, [:start_begin, :run_all_begin]) - end") + end') - ::Guard.should_receive(:add_guard).with('test', anything, anything, {}) do |name, watchers, callbacks, options| + ::Guard.should_receive(:add_guard).with(:dummy, anything, anything, {}) do |name, watchers, callbacks, options| callbacks.should have(2).items - callbacks[0][:events].should == :start_end - callbacks[0][:listener].call.should == proc { 'Guard::Test started!' }.call - callbacks[1][:events].should == [:start_begin, :run_all_begin] - callbacks[1][:listener].should == MyCustomCallback + callbacks[0][:events].should == :start_end + callbacks[0][:listener].call(Guard::Dummy, :start_end, 'foo').should == "Guard::Dummy executed 'start_end' hook with foo!" + callbacks[1][:events].should == [:start_begin, :run_all_begin] + callbacks[1][:listener].should == MyCustomCallback end subject.evaluate_guardfile end diff --git a/spec/guard/notifier_spec.rb b/spec/guard/notifier_spec.rb index b12781b..73aa761 100644 --- a/spec/guard/notifier_spec.rb +++ b/spec/guard/notifier_spec.rb @@ -19,9 +19,8 @@ describe Guard::Notifier do ) subject.notify 'great', :title => 'Guard' end - end - if linux? + elsif linux? require 'libnotify' it "uses Libnotify on Linux" do Libnotify.should_receive(:show).with( @@ -42,9 +41,8 @@ describe Guard::Notifier do Growl.should_not_receive(:notify) subject.notify 'great', :title => 'Guard' end - end - if linux? + elsif linux? require 'libnotify' it "does nothing" do Libnotify.should_not_receive(:show) diff --git a/spec/guard_spec.rb b/spec/guard_spec.rb index 3a1b745..5d5f656 100644 --- a/spec/guard_spec.rb +++ b/spec/guard_spec.rb @@ -30,15 +30,30 @@ describe Guard do end describe ".get_guard_class" do - it "should return Guard::RSpec" do - Guard.get_guard_class('rspec').should == Guard::RSpec + it "should report an error if the class is not found" do + ::Guard::UI.should_receive(:error) + Guard.get_guard_class('notAGuardClass') end context 'loaded some nested classes' do - it "should return Guard::RSpec" do - require 'guard/rspec' - Guard::RSpec.class_eval('class NotGuardClass; end') - Guard.get_guard_class('rspec').should == Guard::RSpec + it "should find and return loaded class" do + Guard.should_receive(:try_to_load_gem) { |className| + className.should == 'classname' + class Guard::Classname + end + } + Guard.get_guard_class('classname').should == Guard::Classname + end + end + + context 'loaded some inline classes ' do + it 'should return inline class' do + module Guard + class Inline < Guard + end + end + + Guard.get_guard_class('inline').should == Guard::Inline end end end