rspactor 0.2.0 → 0.5.4
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/LICENSE +20 -0
- data/Rakefile +58 -0
- data/bin/rspactor +9 -6
- data/images/failed.png +0 -0
- data/images/pending.png +0 -0
- data/images/success.png +0 -0
- data/lib/cucumber_growler.rb +61 -0
- data/lib/rspactor/celerity.rb +29 -0
- data/lib/rspactor/growl.rb +14 -0
- data/lib/rspactor/inspector.rb +110 -0
- data/lib/rspactor/interactor.rb +85 -0
- data/lib/rspactor/listener.rb +88 -0
- data/lib/rspactor/runner.rb +193 -0
- data/lib/rspactor/spork.rb +25 -0
- data/lib/rspactor.rb +11 -0
- data/lib/rspec_growler.rb +24 -0
- data/spec/inspector_spec.rb +131 -0
- data/spec/listener_spec.rb +39 -0
- data/spec/runner_spec.rb +259 -0
- metadata +33 -17
- data/asset/rails_fail.png +0 -0
- data/asset/rails_ok.png +0 -0
- data/lib/inspector.rb +0 -92
- data/lib/interactor.rb +0 -63
- data/lib/listener.rb +0 -55
- data/lib/resulting.rb +0 -47
- data/lib/runner.rb +0 -81
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rspactor'
|
2
|
+
|
3
|
+
module RSpactor
|
4
|
+
class Spork
|
5
|
+
|
6
|
+
def self.start
|
7
|
+
kill_and_launch
|
8
|
+
Interactor.ticker_msg "** Launching Spork for rspec & cucumber"
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.reload
|
12
|
+
kill_and_launch
|
13
|
+
Interactor.ticker_msg "** Reloading Spork for rspec & cucumber"
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def self.kill_and_launch
|
19
|
+
system("kill $(ps aux | awk '/spork/&&!/awk/{print $2;}') >/dev/null 2>&1")
|
20
|
+
system("spork >/dev/null 2>&1 < /dev/null &")
|
21
|
+
system("spork cu >/dev/null 2>&1 < /dev/null &")
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
data/lib/rspactor.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')))
|
2
|
+
|
3
|
+
module RSpactor
|
4
|
+
autoload :Interactor, 'rspactor/interactor'
|
5
|
+
autoload :Listener, 'rspactor/listener'
|
6
|
+
autoload :Inspector, 'rspactor/inspector'
|
7
|
+
autoload :Runner, 'rspactor/runner'
|
8
|
+
autoload :Growl, 'rspactor/growl'
|
9
|
+
autoload :Spork, 'rspactor/spork'
|
10
|
+
autoload :Celerity, 'rspactor/celerity'
|
11
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec/runner/formatter/base_formatter'
|
2
|
+
require File.dirname(__FILE__) + '/rspactor/growl'
|
3
|
+
|
4
|
+
class RSpecGrowler < Spec::Runner::Formatter::BaseFormatter
|
5
|
+
include RSpactor::Growl
|
6
|
+
|
7
|
+
def dump_summary(duration, total, failures, pending)
|
8
|
+
icon = if failures > 0
|
9
|
+
'failed'
|
10
|
+
elsif pending > 0
|
11
|
+
'pending'
|
12
|
+
else
|
13
|
+
'success'
|
14
|
+
end
|
15
|
+
|
16
|
+
# image_path = File.dirname(__FILE__) + "/../images/#{icon}.png"
|
17
|
+
message = "#{total} examples, #{failures} failures"
|
18
|
+
if pending > 0
|
19
|
+
message << " (#{pending} pending)"
|
20
|
+
end
|
21
|
+
|
22
|
+
notify "Spec Results", message, icon
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'rspactor/inspector'
|
2
|
+
|
3
|
+
describe RSpactor::Inspector do
|
4
|
+
before(:all) do
|
5
|
+
options = { :view => true }
|
6
|
+
@inspector = described_class.new(mock('Runner', :dir => '/project', :options => options))
|
7
|
+
end
|
8
|
+
|
9
|
+
def translate(file)
|
10
|
+
@inspector.translate(file)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#translate" do
|
14
|
+
it "should consider all controllers when application_controller changes" do
|
15
|
+
translate('/project/app/controllers/application_controller.rb').should == ['/project/spec/controllers']
|
16
|
+
translate('/project/app/controllers/application.rb').should == ['/project/spec/controllers']
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should translate files under 'app/' directory" do
|
20
|
+
translate('/project/app/controllers/foo_controller.rb').should ==
|
21
|
+
['/project/spec/controllers/foo_controller_spec.rb']
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should translate templates" do
|
25
|
+
translate('/project/app/views/foo/bar.erb').should == ['/project/spec/views/foo/bar.erb_spec.rb']
|
26
|
+
translate('/project/app/views/foo/bar.html.haml').should ==
|
27
|
+
['/project/spec/views/foo/bar.html.haml_spec.rb', '/project/spec/views/foo/bar.html_spec.rb']
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should consider all views when application_helper changes" do
|
31
|
+
translate('/project/app/helpers/application_helper.rb').should == ['/project/spec/helpers', '/project/spec/views']
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should consider related templates when a helper changes" do
|
35
|
+
translate('/project/app/helpers/foo_helper.rb').should ==
|
36
|
+
['/project/spec/helpers/foo_helper_spec.rb', '/project/spec/views/foo']
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should translate files under deep 'lib/' directory" do
|
40
|
+
translate('/project/lib/awesum/rox.rb').should ==
|
41
|
+
['/project/spec/lib/awesum/rox_spec.rb', '/project/spec/awesum/rox_spec.rb', '/project/spec/rox_spec.rb']
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should translate files under shallow 'lib/' directory" do
|
45
|
+
translate('lib/runner.rb').should == ['/project/spec/lib/runner_spec.rb', '/project/spec/runner_spec.rb']
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should handle relative paths" do
|
49
|
+
translate('foo.rb').should == ['/project/spec/foo_spec.rb']
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should handle files without extension" do
|
53
|
+
translate('foo').should == ['/project/spec/foo_spec.rb']
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should consider all controllers, helpers and views when routes.rb changes" do
|
57
|
+
translate('config/routes.rb').should == ['/project/spec/controllers', '/project/spec/helpers', '/project/spec/views', '/project/spec/routing']
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should consider all models when config/database.yml changes" do
|
61
|
+
translate('config/database.yml').should == ['/project/spec/models']
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should consider all models when db/schema.rb changes" do
|
65
|
+
translate('db/schema.rb').should == ['/project/spec/models']
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should consider all models when spec/factories.rb changes" do
|
69
|
+
translate('spec/factories.rb').should == ['/project/spec/models']
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should consider related model when its observer changes" do
|
73
|
+
translate('app/models/user_observer.rb').should == ['/project/spec/models/user_observer_spec.rb', '/project/spec/models/user_spec.rb']
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should consider all specs when spec_helper changes" do
|
77
|
+
translate('spec/spec_helper.rb').should == ['/project/spec']
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should consider all specs when code under spec/shared/ changes" do
|
81
|
+
translate('spec/shared/foo.rb').should == ['/project/spec']
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should consider all specs when app configuration changes" do
|
85
|
+
translate('config/environment.rb').should == ['/project/spec']
|
86
|
+
translate('config/environments/test.rb').should == ['/project/spec']
|
87
|
+
translate('config/boot.rb').should == ['/project/spec']
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should consider cucumber when a features file change" do
|
91
|
+
translate('features/login.feature').should == ['cucumber']
|
92
|
+
translate('features/steps/webrat_steps.rb').should == ['cucumber']
|
93
|
+
translate('features/support/env.rb').should == ['cucumber']
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "#determine_files" do
|
99
|
+
def determine(file)
|
100
|
+
@inspector.determine_files(file)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should filter out files that don't exist on the filesystem" do
|
104
|
+
@inspector.should_receive(:translate).with('foo').and_return(%w(valid_spec.rb invalid_spec.rb))
|
105
|
+
File.should_receive(:exists?).with('valid_spec.rb').and_return(true)
|
106
|
+
File.should_receive(:exists?).with('invalid_spec.rb').and_return(false)
|
107
|
+
determine('foo').should == ['valid_spec.rb']
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should filter out files in subdirectories that are already on the list" do
|
111
|
+
@inspector.should_receive(:translate).with('foo').and_return(%w(
|
112
|
+
spec/foo_spec.rb
|
113
|
+
spec/views/moo/bar_spec.rb
|
114
|
+
spec/views/baa/boo_spec.rb
|
115
|
+
spec/models/baz_spec.rb
|
116
|
+
spec/controllers/moo_spec.rb
|
117
|
+
spec/models
|
118
|
+
spec/controllers
|
119
|
+
spec/views/baa
|
120
|
+
))
|
121
|
+
File.stub!(:exists?).and_return(true)
|
122
|
+
determine('foo').should == %w(
|
123
|
+
spec/foo_spec.rb
|
124
|
+
spec/views/moo/bar_spec.rb
|
125
|
+
spec/models
|
126
|
+
spec/controllers
|
127
|
+
spec/views/baa
|
128
|
+
)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'rspactor/listener'
|
2
|
+
|
3
|
+
describe RSpactor::Listener do
|
4
|
+
before(:all) do
|
5
|
+
@listener = described_class.new(%w(rb erb haml))
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should be timestamped" do
|
9
|
+
@listener.last_check.should be_instance_of(Time)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should not ignore regular directories" do
|
13
|
+
@listener.ignore_path?('/project/foo/bar').should_not be
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should ignore .git directories" do
|
17
|
+
@listener.ignore_path?('/project/.git/index').should be
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should ignore dotfiles" do
|
21
|
+
@listener.ignore_file?('/project/.foo').should be
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should not ignore files in directories which start with a dot" do
|
25
|
+
@listener.ignore_file?('/project/.foo/bar.rb').should be_false
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should not ignore files without extension" do
|
29
|
+
@listener.ignore_file?('/project/foo.rb').should be_false
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should ignore files without extension" do
|
33
|
+
@listener.ignore_file?('/project/foo').should be
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should ignore files with extensions that don't match those specified" do
|
37
|
+
@listener.ignore_file?('/project/foo.bar').should be
|
38
|
+
end
|
39
|
+
end
|
data/spec/runner_spec.rb
ADDED
@@ -0,0 +1,259 @@
|
|
1
|
+
require 'rspactor/runner'
|
2
|
+
|
3
|
+
describe RSpactor::Runner do
|
4
|
+
|
5
|
+
described_class.class_eval do
|
6
|
+
def run_command(cmd)
|
7
|
+
# never shell out in tests
|
8
|
+
cmd
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def with_env(name, value)
|
13
|
+
old_value = ENV[name]
|
14
|
+
ENV[name] = value
|
15
|
+
begin
|
16
|
+
yield
|
17
|
+
ensure
|
18
|
+
ENV[name] = old_value
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def capture_stderr(io = StringIO.new)
|
23
|
+
@old_stderr, $stderr = $stderr, io
|
24
|
+
begin; yield ensure; restore_stderr; end if block_given?
|
25
|
+
end
|
26
|
+
|
27
|
+
def restore_stderr
|
28
|
+
$stderr = @old_stderr
|
29
|
+
end
|
30
|
+
|
31
|
+
def capture_stdout(io = StringIO.new)
|
32
|
+
@old_stdout, $stdout = $stdout, io
|
33
|
+
begin; yield ensure; restore_stdout; end if block_given?
|
34
|
+
end
|
35
|
+
|
36
|
+
def restore_stdout
|
37
|
+
$stdout = @old_stdout
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should use the current directory to run in' do
|
41
|
+
mock_instance = mock('RunnerInstance')
|
42
|
+
mock_instance.stub!(:start)
|
43
|
+
RSpactor::Runner.should_receive(:new).with(Dir.pwd, {}).and_return(mock_instance)
|
44
|
+
RSpactor::Runner.start
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should take an optional directory to run in' do
|
48
|
+
mock_instance = mock('RunnerInstance')
|
49
|
+
mock_instance.stub!(:start)
|
50
|
+
RSpactor::Runner.should_receive(:new).with('/tmp/mu', {}).and_return(mock_instance)
|
51
|
+
RSpactor::Runner.start(:run_in => '/tmp/mu')
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "start" do
|
55
|
+
before(:each) do
|
56
|
+
@runner = described_class.new('/my/path')
|
57
|
+
capture_stdout
|
58
|
+
end
|
59
|
+
|
60
|
+
after(:each) do
|
61
|
+
restore_stdout
|
62
|
+
end
|
63
|
+
|
64
|
+
def setup
|
65
|
+
@runner.start
|
66
|
+
end
|
67
|
+
|
68
|
+
context "Interactor" do
|
69
|
+
before(:each) do
|
70
|
+
@runner.stub!(:load_dotfile)
|
71
|
+
@runner.stub!(:start_listener)
|
72
|
+
@interactor = mock('Interactor')
|
73
|
+
@interactor.should_receive(:start_termination_handler)
|
74
|
+
RSpactor::Interactor.should_receive(:new).and_return(@interactor)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should start Interactor" do
|
78
|
+
@interactor.should_receive(:wait_for_enter_key).with(instance_of(String), 2, false)
|
79
|
+
setup
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should run all specs if Interactor isn't interrupted" do
|
83
|
+
@interactor.should_receive(:wait_for_enter_key).and_return(nil)
|
84
|
+
@runner.should_receive(:run_spec_command).with('/my/path/spec')
|
85
|
+
setup
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should skip running all specs if Interactor is interrupted" do
|
89
|
+
@interactor.should_receive(:wait_for_enter_key).and_return(true)
|
90
|
+
@runner.should_not_receive(:run_spec_command)
|
91
|
+
setup
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should initialize Inspector" do
|
96
|
+
@runner.stub!(:load_dotfile)
|
97
|
+
@runner.stub!(:start_interactor)
|
98
|
+
RSpactor::Inspector.should_receive(:new)
|
99
|
+
RSpactor::Listener.stub!(:new).and_return(mock('Listener').as_null_object)
|
100
|
+
setup
|
101
|
+
end
|
102
|
+
|
103
|
+
context "Listener" do
|
104
|
+
before(:each) do
|
105
|
+
@runner.stub!(:load_dotfile)
|
106
|
+
@runner.stub!(:start_interactor)
|
107
|
+
@inspector = mock("Inspector")
|
108
|
+
RSpactor::Inspector.stub!(:new).and_return(@inspector)
|
109
|
+
@listener = mock('Listener')
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should run Listener" do
|
113
|
+
@listener.should_receive(:run).with('/my/path')
|
114
|
+
RSpactor::Listener.should_receive(:new).with(instance_of(Array)).and_return(@listener)
|
115
|
+
setup
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should output 'watching' message on start" do
|
120
|
+
@runner.stub!(:load_dotfile)
|
121
|
+
@runner.stub!(:start_interactor)
|
122
|
+
@runner.stub!(:start_listener)
|
123
|
+
setup
|
124
|
+
$stdout.string.chomp.should == "** RSpactor, now watching at '/my/path'"
|
125
|
+
end
|
126
|
+
|
127
|
+
context "dotfile" do
|
128
|
+
before(:each) do
|
129
|
+
@runner.stub!(:start_interactor)
|
130
|
+
@runner.stub!(:start_listener)
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should load dotfile if found" do
|
134
|
+
with_env('HOME', '/home/moo') do
|
135
|
+
File.should_receive(:exists?).with('/home/moo/.rspactor').and_return(true)
|
136
|
+
Kernel.should_receive(:load).with('/home/moo/.rspactor')
|
137
|
+
setup
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should continue even if the dotfile raised errors" do
|
142
|
+
with_env('HOME', '/home/moo') do
|
143
|
+
File.should_receive(:exists?).and_return(true)
|
144
|
+
Kernel.should_receive(:load).with('/home/moo/.rspactor').and_raise(ArgumentError)
|
145
|
+
capture_stderr do
|
146
|
+
lambda { setup }.should_not raise_error
|
147
|
+
$stderr.string.split("\n").should include('Error while loading /home/moo/.rspactor: ArgumentError')
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
describe "#run_spec_command" do
|
155
|
+
before(:each) do
|
156
|
+
@runner = described_class.new('/my/path')
|
157
|
+
end
|
158
|
+
|
159
|
+
def with_rubyopt(string, &block)
|
160
|
+
with_env('RUBYOPT', string, &block)
|
161
|
+
end
|
162
|
+
|
163
|
+
def run(paths)
|
164
|
+
@runner.run_spec_command(paths)
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should exit if the paths argument is empty" do
|
168
|
+
@runner.should_not_receive(:run_command)
|
169
|
+
run([])
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should specify runner spec runner with joined paths" do
|
173
|
+
run(%w(foo bar)).should include(' spec foo bar ')
|
174
|
+
end
|
175
|
+
|
176
|
+
it "should specify default options: --color" do
|
177
|
+
run('foo').should include(' --color')
|
178
|
+
end
|
179
|
+
|
180
|
+
it "should setup RUBYOPT environment variable" do
|
181
|
+
with_rubyopt(nil) do
|
182
|
+
run('foo').should include("RUBYOPT='-Ilib:spec' ")
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
it "should concat existing RUBYOPTs" do
|
187
|
+
with_rubyopt('-rubygems -w') do
|
188
|
+
run('foo').should include("RUBYOPT='-Ilib:spec -rubygems -w' ")
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
it "should include growl formatter" do
|
193
|
+
run('foo').should include(' --format RSpecGrowler:STDOUT')
|
194
|
+
end
|
195
|
+
|
196
|
+
it "should include 'progress' formatter" do
|
197
|
+
run('foo').should include(' -f progress')
|
198
|
+
end
|
199
|
+
|
200
|
+
it "should not include 'progress' formatter if there already are 2 or more formatters" do
|
201
|
+
@runner.should_receive(:spec_formatter_opts).and_return('-f foo --format bar')
|
202
|
+
run('foo').should_not include('--format progress')
|
203
|
+
end
|
204
|
+
|
205
|
+
it "should save status of last run" do
|
206
|
+
@runner.should_receive(:run_command).twice.and_return(true, false)
|
207
|
+
run('foo')
|
208
|
+
@runner.last_run_failed?.should be_false
|
209
|
+
run('bar')
|
210
|
+
@runner.last_run_failed?.should be_true
|
211
|
+
run([])
|
212
|
+
@runner.last_run_failed?.should be_false
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
describe "#changed_files" do
|
217
|
+
before(:each) do
|
218
|
+
@runner = described_class.new('.')
|
219
|
+
@runner.stub!(:inspector).and_return(mock("Inspector"))
|
220
|
+
end
|
221
|
+
|
222
|
+
def set_inspector_expectation(file, ret)
|
223
|
+
@runner.inspector.should_receive(:determine_files).with(file).and_return(ret)
|
224
|
+
end
|
225
|
+
|
226
|
+
it "should find and run spec files" do
|
227
|
+
set_inspector_expectation('moo.rb', ['spec/moo_spec.rb'])
|
228
|
+
set_inspector_expectation('views/baz.haml', [])
|
229
|
+
set_inspector_expectation('config/bar.yml', ['spec/bar_spec.rb', 'spec/bar_stuff_spec.rb'])
|
230
|
+
|
231
|
+
expected = %w(spec/moo_spec.rb spec/bar_spec.rb spec/bar_stuff_spec.rb)
|
232
|
+
@runner.should_receive(:run_spec_command).with(expected)
|
233
|
+
|
234
|
+
capture_stdout do
|
235
|
+
@runner.stub!(:dir)
|
236
|
+
@runner.send(:changed_files, %w(moo.rb views/baz.haml config/bar.yml))
|
237
|
+
$stdout.string.split("\n").should == expected
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
it "should run the full suite after a run succeded when the previous one failed" do
|
242
|
+
@runner.inspector.stub!(:determine_files).and_return(['spec/foo_spec.rb'], ['spec/bar_spec.rb'])
|
243
|
+
@runner.stub!(:options).and_return({ :retry_failed => true })
|
244
|
+
|
245
|
+
capture_stdout do
|
246
|
+
@runner.stub!(:run_spec_command)
|
247
|
+
@runner.should_receive(:last_run_failed?).and_return(true, false)
|
248
|
+
@runner.should_receive(:run_all_specs)
|
249
|
+
@runner.send(:changed_files, %w(moo.rb))
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
it "should have Runner in global namespace for backwards compatibility" do
|
255
|
+
defined?(::Runner).should be_true
|
256
|
+
::Runner.should == described_class
|
257
|
+
end
|
258
|
+
|
259
|
+
end
|
metadata
CHANGED
@@ -1,20 +1,23 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspactor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andreas Wolff
|
8
|
+
- "Mislav Marohni\xC4\x87"
|
9
|
+
- Pelle Braendgaard
|
10
|
+
- Thibaud Guillaume-Gentil
|
8
11
|
autorequire:
|
9
12
|
bindir: bin
|
10
13
|
cert_chain: []
|
11
14
|
|
12
|
-
date:
|
13
|
-
default_executable:
|
15
|
+
date: 2009-10-10 00:00:00 +02:00
|
16
|
+
default_executable: rspactor
|
14
17
|
dependencies: []
|
15
18
|
|
16
|
-
description:
|
17
|
-
email:
|
19
|
+
description: read summary!
|
20
|
+
email: rubyphunk@gmail.com
|
18
21
|
executables:
|
19
22
|
- rspactor
|
20
23
|
extensions: []
|
@@ -22,16 +25,29 @@ extensions: []
|
|
22
25
|
extra_rdoc_files: []
|
23
26
|
|
24
27
|
files:
|
28
|
+
- Rakefile
|
25
29
|
- bin/rspactor
|
26
|
-
- lib/
|
27
|
-
- lib/
|
28
|
-
- lib/
|
29
|
-
- lib/
|
30
|
-
- lib/
|
31
|
-
-
|
32
|
-
-
|
30
|
+
- lib/cucumber_growler.rb
|
31
|
+
- lib/rspactor/celerity.rb
|
32
|
+
- lib/rspactor/growl.rb
|
33
|
+
- lib/rspactor/inspector.rb
|
34
|
+
- lib/rspactor/interactor.rb
|
35
|
+
- lib/rspactor/listener.rb
|
36
|
+
- lib/rspactor/runner.rb
|
37
|
+
- lib/rspactor/spork.rb
|
38
|
+
- lib/rspactor.rb
|
39
|
+
- lib/rspec_growler.rb
|
40
|
+
- images/failed.png
|
41
|
+
- images/pending.png
|
42
|
+
- images/success.png
|
43
|
+
- spec/inspector_spec.rb
|
44
|
+
- spec/listener_spec.rb
|
45
|
+
- spec/runner_spec.rb
|
46
|
+
- LICENSE
|
33
47
|
has_rdoc: true
|
34
|
-
homepage: http://
|
48
|
+
homepage: http://github.com/rubyphunk/rspactor
|
49
|
+
licenses: []
|
50
|
+
|
35
51
|
post_install_message:
|
36
52
|
rdoc_options: []
|
37
53
|
|
@@ -51,10 +67,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
51
67
|
version:
|
52
68
|
requirements: []
|
53
69
|
|
54
|
-
rubyforge_project:
|
55
|
-
rubygems_version: 1.
|
70
|
+
rubyforge_project:
|
71
|
+
rubygems_version: 1.3.5
|
56
72
|
signing_key:
|
57
|
-
specification_version:
|
58
|
-
summary: RSpactor is a
|
73
|
+
specification_version: 3
|
74
|
+
summary: RSpactor is a command line tool to automatically run your changed specs & cucumber features (much like autotest).
|
59
75
|
test_files: []
|
60
76
|
|
data/asset/rails_fail.png
DELETED
Binary file
|
data/asset/rails_ok.png
DELETED
Binary file
|
data/lib/inspector.rb
DELETED
@@ -1,92 +0,0 @@
|
|
1
|
-
# The inspector make some assumptions about how your project is structured and where your spec files are located.
|
2
|
-
# That said: The 'spec' directory, containing all your test files, must rest in the root directory of your project.
|
3
|
-
# Futhermore it tries to locate controller, model, helper and view specs for a rails app (or projects with an identical structure)
|
4
|
-
# in root/spec/controllers, root/spec/models, root/spec/helpers and root/spec/views.
|
5
|
-
|
6
|
-
class Inspector
|
7
|
-
|
8
|
-
attr_accessor :base_spec_root
|
9
|
-
|
10
|
-
def self.file_is_invalid?(file)
|
11
|
-
return true unless File.basename(file) =~ /.rb\z|.rhtml\z|.erb\z|.haml\z/
|
12
|
-
false
|
13
|
-
end
|
14
|
-
|
15
|
-
def find_spec_file(file)
|
16
|
-
begin
|
17
|
-
return file if file_is_a_spec?(file)
|
18
|
-
spec_root = find_base_spec_root_by_file(file)
|
19
|
-
if spec_root
|
20
|
-
guessed_spec_location = guess_spec_location(file, spec_root)
|
21
|
-
if File.exist?(guessed_spec_location)
|
22
|
-
@base_spec_root = spec_root
|
23
|
-
return guessed_spec_location
|
24
|
-
end
|
25
|
-
end
|
26
|
-
nil
|
27
|
-
rescue => e
|
28
|
-
puts "Error while parsing a file: '#{file}'"
|
29
|
-
puts e
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def inner_spec_directory(path)
|
34
|
-
spec_base_root = find_base_spec_root_by_file(Dir.pwd + "/.")
|
35
|
-
inner_location = extract_inner_project_location(Dir.pwd, spec_base_root)
|
36
|
-
File.join(spec_base_root, inner_location)
|
37
|
-
end
|
38
|
-
|
39
|
-
def find_base_spec_root_by_file(file)
|
40
|
-
if @base_spec_root
|
41
|
-
return @base_spec_root
|
42
|
-
else
|
43
|
-
dir_parts = File.dirname(file).split("/")
|
44
|
-
dir_parts.size.times do |i|
|
45
|
-
search_dir = dir_parts[0..dir_parts.length - i - 1].join("/") + "/"
|
46
|
-
if Dir.entries(search_dir).include?('spec')
|
47
|
-
@assumed_spec_root = search_dir + "spec"
|
48
|
-
break
|
49
|
-
end
|
50
|
-
end
|
51
|
-
return @assumed_spec_root
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def guess_spec_location(file, spec_root)
|
56
|
-
inner_location = extract_inner_project_location(file, spec_root)
|
57
|
-
append_spec_file_extension(File.join(spec_root, inner_location))
|
58
|
-
end
|
59
|
-
|
60
|
-
def project_root(spec_root)
|
61
|
-
spec_root.split("/")[0...-1].join("/")
|
62
|
-
end
|
63
|
-
|
64
|
-
def extract_inner_project_location(file, spec_root)
|
65
|
-
location = file.sub(project_root(spec_root), "")
|
66
|
-
adapt_rails_specific_app_structure(location)
|
67
|
-
end
|
68
|
-
|
69
|
-
def adapt_rails_specific_app_structure(location)
|
70
|
-
# Removing 'app' if its a rails controller, model, helper or view
|
71
|
-
fu = location.split("/")
|
72
|
-
if fu[1] == "app" && (fu[2] == 'controllers' || fu[2] == 'helpers' || fu[2] == 'models' || fu[2] == 'views')
|
73
|
-
return "/" + fu[2..fu.length].join("/")
|
74
|
-
end
|
75
|
-
location
|
76
|
-
end
|
77
|
-
|
78
|
-
def append_spec_file_extension(spec_file)
|
79
|
-
if File.extname(spec_file) == ".rb"
|
80
|
-
return File.join(File.dirname(spec_file), File.basename(spec_file, ".rb")) + "_spec.rb"
|
81
|
-
else
|
82
|
-
return spec_file + "_spec.rb"
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
def file_is_a_spec?(file)
|
87
|
-
if file.split("/").include?('spec') && File.basename(file).match(/_spec.rb\z/)
|
88
|
-
return true
|
89
|
-
end
|
90
|
-
false
|
91
|
-
end
|
92
|
-
end
|