Skip to content

Commit

Permalink
Introduce a new #normalize_standard_options! method
Browse files Browse the repository at this point in the history
To avoid having a weird implementation for `#notify` in
Guard::Notifier::Base!
  • Loading branch information
rymai committed Jun 13, 2013
1 parent 24d5f09 commit 8cfde67
Show file tree
Hide file tree
Showing 15 changed files with 141 additions and 90 deletions.
36 changes: 19 additions & 17 deletions lib/guard/notifiers/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,23 +54,10 @@ def self.available?(opts = {})
true
end

# This method must be overriden. Subclasses can call `super` as follow
# `type, image, title = super` to automatically get the type, the image
# and the title for the notification. Then they should actually send a
# notification.
#
# @param [String] message the notification message body
# @param [Hash] opts additional notification library options
# option opts [String] type the notification type. Either 'success', 'pending', 'failed' or 'notify'
# option opts [String] title the notification title
# option opts [String] image the path to the notification image
# This method must be implemented.
#
def notify(message, opts = {})
type = opts.delete(:type) { _notification_type(opts.fetch(:image, :success)) }.to_s
image = _image_path(opts.delete(:image) { :success })
title = opts.delete(:title) { 'Guard' }

[type, image, title]
raise NotImplementedError
end

# Returns the title of the notifier.
Expand Down Expand Up @@ -172,6 +159,21 @@ def self._supported_host?
RbConfig::CONFIG['host_os'] =~ /#{supported_hosts.join('|')}/
end

# Set or modify the `:title`, `:type` and `:image` options for a
# notification. Should be used in `#notify`.
#
# @param [Hash] opts additional notification library options
# @option opts [String] type the notification type. Either 'success',
# 'pending', 'failed' or 'notify'
# @option opts [String] title the notification title
# @option opts [String] image the path to the notification image
#
def normalize_standard_options!(opts)
opts[:title] ||= 'Guard'
opts[:type] ||= _notification_type(opts.fetch(:image, :success))
opts[:image] = _image_path(opts.delete(:image) { :success })
end

private

# Get the image path for an image symbol for the following
Expand Down Expand Up @@ -206,9 +208,9 @@ def _image_path(image)
def _notification_type(image)
case image.to_sym
when :failed, :pending, :success
image
image.to_sym
else
'notify'
:notify
end
end

Expand Down
4 changes: 2 additions & 2 deletions lib/guard/notifiers/emacs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ def self.available?(opts = {})
# (default is 0)
#
def notify(message, opts = {})
type, image, title = super
normalize_standard_options!(opts)

