friendlyfashion-parallel_tests 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +44 -0
- data/Rakefile +6 -0
- data/Readme.md +232 -0
- data/ReadmeRails2.md +48 -0
- data/bin/parallel_cucumber +2 -0
- data/bin/parallel_rspec +2 -0
- data/bin/parallel_test +6 -0
- data/lib/parallel_tests.rb +30 -0
- data/lib/parallel_tests/cli.rb +159 -0
- data/lib/parallel_tests/cucumber/gherkin_listener.rb +60 -0
- data/lib/parallel_tests/cucumber/runner.rb +90 -0
- data/lib/parallel_tests/cucumber/runtime_logger.rb +58 -0
- data/lib/parallel_tests/grouper.rb +53 -0
- data/lib/parallel_tests/railtie.rb +8 -0
- data/lib/parallel_tests/rspec/failures_logger.rb +44 -0
- data/lib/parallel_tests/rspec/logger_base.rb +52 -0
- data/lib/parallel_tests/rspec/runner.rb +59 -0
- data/lib/parallel_tests/rspec/runtime_logger.rb +34 -0
- data/lib/parallel_tests/rspec/summary_logger.rb +19 -0
- data/lib/parallel_tests/tasks.rb +134 -0
- data/lib/parallel_tests/test/runner.rb +134 -0
- data/lib/parallel_tests/test/runtime_logger.rb +92 -0
- data/lib/parallel_tests/version.rb +3 -0
- data/parallel_tests.gemspec +14 -0
- data/spec/integration_spec.rb +244 -0
- data/spec/parallel_tests/cli_spec.rb +36 -0
- data/spec/parallel_tests/cucumber/gherkin_listener_spec.rb +48 -0
- data/spec/parallel_tests/cucumber/runner_spec.rb +173 -0
- data/spec/parallel_tests/grouper_spec.rb +52 -0
- data/spec/parallel_tests/rspec/failure_logger_spec.rb +82 -0
- data/spec/parallel_tests/rspec/runner_spec.rb +178 -0
- data/spec/parallel_tests/rspec/runtime_logger_spec.rb +76 -0
- data/spec/parallel_tests/rspec/summary_logger_spec.rb +37 -0
- data/spec/parallel_tests/tasks_spec.rb +151 -0
- data/spec/parallel_tests/test/runner_spec.rb +273 -0
- data/spec/parallel_tests/test/runtime_logger_spec.rb +84 -0
- data/spec/parallel_tests_spec.rb +73 -0
- data/spec/spec_helper.rb +151 -0
- metadata +109 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'parallel_tests/cli'
|
3
|
+
|
4
|
+
describe ParallelTest::CLI do
|
5
|
+
describe ".parse_options" do
|
6
|
+
let(:defaults){ {:files => []} }
|
7
|
+
|
8
|
+
def call(*args)
|
9
|
+
ParallelTest::CLI.send(:parse_options!, *args)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "parses regular count" do
|
13
|
+
call(["-n3"]).should == defaults.merge(:count => 3)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "parses count 0 as non-parallel" do
|
17
|
+
call(["-n0"]).should == defaults.merge(:non_parallel => true)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "parses non-parallel as non-parallel" do
|
21
|
+
call(["--non-parallel"]).should == defaults.merge(:non_parallel => true)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe ".final_fail_message" do
|
26
|
+
it 'returns a plain fail message if colors are nor supported' do
|
27
|
+
ParallelTest::CLI.should_receive(:use_colors?).and_return false
|
28
|
+
ParallelTest::CLI.send(:final_fail_message, "Test").should == "Tests Failed"
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'returns a colorized fail message if colors are supported' do
|
32
|
+
ParallelTest::CLI.should_receive(:use_colors?).and_return true
|
33
|
+
ParallelTest::CLI.send(:final_fail_message, "Test").should == "\e[31mTests Failed\e[0m"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'parallel_tests/cucumber/gherkin_listener'
|
2
|
+
|
3
|
+
describe ParallelTests::Cucumber::GherkinListener do
|
4
|
+
describe :collect do
|
5
|
+
before(:each) do
|
6
|
+
@listener = ParallelTests::Cucumber::GherkinListener.new
|
7
|
+
@listener.uri("feature_file")
|
8
|
+
end
|
9
|
+
|
10
|
+
it "returns steps count" do
|
11
|
+
3.times {@listener.step(nil)}
|
12
|
+
@listener.collect.should == {"feature_file" => 3}
|
13
|
+
end
|
14
|
+
|
15
|
+
it "counts background steps separately" do
|
16
|
+
@listener.background("background")
|
17
|
+
5.times {@listener.step(nil)}
|
18
|
+
@listener.collect.should == {"feature_file" => 0}
|
19
|
+
|
20
|
+
@listener.scenario("scenario")
|
21
|
+
2.times {@listener.step(nil)}
|
22
|
+
@listener.collect.should == {"feature_file" => 2}
|
23
|
+
|
24
|
+
@listener.scenario("scenario")
|
25
|
+
@listener.collect.should == {"feature_file" => 2}
|
26
|
+
|
27
|
+
@listener.eof
|
28
|
+
@listener.collect.should == {"feature_file" => 12}
|
29
|
+
end
|
30
|
+
|
31
|
+
it "counts scenario outlines steps separately" do
|
32
|
+
@listener.scenario_outline("outline")
|
33
|
+
5.times {@listener.step(nil)}
|
34
|
+
@listener.collect.should == {"feature_file" => 0}
|
35
|
+
|
36
|
+
@listener.scenario("scenario")
|
37
|
+
2.times {@listener.step(nil)}
|
38
|
+
@listener.collect.should == {"feature_file" => 2}
|
39
|
+
|
40
|
+
@listener.scenario("scenario")
|
41
|
+
@listener.collect.should == {"feature_file" => 2}
|
42
|
+
|
43
|
+
3.times {@listener.examples}
|
44
|
+
@listener.eof
|
45
|
+
@listener.collect.should == {"feature_file" => 17}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ParallelTests::Cucumber do
|
4
|
+
test_tests_in_groups(ParallelTests::Cucumber::Runner, 'features', ".feature")
|
5
|
+
|
6
|
+
describe :run_tests do
|
7
|
+
before do
|
8
|
+
ParallelTests.stub!(:bundler_enabled?).and_return false
|
9
|
+
File.stub!(:file?).with('.bundle/environment.rb').and_return false
|
10
|
+
File.stub!(:file?).with('script/cucumber').and_return true
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(*args)
|
14
|
+
ParallelTests::Cucumber::Runner.run_tests(*args)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "uses TEST_ENV_NUMBER=blank when called for process 0" do
|
18
|
+
ParallelTests::Cucumber::Runner.should_receive(:open).with{|x,y| x=~/TEST_ENV_NUMBER= /}.and_return mocked_process
|
19
|
+
call(['xxx'],0,{})
|
20
|
+
end
|
21
|
+
|
22
|
+
it "uses TEST_ENV_NUMBER=2 when called for process 1" do
|
23
|
+
ParallelTests::Cucumber::Runner.should_receive(:open).with{|x,y| x=~/TEST_ENV_NUMBER=2/}.and_return mocked_process
|
24
|
+
call(['xxx'],1,{})
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns the output" do
|
28
|
+
io = open('spec/spec_helper.rb')
|
29
|
+
$stdout.stub!(:print)
|
30
|
+
ParallelTests::Cucumber::Runner.should_receive(:open).and_return io
|
31
|
+
call(['xxx'],1,{})[:stdout].should =~ /\$LOAD_PATH << File/
|
32
|
+
end
|
33
|
+
|
34
|
+
it "runs bundle exec cucumber when on bundler 0.9" do
|
35
|
+
ParallelTests.stub!(:bundler_enabled?).and_return true
|
36
|
+
ParallelTests::Cucumber::Runner.should_receive(:open).with{|x,y| x =~ %r{bundle exec cucumber}}.and_return mocked_process
|
37
|
+
call(['xxx'],1,{})
|
38
|
+
end
|
39
|
+
|
40
|
+
it "runs script/cucumber when script/cucumber is found" do
|
41
|
+
ParallelTests::Cucumber::Runner.should_receive(:open).with{|x,y| x =~ %r{script/cucumber}}.and_return mocked_process
|
42
|
+
call(['xxx'],1,{})
|
43
|
+
end
|
44
|
+
|
45
|
+
it "runs cucumber by default" do
|
46
|
+
File.stub!(:file?).with('script/cucumber').and_return false
|
47
|
+
ParallelTests::Cucumber::Runner.should_receive(:open).with{|x,y| x !~ %r{(script/cucumber)|(bundle exec cucumber)}}.and_return mocked_process
|
48
|
+
call(['xxx'],1,{})
|
49
|
+
end
|
50
|
+
|
51
|
+
it "uses options passed in" do
|
52
|
+
ParallelTests::Cucumber::Runner.should_receive(:open).with{|x,y| x =~ %r{script/cucumber .* -p default}}.and_return mocked_process
|
53
|
+
call(['xxx'],1,:test_options => '-p default')
|
54
|
+
end
|
55
|
+
|
56
|
+
context "with parallel profile in config/cucumber.yml" do
|
57
|
+
before do
|
58
|
+
file_contents = 'parallel: -f progress'
|
59
|
+
Dir.stub(:glob).and_return ['config/cucumber.yml']
|
60
|
+
File.stub(:read).with('config/cucumber.yml').and_return file_contents
|
61
|
+
end
|
62
|
+
|
63
|
+
it "uses parallel profile" do
|
64
|
+
ParallelTests::Cucumber::Runner.should_receive(:open).with{|x,y| x =~ %r{script/cucumber .* foo bar --profile parallel xxx}}.and_return mocked_process
|
65
|
+
call(['xxx'],1, :test_options => 'foo bar')
|
66
|
+
end
|
67
|
+
|
68
|
+
it "uses given profile via --profile" do
|
69
|
+
ParallelTests::Cucumber::Runner.should_receive(:open).with{|x,y| x =~ %r{script/cucumber .* --profile foo xxx$}}.and_return mocked_process
|
70
|
+
call(['xxx'],1, :test_options => '--profile foo')
|
71
|
+
end
|
72
|
+
|
73
|
+
it "uses given profile via -p" do
|
74
|
+
ParallelTests::Cucumber::Runner.should_receive(:open).with{|x,y| x =~ %r{script/cucumber .* -p foo xxx$}}.and_return mocked_process
|
75
|
+
call(['xxx'],1, :test_options => '-p foo')
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
it "does not use parallel profile if config/cucumber.yml does not contain it" do
|
80
|
+
file_contents = 'blob: -f progress'
|
81
|
+
ParallelTests::Cucumber::Runner.should_receive(:open).with{|x,y| x =~ %r{script/cucumber .* foo bar}}.and_return mocked_process
|
82
|
+
Dir.should_receive(:glob).and_return ['config/cucumber.yml']
|
83
|
+
File.should_receive(:read).with('config/cucumber.yml').and_return file_contents
|
84
|
+
call(['xxx'],1,:test_options => 'foo bar')
|
85
|
+
end
|
86
|
+
|
87
|
+
it "does not use the parallel profile if config/cucumber.yml does not exist" do
|
88
|
+
ParallelTests::Cucumber::Runner.should_receive(:open).with{|x,y| x =~ %r{script/cucumber .*}}.and_return mocked_process
|
89
|
+
Dir.should_receive(:glob).and_return []
|
90
|
+
call(['xxx'],1,{})
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe :line_is_result? do
|
95
|
+
it "should match lines with only one scenario" do
|
96
|
+
line = "1 scenario (1 failed)"
|
97
|
+
ParallelTests::Cucumber::Runner.line_is_result?(line).should be_true
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should match lines with multiple scenarios" do
|
101
|
+
line = "2 scenarios (1 failed, 1 passed)"
|
102
|
+
ParallelTests::Cucumber::Runner.line_is_result?(line).should be_true
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should match lines with only one step" do
|
106
|
+
line = "1 step (1 failed)"
|
107
|
+
ParallelTests::Cucumber::Runner.line_is_result?(line).should be_true
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should match lines with multiple steps" do
|
111
|
+
line = "5 steps (1 failed, 4 passed)"
|
112
|
+
ParallelTests::Cucumber::Runner.line_is_result?(line).should be_true
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should not match other lines" do
|
116
|
+
line = ' And I should have "2" emails # features/step_definitions/user_steps.rb:25'
|
117
|
+
ParallelTests::Cucumber::Runner.line_is_result?(line).should be_false
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
describe :find_results do
|
122
|
+
it "finds multiple results in test output" do
|
123
|
+
output = <<EOF
|
124
|
+
And I should not see "/en/" # features/step_definitions/webrat_steps.rb:87
|
125
|
+
|
126
|
+
7 scenarios (3 failed, 4 passed)
|
127
|
+
33 steps (3 failed, 2 skipped, 28 passed)
|
128
|
+
/apps/rs/features/signup.feature:2
|
129
|
+
Given I am on "/" # features/step_definitions/common_steps.rb:12
|
130
|
+
When I click "register" # features/step_definitions/common_steps.rb:6
|
131
|
+
And I should have "2" emails # features/step_definitions/user_steps.rb:25
|
132
|
+
|
133
|
+
4 scenarios (4 passed)
|
134
|
+
40 steps (40 passed)
|
135
|
+
|
136
|
+
And I should not see "foo" # features/step_definitions/webrat_steps.rb:87
|
137
|
+
|
138
|
+
1 scenario (1 passed)
|
139
|
+
1 step (1 passed)
|
140
|
+
|
141
|
+
EOF
|
142
|
+
ParallelTests::Cucumber::Runner.find_results(output).should == ["7 scenarios (3 failed, 4 passed)", "33 steps (3 failed, 2 skipped, 28 passed)", "4 scenarios (4 passed)", "40 steps (40 passed)", "1 scenario (1 passed)", "1 step (1 passed)"]
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
describe :summarize_results do
|
147
|
+
def call(*args)
|
148
|
+
ParallelTests::Cucumber::Runner.summarize_results(*args)
|
149
|
+
end
|
150
|
+
|
151
|
+
it "sums up results for scenarios and steps separately from each other" do
|
152
|
+
results = ["7 scenarios (3 failed, 4 passed)", "33 steps (3 failed, 2 skipped, 28 passed)", "4 scenarios (4 passed)",
|
153
|
+
"40 steps (40 passed)", "1 scenario (1 passed)", "1 step (1 passed)"]
|
154
|
+
call(results).should == "12 scenarios (3 failed, 9 passed)\n74 steps (3 failed, 2 skipped, 69 passed)"
|
155
|
+
end
|
156
|
+
|
157
|
+
it "adds same results with plurals" do
|
158
|
+
results = ["1 scenario (1 passed)", "2 steps (2 passed)",
|
159
|
+
"2 scenarios (2 passed)", "7 steps (7 passed)"]
|
160
|
+
call(results).should == "3 scenarios (3 passed)\n9 steps (9 passed)"
|
161
|
+
end
|
162
|
+
|
163
|
+
it "adds non-similar results" do
|
164
|
+
results = ["1 scenario (1 passed)", "1 step (1 passed)",
|
165
|
+
"2 scenarios (1 failed, 1 pending)", "2 steps (1 failed, 1 pending)"]
|
166
|
+
call(results).should == "3 scenarios (1 failed, 1 pending, 1 passed)\n3 steps (1 failed, 1 pending, 1 passed)"
|
167
|
+
end
|
168
|
+
|
169
|
+
it "does not pluralize 1" do
|
170
|
+
call(["1 scenario (1 passed)", "1 step (1 passed)"]).should == "1 scenario (1 passed)\n1 step (1 passed)"
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'parallel_tests/grouper'
|
3
|
+
require 'tmpdir'
|
4
|
+
|
5
|
+
describe ParallelTests::Grouper do
|
6
|
+
describe :by_steps do
|
7
|
+
def write(file, content)
|
8
|
+
File.open(file,'w'){|f| f.write content }
|
9
|
+
end
|
10
|
+
|
11
|
+
it "sorts features by steps" do
|
12
|
+
tmpdir = nil
|
13
|
+
result = Dir.mktmpdir do |dir|
|
14
|
+
tmpdir = dir
|
15
|
+
write("#{dir}/a.feature", "Feature: xxx\n Scenario: xxx\n Given something")
|
16
|
+
write("#{dir}/b.feature", "Feature: xxx\n Scenario: xxx\n Given something\n Scenario: yyy\n Given something")
|
17
|
+
write("#{dir}/c.feature", "Feature: xxx\n Scenario: xxx\n Given something")
|
18
|
+
ParallelTests::Grouper.by_steps(["#{dir}/a.feature", "#{dir}/b.feature", "#{dir}/c.feature"],2)
|
19
|
+
end
|
20
|
+
|
21
|
+
# testing inside mktmpdir is always green
|
22
|
+
result.should =~ [
|
23
|
+
["#{tmpdir}/a.feature", "#{tmpdir}/c.feature"],
|
24
|
+
["#{tmpdir}/b.feature"]
|
25
|
+
]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe :in_even_groups_by_size do
|
30
|
+
let(:files_with_size){ {"1" => 1, "2" => 2, "3" => 3, "4" => 4, "5" => 5} }
|
31
|
+
|
32
|
+
def call(num_groups)
|
33
|
+
ParallelTests::Grouper.in_even_groups_by_size(files_with_size, num_groups)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "groups 1 by 1 for same groups as size" do
|
37
|
+
call(5).should == [["5"], ["4"], ["3"], ["2"], ["1"]]
|
38
|
+
end
|
39
|
+
|
40
|
+
it "groups into even groups" do
|
41
|
+
call(2).should == [["1", "2", "5"], ["3", "4"]]
|
42
|
+
end
|
43
|
+
|
44
|
+
it "groups into a single group" do
|
45
|
+
call(1).should == [["1", "2", "3", "4", "5"]]
|
46
|
+
end
|
47
|
+
|
48
|
+
it "adds empty groups if there are more groups than feature files" do
|
49
|
+
call(6).should == [["5"], ["4"], ["3"], ["2"], ["1"], []]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ParallelTests::RSpec::FailuresLogger do
|
4
|
+
def silence_warnings
|
5
|
+
old_verbose, $VERBOSE = $VERBOSE, nil
|
6
|
+
yield
|
7
|
+
ensure
|
8
|
+
$VERBOSE = old_verbose
|
9
|
+
end
|
10
|
+
|
11
|
+
before do
|
12
|
+
@output = OutputLogger.new([])
|
13
|
+
@example1 = mock( 'example', :location => "#{Dir.pwd}/spec/path/to/example:123", :full_description => 'should do stuff', :description => 'd' )
|
14
|
+
@example2 = mock( 'example', :location => "#{Dir.pwd}/spec/path/to/example2:456", :full_description => 'should do other stuff', :description => 'd')
|
15
|
+
@exception1 = mock( :to_s => 'exception', :backtrace => [ '/path/to/error/line:33' ] )
|
16
|
+
@failure1 = mock( 'example', :location => "#{Dir.pwd}/example:123", :header => 'header', :exception => @exception1 )
|
17
|
+
@logger = ParallelTests::RSpec::FailuresLogger.new(@output)
|
18
|
+
end
|
19
|
+
|
20
|
+
after do
|
21
|
+
silence_warnings{ ParallelTests::RSpec::LoggerBase::RSPEC_1 = false }
|
22
|
+
end
|
23
|
+
|
24
|
+
def clean_output
|
25
|
+
@output.output.join("\n").gsub(/\e\[\d+m/,'')
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should produce a list of command lines for failing examples" do
|
29
|
+
@logger.example_failed @example1
|
30
|
+
@logger.example_failed @example2
|
31
|
+
|
32
|
+
@logger.dump_failures
|
33
|
+
@logger.dump_summary(1,2,3,4)
|
34
|
+
|
35
|
+
clean_output.should =~ /^rspec .*? should do stuff/
|
36
|
+
clean_output.should =~ /^rspec .*? should do other stuff/
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should invoke spec for rspec 1" do
|
40
|
+
silence_warnings{ ParallelTests::RSpec::LoggerBase::RSPEC_1 = true }
|
41
|
+
ParallelTests.stub!(:bundler_enabled?).and_return true
|
42
|
+
ParallelTests::RSpec::Runner.stub!(:run).with("bundle show rspec").and_return "/foo/bar/rspec-1.0.2"
|
43
|
+
@logger.example_failed @example1
|
44
|
+
|
45
|
+
@logger.dump_failures
|
46
|
+
@logger.dump_summary(1,2,3,4)
|
47
|
+
|
48
|
+
clean_output.should =~ /^bundle exec spec/
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should invoke rspec for rspec 2" do
|
52
|
+
ParallelTests.stub!(:bundler_enabled?).and_return true
|
53
|
+
ParallelTests::RSpec::Runner.stub!(:run).with("bundle show rspec").and_return "/foo/bar/rspec-2.0.2"
|
54
|
+
@logger.example_failed @example1
|
55
|
+
|
56
|
+
@logger.dump_failures
|
57
|
+
@logger.dump_summary(1,2,3,4)
|
58
|
+
|
59
|
+
clean_output.should =~ /^rspec/
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should return relative paths" do
|
63
|
+
@logger.example_failed @example1
|
64
|
+
@logger.example_failed @example2
|
65
|
+
|
66
|
+
@logger.dump_failures
|
67
|
+
@logger.dump_summary(1,2,3,4)
|
68
|
+
|
69
|
+
clean_output.should =~ %r(\./spec/path/to/example:123)
|
70
|
+
clean_output.should =~ %r(\./spec/path/to/example2:456)
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
# should not longer be a problem since its using native rspec methods
|
75
|
+
xit "should not log examples without location" do
|
76
|
+
example = mock('example', :location => 'bla', :full_description => 'before :all')
|
77
|
+
@logger.example_failed example
|
78
|
+
@logger.dump_failures
|
79
|
+
@logger.dump_summary(1,2,3,4)
|
80
|
+
clean_output.should == ''
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,178 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ParallelTests::RSpec::Runner do
|
4
|
+
test_tests_in_groups(ParallelTests::RSpec::Runner, 'spec', '_spec.rb')
|
5
|
+
|
6
|
+
describe :run_tests do
|
7
|
+
before do
|
8
|
+
File.stub!(:file?).with('script/spec').and_return false
|
9
|
+
File.stub!(:file?).with('spec/spec.opts').and_return false
|
10
|
+
File.stub!(:file?).with('spec/parallel_spec.opts').and_return false
|
11
|
+
File.stub!(:file?).with('.rspec_parallel').and_return false
|
12
|
+
ParallelTests.stub!(:bundler_enabled?).and_return false
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(*args)
|
16
|
+
ParallelTests::RSpec::Runner.run_tests(*args)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "uses TEST_ENV_NUMBER=blank when called for process 0" do
|
20
|
+
ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y|x=~/TEST_ENV_NUMBER= /}.and_return mocked_process
|
21
|
+
call(['xxx'], 0, {})
|
22
|
+
end
|
23
|
+
|
24
|
+
it "uses TEST_ENV_NUMBER=2 when called for process 1" do
|
25
|
+
ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x=~/TEST_ENV_NUMBER=2/}.and_return mocked_process
|
26
|
+
call(['xxx'],1,{})
|
27
|
+
end
|
28
|
+
|
29
|
+
it "runs with color when called from cmdline" do
|
30
|
+
ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x=~/ --tty /}.and_return mocked_process
|
31
|
+
$stdout.should_receive(:tty?).and_return true
|
32
|
+
call(['xxx'],1,{})
|
33
|
+
end
|
34
|
+
|
35
|
+
it "runs without color when not called from cmdline" do
|
36
|
+
ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x !~ / --tty /}.and_return mocked_process
|
37
|
+
$stdout.should_receive(:tty?).and_return false
|
38
|
+
call(['xxx'],1,{})
|
39
|
+
end
|
40
|
+
|
41
|
+
it "runs with color for rspec 1 when called for the cmdline" do
|
42
|
+
File.should_receive(:file?).with('script/spec').and_return true
|
43
|
+
ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x=~/ RSPEC_COLOR=1 /}.and_return mocked_process
|
44
|
+
$stdout.should_receive(:tty?).and_return true
|
45
|
+
call(['xxx'],1,{})
|
46
|
+
end
|
47
|
+
|
48
|
+
it "runs without color for rspec 1 when not called for the cmdline" do
|
49
|
+
File.should_receive(:file?).with('script/spec').and_return true
|
50
|
+
ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x !~ / RSPEC_COLOR=1 /}.and_return mocked_process
|
51
|
+
$stdout.should_receive(:tty?).and_return false
|
52
|
+
call(['xxx'],1,{})
|
53
|
+
end
|
54
|
+
|
55
|
+
it "run bundle exec spec when on bundler rspec 1" do
|
56
|
+
File.stub!(:file?).with('script/spec').and_return false
|
57
|
+
ParallelTests.stub!(:bundler_enabled?).and_return true
|
58
|
+
ParallelTests::RSpec::Runner.stub!(:run).with("bundle show rspec").and_return "/foo/bar/rspec-1.0.2"
|
59
|
+
ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x =~ %r{bundle exec spec}}.and_return mocked_process
|
60
|
+
call(['xxx'],1,{})
|
61
|
+
end
|
62
|
+
|
63
|
+
it "run bundle exec rspec when on bundler rspec 2" do
|
64
|
+
File.stub!(:file?).with('script/spec').and_return false
|
65
|
+
ParallelTests.stub!(:bundler_enabled?).and_return true
|
66
|
+
ParallelTests::RSpec::Runner.stub!(:run).with("bundle show rspec").and_return "/foo/bar/rspec-2.0.2"
|
67
|
+
ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x =~ %r{bundle exec rspec}}.and_return mocked_process
|
68
|
+
call(['xxx'],1,{})
|
69
|
+
end
|
70
|
+
|
71
|
+
it "runs script/spec when script/spec can be found" do
|
72
|
+
File.should_receive(:file?).with('script/spec').and_return true
|
73
|
+
ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x =~ %r{script/spec}}.and_return mocked_process
|
74
|
+
call(['xxx'],1,{})
|
75
|
+
end
|
76
|
+
|
77
|
+
it "runs spec when script/spec cannot be found" do
|
78
|
+
File.stub!(:file?).with('script/spec').and_return false
|
79
|
+
ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x !~ %r{script/spec}}.and_return mocked_process
|
80
|
+
call(['xxx'],1,{})
|
81
|
+
end
|
82
|
+
|
83
|
+
it "uses no -O when no opts where found" do
|
84
|
+
File.stub!(:file?).with('spec/spec.opts').and_return false
|
85
|
+
ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x !~ %r{spec/spec.opts}}.and_return mocked_process
|
86
|
+
call(['xxx'],1,{})
|
87
|
+
end
|
88
|
+
|
89
|
+
it "uses -O spec/spec.opts when found (with script/spec)" do
|
90
|
+
File.stub!(:file?).with('script/spec').and_return true
|
91
|
+
File.stub!(:file?).with('spec/spec.opts').and_return true
|
92
|
+
ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x =~ %r{script/spec\s+ -O spec/spec.opts}}.and_return mocked_process
|
93
|
+
call(['xxx'],1,{})
|
94
|
+
end
|
95
|
+
|
96
|
+
it "uses -O spec/parallel_spec.opts when found (with script/spec)" do
|
97
|
+
File.stub!(:file?).with('script/spec').and_return true
|
98
|
+
File.should_receive(:file?).with('spec/parallel_spec.opts').and_return true
|
99
|
+
ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x =~ %r{script/spec\s+ -O spec/parallel_spec.opts}}.and_return mocked_process
|
100
|
+
call(['xxx'],1,{})
|
101
|
+
end
|
102
|
+
|
103
|
+
it "uses -O .rspec_parallel when found (with script/spec)" do
|
104
|
+
File.stub!(:file?).with('script/spec').and_return true
|
105
|
+
File.should_receive(:file?).with('.rspec_parallel').and_return true
|
106
|
+
ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x =~ %r{script/spec\s+ -O .rspec_parallel}}.and_return mocked_process
|
107
|
+
call(['xxx'],1,{})
|
108
|
+
end
|
109
|
+
|
110
|
+
it "uses -O spec/parallel_spec.opts with rspec1" do
|
111
|
+
File.should_receive(:file?).with('spec/parallel_spec.opts').and_return true
|
112
|
+
|
113
|
+
ParallelTests.stub!(:bundler_enabled?).and_return true
|
114
|
+
ParallelTests::RSpec::Runner.stub!(:run).with("bundle show rspec").and_return "/foo/bar/rspec-1.0.2"
|
115
|
+
|
116
|
+
ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x =~ %r{spec\s+ -O spec/parallel_spec.opts}}.and_return mocked_process
|
117
|
+
call(['xxx'],1,{})
|
118
|
+
end
|
119
|
+
|
120
|
+
it "uses -O spec/parallel_spec.opts with rspec2" do
|
121
|
+
File.should_receive(:file?).with('spec/parallel_spec.opts').and_return true
|
122
|
+
|
123
|
+
ParallelTests.stub!(:bundler_enabled?).and_return true
|
124
|
+
ParallelTests::RSpec::Runner.stub!(:run).with("bundle show rspec").and_return "/foo/bar/rspec-2.4.2"
|
125
|
+
|
126
|
+
ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x =~ %r{rspec\s+ --color --tty -O spec/parallel_spec.opts}}.and_return mocked_process
|
127
|
+
call(['xxx'],1,{})
|
128
|
+
end
|
129
|
+
|
130
|
+
it "uses options passed in" do
|
131
|
+
ParallelTests::RSpec::Runner.should_receive(:open).with{|x,y| x =~ %r{rspec -f n}}.and_return mocked_process
|
132
|
+
call(['xxx'],1, :test_options => '-f n')
|
133
|
+
end
|
134
|
+
|
135
|
+
it "returns the output" do
|
136
|
+
io = open('spec/spec_helper.rb')
|
137
|
+
$stdout.stub!(:print)
|
138
|
+
ParallelTests::RSpec::Runner.should_receive(:open).and_return io
|
139
|
+
call(['xxx'],1,{})[:stdout].should =~ /\$LOAD_PATH << File/
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe :find_results do
|
144
|
+
def call(*args)
|
145
|
+
ParallelTests::RSpec::Runner.find_results(*args)
|
146
|
+
end
|
147
|
+
|
148
|
+
it "finds multiple results in spec output" do
|
149
|
+
output = "
|
150
|
+
....F...
|
151
|
+
..
|
152
|
+
failute fsddsfsd
|
153
|
+
...
|
154
|
+
ff.**..
|
155
|
+
0 examples, 0 failures, 0 pending
|
156
|
+
ff.**..
|
157
|
+
1 example, 1 failure, 1 pending
|
158
|
+
"
|
159
|
+
|
160
|
+
call(output).should == ['0 examples, 0 failures, 0 pending','1 example, 1 failure, 1 pending']
|
161
|
+
end
|
162
|
+
|
163
|
+
it "is robust against scrambeled output" do
|
164
|
+
output = "
|
165
|
+
....F...
|
166
|
+
..
|
167
|
+
failute fsddsfsd
|
168
|
+
...
|
169
|
+
ff.**..
|
170
|
+
0 exFampl*es, 0 failures, 0 pend.ing
|
171
|
+
ff.**..
|
172
|
+
1 exampF.les, 1 failures, 1 pend.ing
|
173
|
+
"
|
174
|
+
|
175
|
+
call(output).should == ['0 examples, 0 failures, 0 pending','1 examples, 1 failures, 1 pending']
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|