mislav-rspactor 0.3.2 → 0.3.3
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/Rakefile +44 -25
- data/bin/rspactor +1 -1
- data/lib/rspactor/inspector.rb +5 -0
- data/lib/rspactor/runner.rb +86 -31
- data/spec/inspector_spec.rb +38 -0
- data/spec/runner_spec.rb +153 -52
- metadata +2 -2
data/Rakefile
CHANGED
|
@@ -1,38 +1,57 @@
|
|
|
1
|
-
|
|
2
|
-
require 'jeweler'
|
|
3
|
-
|
|
4
|
-
Jeweler.class_eval do
|
|
5
|
-
protected
|
|
6
|
-
|
|
7
|
-
def fill_in_gemspec_defaults(gemspec)
|
|
8
|
-
if gemspec.files.nil? || gemspec.files.empty?
|
|
9
|
-
gemspec.files = FileList['Rakefile', '{bin,lib,images,spec}/**/*', 'README*', 'LICENSE*']
|
|
10
|
-
end
|
|
1
|
+
task :default => :spec
|
|
11
2
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
end
|
|
3
|
+
desc "starts RSpactor"
|
|
4
|
+
task :spec do
|
|
5
|
+
system "ruby -Ilib bin/rspactor"
|
|
6
|
+
end
|
|
17
7
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
Jeweler::Tasks.new do |gem|
|
|
8
|
+
desc "generates .gemspec file"
|
|
9
|
+
task :gemspec => "version:read" do
|
|
10
|
+
spec = Gem::Specification.new do |gem|
|
|
23
11
|
gem.name = "rspactor"
|
|
24
12
|
gem.summary = "RSpactor is a command line tool to automatically run your changed specs (much like autotest)."
|
|
25
13
|
gem.email = "mislav.marohnic@gmail.com"
|
|
26
14
|
gem.homepage = "http://github.com/mislav/rspactor"
|
|
27
15
|
gem.authors = ["Mislav Marohnić", "Andreas Wolff", "Pelle Braendgaard"]
|
|
28
16
|
gem.has_rdoc = false
|
|
17
|
+
|
|
18
|
+
gem.version = GEM_VERSION
|
|
19
|
+
gem.files = FileList['Rakefile', '{bin,lib,images,spec}/**/*', 'README*', 'LICENSE*']
|
|
20
|
+
gem.executables = Dir['bin/*'].map { |f| File.basename(f) }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
spec_string = spec.to_ruby
|
|
24
|
+
|
|
25
|
+
begin
|
|
26
|
+
Thread.new { eval("$SAFE = 3\n#{spec_string}", binding) }.join
|
|
27
|
+
rescue
|
|
28
|
+
abort "unsafe gemspec: #{$!}"
|
|
29
|
+
else
|
|
30
|
+
File.open("#{spec.name}.gemspec", 'w') { |file| file.write spec_string }
|
|
29
31
|
end
|
|
30
|
-
rescue LoadError
|
|
31
|
-
puts "Jeweler gem (technicalpickles-jeweler) not found"
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
-
task :
|
|
35
|
-
|
|
34
|
+
task :bump => ["version:bump", :gemspec]
|
|
35
|
+
|
|
36
|
+
namespace :version do
|
|
37
|
+
task :read do
|
|
38
|
+
unless defined? GEM_VERSION
|
|
39
|
+
GEM_VERSION = File.read("VERSION")
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
task :bump => :read do
|
|
44
|
+
if ENV['VERSION']
|
|
45
|
+
GEM_VERSION.replace ENV['VERSION']
|
|
46
|
+
else
|
|
47
|
+
GEM_VERSION.sub!(/\d+$/) { |num| num.to_i + 1 }
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
File.open("VERSION", 'w') { |v| v.write GEM_VERSION }
|
|
51
|
+
end
|
|
36
52
|
end
|
|
37
53
|
|
|
38
|
-
task :
|
|
54
|
+
task :release => :bump do
|
|
55
|
+
system %(git commit VERSION *.gemspec -m "release v#{GEM_VERSION}")
|
|
56
|
+
system %(git tag -am "release v#{GEM_VERSION}" v#{GEM_VERSION})
|
|
57
|
+
end
|
data/bin/rspactor
CHANGED
data/lib/rspactor/inspector.rb
CHANGED
|
@@ -10,6 +10,9 @@ module RSpactor
|
|
|
10
10
|
|
|
11
11
|
def determine_spec_files(file)
|
|
12
12
|
candidates = translate(file)
|
|
13
|
+
candidates.reject { |candidate| candidate.index('.') }.each do |dir|
|
|
14
|
+
candidates.reject! { |candidate| candidate.index("#{dir}/") == 0 }
|
|
15
|
+
end
|
|
13
16
|
spec_files = candidates.select { |candidate| File.exists? candidate }
|
|
14
17
|
|
|
15
18
|
if spec_files.empty?
|
|
@@ -41,6 +44,8 @@ module RSpactor
|
|
|
41
44
|
candidates << append_spec_file_extension($1)
|
|
42
45
|
elsif file =~ %r:app/helpers/(\w+)_helper.rb:
|
|
43
46
|
candidates << "views/#{$1}"
|
|
47
|
+
elsif file =~ /_observer.rb$/
|
|
48
|
+
candidates << candidates.last.sub('_observer', '')
|
|
44
49
|
end
|
|
45
50
|
end
|
|
46
51
|
when %r:^lib/:
|
data/lib/rspactor/runner.rb
CHANGED
|
@@ -2,52 +2,95 @@ require 'rspactor'
|
|
|
2
2
|
|
|
3
3
|
module RSpactor
|
|
4
4
|
class Runner
|
|
5
|
-
def self.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
def self.start(options = {})
|
|
6
|
+
new(Dir.pwd, options).start
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
attr_reader :dir, :options, :inspector, :interactor
|
|
10
|
+
|
|
11
|
+
def initialize(dir, options = {})
|
|
12
|
+
@dir = dir
|
|
13
|
+
@options = options
|
|
14
|
+
read_git_head
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def start
|
|
18
|
+
load_dotfile
|
|
13
19
|
puts "** RSpactor is now watching at '#{dir}'"
|
|
14
|
-
|
|
15
|
-
|
|
20
|
+
start_interactor
|
|
21
|
+
start_listener
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def start_interactor
|
|
25
|
+
@interactor = Interactor.new
|
|
26
|
+
aborted = @interactor.wait_for_enter_key("** Hit <enter> to skip initial spec run", 3)
|
|
16
27
|
@interactor.start_termination_handler
|
|
17
28
|
run_all_specs unless aborted
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def start_listener
|
|
32
|
+
@inspector = Inspector.new(dir)
|
|
18
33
|
|
|
19
34
|
Listener.new(Inspector::EXTENSIONS) do |files|
|
|
20
|
-
|
|
21
|
-
files.each do |file|
|
|
22
|
-
spec_files = @inspector.determine_spec_files(file)
|
|
23
|
-
unless spec_files.empty?
|
|
24
|
-
puts spec_files.join("\n")
|
|
25
|
-
files_to_spec.concat spec_files
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
run_spec_command(files_to_spec)
|
|
35
|
+
spec_changed_files(files) unless git_head_changed?
|
|
29
36
|
end.run(dir)
|
|
30
37
|
end
|
|
31
|
-
|
|
32
|
-
def
|
|
33
|
-
|
|
38
|
+
|
|
39
|
+
def load_dotfile
|
|
40
|
+
dotfile = File.join(ENV['HOME'], '.rspactor')
|
|
41
|
+
if File.exists?(dotfile)
|
|
42
|
+
begin
|
|
43
|
+
Kernel.load dotfile
|
|
44
|
+
rescue => e
|
|
45
|
+
$stderr.puts "Error while loading #{dotfile}: #{e}"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
34
48
|
end
|
|
35
49
|
|
|
36
|
-
def
|
|
50
|
+
def run_all_specs
|
|
37
51
|
run_spec_command('spec')
|
|
38
52
|
end
|
|
39
53
|
|
|
40
|
-
def
|
|
54
|
+
def run_spec_command(paths)
|
|
41
55
|
paths = Array(paths)
|
|
42
|
-
|
|
43
|
-
|
|
56
|
+
if paths.empty?
|
|
57
|
+
@last_run_failed = nil
|
|
58
|
+
else
|
|
59
|
+
cmd = [ruby_opts, spec_runner, paths, spec_opts].flatten.join(' ')
|
|
60
|
+
@last_run_failed = run_command(cmd)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def last_run_failed?
|
|
65
|
+
@last_run_failed == false
|
|
44
66
|
end
|
|
67
|
+
|
|
68
|
+
protected
|
|
45
69
|
|
|
46
|
-
def
|
|
70
|
+
def run_command(cmd)
|
|
47
71
|
system(cmd)
|
|
72
|
+
$?.success?
|
|
48
73
|
end
|
|
74
|
+
|
|
75
|
+
def spec_changed_files(files)
|
|
76
|
+
files_to_spec = files.inject([]) do |all, file|
|
|
77
|
+
all.concat inspector.determine_spec_files(file)
|
|
78
|
+
end
|
|
79
|
+
unless files_to_spec.empty?
|
|
80
|
+
puts files_to_spec.join("\n")
|
|
81
|
+
|
|
82
|
+
previous_run_failed = last_run_failed?
|
|
83
|
+
run_spec_command(files_to_spec)
|
|
84
|
+
|
|
85
|
+
if options[:retry_failed] and previous_run_failed and not last_run_failed?
|
|
86
|
+
run_all_specs
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
private
|
|
49
92
|
|
|
50
|
-
def
|
|
93
|
+
def spec_opts
|
|
51
94
|
if File.exist?('spec/spec.opts')
|
|
52
95
|
opts = File.read('spec/spec.opts').gsub("\n", ' ')
|
|
53
96
|
else
|
|
@@ -61,11 +104,11 @@ module RSpactor
|
|
|
61
104
|
opts
|
|
62
105
|
end
|
|
63
106
|
|
|
64
|
-
def
|
|
107
|
+
def formatter_opts
|
|
65
108
|
"-r #{File.dirname(__FILE__)}/../rspec_growler.rb -f RSpecGrowler:STDOUT"
|
|
66
109
|
end
|
|
67
110
|
|
|
68
|
-
def
|
|
111
|
+
def spec_runner
|
|
69
112
|
if File.exist?("script/spec")
|
|
70
113
|
"script/spec"
|
|
71
114
|
else
|
|
@@ -73,10 +116,22 @@ module RSpactor
|
|
|
73
116
|
end
|
|
74
117
|
end
|
|
75
118
|
|
|
76
|
-
def
|
|
119
|
+
def ruby_opts
|
|
77
120
|
other = ENV['RUBYOPT'] ? " #{ENV['RUBYOPT']}" : ''
|
|
121
|
+
other << ' -rcoral' if options[:coral]
|
|
78
122
|
%(RUBYOPT='-Ilib:spec#{other}')
|
|
79
123
|
end
|
|
124
|
+
|
|
125
|
+
def git_head_changed?
|
|
126
|
+
old_git_head = @git_head
|
|
127
|
+
read_git_head
|
|
128
|
+
@git_head and old_git_head and @git_head != old_git_head
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def read_git_head
|
|
132
|
+
git_head_file = File.join(dir, '.git', 'HEAD')
|
|
133
|
+
@git_head = File.exists?(git_head_file) && File.read(git_head_file)
|
|
134
|
+
end
|
|
80
135
|
end
|
|
81
136
|
end
|
|
82
137
|
|
data/spec/inspector_spec.rb
CHANGED
|
@@ -64,6 +64,10 @@ describe RSpactor::Inspector do
|
|
|
64
64
|
translate('db/schema.rb').should == ['spec/models']
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
+
it "should consider related model when its observer changes" do
|
|
68
|
+
translate('app/models/user_observer.rb').should == ['spec/models/user_observer_spec.rb', 'spec/models/user_spec.rb']
|
|
69
|
+
end
|
|
70
|
+
|
|
67
71
|
it "should consider all specs when spec_helper changes" do
|
|
68
72
|
translate('spec/spec_helper.rb').should == ['spec']
|
|
69
73
|
end
|
|
@@ -78,4 +82,38 @@ describe RSpactor::Inspector do
|
|
|
78
82
|
translate('config/boot.rb').should == ['spec']
|
|
79
83
|
end
|
|
80
84
|
end
|
|
85
|
+
|
|
86
|
+
describe "#determine_spec_files" do
|
|
87
|
+
def determine(file)
|
|
88
|
+
@inspector.determine_spec_files(file)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it "should filter out files that don't exist on the filesystem" do
|
|
92
|
+
@inspector.should_receive(:translate).with('foo').and_return(%w(valid_spec.rb invalid_spec.rb))
|
|
93
|
+
File.should_receive(:exists?).with('valid_spec.rb').and_return(true)
|
|
94
|
+
File.should_receive(:exists?).with('invalid_spec.rb').and_return(false)
|
|
95
|
+
determine('foo').should == ['valid_spec.rb']
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "should filter out files in subdirectories that are already on the list" do
|
|
99
|
+
@inspector.should_receive(:translate).with('foo').and_return(%w(
|
|
100
|
+
spec/foo_spec.rb
|
|
101
|
+
spec/views/moo/bar_spec.rb
|
|
102
|
+
spec/views/baa/boo_spec.rb
|
|
103
|
+
spec/models/baz_spec.rb
|
|
104
|
+
spec/controllers/moo_spec.rb
|
|
105
|
+
spec/models
|
|
106
|
+
spec/controllers
|
|
107
|
+
spec/views/baa
|
|
108
|
+
))
|
|
109
|
+
File.stub!(:exists?).and_return(true)
|
|
110
|
+
determine('foo').should == %w(
|
|
111
|
+
spec/foo_spec.rb
|
|
112
|
+
spec/views/moo/bar_spec.rb
|
|
113
|
+
spec/models
|
|
114
|
+
spec/controllers
|
|
115
|
+
spec/views/baa
|
|
116
|
+
)
|
|
117
|
+
end
|
|
118
|
+
end
|
|
81
119
|
end
|
data/spec/runner_spec.rb
CHANGED
|
@@ -3,16 +3,12 @@ require 'rspactor/runner'
|
|
|
3
3
|
describe RSpactor::Runner do
|
|
4
4
|
|
|
5
5
|
described_class.class_eval do
|
|
6
|
-
def
|
|
6
|
+
def run_command(cmd)
|
|
7
7
|
# never shell out in tests
|
|
8
8
|
cmd
|
|
9
9
|
end
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
def runner
|
|
13
|
-
described_class
|
|
14
|
-
end
|
|
15
|
-
|
|
16
12
|
def with_env(name, value)
|
|
17
13
|
old_value = ENV[name]
|
|
18
14
|
ENV[name] = value
|
|
@@ -23,81 +19,139 @@ describe RSpactor::Runner do
|
|
|
23
19
|
end
|
|
24
20
|
end
|
|
25
21
|
|
|
26
|
-
|
|
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
|
+
describe "start" do
|
|
27
41
|
before(:each) do
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
runner.stub!(:puts)
|
|
31
|
-
RSpactor::Inspector.stub!(:new)
|
|
32
|
-
RSpactor::Interactor.stub!(:new).and_return(mock('Interactor').as_null_object)
|
|
33
|
-
RSpactor::Listener.stub!(:new).and_return(mock('Listener').as_null_object)
|
|
42
|
+
@runner = described_class.new('/my/path')
|
|
43
|
+
capture_stdout
|
|
34
44
|
end
|
|
35
45
|
|
|
36
|
-
|
|
37
|
-
|
|
46
|
+
after(:each) do
|
|
47
|
+
restore_stdout
|
|
38
48
|
end
|
|
39
49
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
setup
|
|
50
|
+
def setup
|
|
51
|
+
@runner.start
|
|
43
52
|
end
|
|
53
|
+
|
|
54
|
+
context "Interactor" do
|
|
55
|
+
before(:each) do
|
|
56
|
+
@runner.stub!(:load_dotfile)
|
|
57
|
+
@runner.stub!(:start_listener)
|
|
58
|
+
@interactor = mock('Interactor')
|
|
59
|
+
@interactor.should_receive(:start_termination_handler)
|
|
60
|
+
RSpactor::Interactor.should_receive(:new).and_return(@interactor)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "should start Interactor" do
|
|
64
|
+
@interactor.should_receive(:wait_for_enter_key).with(instance_of(String), 3)
|
|
65
|
+
setup
|
|
66
|
+
end
|
|
44
67
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
setup
|
|
51
|
-
end
|
|
68
|
+
it "should run all specs if Interactor isn't interrupted" do
|
|
69
|
+
@interactor.should_receive(:wait_for_enter_key).and_return(nil)
|
|
70
|
+
@runner.should_receive(:run_spec_command).with('spec')
|
|
71
|
+
setup
|
|
72
|
+
end
|
|
52
73
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
setup
|
|
74
|
+
it "should skip running all specs if Interactor is interrupted" do
|
|
75
|
+
@interactor.should_receive(:wait_for_enter_key).and_return(true)
|
|
76
|
+
@runner.should_not_receive(:run_spec_command)
|
|
77
|
+
setup
|
|
78
|
+
end
|
|
59
79
|
end
|
|
60
|
-
|
|
61
|
-
it "should
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
RSpactor::
|
|
65
|
-
|
|
80
|
+
|
|
81
|
+
it "should initialize Inspector" do
|
|
82
|
+
@runner.stub!(:load_dotfile)
|
|
83
|
+
@runner.stub!(:start_interactor)
|
|
84
|
+
RSpactor::Inspector.should_receive(:new).with('/my/path')
|
|
85
|
+
RSpactor::Listener.stub!(:new).and_return(mock('Listener').as_null_object)
|
|
66
86
|
setup
|
|
67
87
|
end
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
88
|
+
|
|
89
|
+
context "Listener" do
|
|
90
|
+
before(:each) do
|
|
91
|
+
@runner.stub!(:load_dotfile)
|
|
92
|
+
@runner.stub!(:start_interactor)
|
|
93
|
+
@inspector = mock("Inspector")
|
|
94
|
+
RSpactor::Inspector.stub!(:new).and_return(@inspector)
|
|
95
|
+
@listener = mock('Listener')
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "should run Listener" do
|
|
99
|
+
@listener.should_receive(:run).with('/my/path')
|
|
100
|
+
RSpactor::Listener.should_receive(:new).with(instance_of(Array)).and_return(@listener)
|
|
101
|
+
setup
|
|
102
|
+
end
|
|
74
103
|
end
|
|
75
104
|
|
|
76
105
|
it "should output 'watching' message on start" do
|
|
77
|
-
runner.
|
|
106
|
+
@runner.stub!(:load_dotfile)
|
|
107
|
+
@runner.stub!(:start_interactor)
|
|
108
|
+
@runner.stub!(:start_listener)
|
|
78
109
|
setup
|
|
110
|
+
$stdout.string.chomp.should == "** RSpactor is now watching at '/my/path'"
|
|
79
111
|
end
|
|
80
112
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
113
|
+
context "dotfile" do
|
|
114
|
+
before(:each) do
|
|
115
|
+
@runner.stub!(:start_interactor)
|
|
116
|
+
@runner.stub!(:start_listener)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it "should load dotfile if found" do
|
|
120
|
+
with_env('HOME', '/home/moo') do
|
|
121
|
+
File.should_receive(:exists?).with('/home/moo/.rspactor').and_return(true)
|
|
122
|
+
Kernel.should_receive(:load).with('/home/moo/.rspactor')
|
|
123
|
+
setup
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
it "should continue even if the dotfile raised errors" do
|
|
128
|
+
with_env('HOME', '/home/moo') do
|
|
129
|
+
File.should_receive(:exists?).and_return(true)
|
|
130
|
+
Kernel.should_receive(:load).with('/home/moo/.rspactor').and_raise(ArgumentError)
|
|
131
|
+
capture_stderr do
|
|
132
|
+
lambda { setup }.should_not raise_error
|
|
133
|
+
$stderr.string.split("\n").should include('Error while loading /home/moo/.rspactor: ArgumentError')
|
|
134
|
+
end
|
|
135
|
+
end
|
|
86
136
|
end
|
|
87
137
|
end
|
|
88
138
|
end
|
|
89
139
|
|
|
90
140
|
describe "#run_spec_command" do
|
|
141
|
+
before(:each) do
|
|
142
|
+
@runner = described_class.new('/my/path')
|
|
143
|
+
end
|
|
144
|
+
|
|
91
145
|
def with_rubyopt(string, &block)
|
|
92
146
|
with_env('RUBYOPT', string, &block)
|
|
93
147
|
end
|
|
94
148
|
|
|
95
149
|
def run(paths)
|
|
96
|
-
runner.run_spec_command(paths)
|
|
150
|
+
@runner.run_spec_command(paths)
|
|
97
151
|
end
|
|
98
152
|
|
|
99
153
|
it "should exit if the paths argument is empty" do
|
|
100
|
-
runner.should_not_receive(:run_command)
|
|
154
|
+
@runner.should_not_receive(:run_command)
|
|
101
155
|
run([])
|
|
102
156
|
end
|
|
103
157
|
|
|
@@ -130,14 +184,61 @@ describe RSpactor::Runner do
|
|
|
130
184
|
end
|
|
131
185
|
|
|
132
186
|
it "should not include 'progress' formatter if there already are 2 or more formatters" do
|
|
133
|
-
runner.should_receive(:formatter_opts).and_return('-f foo --format bar')
|
|
187
|
+
@runner.should_receive(:formatter_opts).and_return('-f foo --format bar')
|
|
134
188
|
run('foo').should_not include('-f progress')
|
|
135
189
|
end
|
|
190
|
+
|
|
191
|
+
it "should save status of last run" do
|
|
192
|
+
@runner.should_receive(:run_command).twice.and_return(true, false)
|
|
193
|
+
run('foo')
|
|
194
|
+
@runner.last_run_failed?.should be_false
|
|
195
|
+
run('bar')
|
|
196
|
+
@runner.last_run_failed?.should be_true
|
|
197
|
+
run([])
|
|
198
|
+
@runner.last_run_failed?.should be_false
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
describe "#spec_changed_files" do
|
|
203
|
+
before(:each) do
|
|
204
|
+
@runner = described_class.new('.')
|
|
205
|
+
@runner.stub!(:inspector).and_return(mock("Inspector"))
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def set_inspector_expectation(file, ret)
|
|
209
|
+
@runner.inspector.should_receive(:determine_spec_files).with(file).and_return(ret)
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
it "should find and run spec files" do
|
|
213
|
+
set_inspector_expectation('moo.rb', ['spec/moo_spec.rb'])
|
|
214
|
+
set_inspector_expectation('views/baz.haml', [])
|
|
215
|
+
set_inspector_expectation('config/bar.yml', ['spec/bar_spec.rb', 'spec/bar_stuff_spec.rb'])
|
|
216
|
+
|
|
217
|
+
expected = %w(spec/moo_spec.rb spec/bar_spec.rb spec/bar_stuff_spec.rb)
|
|
218
|
+
@runner.should_receive(:run_spec_command).with(expected)
|
|
219
|
+
|
|
220
|
+
capture_stdout do
|
|
221
|
+
@runner.send(:spec_changed_files, %w(moo.rb views/baz.haml config/bar.yml))
|
|
222
|
+
$stdout.string.split("\n").should == expected
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
it "should run the full suite after a run succeded when the previous one failed" do
|
|
227
|
+
@runner.inspector.stub!(:determine_spec_files).and_return(['spec/foo_spec.rb'], ['spec/bar_spec.rb'])
|
|
228
|
+
@runner.stub!(:options).and_return({ :retry_failed => true })
|
|
229
|
+
|
|
230
|
+
capture_stdout do
|
|
231
|
+
@runner.stub!(:run_spec_command)
|
|
232
|
+
@runner.should_receive(:last_run_failed?).and_return(true, false)
|
|
233
|
+
@runner.should_receive(:run_all_specs)
|
|
234
|
+
@runner.send(:spec_changed_files, %w(moo.rb))
|
|
235
|
+
end
|
|
236
|
+
end
|
|
136
237
|
end
|
|
137
238
|
|
|
138
239
|
it "should have Runner in global namespace for backwards compatibility" do
|
|
139
240
|
defined?(::Runner).should be_true
|
|
140
|
-
::Runner.should ==
|
|
241
|
+
::Runner.should == described_class
|
|
141
242
|
end
|
|
142
243
|
|
|
143
244
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mislav-rspactor
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- "Mislav Marohni\xC4\x87"
|
|
@@ -11,7 +11,7 @@ autorequire:
|
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
13
|
|
|
14
|
-
date: 2009-03-
|
|
14
|
+
date: 2009-03-27 00:00:00 -07:00
|
|
15
15
|
default_executable: rspactor
|
|
16
16
|
dependencies: []
|
|
17
17
|
|