From dd3ba3e325755f67bdef3d8239ef88d4b3991d81 Mon Sep 17 00:00:00 2001 From: Cezary Baginski Date: Wed, 11 Jun 2014 11:43:11 +0200 Subject: [PATCH] dump Guard:guard + fix specs (stub verification) --- lib/guard/commands/all.rb | 36 ++++---- lib/guard/commands/change.rb | 30 +++---- lib/guard/commands/notification.rb | 24 +++--- lib/guard/commands/pause.rb | 23 ++--- lib/guard/commands/reload.rb | 33 +++---- lib/guard/commands/scope.rb | 37 ++++---- lib/guard/commands/show.rb | 25 +++--- lib/guard/guard.rb | 42 --------- lib/guard/plugin_util.rb | 4 + lib/guard/setuper.rb | 10 +-- spec/guard_spec.rb | 8 +- spec/lib/guard/cli_spec.rb | 2 +- spec/lib/guard/commander_spec.rb | 57 ++++++------ spec/lib/guard/commands/all_spec.rb | 91 ++++++++++---------- spec/lib/guard/commands/change_spec.rb | 49 ++++------- spec/lib/guard/commands/notification_spec.rb | 16 +--- spec/lib/guard/commands/pause_spec.rb | 25 +----- spec/lib/guard/commands/reload_spec.rb | 80 +++++++++-------- spec/lib/guard/commands/scope_spec.rb | 81 ++++++++--------- spec/lib/guard/commands/show_spec.rb | 28 +----- spec/lib/guard/deprecated_methods_spec.rb | 13 ++- spec/lib/guard/dsl_describer_spec.rb | 2 + spec/lib/guard/dsl_spec.rb | 13 +-- spec/lib/guard/guard_spec.rb | 31 ------- spec/lib/guard/guardfile/evaluator_spec.rb | 4 +- spec/lib/guard/guardfile/generator_spec.rb | 2 +- spec/lib/guard/guardfile_spec.rb | 2 +- spec/lib/guard/interactor_spec.rb | 20 +++-- spec/lib/guard/notifier_spec.rb | 10 +-- spec/lib/guard/plugin/hooker_spec.rb | 4 +- spec/lib/guard/plugin_util_spec.rb | 77 ++--------------- spec/lib/guard/runner_spec.rb | 67 ++++++++++---- spec/lib/guard/setuper_spec.rb | 69 +++++++++++---- spec/lib/guard/ui_spec.rb | 24 ++++-- spec/spec_helper.rb | 9 +- 35 files changed, 503 insertions(+), 545 deletions(-) delete mode 100644 lib/guard/guard.rb delete mode 100644 spec/lib/guard/guard_spec.rb diff --git a/lib/guard/commands/all.rb b/lib/guard/commands/all.rb index 757e0d2d1..c0832a36c 100644 --- a/lib/guard/commands/all.rb +++ b/lib/guard/commands/all.rb @@ -1,28 +1,32 @@ -module Guard - # Command to run all default plugin tasks - class Interactor - ALL = Pry::CommandSet.new do - create_command 'all' do +# required for async_queue_add +require 'guard' - group 'Guard' - description 'Run all plugins.' +module Guard + module Commands + class All + def self.import + Pry::Commands.create_command 'all' do + group 'Guard' + description 'Run all plugins.' - banner <<-BANNER + banner <<-BANNER Usage: all Run the Guard plugin `run_all` action. You may want to specify an optional scope to the action, either the name of a Guard plugin or a plugin group. - BANNER + BANNER + + def process(*entries) + scopes, unknown = ::Guard::Interactor.convert_scope(entries) - def process(*entries) - scopes, rest = ::Guard::Interactor.convert_scope(entries) + unless unknown.empty? + output.puts "Unknown scopes: #{ unknown.join(', ') }" + return + end - if rest.empty? - ::Guard.async_queue_add([:guard_run_all, scopes]) - else - output.puts "Unknown scope #{ rest.join(', ') }" + Guard.async_queue_add([:guard_run_all, scopes]) end end end @@ -30,4 +34,4 @@ def process(*entries) end end -Pry.commands.import ::Guard::Interactor::ALL +Guard::Commands::All.import diff --git a/lib/guard/commands/change.rb b/lib/guard/commands/change.rb index 079c6a6c6..bbaa2dfb5 100644 --- a/lib/guard/commands/change.rb +++ b/lib/guard/commands/change.rb @@ -1,31 +1,29 @@ module Guard - # Command to simulate file change events - class Interactor - CHANGE = Pry::CommandSet.new do - create_command 'change' do + module Commands + class Change + def self.import + Pry::Commands.create_command 'change' do + group 'Guard' + description 'Trigger a file change.' - group 'Guard' - description 'Trigger a file change.' - - banner <<-BANNER + banner <<-BANNER Usage: change Pass the given files to the Guard plugin `run_on_changes` action. - BANNER + BANNER - def process(*entries) - _, files = ::Guard::Interactor.convert_scope(entries) + def process(*files) + if files.empty? + output.puts 'Please specify a file.' + return + end - if files.empty? - output.puts 'Please specify a file.' - else ::Guard.async_queue_add(modified: files, added: [], removed: []) end end - end end end end -Pry.commands.import ::Guard::Interactor::CHANGE +Guard::Commands::Change.import diff --git a/lib/guard/commands/notification.rb b/lib/guard/commands/notification.rb index 646707d43..bddf12045 100644 --- a/lib/guard/commands/notification.rb +++ b/lib/guard/commands/notification.rb @@ -1,26 +1,26 @@ require 'guard/notifier' module Guard - # Command to toggle notifications on and off - class Interactor - NOTIFICATION = Pry::CommandSet.new do - create_command 'notification' do + module Commands + class Notification + def self.import + Pry::Commands.create_command 'notification' do + group 'Guard' + description 'Toggles the notifications.' - group 'Guard' - description 'Toggles the notifications.' - - banner <<-BANNER + banner <<-BANNER Usage: notification Toggles the notifications on and off. - BANNER + BANNER - def process - ::Guard::Notifier.toggle + def process + ::Guard::Notifier.toggle + end end end end end end -Pry.commands.import ::Guard::Interactor::NOTIFICATION +Guard::Commands::Notification.import diff --git a/lib/guard/commands/pause.rb b/lib/guard/commands/pause.rb index c30047903..84317f08b 100644 --- a/lib/guard/commands/pause.rb +++ b/lib/guard/commands/pause.rb @@ -1,26 +1,27 @@ module Guard - class Interactor - PAUSE = Pry::CommandSet.new do - create_command 'pause' do + module Commands + class Pause + def self.import + Pry::Commands.create_command 'pause' do + group 'Guard' + description 'Toggles the file listener.' - group 'Guard' - description 'Toggles the file listener.' - - banner <<-BANNER + banner <<-BANNER Usage: pause Toggles the file listener on and off. When the file listener is paused, the default Guard Pry prompt will show the pause sign `[p]`. - BANNER + BANNER - def process - ::Guard.async_queue_add([:guard_pause]) + def process + ::Guard.async_queue_add([:guard_pause]) + end end end end end end -Pry.commands.import ::Guard::Interactor::PAUSE +Guard::Commands::Pause.import diff --git a/lib/guard/commands/reload.rb b/lib/guard/commands/reload.rb index 5d34be0a6..4a56915c5 100644 --- a/lib/guard/commands/reload.rb +++ b/lib/guard/commands/reload.rb @@ -1,33 +1,34 @@ module Guard - class Interactor - RELOAD = Pry::CommandSet.new do - create_command 'reload' do - - group 'Guard' - description 'Reload all plugins.' - - banner <<-BANNER + module Commands + class Reload + def self.import + Pry::Commands.create_command 'reload' do + group 'Guard' + description 'Reload all plugins.' + + banner <<-BANNER Usage: reload Run the Guard plugin `reload` action. You may want to specify an optional scope to the action, either the name of a Guard plugin or a plugin group. - BANNER + BANNER - def process(*entries) - scopes, rest = ::Guard::Interactor.convert_scope(entries) + def process(*entries) + scopes, unknown = ::Guard::Interactor.convert_scope(entries) + + unless unknown.empty? + output.puts "Unknown scopes: #{ unknown.join(', ') }" + return + end - if rest.empty? ::Guard.async_queue_add([:guard_reload, scopes]) - else - output.puts "Unknown scope #{ rest.join(', ') }" end end - end end end end -Pry.commands.import ::Guard::Interactor::RELOAD +Guard::Commands::Reload.import diff --git a/lib/guard/commands/scope.rb b/lib/guard/commands/scope.rb index 8770ab928..18acfbd32 100644 --- a/lib/guard/commands/scope.rb +++ b/lib/guard/commands/scope.rb @@ -1,29 +1,36 @@ module Guard - class Interactor - SCOPE = Pry::CommandSet.new do - create_command 'scope' do - group 'Guard' - description 'Scope Guard actions to groups and plugins.' + module Commands + class Scope + def self.import + Pry::Commands.create_command 'scope' do + group 'Guard' + description 'Scope Guard actions to groups and plugins.' - banner <<-BANNER + banner <<-BANNER Usage: scope Set the global Guard scope. - BANNER + BANNER - def process(*entries) - scope, _ = ::Guard::Interactor.convert_scope(entries) + def process(*entries) + scope, unknown = Guard::Interactor.convert_scope(entries) - if scope[:plugins].empty? && scope[:groups].empty? - output.puts 'Usage: scope ' - else - ::Guard.scope = scope + unless unknown.empty? + output.puts "Unknown scopes: #{unknown.join(',') }" + return + end + + if scope[:plugins].empty? && scope[:groups].empty? + output.puts 'Usage: scope ' + return + end + + Guard.scope = scope end end - end end end end -Pry.commands.import ::Guard::Interactor::SCOPE +Guard::Commands::Scope.import diff --git a/lib/guard/commands/show.rb b/lib/guard/commands/show.rb index 36e9ef29b..e6a10c5e8 100644 --- a/lib/guard/commands/show.rb +++ b/lib/guard/commands/show.rb @@ -1,25 +1,24 @@ -require 'guard/dsl_describer' - module Guard - class Interactor - SHOW = Pry::CommandSet.new do - create_command 'show' do - - group 'Guard' - description 'Show all Guard plugins.' + module Commands + class Show + def self.import + Pry::Commands.create_command 'show' do + group 'Guard' + description 'Show all Guard plugins.' - banner <<-BANNER + banner <<-BANNER Usage: show Show all defined Guard plugins and their options. - BANNER + BANNER - def process - ::Guard.async_queue_add([:guard_show]) + def process + ::Guard.async_queue_add([:guard_show]) + end end end end end end -Pry.commands.import ::Guard::Interactor::SHOW +Guard::Commands::Show.import diff --git a/lib/guard/guard.rb b/lib/guard/guard.rb deleted file mode 100644 index e049e835f..000000000 --- a/lib/guard/guard.rb +++ /dev/null @@ -1,42 +0,0 @@ -require 'guard/plugin/base' - -module Guard - # @deprecated Inheriting from `Guard::Guard` is deprecated, please inherit - # from {Plugin} instead. Please note that the constructor signature has - # changed from `Guard::Guard#initialize(watchers = [], options = {})` to - # `Guard::Plugin#initialize(options = {})`. - # - # @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to - # upgrade for Guard 2.0 - # - class Guard - include ::Guard::Plugin::Base - - # @deprecated Inheriting from `Guard::Guard` is deprecated, please inherit - # from {Plugin} instead. Please note that the constructor signature - # has changed from `Guard::Guard#initialize(watchers = [], options = {})` - # to `Guard::Plugin#initialize(options = {})`. - # - # Initializes a Guard plugin. Don't do any work here, - # especially as Guard plugins get initialized even if they are not in an - # active group! - # - # @see https://github.com/guard/guard/wiki/Upgrading-to-Guard-2.0 How to - # upgrade for Guard 2.0 - # - # @param [Array] watchers the Guard plugin file watchers - # @param [Hash] options the custom Guard plugin options - # @option options [Symbol] group the group this Guard plugin belongs to - # @option options [Boolean] any_return allow any object to be returned from - # a watcher - # @option options [Boolean] first_match stop after the first watcher that - # returns a valid result - # - def initialize(watchers = [], options = {}) - UI.deprecation(Deprecator::GUARD_GUARD_DEPRECATION % title) - - _set_instance_variables_from_options(options.merge(watchers: watchers)) - _register_callbacks - end - end -end diff --git a/lib/guard/plugin_util.rb b/lib/guard/plugin_util.rb index 202c6928a..b44a4cbed 100644 --- a/lib/guard/plugin_util.rb +++ b/lib/guard/plugin_util.rb @@ -37,6 +37,10 @@ def self.plugin_names end end else + Guard::UI.deprecation \ + 'Rubygems version prior to 1.8.0 are no longer supported'\ + ' and may not work' + Gem.source_index.find_name(/^guard-/) end.map { |x| x.name.sub(/^guard-/, '') }.uniq end diff --git a/lib/guard/setuper.rb b/lib/guard/setuper.rb index 90b4cfc4b..d41097c29 100644 --- a/lib/guard/setuper.rb +++ b/lib/guard/setuper.rb @@ -44,10 +44,11 @@ def setup(opts = {}) ::Guard::UI.clear(force: true) _setup_debug if options[:debug] - _setup_listener + @listener = _setup_listener _setup_signal_traps _load_guardfile + @interactor = _setup_interactor self end @@ -151,14 +152,14 @@ def _setup_debug # def _setup_listener if options[:listen_on] - @listener = Listen.on(options[:listen_on], &_listener_callback) + Listen.on(options[:listen_on], &_listener_callback) else listener_options = {} [:latency, :force_polling, :wait_for_delay].each do |option| listener_options[option] = options[option] if options[option] end listen_args = watchdirs + [listener_options] - @listener = Listen.to(*listen_args, &_listener_callback) + Listen.to(*listen_args, &_listener_callback) end end @@ -304,7 +305,7 @@ def _reset_all end def _setup_interactor - @interactor = ::Guard::Interactor.new(options[:no_interactions]) + ::Guard::Interactor.new(options[:no_interactions]) end def _load_guardfile @@ -312,7 +313,6 @@ def _load_guardfile evaluate_guardfile setup_scope(groups: options[:group], plugins: options[:plugin]) _setup_notifier - _setup_interactor end end end diff --git a/spec/guard_spec.rb b/spec/guard_spec.rb index f45bc14f4..124c53f5b 100644 --- a/spec/guard_spec.rb +++ b/spec/guard_spec.rb @@ -171,6 +171,7 @@ describe '.groups' do subject do allow(Guard::Notifier).to receive(:turn_on) + allow(Listen).to receive(:to).with(Dir.pwd, {}) guard = ::Guard.setup @group_backend = guard.add_group(:backend) @group_backflip = guard.add_group(:backflip) @@ -217,7 +218,10 @@ describe '.group' do subject do allow(Guard::Notifier).to receive(:turn_on) + allow(Listen).to receive(:to).with(Dir.pwd, {}) + guard = ::Guard.setup + @group_backend = guard.add_group(:backend) @group_backflip = guard.add_group(:backflip) guard @@ -255,8 +259,8 @@ end describe '.add_plugin' do - let(:plugin_util) { double('Guard::PluginUtil') } - let(:guard_rspec) { double('Guard::RSpec instance') } + let(:plugin_util) { instance_double(Guard::PluginUtil) } + let(:guard_rspec) { instance_double(Guard::RSpec) } before do expect(::Guard::PluginUtil).to receive(:new).with('rspec') { plugin_util } diff --git a/spec/lib/guard/cli_spec.rb b/spec/lib/guard/cli_spec.rb index 677b21413..1ae3d76f7 100644 --- a/spec/lib/guard/cli_spec.rb +++ b/spec/lib/guard/cli_spec.rb @@ -4,7 +4,7 @@ describe Guard::CLI do let(:guard) { Guard } let(:ui) { Guard::UI } - let(:dsl_describer) { double('DslDescriber instance') } + let(:dsl_describer) { instance_double(DslDescriber) } describe '#start' do before { allow(Guard).to receive(:start) } diff --git a/spec/lib/guard/commander_spec.rb b/spec/lib/guard/commander_spec.rb index 6e35a99c8..3ffec3f2f 100644 --- a/spec/lib/guard/commander_spec.rb +++ b/spec/lib/guard/commander_spec.rb @@ -7,27 +7,31 @@ end describe '.start' do - let(:runner) { double('runner', run: true) } - let(:listener) { double('listener', start: true, stop: true) } + let(:runner) { instance_double(Guard::Runner, run: true) } + let(:listener) do + instance_double(Listen::Listener, start: true, stop: true) + end + + let(:watched_dir) { Dir.pwd } + before do ::Guard.instance_variable_set('@watchdirs', []) - allow(::Guard).to receive(:setup) - allow(::Guard).to receive(:listener) { listener } allow(::Guard).to receive(:runner) { runner } + allow(Listen).to receive(:to).with(watched_dir, {}) { listener } + allow(Guard::Notifier).to receive(:turn_on) end context 'Guard has not been setuped' do - it 'setup Guard' do - expect(::Guard).to receive(:setup).with(foo: 'bar') + it 'calls Guard setup' do + expect(::Guard).to receive(:setup).with(foo: 'bar').and_call_original ::Guard.start(foo: 'bar') end end it 'displays an info message' do - ::Guard.instance_variable_set('@watchdirs', ['/foo/bar']) expect(::Guard::UI).to receive(:info). - with("Guard is now watching at '/foo/bar'") + with("Guard is now watching at '#{Dir.pwd}'") ::Guard.start end @@ -46,15 +50,17 @@ end describe '.stop' do - let(:runner) { double('runner', run: true) } - let(:listener) { double('listener', stop: true) } - let(:interactor) { double('interactor', background: nil) } + let(:runner) { instance_double(Guard::Runner, run: true) } + let(:listener) { instance_double(Listen::Listener, stop: true) } + let(:interactor) { instance_double(Guard::Interactor, background: nil) } + before do - allow(::Guard).to receive(:setup) - allow(::Guard).to receive(:listener) { listener } allow(::Guard).to receive(:runner) { runner } allow(::Guard).to receive(:interactor) { interactor } - allow(::Guard).to receive(:within_preserved_state).and_yield + allow(Listen).to receive(:to).with(Dir.pwd, {}) { listener } + allow(Guard::Notifier).to receive(:turn_on) + allow(listener).to receive(:stop) + Guard.setup end it 'turns the notifier off' do @@ -78,7 +84,7 @@ end describe '.reload' do - let(:runner) { double(run: true) } + let(:runner) { instance_double(Guard::Runner, run: true) } let(:group) { ::Guard::Group.new('frontend') } subject { ::Guard.setup } @@ -88,6 +94,7 @@ allow(::Guard).to receive(:scope) { {} } allow(::Guard::UI).to receive(:info) allow(::Guard::UI).to receive(:clear) + allow(Listen).to receive(:to).with(Dir.pwd, {}) end it 'clears the screen' do @@ -128,7 +135,7 @@ end describe '.run_all' do - let(:runner) { double(run: true) } + let(:runner) { instance_double(Guard::Runner, run: true) } let(:group) { ::Guard::Group.new('frontend') } subject { ::Guard.setup } @@ -137,6 +144,7 @@ allow(::Guard).to receive(:runner) { runner } allow(::Guard::UI).to receive(:action_with_scopes) allow(::Guard::UI).to receive(:clear) + allow(Listen).to receive(:to).with(Dir.pwd, {}) end context 'with a given scope' do @@ -157,16 +165,14 @@ end describe '.pause' do - subject { ::Guard.setup } - let!(:listener) { double(:listener) } - before do - allow(::Guard::Notifier).to receive(:turn_on) - allow(subject).to receive(:listener) { listener } - end context 'when unpaused' do + subject { ::Guard.setup } + let(:listener) { instance_double(Listen::Listener) } before do + allow(::Guard::Notifier).to receive(:turn_on) + allow(Listen).to receive(:to).with(Dir.pwd, {}) { listener } allow(listener).to receive(:paused?) { false } end @@ -196,10 +202,13 @@ end context 'when already paused' do - let!(:listener) { ::Guard.listener } + subject { ::Guard.setup } + let(:listener) { instance_double(Listen::Listener) } before do - allow(::Guard.listener).to receive(:paused?) { true } + allow(::Guard::Notifier).to receive(:turn_on) + allow(Listen).to receive(:to).with(Dir.pwd, {}) { listener } + allow(listener).to receive(:paused?) { true } end [:toggle, nil, :unpaused].each do |mode| diff --git a/spec/lib/guard/commands/all_spec.rb b/spec/lib/guard/commands/all_spec.rb index 526d80bbf..fbb324dd5 100644 --- a/spec/lib/guard/commands/all_spec.rb +++ b/spec/lib/guard/commands/all_spec.rb @@ -1,63 +1,64 @@ require 'spec_helper' require 'guard/plugin' -describe 'Guard::Interactor::ALL' do +describe Guard::Commands::All do - let(:guard) { ::Guard.setup } - let(:foo_group) { guard.add_group(:foo) } - let(:bar_guard) { guard.add_plugin(:bar, group: :foo) } + let(:foo_group) { instance_double(Guard::Group) } + let(:bar_guard) { instance_double(Guard::PluginUtil) } before do - allow(Guard::Notifier).to receive(:turn_on) - allow(Guard).to receive(:run_all) - allow(Guard).to receive(:setup_interactor) - allow(Pry.output).to receive(:puts) - - # happens during interactor _cleanup - allow(Guard::Sheller).to receive(:run).with(*%w(hash stty)).and_return(nil) + allow(Guard::Interactor).to receive(:convert_scope) do |*args| + fail "Interactor#convert_scope stub called with: #{args.inspect}" + end - stub_const 'Guard::Bar', Class.new(Guard::Plugin) + allow(Guard::Interactor).to receive(:convert_scope).with(given_scope). + and_return(converted_scope) end - describe '#perform' do - let!(:guard) { ::Guard.setup } - context 'without scope' do - it 'runs the :run_all action' do - expect(Guard).to receive(:run_all).with(groups: [], plugins: []) - Pry.run_command 'all' - sleep 0.01 # sleep to avoid leaking setuper thread - guard.send(:_process_queue) - end - end + context 'without scope' do + let(:given_scope) { [] } + let(:converted_scope) { [{ groups: [], plugins: [] }, []] } + + it 'runs the :run_all action' do + expect(Guard).to receive(:async_queue_add). + with([:guard_run_all, groups: [], plugins: []]) - context 'with a valid Guard group scope' do - it 'runs the :run_all action with the given scope' do - expect(Guard).to receive(:run_all). - with(groups: [foo_group], plugins: []) - Pry.run_command 'all foo' - sleep 0.01 # sleep to avoid leaking setuper thread - guard.send(:_process_queue) - end + Pry.run_command 'all' end + end + + context 'with a valid Guard group scope' do + let(:given_scope) { ['foo'] } + let(:converted_scope) { [{ groups: [foo_group], plugins: [] }, []] } + + it 'runs the :run_all action with the given scope' do + expect(Guard).to receive(:async_queue_add). + with([:guard_run_all, groups: [foo_group], plugins: []]) - context 'with a valid Guard plugin scope' do - it 'runs the :run_all action with the given scope' do - expect(Guard).to receive(:run_all). - with(plugins: [bar_guard], groups: []) - Pry.run_command 'all bar' - sleep 0.01 # sleep to avoid leaking setuper thread - guard.send(:_process_queue) - end + Pry.run_command 'all foo' end + end + + context 'with a valid Guard plugin scope' do + let(:given_scope) { ['bar'] } + let(:converted_scope) { [{ groups: [], plugins: [bar_guard] }, []] } + + it 'runs the :run_all action with the given scope' do + expect(Guard).to receive(:async_queue_add). + with([:guard_run_all, plugins: [bar_guard], groups: []]) - context 'with an invalid scope' do - it 'does not run the action' do - expect(Guard).to_not receive(:run_all) - Pry.run_command 'all baz' - sleep 0.01 # sleep to avoid leaking setuper thread - guard.send(:_process_queue) - end + Pry.run_command 'all bar' end end + context 'with an invalid scope' do + let(:given_scope) { ['baz'] } + let(:converted_scope) { [{ groups: [], plugins: [] }, ['baz']] } + + it 'does not run the action' do + expect(STDOUT).to receive(:print).with("Unknown scopes: baz\n") + expect(Guard).to_not receive(:async_queue_add) + Pry.run_command 'all baz' + end + end end diff --git a/spec/lib/guard/commands/change_spec.rb b/spec/lib/guard/commands/change_spec.rb index 11ddd722d..5342d0310 100644 --- a/spec/lib/guard/commands/change_spec.rb +++ b/spec/lib/guard/commands/change_spec.rb @@ -1,42 +1,29 @@ require 'spec_helper' -describe 'Guard::Interactor::CHANGE' do +describe Guard::Commands::Change do + context 'with a file' do + it 'runs the :run_on_changes action with the given file' do + expect(::Guard).to receive(:async_queue_add). + with(modified: ['foo'], added: [], removed: []) - before do - allow(Guard::Notifier).to receive(:turn_on) - ::Guard.setup - allow(Guard.runner).to receive(:run_on_changes) - allow(Pry.output).to receive(:puts) - - # happens during interactor _cleanup - allow(Guard::Sheller).to receive(:run).with(*%w(hash stty)).and_return(nil) - end - - describe '#perform' do - context 'with a file' do - it 'runs the :run_on_changes action with the given scope' do - expect(::Guard).to receive(:async_queue_add). - with(modified: ['foo'], added: [], removed: []) - - Pry.run_command 'change foo' - end + Pry.run_command 'change foo' end + end - context 'with multiple files' do - it 'runs the :run_on_changes action with the given scope' do - expect(::Guard).to receive(:async_queue_add). - with(modified: ['foo', 'bar', 'baz'], added: [], removed: []) + context 'with multiple files' do + it 'runs the :run_on_changes action with the given files' do + expect(::Guard).to receive(:async_queue_add). + with(modified: ['foo', 'bar', 'baz'], added: [], removed: []) - Pry.run_command 'change foo bar baz' - end + Pry.run_command 'change foo bar baz' end + end - context 'without a file' do - it 'does not run the :run_on_changes action' do - expect(::Guard).to_not receive(:async_queue_add) - - Pry.run_command 'change' - end + context 'without a file' do + it 'does not run the :run_on_changes action' do + expect(::Guard).to_not receive(:async_queue_add) + expect(STDOUT).to receive(:print).with("Please specify a file.\n") + Pry.run_command 'change' end end end diff --git a/spec/lib/guard/commands/notification_spec.rb b/spec/lib/guard/commands/notification_spec.rb index 5c809458a..6b42c5602 100644 --- a/spec/lib/guard/commands/notification_spec.rb +++ b/spec/lib/guard/commands/notification_spec.rb @@ -1,16 +1,8 @@ require 'spec_helper' -describe 'Guard::Interactor::NOTIFICATION' do - - before do - allow(::Guard::Notifier).to receive(:toggle) - end - - describe '#perform' do - it 'toggles the Guard notifier' do - expect(::Guard::Notifier).to receive(:toggle) - Pry.run_command 'notification' - end +describe Guard::Commands::Notification do + it 'toggles the Guard notifier' do + expect(::Guard::Notifier).to receive(:toggle) + Pry.run_command 'notification' end - end diff --git a/spec/lib/guard/commands/pause_spec.rb b/spec/lib/guard/commands/pause_spec.rb index 3e0678a39..fe544939b 100644 --- a/spec/lib/guard/commands/pause_spec.rb +++ b/spec/lib/guard/commands/pause_spec.rb @@ -1,25 +1,8 @@ require 'spec_helper' -describe 'Guard::Interactor::PAUSE' do - - before do - allow(Guard::Notifier).to receive(:turn_on) - - # happens during interactor _cleanup - allow(Guard::Sheller).to receive(:run).with(*%w(hash stty)).and_return(nil) - end - - describe '#perform' do - let!(:guard) { ::Guard.setup } - - it 'pauses Guard' do - expect(::Guard).to receive(:pause) - Pry.run_command 'pause' - - sleep 0.01 # sleep until setuper thread kills Pry to avoid _cleanup - - guard.send(:_process_queue) - end +describe Guard::Commands::Pause do + it 'tells Guard to pause' do + expect(::Guard).to receive(:async_queue_add).with([:guard_pause]) + Pry.run_command 'pause' end - end diff --git a/spec/lib/guard/commands/reload_spec.rb b/spec/lib/guard/commands/reload_spec.rb index ba4e4c99a..b9711f63f 100644 --- a/spec/lib/guard/commands/reload_spec.rb +++ b/spec/lib/guard/commands/reload_spec.rb @@ -1,53 +1,61 @@ require 'spec_helper' require 'guard/plugin' -describe 'Guard::Interactor::RELOAD' do +describe Guard::Commands::Reload do - let(:guard) { ::Guard.setup } - let(:foo_group) { guard.add_group(:foo) } - let(:bar_guard) { guard.add_plugin(:bar, group: :foo) } + let(:foo_group) { instance_double(Guard::Group) } + let(:bar_guard) { instance_double(Guard::PluginUtil) } before do - allow(Guard).to receive(:reload) - allow(Guard).to receive(:setup_interactor) - allow(Pry.output).to receive(:puts) - allow(Guard::Notifier).to receive(:turn_on) - stub_const 'Guard::Bar', Class.new(Guard::Plugin) - - # happens during interactor _cleanup - allow(Guard::Sheller).to receive(:run).with(*%w(hash stty)).and_return(nil) + allow(Guard::Interactor).to receive(:convert_scope) do |*args| + fail "Interactor#convert_scope stub called with: #{args.inspect}" + end + + allow(Guard::Interactor).to receive(:convert_scope).with(given_scope). + and_return(converted_scope) end - describe '#perform' do - context 'without scope' do - it 'runs the :reload action' do - expect(Guard).to receive(:async_queue_add). - with([:guard_reload, { groups: [], plugins: [] }]) - Pry.run_command 'reload' - end + context 'without scope' do + let(:given_scope) { [] } + let(:converted_scope) { [{ groups: [], plugins: [] }, []] } + + it 'triggers the :reload action' do + expect(Guard).to receive(:async_queue_add). + with([:guard_reload, { groups: [], plugins: [] }]) + Pry.run_command 'reload' end + end + + context 'with a valid Guard group scope' do + let(:given_scope) { ['foo'] } + let(:converted_scope) { [{ groups: [foo_group], plugins: [] }, []] } - context 'with a valid Guard group scope' do - it 'runs the :reload action with the given scope' do - expect(Guard).to receive(:async_queue_add). - with([:guard_reload, { groups: [foo_group], plugins: [] }]) - Pry.run_command 'reload foo' - end + it 'triggers the :reload action with the given scope' do + expect(Guard).to receive(:async_queue_add). + with([:guard_reload, { groups: [foo_group], plugins: [] }]) + Pry.run_command 'reload foo' end + end + + context 'with a valid Guard plugin scope' do + let(:given_scope) { ['bar'] } + let(:converted_scope) { [{ groups: [], plugins: [bar_guard] }, []] } - context 'with a valid Guard plugin scope' do - it 'runs the :reload action with the given scope' do - expect(Guard).to receive(:async_queue_add). - with([:guard_reload, { plugins: [bar_guard], groups: [] }]) - Pry.run_command 'reload bar' - end + it 'triggers the :reload action with the given scope' do + expect(Guard).to receive(:async_queue_add). + with([:guard_reload, { plugins: [bar_guard], groups: [] }]) + Pry.run_command 'reload bar' end + end + + context 'with an invalid scope' do + let(:given_scope) { ['baz'] } + let(:converted_scope) { [{ groups: [], plugins: [] }, ['baz']] } - context 'with an invalid scope' do - it 'does not run the action' do - expect(Guard).to_not receive(:reload) - Pry.run_command 'reload baz' - end + it 'does not trigger the action' do + allow(STDOUT).to receive(:print).with("Unknown scopes: baz\n") + expect(Guard).to_not receive(:async_queue_add) + Pry.run_command 'reload baz' end end end diff --git a/spec/lib/guard/commands/scope_spec.rb b/spec/lib/guard/commands/scope_spec.rb index d0a5a7f98..f9a4b1d9d 100644 --- a/spec/lib/guard/commands/scope_spec.rb +++ b/spec/lib/guard/commands/scope_spec.rb @@ -1,56 +1,59 @@ require 'spec_helper' require 'guard/plugin' -describe 'Guard::Interactor::SCOPE' do +describe Guard::Commands::Scope do - let(:guard) { ::Guard.setup } - let(:foo_group) { guard.add_group(:foo) } - let(:bar_guard) { guard.add_plugin(:bar, group: :foo) } + let(:foo_group) { instance_double(Guard::Group) } + let(:bar_guard) { instance_double(Guard::PluginUtil) } before do - allow(Guard::Notifier).to receive(:turn_on) - allow(Guard).to receive(:scope=) - allow(Guard).to receive(:setup_interactor) - allow(Pry.output).to receive(:puts).and_return(true) - stub_const 'Guard::Bar', Class.new(Guard::Plugin) - - # happens during interactor _cleanup - allow(Guard::Sheller).to receive(:run).with(*%w(hash stty)).and_return(nil) + allow(Guard::Interactor).to receive(:convert_scope) do |*args| + fail "Interactor#convert_scope stub called with: #{args.inspect}" + end + + allow(Guard::Interactor).to receive(:convert_scope).with(given_scope). + and_return(converted_scope) end - describe '#perform' do - context 'without scope' do - it 'does not call :scope=' do - expect(Guard).to_not receive(:scope=) - expect(STDOUT).to receive(:print).with "Usage: scope \n" - Pry.run_command 'scope' - sleep 0.01 # sleep until setuper thread kills Pry to avoid _cleanup - end - end + context 'without scope' do + let(:given_scope) { [] } + let(:converted_scope) { [{ groups: [], plugins: [] }, []] } - context 'with a valid Guard group scope' do - it 'runs the :scope= action with the given scope' do - expect(Guard).to receive(:scope=).with(groups: [foo_group], plugins: []) - Pry.run_command 'scope foo' - sleep 0.01 # sleep until setuper thread kills Pry to avoid _cleanup - end + it 'does not call :scope= and shows usage' do + expect(STDOUT).to receive(:print).with("Usage: scope \n") + expect(Guard).to_not receive(:scope=) + Pry.run_command 'scope' end + end + + context 'with a valid Guard group scope' do + let(:given_scope) { ['foo'] } + let(:converted_scope) { [{ groups: [foo_group], plugins: [] }, []] } - context 'with a valid Guard plugin scope' do - it 'runs the :scope= action with the given scope' do - expect(Guard).to receive(:scope=).with(plugins: [bar_guard], groups: []) - Pry.run_command 'scope bar' - sleep 0.01 # sleep until setuper thread kills Pry to avoid _cleanup - end + it 'runs the :scope= action with the given scope' do + expect(Guard).to receive(:scope=).with(groups: [foo_group], plugins: []) + Pry.run_command 'scope foo' end + end + + context 'with a valid Guard plugin scope' do + let(:given_scope) { ['bar'] } + let(:converted_scope) { [{ groups: [], plugins: [bar_guard] }, []] } - context 'with an invalid scope' do - it 'does not run the action' do - expect(Guard).to_not receive(:scope=) - Pry.run_command 'scope baz' - sleep 0.01 # sleep until setuper thread kills Pry to avoid _cleanup - end + it 'runs the :scope= action with the given scope' do + expect(Guard).to receive(:scope=).with(plugins: [bar_guard], groups: []) + Pry.run_command 'scope bar' end end + context 'with an invalid scope' do + let(:given_scope) { ['baz'] } + let(:converted_scope) { [{ groups: [], plugins: [] }, ['baz']] } + + it 'does not change the scope and shows unknown scopes' do + expect(STDOUT).to receive(:print).with("Unknown scopes: baz\n") + expect(Guard).to_not receive(:scope=) + Pry.run_command 'scope baz' + end + end end diff --git a/spec/lib/guard/commands/show_spec.rb b/spec/lib/guard/commands/show_spec.rb index 17da5c15d..27c258137 100644 --- a/spec/lib/guard/commands/show_spec.rb +++ b/spec/lib/guard/commands/show_spec.rb @@ -1,28 +1,8 @@ require 'spec_helper' -describe 'Guard::Interactor::SHOW' do - - describe '#perform' do - let(:guard) { ::Guard.setup } - let(:dsl_describer) { double(:describer) } - - before do - allow(Guard::Notifier).to receive(:turn_on) - allow(::Guard::DslDescriber).to receive(:new) { dsl_describer } - - # happens during interactor _cleanup - allow(Guard::Sheller).to receive(:run).with(*%w(hash stty)) { nil } - end - - it 'outputs the DSL description' do - guard # call let here so it's after the notifier stub - expect(dsl_describer).to receive(:show) - Pry.run_command 'show' - - sleep 0.01 # sleep until setuper thread kills Pry to avoid _cleanup - - guard.send(:_process_queue) - end +describe Guard::Commands::Show do + it 'tells Guard to output DSL description' do + expect(::Guard).to receive(:async_queue_add).with([:guard_show]) + Pry.run_command 'show' end - end diff --git a/spec/lib/guard/deprecated_methods_spec.rb b/spec/lib/guard/deprecated_methods_spec.rb index 5b7900a33..b776d53d3 100644 --- a/spec/lib/guard/deprecated_methods_spec.rb +++ b/spec/lib/guard/deprecated_methods_spec.rb @@ -6,6 +6,12 @@ before(:all) do module TestModule extend DeprecatedMethods + + def self.plugins(_filter) + end + + def self.add_plugin(*_args) + end end end @@ -43,7 +49,7 @@ module TestModule end describe '.get_guard_class' do - let(:plugin_util) { double('Guard::PluginUtil', plugin_class: true) } + let(:plugin_util) { instance_double(Guard::PluginUtil, plugin_class: true) } before { allow(PluginUtil).to receive(:new).and_return(plugin_util) } it 'displays a deprecation warning to the user' do @@ -72,7 +78,10 @@ module TestModule end describe '.locate_guard' do - let(:plugin_util) { double('Guard::PluginUtil', plugin_location: true) } + let(:plugin_util) do + instance_double(Guard::PluginUtil, plugin_location: true) + end + before do allow(PluginUtil).to receive(:new) { plugin_util } end diff --git a/spec/lib/guard/dsl_describer_spec.rb b/spec/lib/guard/dsl_describer_spec.rb index 03c2d7289..992f2f80a 100644 --- a/spec/lib/guard/dsl_describer_spec.rb +++ b/spec/lib/guard/dsl_describer_spec.rb @@ -1,6 +1,7 @@ # encoding: utf-8 require 'spec_helper' require 'guard/plugin' +require 'guard/dsl_describer' require 'formatador' describe Guard::DslDescriber do @@ -31,6 +32,7 @@ before do allow(Guard::Notifier).to receive(:turn_on) + allow(Listen).to receive(:to).with(Dir.pwd, {}) Guard.setup stub_const 'Guard::Test', Class.new(Guard::Plugin) diff --git a/spec/lib/guard/dsl_spec.rb b/spec/lib/guard/dsl_spec.rb index 228ea3c85..3aec92ef6 100644 --- a/spec/lib/guard/dsl_spec.rb +++ b/spec/lib/guard/dsl_spec.rb @@ -6,13 +6,14 @@ let(:local_guardfile) { File.join(Dir.pwd, 'Guardfile') } let(:home_guardfile) { File.expand_path(File.join('~', '.Guardfile')) } let(:home_config) { File.expand_path(File.join('~', '.guard.rb')) } - let(:guardfile_evaluator) { double('Guard::Guardfile::Evaluator') } + let(:guardfile_evaluator) { instance_double(Guard::Guardfile::Evaluator) } + before do stub_const 'Guard::Foo', Class.new(Guard::Plugin) stub_const 'Guard::Bar', Class.new(Guard::Plugin) stub_const 'Guard::Baz', Class.new(Guard::Plugin) - allow(::Guard).to receive(:setup_interactor) allow(Guard::Notifier).to receive(:turn_on) + allow(Listen).to receive(:to).with(Dir.pwd, {}) ::Guard.setup end @@ -40,7 +41,7 @@ def self.disable_user_config describe '#ignore' do disable_user_config - let(:listener) { double } + let(:listener) { instance_double(Listen::Listener) } it 'adds ignored regexps to the listener' do allow(::Guard).to receive(:listener) { listener } @@ -54,7 +55,7 @@ def self.disable_user_config describe '#ignore!' do disable_user_config - let(:listener) { double } + let(:listener) { instance_double(Listen::Listener) } context 'when ignoring only foo* and *bar*' do let(:contents) { 'ignore! %r{^foo}, /bar/' } @@ -83,7 +84,7 @@ def self.disable_user_config describe '#filter' do disable_user_config - let(:listener) { double } + let(:listener) { instance_double(Listen::Listener) } it 'adds ignored regexps to the listener' do allow(::Guard).to receive(:listener) { listener } @@ -97,7 +98,7 @@ def self.disable_user_config describe '#filter!' do disable_user_config - let(:listener) { double } + let(:listener) { instance_double(Listen::Listener) } it 'replaces ignored regexps in the listener' do allow(::Guard).to receive(:listener) { listener } diff --git a/spec/lib/guard/guard_spec.rb b/spec/lib/guard/guard_spec.rb deleted file mode 100644 index 2b4f7b3ba..000000000 --- a/spec/lib/guard/guard_spec.rb +++ /dev/null @@ -1,31 +0,0 @@ -require 'spec_helper' -require 'guard/guard' - -describe Guard::Guard do - - describe '#initialize' do - it 'assigns the defined watchers' do - watchers = [Guard::Watcher.new('*')] - expect(Guard::Guard.new(watchers).watchers).to eq watchers - end - - it 'assigns the defined options' do - options = { a: 1, b: 2 } - expect(Guard::Guard.new([], options).options).to eq options - end - - context 'with a group in the options' do - it 'assigns the given group' do - expect(Guard::Guard.new([], group: :test).group). - to eq Guard.group(:test) - end - end - - context 'without a group in the options' do - it 'assigns a default group' do - expect(Guard::Guard.new.group).to eq Guard.group(:default) - end - end - end - -end diff --git a/spec/lib/guard/guardfile/evaluator_spec.rb b/spec/lib/guard/guardfile/evaluator_spec.rb index 3a97bed46..978df4b27 100644 --- a/spec/lib/guard/guardfile/evaluator_spec.rb +++ b/spec/lib/guard/guardfile/evaluator_spec.rb @@ -10,7 +10,9 @@ let(:rel_guardfile) { File.expand_path('../relative_path_to_Guardfile') } before do - allow(::Guard).to receive(:setup_interactor) + allow(::Guard::Interactor).to receive(:new).with(false) + allow(Listen).to receive(:to).with(Dir.pwd, {}) + allow(Guard::Notifier).to receive(:turn_on) ::Guard.setup allow(Guard::Notifier).to receive(:notify) diff --git a/spec/lib/guard/guardfile/generator_spec.rb b/spec/lib/guard/guardfile/generator_spec.rb index 3e4ec9378..7ec59ea98 100644 --- a/spec/lib/guard/guardfile/generator_spec.rb +++ b/spec/lib/guard/guardfile/generator_spec.rb @@ -2,7 +2,7 @@ describe Guard::Guardfile::Generator do - let(:plugin_util) { double('Guard::PluginUtil') } + let(:plugin_util) { instance_double(Guard::PluginUtil) } let(:guardfile_generator) { described_class.new } it 'has a valid Guardfile template' do diff --git a/spec/lib/guard/guardfile_spec.rb b/spec/lib/guard/guardfile_spec.rb index 47d54477f..82266906c 100644 --- a/spec/lib/guard/guardfile_spec.rb +++ b/spec/lib/guard/guardfile_spec.rb @@ -4,7 +4,7 @@ describe Guardfile do - let(:guardfile_generator) { double('Guard::Guardfile::Generator') } + let(:guardfile_generator) { instance_double(Guard::Guardfile::Generator) } describe '.create_guardfile' do it 'displays a deprecation warning to the user' do diff --git a/spec/lib/guard/interactor_spec.rb b/spec/lib/guard/interactor_spec.rb index caa222b25..a91bff9b2 100644 --- a/spec/lib/guard/interactor_spec.rb +++ b/spec/lib/guard/interactor_spec.rb @@ -42,6 +42,7 @@ describe '.convert_scope' do before do allow(::Guard::Notifier).to receive(:turn_on) { nil } + allow(Listen).to receive(:to).with(Dir.pwd, {}) guard = ::Guard.setup stub_const 'Guard::Foo', Class.new(Guard::Plugin) @@ -90,6 +91,8 @@ end context 'interactor enabled' do + let(:listener) { instance_double(Listen::Listener) } + before do @interactor_enabled = described_class.enabled? described_class.enabled = nil @@ -97,6 +100,7 @@ allow(Guard::Sheller).to receive(:run).with(*%w(hash stty)) { false } allow(::Guard::Notifier).to receive(:turn_on) { nil } + allow(Listen).to receive(:to).with(Dir.pwd, {}) { listener } Guard.setup ::Guard.interactor.background @@ -109,12 +113,17 @@ end describe '#foreground and #background' do + let(:pry_output) { instance_double(IO) } + before do allow(::Guard.interactor).to receive(:_block) {} + + allow(listener).to receive(:paused?).and_return(false) + end + it 'instantiate @thread as an instance of a Thread on #foreground' do ::Guard.interactor.foreground - expect(::Guard.interactor.thread).to be_a(Thread) end @@ -131,12 +140,11 @@ allow(::Guard.scope).to receive(:[]).with(:plugins).and_return([]) allow(::Guard.scope).to receive(:[]).with(:groups).and_return([]) - allow(::Guard).to receive(:listener). - and_return(double('listener', paused?: false)) + allow(listener).to receive(:paused?).and_return(false) expect(::Guard.interactor).to receive(:_clip_name).and_return('main') end - let(:pry) { double(input_array: []) } + let(:pry) { instance_double(Pry, input_array: []) } context 'Guard is not paused' do it 'displays "guard"' do @@ -147,8 +155,7 @@ context 'Guard is paused' do before do - allow(::Guard).to receive(:listener). - and_return(double('listener', paused?: true)) + allow(listener).to receive(:paused?).and_return(true) end it 'displays "pause"' do @@ -171,6 +178,7 @@ end context 'with a plugins scope' do + before do allow(::Guard.scope).to receive(:[]).with(:plugins). and_return([double(title: 'RSpec'), double(title: 'Ronn')]) diff --git a/spec/lib/guard/notifier_spec.rb b/spec/lib/guard/notifier_spec.rb index 045a893cc..52c46c2dc 100644 --- a/spec/lib/guard/notifier_spec.rb +++ b/spec/lib/guard/notifier_spec.rb @@ -32,8 +32,6 @@ end it 'turns on the defined notification module' do - expect(Guard::Notifier::GNTP).to receive(:turn_on) - Guard::Notifier.turn_on end end @@ -156,9 +154,9 @@ end it 'does not try to add each available notification silently' do - expect(Guard::Notifier).to_not receive(:auto_detect_notification) + expect(Guard::Notifier).to_not receive(:_auto_detect_notification) Guard::Notifier.turn_on - expect(Guard::Notifier).not_to be_enabled + expect(Guard::Notifier).to_not be_enabled end end end @@ -298,8 +296,8 @@ end it 'does not send any notifications to a notifier' do - expect(gntp).to_not receive(:notify) - expect(growl).to_not receive(:notify) + expect(gntp_object).to_not receive(:notify) + expect(growl_object).to_not receive(:notify) ::Guard::Notifier.notify('Hi to everyone') end diff --git a/spec/lib/guard/plugin/hooker_spec.rb b/spec/lib/guard/plugin/hooker_spec.rb index 05ec442bb..726abfd54 100644 --- a/spec/lib/guard/plugin/hooker_spec.rb +++ b/spec/lib/guard/plugin/hooker_spec.rb @@ -3,8 +3,6 @@ describe Guard::Plugin::Hooker do - let(:listener) { double('listener').as_null_object } - let(:fake_plugin) do Class.new(Guard::Plugin) do def start @@ -29,6 +27,8 @@ def run_on_modifications(_paths) let(:dummy1) { fake_plugin.new } let(:dummy2) { fake_plugin.new } + let(:listener) { instance_double(Proc, call: nil) } + before do stub_const 'Guard::Dummy', fake_plugin described_class.add_callback(listener, dummy1, :start_begin) diff --git a/spec/lib/guard/plugin_util_spec.rb b/spec/lib/guard/plugin_util_spec.rb index 4fb4187f1..cb5938de6 100644 --- a/spec/lib/guard/plugin_util_spec.rb +++ b/spec/lib/guard/plugin_util_spec.rb @@ -1,48 +1,23 @@ require 'spec_helper' require 'guard/plugin' -require 'guard/guard' - -# Needed for a test below -module Guard - class Guard - end -end describe Guard::PluginUtil do - let!(:rubygems_version_1_7_2) { Gem::Version.create('1.7.2') } let!(:rubygems_version_1_8_0) { Gem::Version.create('1.8.0') } - let(:guard_rspec_class) { double('Guard::RSpec') } - let(:guard_rspec) { double('Guard::RSpec instance') } - let(:guardfile_evaluator) { double('Guard::Guardfile::Evaluator instance') } + let(:guard_rspec_class) { class_double(Guard::RSpec) } + let(:guard_rspec) { instance_double(Guard::RSpec) } + let(:guardfile_evaluator) { instance_double(Guard::Guardfile::Evaluator) } before do - allow(Notifier).to receive(:turn_on) {} + allow(Listen).to receive(:to).with(Dir.pwd, {}) + allow(Guard::Notifier).to receive(:turn_on) {} Guard.setup end describe '.plugin_names' do context 'Rubygems < 1.8.0' do - before do - expect(Gem::Version).to receive(:create).with(Gem::VERSION) do - rubygems_version_1_7_2 - end - - expect(Gem::Version).to receive(:create).with('1.8.0') do - rubygems_version_1_8_0 - end - - gems_source_index = double - expect(Gem).to receive(:source_index) { gems_source_index } - expect(gems_source_index).to receive(:find_name).with(/^guard-/) do - [double(name: 'guard-rspec'), double(name: 'guard-rspec')] - end - end - - it 'returns the list of guard gems' do - expect(described_class.plugin_names).to eq ['rspec'] - end + it 'fails' end context 'Rubygems >= 1.8.0' do @@ -99,21 +74,6 @@ class Guard and_return(guard_rspec_class) end - context 'with a plugin inheriting from Guard::Guard (deprecated)' do - before do - expect(guard_rspec_class).to receive(:superclass) { ::Guard::Guard } - end - - it 'instantiate the plugin using the old API' do - expect(guard_rspec_class).to receive(:new). - with(['watcher'], group: 'foo') { guard_rspec } - - options = { watchers: ['watcher'], group: 'foo' } - old_plugin = plugin_util.initialize_plugin(options) - expect(old_plugin).to eq guard_rspec - end - end - context 'with a plugin inheriting from Guard::Plugin' do before do expect(guard_rspec_class).to receive(:superclass) { ::Guard::Plugin } @@ -133,28 +93,7 @@ class Guard subject { described_class.new('rspec') } context 'Rubygems < 1.8.0' do - - before do - expect(Gem::Version).to receive(:create).with(Gem::VERSION) do - rubygems_version_1_7_2 - end - - expect(Gem::Version).to receive(:create).with('1.8.0') do - rubygems_version_1_8_0 - end - end - - it 'returns the path of a Guard gem' do - gems_source_index = double - gems_found = [double(full_gem_path: 'gems/guard-rspec')] - expect(Gem).to receive(:source_index) { gems_source_index } - - expect(gems_source_index).to receive(:find_name).with('guard-rspec') do - gems_found - end - - expect(subject.plugin_location).to eq 'gems/guard-rspec' - end + it 'fails' end context 'Rubygems >= 1.8.0' do @@ -272,7 +211,7 @@ class VSpec it 'returns the Guard class' do plugin = described_class.new('inline') module Guard - class Inline < Guard + class Inline < Guard::Plugin end end diff --git a/spec/lib/guard/runner_spec.rb b/spec/lib/guard/runner_spec.rb index 89533aeef..bd25eb59c 100644 --- a/spec/lib/guard/runner_spec.rb +++ b/spec/lib/guard/runner_spec.rb @@ -4,12 +4,46 @@ describe Guard::Runner do before do - allow(Notifier).to receive(:turn_on) {} + # These are implemented, because otherwise stubbing _scoped_plugins is too + # much work + module Guard + class Foo < Guard::Plugin + def my_task; fail "#{__method__} is not stubbed"; end + + def my_hard_task; fail "#{__method__} is not stubbed"; end + + def regular_without_arg; fail "#{__method__} is not stubbed"; end + + def regular_with_arg(_arg); fail "#{__method__} is not stubbed"; end + + def failing; fail "#{__method__} is not stubbed"; end + + def run_on_modifications; fail "#{__method__} is not stubbed"; end + + def run_on_change; fail "#{__method__} is not stubbed"; end + + def run_on_additions; fail "#{__method__} is not stubbed"; end + + def run_on_removals; fail "#{__method__} is not stubbed"; end + + def run_on_deletion; fail "#{__method__} is not stubbed"; end + end + + class Bar < Guard::Plugin + def my_task; fail "#{__method__} is not stubbed"; end + + def my_hard_task; fail "#{__method__} is not stubbed"; end + end + + class Baz < Guard::Plugin + def my_task; fail "#{__method__} is not stubbed"; end + end + end + + allow(Guard::Notifier).to receive(:turn_on) {} + allow(Listen).to receive(:to).with(Dir.pwd, {}) guard = ::Guard.setup - stub_const 'Guard::Foo', Class.new(Guard::Plugin) - stub_const 'Guard::Bar', Class.new(Guard::Plugin) - stub_const 'Guard::Baz', Class.new(Guard::Plugin) @backend_group = guard.add_group(:backend) @frontend_group = guard.add_group(:frontend) @@ -23,6 +57,13 @@ allow(@foo_guard).to receive(:my_hard_task) allow(@bar_guard).to receive(:my_hard_task) + + end + + after do + Guard.module_eval do + %w(Foo Bar Baz).each { |klass| remove_const(klass) } + end end describe '#run' do @@ -372,30 +413,24 @@ expect(result).to be_truthy end - it 'passes the args to the :begin hook' do + it 'calls :begin and :end hooks' do expect(@foo_guard).to receive(:hook). - with('regular_without_arg_begin', 'given_path') + with('regular_without_arg_begin') expect(@foo_guard).to receive(:hook). with('regular_without_arg_end', true) - subject.run_supervised_task( - @foo_guard, - :regular_without_arg, - 'given_path') + subject.run_supervised_task(@foo_guard, :regular_without_arg) end it 'passes the result of the supervised method to the :end hook' do expect(@foo_guard).to receive(:hook). - with('regular_without_arg_begin', 'given_path') + with('regular_without_arg_begin') expect(@foo_guard).to receive(:hook). with('regular_without_arg_end', true) - subject.run_supervised_task( - @foo_guard, - :regular_without_arg, - 'given_path') + subject.run_supervised_task(@foo_guard, :regular_without_arg) end end @@ -489,7 +524,7 @@ end describe '.stopping_symbol_for' do - let(:guard_plugin) { double(Guard::Plugin).as_null_object } + let(:guard_plugin) { instance_double(Guard::Plugin).as_null_object } context 'for a group with :halt_on_fail' do before do diff --git a/spec/lib/guard/setuper_spec.rb b/spec/lib/guard/setuper_spec.rb index b5a87e916..6d60d6f64 100644 --- a/spec/lib/guard/setuper_spec.rb +++ b/spec/lib/guard/setuper_spec.rb @@ -3,7 +3,7 @@ describe Guard::Setuper do - let(:guardfile_evaluator) { double('Guard::Guardfile::Evaluator instance') } + let(:guardfile_evaluator) { instance_double(Guard::Guardfile::Evaluator) } before do Guard::Interactor.enabled = true @@ -11,6 +11,8 @@ end describe '.setup' do + subject { Guard.setup(options) } + let(:options) do { my_opts: true, @@ -18,13 +20,13 @@ } end + let(:listener) { instance_double(Listen::Listener) } + before do + allow(Listen).to receive(:to).with(Dir.pwd, {}) { listener } allow(Guard::Notifier).to receive(:turn_on) end - subject { Guard.setup(options) } - after { Guard.remove_instance_variable '@watchdirs' } - it 'returns itself for chaining' do expect(subject).to be Guard end @@ -47,22 +49,31 @@ end it 'initializes the listener' do - expect(subject.listener).to be_kind_of(Listen::Listener) + expect(subject.listener).to be(listener) end it 'respect the watchdir option' do - Guard.setup(watchdir: '/usr') + if Guard::WINDOWS + expect(Listen).to receive(:to). + with('C:/usr', {}) { listener } + else + expect(Listen).to receive(:to). + with('/usr', {}) { listener } + end - path = Pathname.new(Guard::WINDOWS ? 'C:/usr' : '/usr') - expect(Guard.listener.directories).to eq [path] + Guard.setup(watchdir: '/usr') end it 'respect the watchdir option with multiple directories' do - ::Guard.setup(watchdir: ['/usr', '/bin']) + if Guard::WINDOWS + expect(Listen).to receive(:to). + with('C:/usr', 'C:/bin', {}) { listener } + else + expect(Listen).to receive(:to). + with('/usr', '/bin', {}) { listener } + end - expect(::Guard.listener.directories).to eq [ - Pathname.new(Guard::WINDOWS ? 'C:/usr' : '/usr'), - Pathname.new(Guard::WINDOWS ? 'C:/bin' : '/bin')] + ::Guard.setup(watchdir: ['/usr', '/bin']) end it 'call setup_signal_traps' do @@ -118,7 +129,7 @@ { plugin: %w(cucumber jasmine), guardfile_contents: 'guard :jasmine do; end; '\ - 'guard :cucumber do; end; guard :coffeescript do; end' + 'guard :cucumber do; end; guard :coffeescript do; end' } end @@ -164,8 +175,11 @@ describe '.reset_groups' do subject do + allow(Listen).to receive(:to).with(Dir.pwd, {}) allow(Guard::Notifier).to receive(:turn_on) + guard = Guard.setup(guardfile: File.join(@fixture_path, 'Guardfile')) + @group_backend = guard.add_group(:backend) @group_backflip = guard.add_group(:backflip) guard @@ -182,7 +196,9 @@ describe '.reset_plugins' do before do + allow(Listen).to receive(:to).with(Dir.pwd, {}) allow(Guard::Notifier).to receive(:turn_on) + Guard.setup module Guard class FooBar < Guard::Plugin; end @@ -219,6 +235,7 @@ class FooBar < Guard::Plugin; end describe '._setup_signal_traps', speed: 'slow' do before do allow(::Guard).to receive(:evaluate_guardfile) + allow(Listen).to receive(:to).with(Dir.pwd, {}) allow(Guard::Notifier).to receive(:turn_on) ::Guard.setup end @@ -246,7 +263,11 @@ class FooBar < Guard::Plugin; end context 'when receiving SIGINT' do context 'with an interactor' do - let(:interactor) { double('interactor', thread: double('thread')) } + let(:interactor) do + instance_double( + Guard::Interactor, + thread: instance_double(Thread)) + end before { allow(Guard).to receive(:interactor) { interactor } } it 'delegates to the Pry thread' do @@ -267,6 +288,7 @@ class FooBar < Guard::Plugin; end it 'turns on the notifier on' do expect(::Guard::Notifier).to receive(:turn_on) + allow(Listen).to receive(:to).with(Dir.pwd, {}) ::Guard.setup(notify: true) end end @@ -277,6 +299,7 @@ class FooBar < Guard::Plugin; end it 'turns on the notifier on' do expect(::Guard::Notifier).to receive(:turn_on) + allow(Listen).to receive(:to).with(Dir.pwd, {}) ::Guard.setup(notify: true) end end @@ -287,6 +310,7 @@ class FooBar < Guard::Plugin; end it 'turns on the notifier off' do expect(::Guard::Notifier).to receive(:turn_off) + allow(Listen).to receive(:to).with(Dir.pwd, {}) ::Guard.setup(notify: true) end end @@ -299,6 +323,7 @@ class FooBar < Guard::Plugin; end it 'turns on the notifier off' do expect(::Guard::Notifier).to receive(:turn_off) + allow(Listen).to receive(:to).with(Dir.pwd, {}) ::Guard.setup(notify: false) end end @@ -309,6 +334,7 @@ class FooBar < Guard::Plugin; end it 'turns on the notifier on' do expect(::Guard::Notifier).to receive(:turn_off) + allow(Listen).to receive(:to).with(Dir.pwd, {}) ::Guard.setup(notify: false) end end @@ -319,6 +345,7 @@ class FooBar < Guard::Plugin; end it 'turns on the notifier off' do expect(::Guard::Notifier).to receive(:turn_off) + allow(Listen).to receive(:to).with(Dir.pwd, {}) ::Guard.setup(notify: false) end end @@ -327,7 +354,6 @@ class FooBar < Guard::Plugin; end describe '._setup_listener' do let(:listener) { double.as_null_object } - before { Guard.instance_variable_set '@watchdirs', ['/home/user/test'] } context 'with latency option' do before do @@ -418,6 +444,7 @@ class FooBar < Guard::Plugin; end context 'with interactions enabled' do before do allow(Guard::Notifier).to receive(:turn_on) + allow(Listen).to receive(:to).with(Dir.pwd, {}) Guard.setup(no_interactions: false) end @@ -427,6 +454,7 @@ class FooBar < Guard::Plugin; end context 'with interactions disabled' do before do allow(Guard::Notifier).to receive(:turn_on) + allow(Listen).to receive(:to).with(Dir.pwd, {}) Guard.setup(no_interactions: true) end @@ -442,6 +470,7 @@ class FooBar < Guard::Plugin; end before do Guard::Interactor.enabled = true allow(Guard::Notifier).to receive(:turn_on) + allow(Listen).to receive(:to).with(Dir.pwd, {}) Guard.setup end @@ -452,6 +481,7 @@ class FooBar < Guard::Plugin; end before do Guard::Interactor.enabled = false allow(Guard::Notifier).to receive(:turn_on) + allow(Listen).to receive(:to).with(Dir.pwd, {}) Guard.setup end @@ -464,6 +494,7 @@ class FooBar < Guard::Plugin; end subject { Guard.setup } before do + allow(Listen).to receive(:to).with(Dir.pwd, {}) allow(Guard::Notifier).to receive(:turn_on) # Unstub global stub @@ -471,10 +502,16 @@ class FooBar < Guard::Plugin; end @original_system = Kernel.method(:system) @original_command = Kernel.method(:`) + Kernel.send(:define_method, :original_system, proc { |*_args| }) + Kernel.send(:define_method, :original_backtick, proc { |*_args| }) end after do - Kernel.send(:remove_method, :system, :`) + Kernel.send(:remove_method, :system) + Kernel.send(:remove_method, :`) + Kernel.send(:remove_method, :original_system) + Kernel.send(:remove_method, :original_backtick) + Kernel.send(:define_method, :system, @original_system.to_proc) Kernel.send(:define_method, :`, @original_command.to_proc) end diff --git a/spec/lib/guard/ui_spec.rb b/spec/lib/guard/ui_spec.rb index bf9db4baf..ae4d0e62e 100644 --- a/spec/lib/guard/ui_spec.rb +++ b/spec/lib/guard/ui_spec.rb @@ -28,7 +28,6 @@ allow(UI.logger).to receive(:info) allow(UI.logger).to receive(:warn) allow(UI.logger).to receive(:error) - allow(UI.logger).to receive(:deprecation) allow(UI.logger).to receive(:debug) allow($stderr).to receive(:print) @@ -205,7 +204,10 @@ describe '.deprecation' do context 'with the :show_deprecation option set to false (default)' do - before { Guard.setup(show_deprecations: false) } + before do + allow(Listen).to receive(:to).with(Dir.pwd, {}) + Guard.setup(show_deprecations: false) + end it 'do not log' do expect(UI.logger).to_not receive(:warn) @@ -214,7 +216,10 @@ end context 'with the :show_deprecation option set to true' do - before { Guard.setup(show_deprecations: true) } + before do + allow(Listen).to receive(:to).with(Dir.pwd, {}) + Guard.setup(show_deprecations: true) + end it 'resets the line with the :reset option' do expect(UI).to receive :reset_line @@ -324,6 +329,7 @@ context 'when the Guard clear option is enabled' do before do allow(Sheller).to receive(:run).with('clear;') + allow(Listen).to receive(:to).with(Dir.pwd, {}) Guard.setup(clear: true) end @@ -347,7 +353,10 @@ end context 'when the Guard clear option is disabled' do - before { Guard.setup(clear: false) } + before do + allow(Listen).to receive(:to).with(Dir.pwd, {}) + Guard.setup(clear: false) + end it 'does not clear the output' do expect(::Guard::Sheller).to_not receive(:run) @@ -357,11 +366,14 @@ end describe '.action_with_scopes' do - before { Guard.setup } + before do + allow(Listen).to receive(:to).with(Dir.pwd, {}) + Guard.setup + end let(:rspec) { double('Rspec', title: 'Rspec') } let(:jasmine) { double('Jasmine', title: 'Jasmine') } - let(:group) { double('Group frontend', title: 'Frontend') } + let(:group) { instance_double(Guard::Group, title: 'Frontend') } context 'with a plugins scope' do it 'shows the plugin scoped action' do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index f032362e5..60696de0e 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -20,6 +20,11 @@ c.syntax = :expect end + config.mock_with :rspec do |mocks| + mocks.verify_doubled_constant_names = true + mocks.verify_partial_doubles = true + end + config.before(:each) do |example| @fixture_path = Pathname.new(File.expand_path('../fixtures/', __FILE__)) @@ -54,7 +59,9 @@ end end - allow(Pry.output).to receive(:puts) + allow(Listen).to receive(:to) do |*args| + fail "stub for Listen.to called with: #{args.inspect}" + end ::Guard.reset_groups ::Guard.reset_plugins