From 9f0b57c523dd4141d8422b1c88e22dff7a83830e Mon Sep 17 00:00:00 2001 From: Michael Kessler Date: Fri, 21 Dec 2012 23:06:47 +0100 Subject: [PATCH] Refactor Tmux options store/restore. --- lib/guard.rb | 2 +- lib/guard/notifier.rb | 1 + lib/guard/notifiers/tmux.rb | 86 ++++++++++---------- spec/guard/notifier_spec.rb | 28 ++++++- spec/guard/notifiers/tmux_spec.rb | 128 ++++++++++++++++++++++-------- spec/guard_spec.rb | 34 +++++++- 6 files changed, 197 insertions(+), 82 deletions(-) diff --git a/lib/guard.rb b/lib/guard.rb index d61668862..364035757 100644 --- a/lib/guard.rb +++ b/lib/guard.rb @@ -196,9 +196,9 @@ def stop within_preserved_state(false) do ::Guard::UI.debug 'Guard stops all plugins' runner.run(:stop) + ::Guard::Notifier.turn_off ::Guard::UI.info 'Bye bye...', :reset => true listener.stop - ::Guard::Notifier.turn_off ::Guard.running = false end end diff --git a/lib/guard/notifier.rb b/lib/guard/notifier.rb index fdcaef09c..1ac3dcf24 100644 --- a/lib/guard/notifier.rb +++ b/lib/guard/notifier.rb @@ -118,6 +118,7 @@ def turn_off notifier = get_notifier_module(notification[:name]) notifier.turn_off(notification[:options]) if notifier.respond_to?(:turn_off) end + ENV['GUARD_NOTIFY'] = 'false' end diff --git a/lib/guard/notifiers/tmux.rb b/lib/guard/notifiers/tmux.rb index 2628dd50b..65af0ec48 100644 --- a/lib/guard/notifiers/tmux.rb +++ b/lib/guard/notifiers/tmux.rb @@ -1,8 +1,6 @@ module Guard module Notifier - # Default options for Tmux - # Changes the color of the Tmux status bar and optionally # shows messages in the status bar. # @@ -18,6 +16,7 @@ module Notifier module Tmux extend self + # Default options for Tmux DEFAULTS = { :client => 'tmux', :tmux_environment => 'TMUX', @@ -62,7 +61,7 @@ def available?(silent = false) # @option options [Boolean] display_message whether to display a message or not # def notify(type, title, message, image, options = { }) - color = tmux_color type, options + color = tmux_color(type, options) color_location = options[:color_location] || DEFAULTS[:color_location] system("#{ DEFAULTS[:client] } set #{ color_location } #{ color }") @@ -123,64 +122,61 @@ def tmux_color(type, options = { }) end end - # Notfications starting, - # quiet tmux output + # Notification starting, save the current Tmux settings + # and quiet the Tmux output. # def turn_on(options = { }) - save_tmux_state - system(" #{ DEFAULTS[:client] } set quiet on") + unless @options_stored + reset_options_store + + `#{ DEFAULTS[:client] } show`.each_line do |line| + option, _, setting = line.chomp.partition(' ') + @options_store[option] = setting + end + + @options_stored = true + end + + system("#{ DEFAULTS[:client] } set quiet on") end + # Notification stopping. Restore the previous Tmux state + # if available (existing options are restored, new options + # are unset) and unquite the Tmux output. + # def turn_off(options = { }) - restore_tmux_state + if @options_stored + @options_store.each do |key, value| + if value + system("#{ DEFAULTS[:client] } set #{ key } #{ value }") + else + system("#{ DEFAULTS[:client] } set -u #{ key }") + end + end + + reset_options_store + end + + system("#{ DEFAULTS[:client] } set quiet off") end - # Saves current tmux options that will be restored when notifications are turned off. - # @tmux_state { }, nil marks options to be 'unset' - def save_tmux_state - @tmux_state = { + private + + # Reset the internal Tmux options store defaults. + # + def reset_options_store + @options_stored = false + @options_store = { 'status-left-bg' => nil, 'status-right-bg' => nil, 'status-left-fg' => nil, 'status-right-fg' => nil, 'message-bg' => nil, 'message-fg' => nil, - 'display-time' => nil, + 'display-time' => nil } - tmux_state = `#{ DEFAULTS[:client] } show` - - tmux_state.each_line do |line| - option, space, setting = line.chomp.partition(' ') - @tmux_state[option] = setting - end - @ready_to_restore = true - end - - # Restore tmux settings, if previously saved. - # If an option was saved it restores the value - # If an option did not exist it attempts to un-set it - # tmux output, back on - # - def restore_tmux_state - return unless ready_to_restore - @ready_to_restore = false - - @tmux_state.each do |key, value| - if value - system("#{ DEFAULTS[:client] } set #{ key } #{ value }") - else - system("#{ DEFAULTS[:client] } set -u #{ key }") - end - end - system("#{ DEFAULTS[:client] } set quiet off") end - def get_tmux_option option - @tmux_state[option] - end - - attr_accessor :ready_to_restore - end end end diff --git a/spec/guard/notifier_spec.rb b/spec/guard/notifier_spec.rb index 4817db923..732565682 100644 --- a/spec/guard/notifier_spec.rb +++ b/spec/guard/notifier_spec.rb @@ -17,6 +17,11 @@ Guard::Notifier.turn_on Guard::Notifier.should be_enabled end + + it 'turns on the defined notification module' do + ::Guard::Notifier::GNTP.should_receive(:turn_on) + Guard::Notifier.turn_on + end end context 'without configured notifications' do @@ -58,7 +63,6 @@ Guard::Notifier.turn_on end - it 'does enable the notifications when a library is available' do Guard::Notifier.should_receive(:add_notification) do Guard::Notifier.notifications = [{ :name => :gntp, :options => { } }] @@ -68,6 +72,15 @@ Guard::Notifier.should be_enabled end + it 'does turn on the notification module for libraries that are available' do + ::Guard::Notifier::GNTP.should_receive(:turn_on) + Guard::Notifier.should_receive(:add_notification) do + Guard::Notifier.notifications = [{ :name => :gntp, :options => { } }] + true + end.any_number_of_times + Guard::Notifier.turn_on + end + it 'does not enable the notifications when no library is available' do Guard::Notifier.should_receive(:add_notification).any_number_of_times.and_return false Guard::Notifier.turn_on @@ -94,9 +107,20 @@ before { ENV['GUARD_NOTIFY'] = 'true' } it 'disables the notifications' do - subject.turn_off + Guard::Notifier.turn_off ENV['GUARD_NOTIFY'].should == 'false' end + + context 'when turned on with available notifications' do + before do + Guard::Notifier.notifications = [{ :name => :gntp, :options => { } }] + end + + it 'turns off each notification' do + ::Guard::Notifier::GNTP.should_receive(:turn_off) + Guard::Notifier.turn_off + end + end end describe 'toggle_notification' do diff --git a/spec/guard/notifiers/tmux_spec.rb b/spec/guard/notifiers/tmux_spec.rb index 8146f980c..0c34b0e83 100644 --- a/spec/guard/notifiers/tmux_spec.rb +++ b/spec/guard/notifiers/tmux_spec.rb @@ -3,24 +3,24 @@ describe Guard::Notifier::Tmux do describe '.available?' do - context "when the TMUX environment variable is set" do + context 'when the TMUX environment variable is set' do before :each do ENV['TMUX'] = 'something' end - it "should return true" do + it 'should return true' do subject.available?.should be_true end end - context "when the TMUX environment variable is not set" do + context 'when the TMUX environment variable is not set' do before :each do ENV['TMUX'] = nil end context 'without the silent option' do it 'shows an error message when the TMUX environment variable is not set' do - ::Guard::UI.should_receive(:error).with "The :tmux notifier runs only on when Guard is executed inside of a tmux session." + ::Guard::UI.should_receive(:error).with 'The :tmux notifier runs only on when Guard is executed inside of a tmux session.' subject.available? end end @@ -35,7 +35,7 @@ describe '.notify' do it 'should set the tmux status bar color to green on success' do - subject.should_receive(:system).with "tmux set status-left-bg green" + subject.should_receive(:system).with 'tmux set status-left-bg green' subject.notify('success', 'any title', 'any message', 'any image', { }) end @@ -47,25 +47,25 @@ end it 'should set the tmux status bar color to red on failure' do - subject.should_receive(:system).with "tmux set status-left-bg red" + subject.should_receive(:system).with 'tmux set status-left-bg red' subject.notify('failed', 'any title', 'any message', 'any image', { }) end it 'should set the tmux status bar color to yellow on pending' do - subject.should_receive(:system).with "tmux set status-left-bg yellow" + subject.should_receive(:system).with 'tmux set status-left-bg yellow' subject.notify('pending', 'any title', 'any message', 'any image', { }) end it 'should set the tmux status bar color to green on notify' do - subject.should_receive(:system).with "tmux set status-left-bg green" + subject.should_receive(:system).with 'tmux set status-left-bg green' subject.notify('notify', 'any title', 'any message', 'any image', { }) end it 'should set the right tmux status bar color on success when the right status bar is passed in as an option' do - subject.should_receive(:system).with "tmux set status-right-bg green" + subject.should_receive(:system).with 'tmux set status-right-bg green' subject.notify('success', 'any title', 'any message', 'any image', { :color_location => 'status-right-bg' }) end @@ -158,46 +158,108 @@ end - describe '.save_tmux_state' do + describe '.turn_on' do before do subject.stub(:`).and_return("option1 setting1\noption2 setting2\n") + subject.stub :system => true end - it 'saves the current tmux options' do - subject.should_receive(:`).with('tmux show') - subject.save_tmux_state - subject.get_tmux_option("option1").should eq "setting1" - subject.get_tmux_option("option2").should eq "setting2" + it 'quiets the tmux output' do + subject.should_receive(:system).with 'tmux set quiet on' + subject.turn_on end - it 'sets the ready_to_restore flag to true after state is saved' do - subject.should_receive(:`).with('tmux show') - subject.save_tmux_state - subject.ready_to_restore.should be_true + context 'when off' do + before do + subject.turn_off + end + + it 'resets the options store' do + subject.should_receive(:reset_options_store) + subject.turn_on + end + + it 'saves the current tmux options' do + subject.should_receive(:`).with('tmux show') + subject.turn_on + end end + context 'when on' do + before do + subject.turn_on + end + + it 'does not reset the options store' do + subject.should_not_receive(:reset_options_store) + subject.turn_on + end + + it 'does not save the current tmux options' do + subject.should_not_receive(:`).with('tmux show') + subject.turn_on + end + end end - describe '.restore_tmux_state' do + describe '.turn_off' do before do subject.stub(:`).and_return("option1 setting1\noption2 setting2\n") subject.stub :system => true end - it 'restores the tmux options' do - subject.should_receive(:`).with('tmux show') - subject.save_tmux_state - subject.should_receive(:system).with('tmux set quiet off') - subject.should_receive(:system).with('tmux set option2 setting2') - subject.should_receive(:system).with('tmux set -u status-left-bg') - subject.should_receive(:system).with('tmux set option1 setting1') - subject.should_receive(:system).with('tmux set -u status-right-bg') - subject.should_receive(:system).with('tmux set -u status-right-fg') - subject.should_receive(:system).with('tmux set -u status-left-fg') - subject.should_receive(:system).with('tmux set -u message-fg') - subject.should_receive(:system).with('tmux set -u message-bg') - subject.restore_tmux_state + context 'when on' do + before do + subject.turn_on + end + + it 'restores the tmux options' do + subject.should_receive(:system).with('tmux set option2 setting2') + subject.should_receive(:system).with('tmux set -u status-left-bg') + subject.should_receive(:system).with('tmux set option1 setting1') + subject.should_receive(:system).with('tmux set -u status-right-bg') + subject.should_receive(:system).with('tmux set -u status-right-fg') + subject.should_receive(:system).with('tmux set -u status-left-fg') + subject.should_receive(:system).with('tmux set -u message-fg') + subject.should_receive(:system).with('tmux set -u message-bg') + subject.turn_off + end + + it 'resets the options store' do + subject.should_receive(:reset_options_store) + subject.turn_off + end + + it 'unquiets the tmux output' do + subject.should_receive(:system).with 'tmux set quiet off' + subject.turn_off + end end + context 'when off' do + before do + subject.turn_off + end + + it 'does not restore the tmux options' do + subject.should_not_receive(:system).with('tmux set -u status-left-bg') + subject.should_not_receive(:system).with('tmux set -u status-right-bg') + subject.should_not_receive(:system).with('tmux set -u status-right-fg') + subject.should_not_receive(:system).with('tmux set -u status-left-fg') + subject.should_not_receive(:system).with('tmux set -u message-fg') + subject.should_not_receive(:system).with('tmux set -u message-bg') + subject.turn_off + end + + it 'does not reset the options store' do + subject.should_not_receive(:reset_options_store) + subject.turn_off + end + + it 'unquiets the tmux output' do + subject.should_receive(:system).with 'tmux set quiet off' + subject.turn_off + end + end end end diff --git a/spec/guard_spec.rb b/spec/guard_spec.rb index 8c709a37a..b57e1b565 100644 --- a/spec/guard_spec.rb +++ b/spec/guard_spec.rb @@ -601,7 +601,6 @@ class Guard::FooBar < Guard::Guard; ::Guard.stub(:listener => mock('listener', :start => true)) ::Guard.stub(:runner => mock('runner', :run => true)) ::Guard.stub(:within_preserved_state).and_yield - ::Guard.instance_variable_set('@allow_stop', mock('turnstile', :wait => true, :signal => true)) end it "setup Guard" do @@ -630,6 +629,39 @@ class Guard::FooBar < Guard::Guard; end end + describe ".stop" do + before do + ::Guard.stub(:setup) + ::Guard.stub(:listener => mock('listener', :stop => true)) + ::Guard.stub(:runner => mock('runner', :run => true)) + ::Guard.stub(:within_preserved_state).and_yield + end + + it "turns the notifier off" do + ::Guard::Notifier.should_receive(:turn_off) + + ::Guard.stop + end + + it "tell the runner to run the :stop task" do + ::Guard.runner.should_receive(:run).with(:stop) + + ::Guard.stop + end + + it "stops the listener" do + ::Guard.listener.should_receive(:stop) + + ::Guard.stop + end + + it "sets the running state to false" do + ::Guard.running = true + ::Guard.stop + ::Guard.running.should be_false + end + end + describe ".add_guard" do before do @guard_rspec_class = double('Guard::RSpec')