This repository has been archived by the owner on Mar 1, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 15
/
growl.rb
executable file
·206 lines (187 loc) · 7.51 KB
/
growl.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
require 'rubygems'
require 'autotest'
require 'rbconfig'
require File.join(File.dirname(__FILE__), 'result')
##
# Autotest::Growl
#
# == FEATUERS:
# * Display autotest results as local or remote Growl notifications.
# * Clean the terminal on every test cycle while maintaining scrollback.
#
# == SYNOPSIS:
# ~/.autotest
# require 'autotest/growl'
module Autotest::Growl
GEM_PATH = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
@label = ''
@modified_files = []
@ran_tests = false
@ran_features = false
@@remote_notification = false
@@one_notification_per_run = false
@@sticky_failure_notifications = false
@@custom_options = ''
@@clear_terminal = true
@@hide_label = false
@@label_override = nil
@@show_modified_files = false
@@image_dir = File.join(GEM_PATH, 'img', 'ruby')
##
# Whether to use remote or local notificaton (default).
def self.remote_notification=(boolean)
@@remote_notification = boolean
end
##
# Whether to limit the number of notifications per run to one or not (default).
def self.one_notification_per_run=(boolean)
@@one_notification_per_run = boolean
end
##
# Whether to make failure and error notifications sticky.
def self.sticky_failure_notifications=(boolean)
@@sticky_failure_notifications = boolean
end
##
# Custom options passed to the notification binary
def self.custom_options=(options)
@@custom_options = options
end
##
# Whether to clear the terminal before running tests (default) or not.
def self.clear_terminal=(boolean)
@@clear_terminal = boolean
end
##
# Whether to display the label (default) or not.
def self.hide_label=(boolean)
@@hide_label = boolean
end
##
# Set the label to be shown.
def self.label=(string)
@@label_override = string
end
##
# Whether to display the modified files or not (default).
def self.show_modified_files=(boolean)
@@show_modified_files = boolean
end
##
# Directory where notification icons can be found
def self.image_dir=(path)
if File.directory?(File.join(GEM_PATH, 'img', path))
@@image_dir = File.join(GEM_PATH, 'img', path)
else
@@image_dir = path
end
end
##
# Display a message through Growl.
def self.growl(title, message, icon, priority=0, sticky=false)
growl = File.join(GEM_PATH, 'growl', 'growlnotify')
sender = 'Autotest'
image = File.join(@@image_dir, "#{icon}.png")
case RbConfig::CONFIG['host_os']
when /mac os|darwin/i
options = %(-n "#{sender}" --image "#{image}" -p #{priority} -m "#{message}" "#{title}" #{'-s' if sticky} #{@@custom_options})
options << " -H localhost" if @@remote_notification
system %(#{growl} #{options} &)
when /linux|bsd/i
growl = 'notify-send'
options = %("#{title}" "#{message}" -i #{image} -t 5000 #{@@custom_options})
system %(#{growl} #{options})
when /windows|mswin|mingw|cygwin/i
growl += '.com'
image = `cygpath -w #{image}` if RbConfig::CONFIG['host_os'] =~ /cygwin/i
options = %(/a:"#{sender}" /n:"#{sender}-#{icon}" /i:"#{image}" /p:#{priority} /t:"#{title}" /s:#{sticky} /silent:true)
options << %( /r:"#{sender}-failed","#{sender}-passed","#{sender}-pending","#{sender}-error","#{sender}-info")
system %(#{growl} #{message.inspect} #{options})
else
raise "#{RbConfig::CONFIG['host_os']} is not supported by autotest-growl (feel free to submit a patch)"
end
end
##
# Display the modified files.
Autotest.add_hook :updated do |autotest, modified|
@ran_tests = @ran_features = false
if @@show_modified_files
if modified != @last_modified
growl @label + 'Modifications detected.', modified.collect {|m| m[0]}.join(', '), 'info', 0
@last_modified = modified
end
end
false
end
##
# Set the label and clear the terminal.
Autotest.add_hook :run_command do
@label = (@@label_override || File.basename(Dir.pwd).upcase) + ': ' if !@@hide_label
print "\n"*2 + '-'*80 + "\n"*2
print "\e[2J\e[f" if @@clear_terminal
false
end
##
# Parse the RSpec and Test::Unit results and send them to Growl.
Autotest.add_hook :ran_command do |autotest|
unless @@one_notification_per_run && @ran_tests
result = Autotest::Result.new(autotest)
if result.exists?
case result.framework
when 'test-unit'
if result.has?('test-error')
growl @label + 'Cannot run some unit tests.', "#{result.get('test-error')} in #{result.get('test')}", 'error', 2, @@sticky_failure_notifications
elsif result.has?('test-failed')
growl @label + 'Some unit tests failed.', "#{result['test-failed']} of #{result.get('test-assertion')} in #{result.get('test')} failed", 'failed', 2, @@sticky_failure_notifications
else
growl @label + 'All unit tests passed.', "#{result.get('test-assertion')} in #{result.get('test')}", 'passed', -2
end
when 'rspec'
if result.has?('example-failed')
growl @label + 'Some RSpec examples failed.', "#{result['example-failed']} of #{result.get('example')} failed", 'failed', 2, @@sticky_failure_notifications
elsif result.has?('example-pending')
growl @label + 'Some RSpec examples are pending.', "#{result['example-pending']} of #{result.get('example')} pending", 'pending', -1
else
growl @label + 'All RSpec examples passed.', "#{result.get('example')}", 'passed', -2
end
end
else
growl @label + 'Could not run tests.', '', 'error', 2, @@sticky_failure_notifications
end
@ran_tests = true
end
false
end
##
# Parse the Cucumber results and sent them to Growl.
Autotest.add_hook :ran_features do |autotest|
unless @@one_notification_per_run && @ran_features
result = Autotest::Result.new(autotest)
if result.exists?
case result.framework
when 'cucumber'
explanation = []
if result.has?('scenario-undefined') || result.has?('step-undefined')
explanation << "#{result['scenario-undefined']} of #{result.get('scenario')} not defined" if result['scenario-undefined']
explanation << "#{result['step-undefined']} of #{result.get('step')} not defined" if result['step-undefined']
growl @label + 'Some Cucumber scenarios are not defined.', "#{explanation.join("\n")}", 'pending', -1
elsif result.has?('scenario-failed') || result.has?('step-failed')
explanation << "#{result['scenario-failed']} of #{result.get('scenario')} failed" if result['scenario-failed']
explanation << "#{result['step-failed']} of #{result.get('step')} failed" if result['step-failed']
growl @label + 'Some Cucumber scenarios failed.', "#{explanation.join("\n")}", 'failed', 2, @@sticky_failure_notifications
elsif result.has?('scenario-pending') || result.has?('step-pending')
explanation << "#{result['scenario-pending']} of #{result.get('scenario')} pending" if result['scenario-pending']
explanation << "#{result['step-pending']} of #{result.get('step')} pending" if result['step-pending']
growl @label + 'Some Cucumber scenarios are pending.', "#{explanation.join("\n")}", 'pending', -1
else
growl @label + 'All Cucumber features passed.', '', 'passed', -2
end
end
else
growl @label + 'Could not run features.', '', 'error', 2, @@sticky_failure_notifications
end
@ran_features = true
end
false
end
end