spectator 1.1.a4 → 1.2
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/README.md +4 -12
- data/bin/spectator +5 -50
- data/lib/spectator.rb +92 -0
- data/lib/spectator/command_line.rb +19 -0
- data/lib/spectator/control.rb +39 -0
- data/lib/spectator/specs.rb +51 -0
- data/lib/spectator/version.rb +2 -2
- data/spectator.gemspec +2 -2
- metadata +68 -104
- data/lib/rspec-rails-watchr.rb +0 -154
- data/lib/rspec-rails-watchr/version.rb +0 -7
data/README.md
CHANGED
@@ -1,14 +1,6 @@
|
|
1
1
|
# Usage
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
```ruby
|
6
|
-
require 'rspec-rails-watchr'
|
7
|
-
|
8
|
-
@specs_watchr ||= Rspec::Rails::Watchr.new(self)
|
9
|
-
```
|
10
|
-
|
11
|
-
Then launch `watchr` as usual (probably `bundle exec watchr`).
|
3
|
+
Launch `spectator` as usual (probably `bundle exec spectator`).
|
12
4
|
|
13
5
|
## Instructions
|
14
6
|
|
@@ -19,12 +11,12 @@ you get the following prompt:
|
|
19
11
|
^C (Interrupted with CTRL+C)
|
20
12
|
--- What to do now? (q=quit, a=all-specs, r=reload):
|
21
13
|
|
22
|
-
## Advanced
|
14
|
+
## Advanced (upcoming!)
|
23
15
|
|
24
16
|
If you want to override some path matching:
|
25
17
|
|
26
18
|
```ruby
|
27
|
-
|
19
|
+
spectate do
|
28
20
|
case path
|
29
21
|
when %r{lib/calibration_with_coefficients}
|
30
22
|
specs.grep(%r{models/(logarithmic|polynomial)_calibration})
|
@@ -36,4 +28,4 @@ If you want to override some path matching:
|
|
36
28
|
|
37
29
|
|
38
30
|
|
39
|
-
Copyright (c) 2011 Elia Schito, released under the MIT license
|
31
|
+
Copyright (c) 2011-2012 Elia Schito, released under the [MIT license](https://github.com/elia/spectator/blob/master/MIT-LICENSE)
|
data/bin/spectator
CHANGED
@@ -1,57 +1,12 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# coding: utf-8
|
3
3
|
|
4
|
-
require 'fssm'
|
5
|
-
require 'rspec-rails-watchr'
|
6
|
-
require 'pathname'
|
7
4
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
@rules << [regexp, block]
|
12
|
-
end
|
13
|
-
attr_reader :rules
|
14
|
-
|
15
|
-
|
16
|
-
def set_files files
|
17
|
-
files.each do |file|
|
18
|
-
changed? file
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def changed? file
|
23
|
-
@files ||= {}
|
24
|
-
return false unless File.exists? file
|
25
|
-
mtime = File.mtime(file)
|
26
|
-
changed = (@files[file] and @files[file] < mtime)
|
27
|
-
@files[file] = mtime
|
28
|
-
return changed
|
29
|
-
end
|
5
|
+
if %w[--help help -h].include? ARGV.first
|
6
|
+
echo "Spectator doesn't take any arguments, to run the whole suite hit CTRL-C, type 'a' and press ENTER."
|
7
|
+
exit
|
30
8
|
end
|
31
9
|
|
32
|
-
|
33
|
-
# fsevent = FSEvent .new
|
34
|
-
watchr = SpecWatchr.new(peepr)
|
10
|
+
require 'spectator'
|
35
11
|
|
36
|
-
|
37
|
-
end
|
38
|
-
|
39
|
-
peepr.set_files Dir[File.join(Dir.pwd, '{app,spec,lib,script}/**/*')]
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
$launcher = lambda do |_, file|
|
44
|
-
peepr.rules.each do |(regexp, action)|
|
45
|
-
regexp = Regexp.new(regexp)
|
46
|
-
if file =~ regexp
|
47
|
-
m = regexp.match(file)
|
48
|
-
action.call(m)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
FSSM.monitor(Dir.pwd, '{app,spec,lib,script}/**/*') do
|
54
|
-
update {|base, relative| $launcher[base, relative] }
|
55
|
-
create {|base, relative| $launcher[base, relative] }
|
56
|
-
delete {|base, relative| '''do nothing''' }
|
57
|
-
end
|
12
|
+
Spectator.run
|
data/lib/spectator.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'term/ansicolor'
|
4
|
+
require 'thread'
|
5
|
+
require 'fssm'
|
6
|
+
require 'set'
|
7
|
+
|
8
|
+
require 'spectator/version'
|
9
|
+
require 'spectator/command_line'
|
10
|
+
require 'spectator/specs'
|
11
|
+
require 'spectator/control'
|
12
|
+
|
13
|
+
module Spectator
|
14
|
+
class Runner
|
15
|
+
String.send :include, Term::ANSIColor
|
16
|
+
|
17
|
+
include CommandLine
|
18
|
+
include Specs
|
19
|
+
include Control
|
20
|
+
|
21
|
+
def matchers
|
22
|
+
@matchers ||= []
|
23
|
+
end
|
24
|
+
|
25
|
+
def queue
|
26
|
+
@queue ||= Queue.new
|
27
|
+
end
|
28
|
+
|
29
|
+
def watch_paths!
|
30
|
+
FSSM.monitor(Dir.pwd, '{app,spec,lib,script}/**/*') do |monitor|
|
31
|
+
monitor.update {|base, relative| puts relative; queue.push relative }
|
32
|
+
monitor.create {|base, relative| puts relative; queue.push relative }
|
33
|
+
monitor.delete {|base, relative| puts relative; '''do nothing''' }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def puts *args
|
38
|
+
print args.join("\n")+"\n"
|
39
|
+
end
|
40
|
+
|
41
|
+
def run_specs specs
|
42
|
+
rules.each do |(regexp, action)|
|
43
|
+
regexp = Regexp.new(regexp)
|
44
|
+
if file =~ regexp
|
45
|
+
m = regexp.match(file)
|
46
|
+
action.call(m)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def wait_for_changes
|
52
|
+
puts '--- Waiting for changes...'.cyan
|
53
|
+
|
54
|
+
loop do
|
55
|
+
sleep 0.1 while queue.empty?
|
56
|
+
|
57
|
+
files = []
|
58
|
+
queue.size.times do
|
59
|
+
files << queue.pop
|
60
|
+
end
|
61
|
+
|
62
|
+
specs = Set.new
|
63
|
+
files.each do |file|
|
64
|
+
specs += matchers.map do |matcher|
|
65
|
+
file_signature = $1.gsub(/\.rb$/,'') if matcher =~ file
|
66
|
+
specs_for file
|
67
|
+
end.flatten
|
68
|
+
end
|
69
|
+
|
70
|
+
rspec_files specs
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def initialize &block
|
75
|
+
yield self if block_given?
|
76
|
+
|
77
|
+
|
78
|
+
matchers << %r{^spec/(.*)_spec\.rb$}
|
79
|
+
matchers << %r{^(?:app|lib|script)/(.*)(?:\.rb|\.\w+|)$}
|
80
|
+
|
81
|
+
trap_int!
|
82
|
+
@runner = Thread.new { wait_for_changes }
|
83
|
+
watch_paths!
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
def self.run
|
90
|
+
Runner.new
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Spectator
|
2
|
+
module CommandLine
|
3
|
+
def terminal_columns
|
4
|
+
cols = `stty -a`.scan(/ (\d+) columns/).flatten.first
|
5
|
+
$?.success? ? cols.to_i : nil
|
6
|
+
end
|
7
|
+
|
8
|
+
def run cmd
|
9
|
+
puts "=== running: #{cmd} ".ljust(terminal_columns, '=').cyan
|
10
|
+
success = system cmd
|
11
|
+
puts "===".ljust(terminal_columns, '=').cyan
|
12
|
+
success
|
13
|
+
end
|
14
|
+
|
15
|
+
def clear!
|
16
|
+
system 'clear'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Spectator
|
2
|
+
module Control
|
3
|
+
def exit
|
4
|
+
@exiting = true
|
5
|
+
puts '--- Exiting...'.white
|
6
|
+
Kernel.exit
|
7
|
+
end
|
8
|
+
|
9
|
+
def abort!
|
10
|
+
puts '--- Forcing abort...'.white
|
11
|
+
Kernel.abort("\n")
|
12
|
+
end
|
13
|
+
|
14
|
+
def trap_int!
|
15
|
+
# Ctrl-C
|
16
|
+
|
17
|
+
@interrupted ||= false
|
18
|
+
|
19
|
+
Signal.trap('INT') do
|
20
|
+
puts ' (Interrupted with CTRL+C)'.red
|
21
|
+
if @interrupted
|
22
|
+
@exiting ? abort! : exit
|
23
|
+
else
|
24
|
+
@interrupted = true
|
25
|
+
print '--- What to do now? (q=quit, a=all-specs): '.yellow
|
26
|
+
case STDIN.gets.chomp.strip.downcase
|
27
|
+
when 'q'; @interrupted = false; exit
|
28
|
+
when 'a'; @interrupted = false; rspec_all
|
29
|
+
else
|
30
|
+
@interrupted = false
|
31
|
+
puts '--- Bad input, ignored.'.yellow
|
32
|
+
end
|
33
|
+
puts '--- Waiting for changes...'.cyan
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Spectator
|
4
|
+
module Specs
|
5
|
+
def notify message
|
6
|
+
Thread.new do
|
7
|
+
begin
|
8
|
+
require 'notify'
|
9
|
+
Notify.notify 'RSpec Result:', message
|
10
|
+
rescue
|
11
|
+
nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def rspec_command
|
17
|
+
@rspec_command ||= File.exist?('./.rspec') ? 'rspec' : 'spec'
|
18
|
+
end
|
19
|
+
|
20
|
+
def rspec options
|
21
|
+
unless options.empty?
|
22
|
+
success = run("bundle exec #{rspec_command} #{options}")
|
23
|
+
notify( success ? '♥♥ SUCCESS :) ♥♥' : '♠♠ FAILED >:( ♠♠' )
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def rspec_all
|
28
|
+
rspec 'spec'
|
29
|
+
end
|
30
|
+
|
31
|
+
def rspec_files *files
|
32
|
+
rspec files.join(' ')
|
33
|
+
end
|
34
|
+
|
35
|
+
def specs_for(path)
|
36
|
+
print "--- Searching specs for #{path.inspect}...".yellow
|
37
|
+
specs = match_specs path, Dir['spec/**/*_spec.rb']
|
38
|
+
puts specs.empty? ? ' nothing found.'.red : " #{specs.size} matched.".green
|
39
|
+
specs
|
40
|
+
end
|
41
|
+
|
42
|
+
def default_rails_matcher path, specs
|
43
|
+
specs.grep(/\b#{path}((_spec)?\.rb)?$/)
|
44
|
+
end
|
45
|
+
|
46
|
+
def match_specs path, specs
|
47
|
+
matched_specs = @custom_matcher.call(path, specs) if @custom_matcher
|
48
|
+
matched_specs = default_rails_matcher(path, specs) if matched_specs.nil?
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/spectator/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module Spectator
|
2
|
-
VERSION = '1.
|
3
|
-
end
|
2
|
+
VERSION = '1.2'
|
3
|
+
end
|
data/spectator.gemspec
CHANGED
@@ -7,9 +7,9 @@ Gem::Specification.new do |s|
|
|
7
7
|
s.name = 'spectator'
|
8
8
|
s.version = Spectator::VERSION
|
9
9
|
s.authors = %w[Elia Schito]
|
10
|
-
s.email = %w[
|
10
|
+
s.email = %w[elia@schito.me]
|
11
11
|
s.homepage = ''
|
12
|
-
s.summary = %q{Watches specs for a Ruby
|
12
|
+
s.summary = %q{Watches specs for a Ruby or Rails project}
|
13
13
|
s.description = %q{Watches specs for a Ruby (1.8 or 1.9) or Rails (2 or 3) project}
|
14
14
|
s.license = 'MIT'
|
15
15
|
|
metadata
CHANGED
@@ -1,151 +1,115 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: spectator
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 1
|
8
|
-
- 1
|
9
|
-
- a
|
10
|
-
- 4
|
11
|
-
version: 1.1.a4
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '1.2'
|
5
|
+
prerelease:
|
12
6
|
platform: ruby
|
13
|
-
authors:
|
7
|
+
authors:
|
14
8
|
- Elia
|
15
9
|
- Schito
|
16
10
|
autorequire:
|
17
11
|
bindir: bin
|
18
12
|
cert_chain: []
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
- !ruby/object:Gem::Dependency
|
13
|
+
date: 2012-03-20 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
23
16
|
name: fssm
|
24
|
-
|
25
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
17
|
+
requirement: &70097386550760 !ruby/object:Gem::Requirement
|
26
18
|
none: false
|
27
|
-
requirements:
|
28
|
-
- -
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
|
31
|
-
segments:
|
32
|
-
- 0
|
33
|
-
version: "0"
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
34
23
|
type: :runtime
|
35
|
-
version_requirements: *id001
|
36
|
-
- !ruby/object:Gem::Dependency
|
37
|
-
name: term-ansicolor
|
38
24
|
prerelease: false
|
39
|
-
|
25
|
+
version_requirements: *70097386550760
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: term-ansicolor
|
28
|
+
requirement: &70097386550340 !ruby/object:Gem::Requirement
|
40
29
|
none: false
|
41
|
-
requirements:
|
42
|
-
- -
|
43
|
-
- !ruby/object:Gem::Version
|
44
|
-
|
45
|
-
segments:
|
46
|
-
- 0
|
47
|
-
version: "0"
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
48
34
|
type: :runtime
|
49
|
-
version_requirements: *id002
|
50
|
-
- !ruby/object:Gem::Dependency
|
51
|
-
name: notify
|
52
35
|
prerelease: false
|
53
|
-
|
36
|
+
version_requirements: *70097386550340
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: notify
|
39
|
+
requirement: &70097386549920 !ruby/object:Gem::Requirement
|
54
40
|
none: false
|
55
|
-
requirements:
|
56
|
-
- -
|
57
|
-
- !ruby/object:Gem::Version
|
58
|
-
|
59
|
-
segments:
|
60
|
-
- 0
|
61
|
-
version: "0"
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
62
45
|
type: :runtime
|
63
|
-
version_requirements: *id003
|
64
|
-
- !ruby/object:Gem::Dependency
|
65
|
-
name: rake
|
66
46
|
prerelease: false
|
67
|
-
|
47
|
+
version_requirements: *70097386549920
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: rake
|
50
|
+
requirement: &70097386549360 !ruby/object:Gem::Requirement
|
68
51
|
none: false
|
69
|
-
requirements:
|
52
|
+
requirements:
|
70
53
|
- - ~>
|
71
|
-
- !ruby/object:Gem::Version
|
72
|
-
|
73
|
-
segments:
|
74
|
-
- 0
|
75
|
-
- 9
|
76
|
-
version: "0.9"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0.9'
|
77
56
|
type: :development
|
78
|
-
version_requirements: *id004
|
79
|
-
- !ruby/object:Gem::Dependency
|
80
|
-
name: bundler
|
81
57
|
prerelease: false
|
82
|
-
|
58
|
+
version_requirements: *70097386549360
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: bundler
|
61
|
+
requirement: &70097386548840 !ruby/object:Gem::Requirement
|
83
62
|
none: false
|
84
|
-
requirements:
|
63
|
+
requirements:
|
85
64
|
- - ~>
|
86
|
-
- !ruby/object:Gem::Version
|
87
|
-
|
88
|
-
segments:
|
89
|
-
- 1
|
90
|
-
- 0
|
91
|
-
version: "1.0"
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '1.0'
|
92
67
|
type: :development
|
93
|
-
|
68
|
+
prerelease: false
|
69
|
+
version_requirements: *70097386548840
|
94
70
|
description: Watches specs for a Ruby (1.8 or 1.9) or Rails (2 or 3) project
|
95
|
-
email:
|
96
|
-
-
|
97
|
-
executables:
|
71
|
+
email:
|
72
|
+
- elia@schito.me
|
73
|
+
executables:
|
98
74
|
- spectator
|
99
75
|
extensions: []
|
100
|
-
|
101
76
|
extra_rdoc_files: []
|
102
|
-
|
103
|
-
files:
|
77
|
+
files:
|
104
78
|
- .gitignore
|
105
79
|
- Gemfile
|
106
80
|
- MIT-LICENSE
|
107
81
|
- README.md
|
108
82
|
- Rakefile
|
109
83
|
- bin/spectator
|
110
|
-
- lib/
|
111
|
-
- lib/
|
84
|
+
- lib/spectator.rb
|
85
|
+
- lib/spectator/command_line.rb
|
86
|
+
- lib/spectator/control.rb
|
87
|
+
- lib/spectator/specs.rb
|
112
88
|
- lib/spectator/version.rb
|
113
89
|
- spectator.gemspec
|
114
|
-
homepage:
|
115
|
-
licenses:
|
90
|
+
homepage: ''
|
91
|
+
licenses:
|
116
92
|
- MIT
|
117
93
|
post_install_message:
|
118
94
|
rdoc_options: []
|
119
|
-
|
120
|
-
require_paths:
|
95
|
+
require_paths:
|
121
96
|
- lib
|
122
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
123
98
|
none: false
|
124
|
-
requirements:
|
125
|
-
- -
|
126
|
-
- !ruby/object:Gem::Version
|
127
|
-
|
128
|
-
|
129
|
-
- 0
|
130
|
-
version: "0"
|
131
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ! '>='
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
104
|
none: false
|
133
|
-
requirements:
|
134
|
-
- -
|
135
|
-
- !ruby/object:Gem::Version
|
136
|
-
|
137
|
-
segments:
|
138
|
-
- 1
|
139
|
-
- 3
|
140
|
-
- 1
|
141
|
-
version: 1.3.1
|
105
|
+
requirements:
|
106
|
+
- - ! '>='
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
142
109
|
requirements: []
|
143
|
-
|
144
110
|
rubyforge_project: rspec-rails-watchr
|
145
|
-
rubygems_version: 1.8.
|
111
|
+
rubygems_version: 1.8.17
|
146
112
|
signing_key:
|
147
113
|
specification_version: 3
|
148
|
-
summary: Watches specs for a Ruby
|
114
|
+
summary: Watches specs for a Ruby or Rails project
|
149
115
|
test_files: []
|
150
|
-
|
151
|
-
has_rdoc:
|
data/lib/rspec-rails-watchr.rb
DELETED
@@ -1,154 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
require 'rspec-rails-watchr/version'
|
4
|
-
require 'term/ansicolor'
|
5
|
-
|
6
|
-
class SpecWatchr
|
7
|
-
String.send :include, Term::ANSIColor
|
8
|
-
|
9
|
-
module CommandLine
|
10
|
-
def terminal_columns
|
11
|
-
cols = `stty -a`.scan(/ (\d+) columns/).flatten.first
|
12
|
-
$?.success? ? cols.to_i : nil
|
13
|
-
end
|
14
|
-
|
15
|
-
def run cmd
|
16
|
-
puts "=== running: #{cmd} ".ljust(terminal_columns, '=').cyan
|
17
|
-
success = system cmd
|
18
|
-
puts "===".ljust(terminal_columns, '=').cyan
|
19
|
-
success
|
20
|
-
end
|
21
|
-
|
22
|
-
def clear!
|
23
|
-
system 'clear'
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
module Specs
|
28
|
-
def notify message
|
29
|
-
Thread.new do
|
30
|
-
begin
|
31
|
-
require 'notify'
|
32
|
-
Notify.notify 'RSpec Result:', message
|
33
|
-
rescue
|
34
|
-
nil
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def rspec_command
|
40
|
-
@rspec_command ||= File.exist?('./.rspec') ? 'rspec' : 'spec'
|
41
|
-
end
|
42
|
-
|
43
|
-
def rspec options
|
44
|
-
unless options.empty?
|
45
|
-
success = run("bundle exec #{rspec_command} #{options}")
|
46
|
-
notify( success ? '♥♥ SUCCESS :) ♥♥' : '♠♠ FAILED >:( ♠♠' )
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def rspec_all
|
51
|
-
rspec 'spec'
|
52
|
-
end
|
53
|
-
|
54
|
-
def rspec_files *files
|
55
|
-
rspec files.join(' ')
|
56
|
-
end
|
57
|
-
|
58
|
-
def specs_for(path)
|
59
|
-
print "--- Searching specs for #{path.inspect}...".yellow
|
60
|
-
specs = match_specs path, Dir['spec/**/*_spec.rb']
|
61
|
-
puts specs.empty? ? ' nothing found.'.red : " #{specs.size} matched.".green
|
62
|
-
specs
|
63
|
-
end
|
64
|
-
|
65
|
-
def default_rails_matcher path, specs
|
66
|
-
specs.grep(/\b#{path}((_spec)?\.rb)?$/)
|
67
|
-
end
|
68
|
-
|
69
|
-
def match_specs path, specs
|
70
|
-
matched_specs = @custom_matcher.call(path, specs) if @custom_matcher
|
71
|
-
matched_specs = default_rails_matcher(path, specs) if matched_specs.nil?
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
module Control
|
76
|
-
def exit_watchr
|
77
|
-
@exiting = true
|
78
|
-
puts '--- Exiting...'.white
|
79
|
-
exit
|
80
|
-
end
|
81
|
-
|
82
|
-
def abort_watchr!
|
83
|
-
puts '--- Forcing abort...'.white
|
84
|
-
abort("\n")
|
85
|
-
end
|
86
|
-
|
87
|
-
def reload!
|
88
|
-
# puts ARGV.join(' ')
|
89
|
-
exec('bundle exec ' << $0)
|
90
|
-
end
|
91
|
-
|
92
|
-
def reload_file_list
|
93
|
-
require 'shellwords'
|
94
|
-
system "touch #{__FILE__.shellescape}"
|
95
|
-
# puts '--- Watch\'d file list reloaded.'.green
|
96
|
-
end
|
97
|
-
|
98
|
-
def trap_int!
|
99
|
-
# Ctrl-C
|
100
|
-
|
101
|
-
@interrupted ||= false
|
102
|
-
|
103
|
-
Signal.trap('INT') {
|
104
|
-
puts ' (Interrupted with CTRL+C)'.red
|
105
|
-
if @interrupted
|
106
|
-
@exiting ? abort_watchr : exit_watchr
|
107
|
-
else
|
108
|
-
@interrupted = true
|
109
|
-
# reload_file_list
|
110
|
-
print '--- What to do now? (q=quit, a=all-specs, r=reload): '.yellow
|
111
|
-
case STDIN.gets.chomp.strip.downcase
|
112
|
-
when 'q'; @interrupted = false; exit_watchr
|
113
|
-
when 'a'; @interrupted = false; rspec_all
|
114
|
-
when 'r'; @interrupted = false; reload!
|
115
|
-
else
|
116
|
-
@interrupted = false
|
117
|
-
puts '--- Bad input, ignored.'.yellow
|
118
|
-
end
|
119
|
-
puts '--- Waiting for changes...'.cyan
|
120
|
-
end
|
121
|
-
}
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
|
126
|
-
include CommandLine
|
127
|
-
include Specs
|
128
|
-
include Control
|
129
|
-
|
130
|
-
def initialize watchr, &block
|
131
|
-
@custom_matcher = block if block_given?
|
132
|
-
@watchr = watchr
|
133
|
-
|
134
|
-
watchr.watch('^spec/(.*)_spec\.rb$') {|m| rspec_files specs_for(m[1])}
|
135
|
-
watchr.watch('^(?:app|lib|script)/(.*)(?:\.rb|\.\w+|)$') {|m| rspec_files specs_for(m[1].gsub(/\.rb$/,''))}
|
136
|
-
|
137
|
-
trap_int!
|
138
|
-
|
139
|
-
puts '--- Waiting for changes...'.cyan
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
|
144
|
-
class Object
|
145
|
-
module Rspec
|
146
|
-
module Rails
|
147
|
-
module Watchr
|
148
|
-
def self.new *args, &block
|
149
|
-
SpecWatchr.new *args, &block
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|