opts = DEFAULTS.merge(opts)
color = emacs_color(type, opts)
color = emacs_color(opts[:type], opts)
fontcolor = emacs_color(:fontcolor, opts)
elisp = <<-EOF.gsub(/\s+/, ' ').strip
(set-face-attribute 'mode-line nil
Expand Down
4 changes: 2 additions & 2 deletions lib/guard/notifiers/file_notifier.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ def self.available?(opts = {})
# @option opts [String] path the path of where to write the file
#
def notify(message, opts = {})
type, image, title = super
normalize_standard_options!(opts)

if opts[:path]
format = opts.fetch(:format, DEFAULTS[:format])

_write(opts[:path], format % [type, title, message])
_write(opts[:path], format % [opts[:type], opts[:title], message])
else
::Guard::UI.error ':file notifier requires a :path option'
end
Expand Down
13 changes: 6 additions & 7 deletions lib/guard/notifiers/gntp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,13 @@ def self.available?(opts = {})
# @option opts [Boolean] sticky make the notification sticky
#
def notify(message, opts = {})
type, image, title = super
normalize_standard_options!(opts)

opts = DEFAULTS.merge(opts).merge(
:name => type.to_s,
:title => title,
:text => message,
:icon => image
)
opts = DEFAULTS.merge(
:name => opts.delete(:type).to_s,
:text => message,
:icon => opts.delete(:image)
).merge(opts)

_client(opts).notify(opts)
end
Expand Down
9 changes: 3 additions & 6 deletions lib/guard/notifiers/growl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,10 @@ def self.available?(opts = {})
# notifications
#
def notify(message, opts = {})
type, image, title = super
normalize_standard_options!(opts)
opts.delete(:type)

opts = DEFAULTS.merge(opts).merge(
:name => 'Guard',
:title => title,
:image => image
)
opts = DEFAULTS.merge(opts).merge(:name => 'Guard')

::Growl.notify(message, opts)
end
Expand Down
11 changes: 5 additions & 6 deletions lib/guard/notifiers/growl_notify.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,14 @@ def self.available?(opts = {})
# low) to 2 (emergency)
#
def notify(message, opts = {})
type, image, title = super
normalize_standard_options!(opts)

opts = DEFAULTS.merge(opts).merge(
opts = DEFAULTS.merge(
:application_name => 'Guard',
:with_name => type.to_s,
:title => title,
:with_name => opts.delete(:type).to_s,
:description => message,
:icon => image
)
:icon => opts.delete(:image)
).merge(opts)

::GrowlNotify.send_notification(opts)
end
Expand Down
12 changes: 6 additions & 6 deletions lib/guard/notifiers/libnotify.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,14 @@ def self.available?(opts = {})
# (1.5 (s), 1000 (ms), false)
#
def notify(message, opts = {})
type, image, title = super
normalize_standard_options!(opts)

opts = DEFAULTS.merge(opts).merge(
:summary => title,
opts = DEFAULTS.merge(
:summary => opts.delete(:title),
:icon_path => opts.delete(:image),
:body => message,
:icon_path => image
)
opts[:urgency] ||= _libnotify_urgency(type)
:urgency => _libnotify_urgency(opts.delete(:type))
).merge(opts)

::Libnotify.show(opts)
end
Expand Down
10 changes: 6 additions & 4 deletions lib/guard/notifiers/notifysend.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,13 @@ def self.available?(opts = {})
# 3000)
#
def notify(message, opts = {})
type, image, title = super
normalize_standard_options!(opts)

command = "notify-send '#{title}' '#{message}'"
opts = DEFAULTS.merge(opts).merge(:i => image)
opts[:u] ||= _notifysend_urgency(type)
command = "notify-send '#{opts.delete(:title)}' '#{message}'"
opts = DEFAULTS.merge(
:i => opts.delete(:image),
:u => _notifysend_urgency(opts.delete(:type))
).merge(opts)

system(_to_command_string(command, SUPPORTED, opts))
end
Expand Down
9 changes: 4 additions & 5 deletions lib/guard/notifiers/rb_notifu.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,12 @@ def self.available?(opts = {})
# IUserNotification2 is available
#
def notify(message, opts = {})
type, image, title = super
normalize_standard_options!(opts)

opts = DEFAULTS.merge(opts).merge(
:type => _notifu_type(type),
:title => title,
opts = DEFAULTS.merge(
:type => _notifu_type(opts.delete(:type)),
:message => message
)
).merge(opts)

::Notifu.show(opts)
end
Expand Down
9 changes: 5 additions & 4 deletions lib/guard/notifiers/terminal_notifier.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,13 @@ def self.available?(opts = {})
# @option opts [String] open some url or file
#
def notify(message, opts = {})
type, image, title = super
title = opts[:title]
normalize_standard_options!(opts)

opts[:title] = title || [opts.delete(:app_name) { 'Guard' }, type.downcase.capitalize].join(' ')
opts.merge!(:type => type.to_sym, :message => message)
opts.delete(:image)
opts[:title] = title || [opts.delete(:app_name) { 'Guard' }, opts[:type].downcase.capitalize].join(' ')

::TerminalNotifier::Guard.execute(false, opts)
::TerminalNotifier::Guard.execute(false, opts.merge(:message => message))
end

# @private
Expand Down
4 changes: 2 additions & 2 deletions lib/guard/notifiers/terminal_title.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ class TerminalTitle < Base
# @option opts [String] title the notification title
#
def notify(message, opts = {})
type, _, title = super
normalize_standard_options!(opts)

first_line = message.sub(/^\n/, '').sub(/\n.*/m, '')

puts "\e]2;[#{ title }] #{ first_line }\a"
puts "\e]2;[#{ opts[:title] }] #{ first_line }\a"
end

end
Expand Down
7 changes: 4 additions & 3 deletions lib/guard/notifiers/tmux.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,16 @@ def self.available?(opts = {})
# or not
#
def notify(message, opts = {})
type, image, title = super
normalize_standard_options!(opts)
opts.delete(:image)

color_location = opts.fetch(:color_location, DEFAULTS[:color_location])
color = tmux_color(type, opts)
color = tmux_color(opts[:type], opts)

_run_client "set #{ color_location } #{ color }"

if opts.fetch(:display_message, DEFAULTS[:display_message])
display_message(type.to_s, title, message, opts)
display_message(opts.delete(:type).to_s, opts.delete(:title), message, opts)
end
end

Expand Down
88 changes: 67 additions & 21 deletions spec/guard/notifiers/base_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,41 +36,87 @@ def self.supported_hosts
end
end

describe '#notify' do
it 'returns the :success type when no :type is defined' do
described_class.new.notify('Hi to everyone')[0].should eq 'success'
end
describe '.normalize_standard_options!' do
context 'no opts given' do
let(:opts) { {} }

it 'returns the success.png image when no image is defined' do
described_class.new.notify('Hi to everyone')[1].should =~ /success.png/
end
it 'returns the Guard title image when no :title is defined' do
described_class.new.normalize_standard_options!(opts)

opts[:title].should eq 'Guard'
end

it 'returns the :success type when no :type is defined' do
described_class.new.normalize_standard_options!(opts)

opts[:type].should eq :success
end

it 'returns the Guard title image when no :title is defined' do
described_class.new.notify('Hi to everyone')[2].should eq 'Guard'
it 'returns the success.png image when no image is defined' do
described_class.new.normalize_standard_options!(opts)

opts[:image].should =~ /success.png/
end
end

it 'returns the passed :type' do
described_class.new.notify('Hi to everyone', :type => :foo)[0].should eq 'foo'
context ':title given' do
let(:opts) { { :title => 'Hi' } }

it 'returns the passed :title' do
described_class.new.normalize_standard_options!(opts)

opts[:title].should eq 'Hi'
end
end

it 'sets the "failed" type for a :failed image' do
described_class.new.notify('Hi to everyone', :image => :failed)[1].should =~ /failed.png/
context ':type given' do
let(:opts) { { :type => :foo } }

it 'returns the passed :type' do
described_class.new.normalize_standard_options!(opts)

opts[:type].should eq :foo
end
end

it 'sets the "failed" type for a :pending image' do
described_class.new.notify('Hi to everyone', :image => :pending)[1].should =~ /pending.png/
context ':image => :failed given' do
let(:opts) { { :image => :failed } }

it 'sets the "failed" type for a :failed image' do
described_class.new.normalize_standard_options!(opts)

opts[:image].should =~ /failed.png/
end
end

it 'sets the "failed" type for a :success image' do
described_class.new.notify('Hi to everyone', :image => :success)[1].should =~ /success.png/
context ':image => :pending given' do
let(:opts) { { :image => :pending } }

it 'sets the "pending" type for a :pending image' do
described_class.new.normalize_standard_options!(opts)

opts[:image].should =~ /pending.png/
end
end

it 'returns the passed custom :image' do
described_class.new.notify('Hi to everyone', :image => 'foo.png')[1].should eq 'foo.png'
context ':image => :success given' do
let(:opts) { { :image => :success } }

it 'sets the "success" type for a :success image' do
described_class.new.normalize_standard_options!(opts)

opts[:image].should =~ /success.png/
end
end

it 'returns the passed :title' do
described_class.new.notify('Hi to everyone', :title => 'Hi')[2].should eq 'Hi'
context ':image => "foo.png" given' do
let(:opts) { { :image => 'foo.png' } }

it 'sets the "success" type for a :success image' do
described_class.new.normalize_standard_options!(opts)

opts[:image].should eq 'foo.png'
end
end
end

Expand Down
2 changes: 1 addition & 1 deletion spec/guard/notifiers/notifysend_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
command.should include("-t '5'")
end

notifier.notify('Waiting for something', :type => 'pending', :title => 'Waiting', :image => '/tmp/wait.png',
notifier.notify('Waiting for something', :type => :pending, :title => 'Waiting', :image => '/tmp/wait.png',
:t => 5,
:u => :critical
)
Expand Down

0 comments on commit 8cfde67

Please sign in to comment.