spectator 1.1.a4 → 1.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,14 +1,6 @@
1
1
  # Usage
2
2
 
3
- In your specs.watchr file just add:
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
- @specs_watchr ||= Rspec::Rails::Watchr.new(self) do |path, specs|
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)
@@ -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
- class Peepr
9
- def watch regexp, &block
10
- @rules ||= []
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
- peepr = Peepr.new
33
- # fsevent = FSEvent .new
34
- watchr = SpecWatchr.new(peepr)
10
+ require 'spectator'
35
11
 
36
- def watchr.reload!
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
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Spectator
2
- VERSION = '1.1.a4'
3
- end
2
+ VERSION = '1.2'
3
+ end
@@ -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[perlelia@gmail.com]
10
+ s.email = %w[elia@schito.me]
11
11
  s.homepage = ''
12
- s.summary = %q{Watches specs for a Ruby (1.8 or 1.9) or Rails (2 or 3) project}
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
- hash: 149
5
- prerelease: 4
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
- date: 2012-02-20 00:00:00 Z
21
- dependencies:
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
- prerelease: false
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
- hash: 3
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
- requirement: &id002 !ruby/object:Gem::Requirement
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
- hash: 3
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
- requirement: &id003 !ruby/object:Gem::Requirement
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
- hash: 3
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
- requirement: &id004 !ruby/object:Gem::Requirement
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
- hash: 25
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
- requirement: &id005 !ruby/object:Gem::Requirement
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
- hash: 15
88
- segments:
89
- - 1
90
- - 0
91
- version: "1.0"
65
+ - !ruby/object:Gem::Version
66
+ version: '1.0'
92
67
  type: :development
93
- version_requirements: *id005
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
- - perlelia@gmail.com
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/rspec-rails-watchr.rb
111
- - lib/rspec-rails-watchr/version.rb
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
- hash: 3
128
- segments:
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
- hash: 25
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.11
111
+ rubygems_version: 1.8.17
146
112
  signing_key:
147
113
  specification_version: 3
148
- summary: Watches specs for a Ruby (1.8 or 1.9) or Rails (2 or 3) project
114
+ summary: Watches specs for a Ruby or Rails project
149
115
  test_files: []
150
-
151
- has_rdoc:
@@ -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
@@ -1,7 +0,0 @@
1
- module Rspec
2
- module Rails
3
- module Watchr
4
- VERSION = '1.0.2'
5
- end
6
- end
7
- end