rspec-rails-watchr-emacs 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/MIT-LICENSE +20 -0
- data/README.md +122 -0
- data/Rakefile +1 -0
- data/emacs/enotify-espectator.el +29 -0
- data/lib/rspec-rails-watchr-emacs.rb +364 -0
- data/lib/rspec-rails-watchr-emacs/version.rb +7 -0
- data/rspec-rails-watchr-emacs.gemspec +23 -0
- metadata +90 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Elia Schito
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
# ESpectator (a fork of [Spectator][spectator] that integrates with emacs)
|
2
|
+
|
3
|
+
ESpectator provides discreet notifications in the emacs modeline, via
|
4
|
+
the [Enotify][enotify] emacs notification system.
|
5
|
+
|
6
|
+
Test results are displayed in an emacs buffer, so no more switching
|
7
|
+
between emacs and the window were the test results are displayed are
|
8
|
+
necessary :-)
|
9
|
+
|
10
|
+
If you hate growl-style popups and prefer a simple indicator on the
|
11
|
+
modeline, ESpectator is for you. It's best used together with
|
12
|
+
[RSpec Org Formatter][RSpecOrgFormatter], which provides org formatted
|
13
|
+
test results that do look nice on emacs.
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
### Emacs side
|
18
|
+
|
19
|
+
You need to install [Enotify][enotify] first. Please refer to its
|
20
|
+
README for this step.
|
21
|
+
|
22
|
+
Copy the emacs/enotify-espectator.el file in a directory in your
|
23
|
+
load-path and add this line after the enotify configuration in your
|
24
|
+
.emacs:
|
25
|
+
|
26
|
+
```lisp
|
27
|
+
(require 'enotify-espectator)
|
28
|
+
```
|
29
|
+
|
30
|
+
Note that enotify uses the TCP port 5000 to listen to notification
|
31
|
+
messages. If you specified a different port, refer to the ``Advanced''
|
32
|
+
section of this document to see how to specify various ESpectator
|
33
|
+
options
|
34
|
+
|
35
|
+
### Watchr
|
36
|
+
|
37
|
+
In your specs.watchr file just add:
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
require 'rspec-rails-watchr-emacs'
|
41
|
+
@specs_watchr ||= Rspec::Rails::Watchr.new(self)
|
42
|
+
```
|
43
|
+
|
44
|
+
Then launch `watchr` as usual (probably `bundle exec watchr`). If you
|
45
|
+
are using RspecOrgFormatter, see the *Advanced* section of this
|
46
|
+
document.
|
47
|
+
|
48
|
+
### Instructions
|
49
|
+
|
50
|
+
The normal behavior is similar to `autotest --fast-start
|
51
|
+
--no-full-after-failed` but gives the user a bit more control over
|
52
|
+
execution. By hitting CTRL+C (or CMD+. on OSX) you get the following
|
53
|
+
prompt:
|
54
|
+
|
55
|
+
^C (Interrupted with CTRL+C)
|
56
|
+
--- What to do now? (q=quit, a=all-specs, r=reload):
|
57
|
+
|
58
|
+
### Advanced
|
59
|
+
|
60
|
+
ESpectator supports the following options (here reported with their
|
61
|
+
default values):
|
62
|
+
```ruby
|
63
|
+
{ :enotify_port => 5000, # TCP port for the enotify connection
|
64
|
+
:enotify_host => 'localhost', # host name for the enotify connection
|
65
|
+
:notification_message => { # Text displayed on the modeline when
|
66
|
+
:failure => "F", # there is at least 1 failing spec
|
67
|
+
:success => "S", # there are no failing or pending spec
|
68
|
+
:pending => "P" # there are no failing spec and at least 1 pending
|
69
|
+
},
|
70
|
+
:notification_face => { # Face used to display the text in the modeline
|
71
|
+
:failure => keyword(:failure),
|
72
|
+
:success => keyword(:success),
|
73
|
+
:pending => keyword(:warning)},
|
74
|
+
#
|
75
|
+
# custom_extract_summary_proc: takes the result text as argument
|
76
|
+
# and returns an hash of the form
|
77
|
+
# {:errors => #errors
|
78
|
+
# :pending => #pending
|
79
|
+
# :examples => #examples
|
80
|
+
# :status => (:success|:failure|:pending) }
|
81
|
+
:custom_extract_summary_proc => nil,
|
82
|
+
#
|
83
|
+
# index of the Rspec summary line.
|
84
|
+
# It should look like this:
|
85
|
+
# 25 examples, 2 failures, 1 pending
|
86
|
+
:error_count_line => -1,
|
87
|
+
#
|
88
|
+
# A proc that takes two arguments |path, specs|
|
89
|
+
# where path is the file that has been modified
|
90
|
+
# and specs is a vector containing all the spec
|
91
|
+
# files.
|
92
|
+
# It should return a vector containing the matching
|
93
|
+
# specs for `path'.
|
94
|
+
:custom_matcher => nil
|
95
|
+
}
|
96
|
+
```
|
97
|
+
An example of a custom matcher:
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
@specs_watchr ||= Rspec::Rails::Watchr.new(self,
|
101
|
+
:custom_matcher => lambda { |path, specs|
|
102
|
+
case path
|
103
|
+
when %r{lib/calibration_with_coefficients}
|
104
|
+
specs.grep(%r{models/(logarithmic|polynomial)_calibration})
|
105
|
+
when %r{app/models/telemetry_parameter}
|
106
|
+
specs.grep(%r{models/telemetry_parameter})
|
107
|
+
end
|
108
|
+
})
|
109
|
+
```
|
110
|
+
|
111
|
+
To use it with the [RSpec Org Formatter][RSpecOrgFormatter], the
|
112
|
+
:error_count_line option should be set to -6:
|
113
|
+
```ruby
|
114
|
+
@specs_watchr ||= Rspec::Rails::Watchr.new(self, :error_count_line => -6)
|
115
|
+
```
|
116
|
+
|
117
|
+
|
118
|
+
Copyright (c) 2012 Alessandro Piras, 2011 Elia Schito, released under the MIT license
|
119
|
+
|
120
|
+
[enotify]:https://github.com/laynor/enotify
|
121
|
+
[RSpecOrgFormatter]:https://github.com/laynor/rspec_org_formatter
|
122
|
+
[spectator]:https://github.com/elia/spectator
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
@@ -0,0 +1,29 @@
|
|
1
|
+
;;;; Espectator plugin for enotify
|
2
|
+
(require 'enotify)
|
3
|
+
|
4
|
+
(defun enotify-rspec-result-buffer-name (id)
|
5
|
+
(format "*RSpec Results: %s*" id))
|
6
|
+
|
7
|
+
(defun enotify-rspec-result-message-handler (id data)
|
8
|
+
(let ((buf (get-buffer-create (enotify-rspec-result-buffer-name id))))
|
9
|
+
(save-current-buffer
|
10
|
+
(set-buffer buf)
|
11
|
+
(erase-buffer)
|
12
|
+
(insert data)
|
13
|
+
(flet ((message (&rest args) (apply 'format args)))
|
14
|
+
(org-mode)))))
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
(defvar enotify-rspec-result-message-handler 'enotify-rspec-result-message-handler)
|
19
|
+
|
20
|
+
(defun enotify-rspec-mouse-1-handler (event)
|
21
|
+
(interactive "e")
|
22
|
+
(switch-to-buffer-other-window
|
23
|
+
(enotify-rspec-result-buffer-name
|
24
|
+
(enotify-event->slot-id event))))
|
25
|
+
|
26
|
+
(defvar enotify-rspec-mouse-1-handler 'enotify-rspec-mouse-1-handler)
|
27
|
+
|
28
|
+
(provide 'enotify-espectator)
|
29
|
+
|
@@ -0,0 +1,364 @@
|
|
1
|
+
# coding: utf-8)
|
2
|
+
|
3
|
+
require 'rspec-rails-watchr-emacs/version'
|
4
|
+
require 'term/ansicolor'
|
5
|
+
|
6
|
+
class SpecWatchr
|
7
|
+
String.send :include, Term::ANSIColor
|
8
|
+
|
9
|
+
|
10
|
+
module CommandLine
|
11
|
+
def terminal_columns
|
12
|
+
cols = `stty -a`.scan(/ (\d+) columns/).flatten.first
|
13
|
+
$?.success? ? cols.to_i : nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def run cmd
|
17
|
+
puts "=== running: #{cmd} ".ljust(terminal_columns, '=').cyan
|
18
|
+
results = `#{cmd}`
|
19
|
+
success = $?.success?
|
20
|
+
unless @custom_extract_summary_proc
|
21
|
+
puts " " + results.split("\n")[@error_count_line].strip.send(success ? :green : :red)
|
22
|
+
end
|
23
|
+
puts "===".ljust(terminal_columns, '=').cyan
|
24
|
+
# {:success => success, :results => message}
|
25
|
+
results
|
26
|
+
end
|
27
|
+
|
28
|
+
def clear!
|
29
|
+
system 'clear'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
module EmacsConnection
|
34
|
+
def alist (hash)
|
35
|
+
hash.merge(:magic_convert_to => :alist)
|
36
|
+
end
|
37
|
+
def flatten (hash)
|
38
|
+
hash.merge(:magic_convert_to => :flat)
|
39
|
+
end
|
40
|
+
def keyword (symbol)
|
41
|
+
:"#{symbol.inspect}"
|
42
|
+
end
|
43
|
+
def elispify_symbol(symbol)
|
44
|
+
symbol.to_s.gsub(/_/,'-')
|
45
|
+
end
|
46
|
+
def hash_to_esexp (hash)
|
47
|
+
h = hash.clone
|
48
|
+
h.delete(:magic_convert_to)
|
49
|
+
case hash[:magic_convert_to]
|
50
|
+
when :alist
|
51
|
+
res = h.map { |k, v| "(#{object_to_esexp k} . #{object_to_esexp v})" }
|
52
|
+
"(#{res.join(' ')})"
|
53
|
+
when :flat
|
54
|
+
res = h.map { |k, v| "#{object_to_esexp k} #{object_to_esexp v}" }
|
55
|
+
"(#{res.join(' ')})"
|
56
|
+
else
|
57
|
+
if hash.keys.reduce(true) { |base, el| base && Symbol === el }
|
58
|
+
res = h.map { |k, v| "#{object_to_esexp keyword(k)} #{object_to_esexp v}" }
|
59
|
+
"(#{res.join(' ')})"
|
60
|
+
else
|
61
|
+
h[:magic_convert_to] = :alist
|
62
|
+
hash_to_esexp h
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
def object_to_esexp (object)
|
67
|
+
case object
|
68
|
+
when String
|
69
|
+
object.inspect
|
70
|
+
when Array
|
71
|
+
res = object.map { |el| object_to_esexp(el) }
|
72
|
+
"(#{res.join(' ')})"
|
73
|
+
when Symbol
|
74
|
+
elispify_symbol(object)
|
75
|
+
when Hash
|
76
|
+
hash_to_esexp object
|
77
|
+
else
|
78
|
+
object.to_s
|
79
|
+
end
|
80
|
+
end
|
81
|
+
def esend (object)
|
82
|
+
msg = object_to_esexp object
|
83
|
+
@sock.puts("|#{msg.length}|#{msg}")
|
84
|
+
# @sock.print("|#{msg.length}|")
|
85
|
+
# sleep 2
|
86
|
+
# @sock.puts msg
|
87
|
+
end
|
88
|
+
|
89
|
+
def rspec_status(err_cnt)
|
90
|
+
if err_cnt[:errors] > 0
|
91
|
+
:failure
|
92
|
+
elsif err_cnt[:pending] > 0
|
93
|
+
:pending
|
94
|
+
else
|
95
|
+
:success
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def extract_rspec_counts(results, line)
|
100
|
+
err_line = results.split("\n")[line]
|
101
|
+
err_regex = /^(\d*)\sexamples?,\s(\d*)\s(errors?|failures?)[^\d]*((\d*)\spending)?/
|
102
|
+
_, examples, errors, _, pending = (err_line.match err_regex).to_a
|
103
|
+
summ = { :examples => examples.to_i, :errors => errors.to_i, :pending => pending.to_i }
|
104
|
+
summ.merge(:status => rspec_status(summ))
|
105
|
+
end
|
106
|
+
|
107
|
+
def extract_rspec_summary(results)
|
108
|
+
case @custom_extract_summary_proc
|
109
|
+
when Proc
|
110
|
+
@custom_extract_summary_proc.call(results)
|
111
|
+
else
|
112
|
+
begin
|
113
|
+
extract_rspec_counts(results, @error_count_line)
|
114
|
+
rescue
|
115
|
+
puts "--- Error while matching error counts.".red
|
116
|
+
print "--- Summary line number: ".yellow
|
117
|
+
@error_count_line = STDIN.gets.to_i
|
118
|
+
extract_rspec_summary results
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def format_help(summary)
|
124
|
+
h = "#{summary[:errors]} errors\n"
|
125
|
+
h << ("#{summary[:pending]} pending\n" if summary[:pending]>0).to_s
|
126
|
+
h << "\nmouse-1: switch to result buffer"
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
def eregister
|
131
|
+
esend :register => @enotify_slot_id, :handler_fn => :enotify_rspec_result_message_handler
|
132
|
+
end
|
133
|
+
|
134
|
+
|
135
|
+
|
136
|
+
def esend_results(results)
|
137
|
+
summ = extract_rspec_summary(results)
|
138
|
+
status = summ[:status]
|
139
|
+
message = { :id => @enotify_slot_id,
|
140
|
+
:notification => {
|
141
|
+
:text => @notification_message[status],
|
142
|
+
:face => @notification_face[status],
|
143
|
+
:help => format_help(summ),
|
144
|
+
:mouse_1 => :enotify_rspec_mouse_1_handler},
|
145
|
+
:data => results,
|
146
|
+
}
|
147
|
+
esend message
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
|
152
|
+
module Specs
|
153
|
+
|
154
|
+
def rspec_command
|
155
|
+
@rspec_command ||= File.exist?('./.rspec') ? 'rspec' : 'spec'
|
156
|
+
end
|
157
|
+
|
158
|
+
def rspec_send_results(results)
|
159
|
+
begin
|
160
|
+
print "--- Sending notification to #{@enotify_host}:#{@enotify_port}" \
|
161
|
+
" through #{@enotify_slot_id}... ".cyan
|
162
|
+
esend_results results
|
163
|
+
puts "Success!".green
|
164
|
+
rescue
|
165
|
+
puts "Failed!".red
|
166
|
+
init_network
|
167
|
+
rspec_send_results results
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def check_if_bundle_needed
|
172
|
+
if `bundle exec #{rspec_command} -v` == `#{rspec_command} -v`
|
173
|
+
@bundle = ""
|
174
|
+
else
|
175
|
+
@bundle = "bundle exec "
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def rspec options
|
180
|
+
unless options.empty?
|
181
|
+
results = run("#{@bundle}#{rspec_command} #{options}")
|
182
|
+
# notify( success ? '♥♥ SUCCESS :) ♥♥' : '♠♠ FAILED >:( ♠♠' )
|
183
|
+
rspec_send_results(results)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def rspec_all
|
188
|
+
rspec 'spec'
|
189
|
+
end
|
190
|
+
|
191
|
+
def rspec_files *files
|
192
|
+
rspec files.join(' ')
|
193
|
+
end
|
194
|
+
|
195
|
+
def specs_for(path)
|
196
|
+
print "--- Searching specs for #{path.inspect}...".yellow
|
197
|
+
specs = match_specs path, Dir['spec/**/*_spec.rb']
|
198
|
+
puts specs.empty? ? ' nothing found.'.red : " #{specs.size} matched.".green
|
199
|
+
specs
|
200
|
+
end
|
201
|
+
|
202
|
+
def default_rails_matcher path, specs
|
203
|
+
specs.grep(/\b#{path}((_spec)?\.rb)?$/)
|
204
|
+
end
|
205
|
+
|
206
|
+
def match_specs path, specs
|
207
|
+
matched_specs = @custom_matcher.call(path, specs) if @custom_matcher
|
208
|
+
matched_specs = default_rails_matcher(path, specs) if matched_specs.nil?
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
module Control
|
213
|
+
def exit_watchr
|
214
|
+
@exiting = true
|
215
|
+
puts '--- Exiting...'.white
|
216
|
+
exit
|
217
|
+
end
|
218
|
+
|
219
|
+
def abort_watchr!
|
220
|
+
puts '--- Forcing abort...'.white
|
221
|
+
abort("\n")
|
222
|
+
end
|
223
|
+
|
224
|
+
def reload!
|
225
|
+
# puts ARGV.join(' ')
|
226
|
+
exec('bundle exec watchr')
|
227
|
+
end
|
228
|
+
|
229
|
+
def reload_file_list
|
230
|
+
require 'shellwords'
|
231
|
+
system "touch #{__FILE__.shellescape}"
|
232
|
+
# puts '--- Watch\'d file list reloaded.'.green
|
233
|
+
end
|
234
|
+
|
235
|
+
def trap_int!
|
236
|
+
# Ctrl-C
|
237
|
+
|
238
|
+
@interrupted ||= false
|
239
|
+
|
240
|
+
Signal.trap('INT') {
|
241
|
+
puts ' (Interrupted with CTRL+C)'.red
|
242
|
+
if @interrupted
|
243
|
+
@exiting ? abort_watchr : exit_watchr
|
244
|
+
else
|
245
|
+
@interrupted = true
|
246
|
+
# reload_file_list
|
247
|
+
print '--- What to do now? (q=quit, a=all-specs, r=reload): '.yellow
|
248
|
+
case STDIN.gets.chomp.strip.downcase
|
249
|
+
when 'q'; @interrupted = false; exit_watchr
|
250
|
+
when 'a'; @interrupted = false; rspec_all
|
251
|
+
when 'r'; @interrupted = false; reload!
|
252
|
+
else
|
253
|
+
@interrupted = false
|
254
|
+
puts '--- Bad input, ignored.'.yellow
|
255
|
+
end
|
256
|
+
puts '--- Waiting for changes...'.cyan
|
257
|
+
end
|
258
|
+
}
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
|
263
|
+
|
264
|
+
include CommandLine
|
265
|
+
include Specs
|
266
|
+
include Control
|
267
|
+
include EmacsConnection
|
268
|
+
|
269
|
+
def blank_string?(string)
|
270
|
+
string =~ /\A\s*\n?\z/
|
271
|
+
end
|
272
|
+
|
273
|
+
def rescue_sock_error
|
274
|
+
print "--- Enter Enotify host [localhost:5000]: ".yellow
|
275
|
+
host_and_port = STDIN.gets.strip
|
276
|
+
if blank_string?(host_and_port)
|
277
|
+
@enotify_host, @enotify_port = ['localhost', @default_options[:enotify_port]]
|
278
|
+
else
|
279
|
+
@enotify_host, @enotify_port = host_and_port.split(/\s:\s/)
|
280
|
+
@enotify_port = @enotify_port.to_i
|
281
|
+
end
|
282
|
+
init_network
|
283
|
+
end
|
284
|
+
|
285
|
+
def init_network
|
286
|
+
begin
|
287
|
+
print "=== Connecting to emacs... ".cyan
|
288
|
+
@sock = TCPSocket.new(@enotify_host, @enotify_port)
|
289
|
+
eregister
|
290
|
+
puts "Success!".green
|
291
|
+
rescue
|
292
|
+
puts "Failed!".red
|
293
|
+
rescue_sock_error
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
def initialize watchr, options = {}
|
298
|
+
@default_options = {
|
299
|
+
:enotify_port => 5000,
|
300
|
+
:enotify_host => 'localhost',
|
301
|
+
:notification_message => {:failure => "F", :success => "S", :pending => "P"},
|
302
|
+
:notification_face => {
|
303
|
+
:failure => keyword(:failure),
|
304
|
+
:success => keyword(:success),
|
305
|
+
:pending => keyword(:warning)},
|
306
|
+
# custom_extract_summary_proc: takes the result text as argument
|
307
|
+
# and returns an hash of the form
|
308
|
+
# {:errors => #errors
|
309
|
+
# :pending => #pending
|
310
|
+
# :examples => #examples
|
311
|
+
# :status => (:success|:failure|:pending) }
|
312
|
+
:custom_extract_summary_proc => nil,
|
313
|
+
:error_count_line => -1,
|
314
|
+
|
315
|
+
# custom_matcher : takes two arguments: the path of the modified
|
316
|
+
# file (CHECK) and an array of spec files. Returns an array of
|
317
|
+
# matching spec files for the path given.
|
318
|
+
:custom_matcher => nil }
|
319
|
+
|
320
|
+
options = @default_options.merge(options)
|
321
|
+
puts "========OPTIONS=========="
|
322
|
+
puts options
|
323
|
+
puts "========================="
|
324
|
+
@enotify_host = options[:enotify_host]
|
325
|
+
@enotify_port = options[:enotify_port]
|
326
|
+
@notification_message = options[:notification_message]
|
327
|
+
@notification_face = options[:notification_face]
|
328
|
+
@custom_extract_summary_proc = options[:custom_extract_summary_proc]
|
329
|
+
@error_count_line = options[:error_count_line]
|
330
|
+
|
331
|
+
@custom_matcher = options[:custom_matcher]
|
332
|
+
|
333
|
+
yield if block_given?
|
334
|
+
@enotify_slot_id = ((File.basename Dir.pwd).split('_').map { |s| s.capitalize }).join
|
335
|
+
check_if_bundle_needed
|
336
|
+
init_network
|
337
|
+
@watchr = watchr
|
338
|
+
|
339
|
+
|
340
|
+
|
341
|
+
|
342
|
+
|
343
|
+
|
344
|
+
watchr.watch('^spec/(.*)_spec\.rb$') {|m| rspec_files specs_for(m[1])}
|
345
|
+
watchr.watch('^(?:app|lib|script)/(.*)(?:\.rb|\.\w+|)$') {|m| rspec_files specs_for(m[1].gsub(/\.rb$/,''))}
|
346
|
+
|
347
|
+
trap_int!
|
348
|
+
|
349
|
+
puts '--- Waiting for changes...'.cyan
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
|
354
|
+
class Object
|
355
|
+
module Rspec
|
356
|
+
module Rails
|
357
|
+
module Watchr
|
358
|
+
def self.new *args, &block
|
359
|
+
SpecWatchr.new *args, &block
|
360
|
+
end
|
361
|
+
end
|
362
|
+
end
|
363
|
+
end
|
364
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "rspec-rails-watchr-emacs/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'rspec-rails-watchr-emacs'
|
7
|
+
s.version = Rspec::Rails::Watchr::VERSION
|
8
|
+
s.authors = %w[Alessandro Piras]
|
9
|
+
s.email = %w[laynor@gmail.com]
|
10
|
+
s.homepage = 'https://github.com/laynor/spectator'
|
11
|
+
s.summary = %q{Watches specs for a Rails (2 or 3) project - notifications via Emacs enotify}
|
12
|
+
s.description = %q{Watches specs for a Rails (2 or 3) project - notifications via Emacs enotify. Fork of rspec-rails-watchr (spectator)}
|
13
|
+
s.license = 'MIT'
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = %w[lib]
|
19
|
+
|
20
|
+
s.add_dependency 'watchr'
|
21
|
+
s.add_dependency 'term-ansicolor'
|
22
|
+
s.add_dependency 'notify'
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rspec-rails-watchr-emacs
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Alessandro
|
9
|
+
- Piras
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2012-01-12 00:00:00.000000000Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: watchr
|
17
|
+
requirement: &76086330 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *76086330
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: term-ansicolor
|
28
|
+
requirement: &76083960 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *76083960
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: notify
|
39
|
+
requirement: &76083660 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
type: :runtime
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: *76083660
|
48
|
+
description: Watches specs for a Rails (2 or 3) project - notifications via Emacs
|
49
|
+
enotify. Fork of rspec-rails-watchr (spectator)
|
50
|
+
email:
|
51
|
+
- laynor@gmail.com
|
52
|
+
executables: []
|
53
|
+
extensions: []
|
54
|
+
extra_rdoc_files: []
|
55
|
+
files:
|
56
|
+
- .gitignore
|
57
|
+
- Gemfile
|
58
|
+
- MIT-LICENSE
|
59
|
+
- README.md
|
60
|
+
- Rakefile
|
61
|
+
- emacs/enotify-espectator.el
|
62
|
+
- lib/rspec-rails-watchr-emacs.rb
|
63
|
+
- lib/rspec-rails-watchr-emacs/version.rb
|
64
|
+
- rspec-rails-watchr-emacs.gemspec
|
65
|
+
homepage: https://github.com/laynor/spectator
|
66
|
+
licenses:
|
67
|
+
- MIT
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options: []
|
70
|
+
require_paths:
|
71
|
+
- lib
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
80
|
+
requirements:
|
81
|
+
- - ! '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
requirements: []
|
85
|
+
rubyforge_project:
|
86
|
+
rubygems_version: 1.8.5
|
87
|
+
signing_key:
|
88
|
+
specification_version: 3
|
89
|
+
summary: Watches specs for a Rails (2 or 3) project - notifications via Emacs enotify
|
90
|
+
test_files: []
|