parallelized_specs 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +10 -0
- data/Gemfile.lock +30 -0
- data/Rakefile +21 -0
- data/Readme.md +240 -0
- data/VERSION +1 -0
- data/bin/parallel_spec +2 -0
- data/bin/parallel_test +97 -0
- data/lib/parallel_specs/spec_error_count_logger.rb +30 -0
- data/lib/parallel_specs/spec_error_logger.rb +45 -0
- data/lib/parallel_specs/spec_failures_logger.rb +43 -0
- data/lib/parallel_specs/spec_logger_base.rb +56 -0
- data/lib/parallel_specs/spec_runtime_logger.rb +34 -0
- data/lib/parallel_specs/spec_start_finish_logger.rb +38 -0
- data/lib/parallel_specs/spec_summary_logger.rb +19 -0
- data/lib/parallel_specs.rb +52 -0
- data/lib/parallel_tests/grouper.rb +49 -0
- data/lib/parallel_tests/railtie.rb +10 -0
- data/lib/parallel_tests/runtime_logger.rb +78 -0
- data/lib/parallel_tests/tasks.rb +80 -0
- data/lib/parallel_tests.rb +163 -0
- data/lib/tasks/parallel_tests.rake +1 -0
- data/parallelized_specs.gemspec +64 -0
- data/spec/integration_spec.rb +133 -0
- data/spec/parallel_specs/spec_failure_logger_spec.rb +82 -0
- data/spec/parallel_specs/spec_runtime_logger_spec.rb +76 -0
- data/spec/parallel_specs/spec_summary_logger_spec.rb +33 -0
- data/spec/parallel_specs_spec.rb +165 -0
- data/spec/parallel_tests/runtime_logger_spec.rb +74 -0
- data/spec/parallel_tests_spec.rb +229 -0
- data/spec/spec_helper.rb +149 -0
- metadata +109 -0
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ParallelSpecs::SpecRuntimeLogger do
|
4
|
+
before do
|
5
|
+
# pretend we run in parallel or the logger will log nothing
|
6
|
+
ENV['TEST_ENV_NUMBER'] = ''
|
7
|
+
@clean_output = %r{^spec/foo.rb:[-\.e\d]+$}m
|
8
|
+
end
|
9
|
+
|
10
|
+
after do
|
11
|
+
ENV.delete 'TEST_ENV_NUMBER'
|
12
|
+
end
|
13
|
+
|
14
|
+
def log_for_a_file(options={})
|
15
|
+
Tempfile.open('xxx') do |temp|
|
16
|
+
temp.close
|
17
|
+
f = File.open(temp.path,'w')
|
18
|
+
logger = if block_given?
|
19
|
+
yield(f)
|
20
|
+
else
|
21
|
+
ParallelSpecs::SpecRuntimeLogger.new(f)
|
22
|
+
end
|
23
|
+
|
24
|
+
example = (mock(:location => "#{Dir.pwd}/spec/foo.rb:123"))
|
25
|
+
logger.example_started example
|
26
|
+
logger.example_passed example
|
27
|
+
if options[:pending]
|
28
|
+
logger.example_pending example
|
29
|
+
logger.dump_pending
|
30
|
+
end
|
31
|
+
if options[:failed]
|
32
|
+
logger.example_failed example
|
33
|
+
logger.dump_failures
|
34
|
+
end
|
35
|
+
logger.start_dump
|
36
|
+
|
37
|
+
#f.close
|
38
|
+
return File.read(f.path)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
it "logs runtime with relative paths" do
|
43
|
+
log_for_a_file.should =~ @clean_output
|
44
|
+
end
|
45
|
+
|
46
|
+
it "does not log pending" do
|
47
|
+
log_for_a_file(:pending => true).should =~ @clean_output
|
48
|
+
end
|
49
|
+
|
50
|
+
it "does not log failures" do
|
51
|
+
log_for_a_file(:failed => true).should =~ @clean_output
|
52
|
+
end
|
53
|
+
|
54
|
+
it "does not log if we do not run in parallel" do
|
55
|
+
ENV.delete 'TEST_ENV_NUMBER'
|
56
|
+
log_for_a_file.should == ""
|
57
|
+
end
|
58
|
+
|
59
|
+
it "appends to a given file" do
|
60
|
+
result = log_for_a_file do |f|
|
61
|
+
f.write 'FooBar'
|
62
|
+
ParallelSpecs::SpecRuntimeLogger.new(f)
|
63
|
+
end
|
64
|
+
result.should include('FooBar')
|
65
|
+
result.should include('foo.rb')
|
66
|
+
end
|
67
|
+
|
68
|
+
it "overwrites a given path" do
|
69
|
+
result = log_for_a_file do |f|
|
70
|
+
f.write 'FooBar'
|
71
|
+
ParallelSpecs::SpecRuntimeLogger.new(f.path)
|
72
|
+
end
|
73
|
+
result.should_not include('FooBar')
|
74
|
+
result.should include('foo.rb')
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ParallelSpecs::SpecSummaryLogger do
|
4
|
+
let(:output){ OutputLogger.new([]) }
|
5
|
+
let(:logger){ ParallelSpecs::SpecSummaryLogger.new(output) }
|
6
|
+
|
7
|
+
# TODO somehow generate a real example with an exception to test this
|
8
|
+
xit "prints failing examples" do
|
9
|
+
logger.example_failed XXX
|
10
|
+
logger.example_failed XXX
|
11
|
+
logger.dump_failures
|
12
|
+
output.output.should == [
|
13
|
+
"bundle exec rspec ./spec/path/to/example.rb:123 # should do stuff",
|
14
|
+
"bundle exec rspec ./spec/path/to/example.rb:125 # should not do stuff"
|
15
|
+
]
|
16
|
+
end
|
17
|
+
|
18
|
+
it "does not print anything for passing examples" do
|
19
|
+
logger.example_passed mock(:location => "/my/spec/foo.rb:123")
|
20
|
+
logger.dump_failures
|
21
|
+
output.output.should == []
|
22
|
+
logger.dump_summary(1,2,3,4)
|
23
|
+
output.output.should == ["\nFinished in 1 seconds\n", "\e[31m2 examples, 3 failures, 4 pending\e[0m"]
|
24
|
+
end
|
25
|
+
|
26
|
+
it "does not print anything for pending examples" do
|
27
|
+
logger.example_pending mock(:location => "/my/spec/foo.rb:123")
|
28
|
+
logger.dump_failures
|
29
|
+
output.output.should == []
|
30
|
+
logger.dump_summary(1,2,3,4)
|
31
|
+
output.output.should == ["\nFinished in 1 seconds\n", "\e[31m2 examples, 3 failures, 4 pending\e[0m"]
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'parallel_specs/spec_runtime_logger'
|
3
|
+
require 'parallel_specs/spec_summary_logger'
|
4
|
+
require 'parallel_specs/spec_failures_logger'
|
5
|
+
|
6
|
+
describe ParallelSpecs do
|
7
|
+
test_tests_in_groups(ParallelSpecs, 'spec', '_spec.rb')
|
8
|
+
|
9
|
+
describe :run_tests do
|
10
|
+
before do
|
11
|
+
File.stub!(:file?).with('script/spec').and_return false
|
12
|
+
File.stub!(:file?).with('spec/spec.opts').and_return false
|
13
|
+
File.stub!(:file?).with('spec/parallel_spec.opts').and_return false
|
14
|
+
ParallelSpecs.stub!(:bundler_enabled?).and_return false
|
15
|
+
end
|
16
|
+
|
17
|
+
it "uses TEST_ENV_NUMBER=blank when called for process 0" do
|
18
|
+
ParallelSpecs.should_receive(:open).with{|x,y|x=~/TEST_ENV_NUMBER= /}.and_return mocked_process
|
19
|
+
ParallelSpecs.run_tests(['xxx'],0,{})
|
20
|
+
end
|
21
|
+
|
22
|
+
it "uses TEST_ENV_NUMBER=2 when called for process 1" do
|
23
|
+
ParallelSpecs.should_receive(:open).with{|x,y| x=~/TEST_ENV_NUMBER=2/}.and_return mocked_process
|
24
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
25
|
+
end
|
26
|
+
|
27
|
+
it "runs with color when called from cmdline" do
|
28
|
+
ParallelSpecs.should_receive(:open).with{|x,y| x=~/ --tty /}.and_return mocked_process
|
29
|
+
$stdout.should_receive(:tty?).and_return true
|
30
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
31
|
+
end
|
32
|
+
|
33
|
+
it "runs without color when not called from cmdline" do
|
34
|
+
ParallelSpecs.should_receive(:open).with{|x,y| x !~ / --tty /}.and_return mocked_process
|
35
|
+
$stdout.should_receive(:tty?).and_return false
|
36
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
37
|
+
end
|
38
|
+
|
39
|
+
it "runs with color for rspec 1 when called for the cmdline" do
|
40
|
+
File.should_receive(:file?).with('script/spec').and_return true
|
41
|
+
ParallelSpecs.should_receive(:open).with{|x,y| x=~/ RSPEC_COLOR=1 /}.and_return mocked_process
|
42
|
+
$stdout.should_receive(:tty?).and_return true
|
43
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
44
|
+
end
|
45
|
+
|
46
|
+
it "runs without color for rspec 1 when not called for the cmdline" do
|
47
|
+
File.should_receive(:file?).with('script/spec').and_return true
|
48
|
+
ParallelSpecs.should_receive(:open).with{|x,y| x !~ / RSPEC_COLOR=1 /}.and_return mocked_process
|
49
|
+
$stdout.should_receive(:tty?).and_return false
|
50
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
51
|
+
end
|
52
|
+
|
53
|
+
it "run bundle exec spec when on bundler rspec 1" do
|
54
|
+
File.stub!(:file?).with('script/spec').and_return false
|
55
|
+
ParallelSpecs.stub!(:bundler_enabled?).and_return true
|
56
|
+
ParallelSpecs.stub!(:run).with("bundle show rspec").and_return "/foo/bar/rspec-1.0.2"
|
57
|
+
ParallelSpecs.should_receive(:open).with{|x,y| x =~ %r{bundle exec spec}}.and_return mocked_process
|
58
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
59
|
+
end
|
60
|
+
|
61
|
+
it "run bundle exec rspec when on bundler rspec 2" do
|
62
|
+
File.stub!(:file?).with('script/spec').and_return false
|
63
|
+
ParallelSpecs.stub!(:bundler_enabled?).and_return true
|
64
|
+
ParallelSpecs.stub!(:run).with("bundle show rspec").and_return "/foo/bar/rspec-2.0.2"
|
65
|
+
ParallelSpecs.should_receive(:open).with{|x,y| x =~ %r{bundle exec rspec}}.and_return mocked_process
|
66
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
67
|
+
end
|
68
|
+
|
69
|
+
it "runs script/spec when script/spec can be found" do
|
70
|
+
File.should_receive(:file?).with('script/spec').and_return true
|
71
|
+
ParallelSpecs.should_receive(:open).with{|x,y| x =~ %r{script/spec}}.and_return mocked_process
|
72
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
73
|
+
end
|
74
|
+
|
75
|
+
it "runs spec when script/spec cannot be found" do
|
76
|
+
File.stub!(:file?).with('script/spec').and_return false
|
77
|
+
ParallelSpecs.should_receive(:open).with{|x,y| x !~ %r{script/spec}}.and_return mocked_process
|
78
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
79
|
+
end
|
80
|
+
|
81
|
+
it "uses no -O when no opts where found" do
|
82
|
+
File.stub!(:file?).with('spec/spec.opts').and_return false
|
83
|
+
ParallelSpecs.should_receive(:open).with{|x,y| x !~ %r{spec/spec.opts}}.and_return mocked_process
|
84
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
85
|
+
end
|
86
|
+
|
87
|
+
it "uses -O spec/spec.opts when found (with script/spec)" do
|
88
|
+
File.stub!(:file?).with('script/spec').and_return true
|
89
|
+
File.stub!(:file?).with('spec/spec.opts').and_return true
|
90
|
+
ParallelSpecs.should_receive(:open).with{|x,y| x =~ %r{script/spec\s+ -O spec/spec.opts}}.and_return mocked_process
|
91
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
92
|
+
end
|
93
|
+
|
94
|
+
it "uses -O spec/parallel_spec.opts when found (with script/spec)" do
|
95
|
+
File.stub!(:file?).with('script/spec').and_return true
|
96
|
+
File.should_receive(:file?).with('spec/parallel_spec.opts').and_return true
|
97
|
+
ParallelSpecs.should_receive(:open).with{|x,y| x =~ %r{script/spec\s+ -O spec/parallel_spec.opts}}.and_return mocked_process
|
98
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
99
|
+
end
|
100
|
+
|
101
|
+
it "uses -O spec/parallel_spec.opts with rspec1" do
|
102
|
+
File.should_receive(:file?).with('spec/parallel_spec.opts').and_return true
|
103
|
+
|
104
|
+
ParallelSpecs.stub!(:bundler_enabled?).and_return true
|
105
|
+
ParallelSpecs.stub!(:run).with("bundle show rspec").and_return "/foo/bar/rspec-1.0.2"
|
106
|
+
|
107
|
+
ParallelSpecs.should_receive(:open).with{|x,y| x =~ %r{spec\s+ -O spec/parallel_spec.opts}}.and_return mocked_process
|
108
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
109
|
+
end
|
110
|
+
|
111
|
+
it "uses -O spec/parallel_spec.opts with rspec2" do
|
112
|
+
File.should_receive(:file?).with('spec/parallel_spec.opts').and_return true
|
113
|
+
|
114
|
+
ParallelSpecs.stub!(:bundler_enabled?).and_return true
|
115
|
+
ParallelSpecs.stub!(:run).with("bundle show rspec").and_return "/foo/bar/rspec-2.4.2"
|
116
|
+
|
117
|
+
ParallelSpecs.should_receive(:open).with{|x,y| x =~ %r{rspec\s+ --color --tty -O spec/parallel_spec.opts}}.and_return mocked_process
|
118
|
+
ParallelSpecs.run_tests(['xxx'],1,{})
|
119
|
+
end
|
120
|
+
|
121
|
+
it "uses options passed in" do
|
122
|
+
ParallelSpecs.should_receive(:open).with{|x,y| x =~ %r{rspec -f n}}.and_return mocked_process
|
123
|
+
ParallelSpecs.run_tests(['xxx'],1, :test_options => '-f n')
|
124
|
+
end
|
125
|
+
|
126
|
+
it "returns the output" do
|
127
|
+
io = open('spec/spec_helper.rb')
|
128
|
+
ParallelSpecs.stub!(:print)
|
129
|
+
ParallelSpecs.should_receive(:open).and_return io
|
130
|
+
ParallelSpecs.run_tests(['xxx'],1,{})[:stdout].should =~ /\$LOAD_PATH << File/
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe :find_results do
|
135
|
+
it "finds multiple results in spec output" do
|
136
|
+
output = <<EOF
|
137
|
+
....F...
|
138
|
+
..
|
139
|
+
failute fsddsfsd
|
140
|
+
...
|
141
|
+
ff.**..
|
142
|
+
0 examples, 0 failures, 0 pending
|
143
|
+
ff.**..
|
144
|
+
1 example, 1 failure, 1 pending
|
145
|
+
EOF
|
146
|
+
|
147
|
+
ParallelSpecs.find_results(output).should == ['0 examples, 0 failures, 0 pending','1 example, 1 failure, 1 pending']
|
148
|
+
end
|
149
|
+
|
150
|
+
it "is robust against scrambeled output" do
|
151
|
+
output = <<EOF
|
152
|
+
....F...
|
153
|
+
..
|
154
|
+
failute fsddsfsd
|
155
|
+
...
|
156
|
+
ff.**..
|
157
|
+
0 exFampl*es, 0 failures, 0 pend.ing
|
158
|
+
ff.**..
|
159
|
+
1 exampF.les, 1 failures, 1 pend.ing
|
160
|
+
EOF
|
161
|
+
|
162
|
+
ParallelSpecs.find_results(output).should == ['0 examples, 0 failures, 0 pending','1 examples, 1 failures, 1 pending']
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ParallelTests::RuntimeLogger do
|
4
|
+
|
5
|
+
describe :writing do
|
6
|
+
it "overwrites the runtime_log file on first log invocation" do
|
7
|
+
class FakeTest
|
8
|
+
end
|
9
|
+
test = FakeTest.new
|
10
|
+
time = Time.now
|
11
|
+
File.open(ParallelTests.runtime_log, 'w'){ |f| f.puts("FooBar") }
|
12
|
+
ParallelTests::RuntimeLogger.send(:class_variable_set,:@@has_started, false)
|
13
|
+
ParallelTests::RuntimeLogger.log(test, time, Time.at(time.to_f+2.00))
|
14
|
+
result = File.read(ParallelTests.runtime_log)
|
15
|
+
result.should_not include('FooBar')
|
16
|
+
result.should include('test/fake_test.rb:2.00')
|
17
|
+
end
|
18
|
+
|
19
|
+
it "appends to the runtime_log file after first log invocation" do
|
20
|
+
class FakeTest
|
21
|
+
end
|
22
|
+
test = FakeTest.new
|
23
|
+
class OtherFakeTest
|
24
|
+
end
|
25
|
+
other_test = OtherFakeTest.new
|
26
|
+
|
27
|
+
time = Time.now
|
28
|
+
File.open(ParallelTests.runtime_log, 'w'){ |f| f.puts("FooBar") }
|
29
|
+
ParallelTests::RuntimeLogger.send(:class_variable_set,:@@has_started, false)
|
30
|
+
ParallelTests::RuntimeLogger.log(test, time, Time.at(time.to_f+2.00))
|
31
|
+
ParallelTests::RuntimeLogger.log(other_test, time, Time.at(time.to_f+2.00))
|
32
|
+
result = File.read(ParallelTests.runtime_log)
|
33
|
+
result.should_not include('FooBar')
|
34
|
+
result.should include('test/fake_test.rb:2.00')
|
35
|
+
result.should include('test/other_fake_test.rb:2.00')
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
describe :formatting do
|
41
|
+
it "formats results for simple test names" do
|
42
|
+
class FakeTest
|
43
|
+
end
|
44
|
+
test = FakeTest.new
|
45
|
+
time = Time.now
|
46
|
+
ParallelTests::RuntimeLogger.message(test, time, Time.at(time.to_f+2.00)).should == 'test/fake_test.rb:2.00'
|
47
|
+
end
|
48
|
+
|
49
|
+
it "formats results for complex test names" do
|
50
|
+
class AVeryComplex
|
51
|
+
class FakeTest
|
52
|
+
end
|
53
|
+
end
|
54
|
+
test = AVeryComplex::FakeTest.new
|
55
|
+
time = Time.now
|
56
|
+
ParallelTests::RuntimeLogger.message(test, time, Time.at(time.to_f+2.00)).should == 'test/a_very_complex/fake_test.rb:2.00'
|
57
|
+
end
|
58
|
+
|
59
|
+
it "guesses subdirectory structure for rails test classes" do
|
60
|
+
module Rails
|
61
|
+
end
|
62
|
+
class ActionController
|
63
|
+
class TestCase
|
64
|
+
end
|
65
|
+
end
|
66
|
+
class FakeControllerTest < ActionController::TestCase
|
67
|
+
end
|
68
|
+
test = FakeControllerTest.new
|
69
|
+
time = Time.now
|
70
|
+
ParallelTests::RuntimeLogger.message(test, time, Time.at(time.to_f+2.00)).should == 'test/functional/fake_controller_test.rb:2.00'
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
@@ -0,0 +1,229 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ParallelTests do
|
4
|
+
test_tests_in_groups(ParallelTests, 'test', '_test.rb')
|
5
|
+
|
6
|
+
describe :parse_rake_args do
|
7
|
+
it "should return the count" do
|
8
|
+
args = {:count => 2}
|
9
|
+
ParallelTests.parse_rake_args(args).should == [2, '', ""]
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should default to the prefix" do
|
13
|
+
args = {:count => "models"}
|
14
|
+
ParallelTests.parse_rake_args(args).should == [Parallel.processor_count, "models", ""]
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should return the count and pattern" do
|
18
|
+
args = {:count => 2, :pattern => "models"}
|
19
|
+
ParallelTests.parse_rake_args(args).should == [2, "models", ""]
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should return the count, pattern, and options" do
|
23
|
+
args = {:count => 2, :pattern => "plain", :options => "-p default" }
|
24
|
+
ParallelTests.parse_rake_args(args).should == [2, "plain", "-p default"]
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should use the PARALLEL_TEST_PROCESSORS env var for processor_count if set" do
|
28
|
+
ENV['PARALLEL_TEST_PROCESSORS'] = '28'
|
29
|
+
ParallelTests.parse_rake_args({}).should == [28, '', '']
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should use count over PARALLEL_TEST_PROCESSORS env var" do
|
33
|
+
ENV['PARALLEL_TEST_PROCESSORS'] = '28'
|
34
|
+
args = {:count => 2}
|
35
|
+
ParallelTests.parse_rake_args(args).should == [2, '', ""]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe :run_tests do
|
40
|
+
it "uses TEST_ENV_NUMBER=blank when called for process 0" do
|
41
|
+
ParallelTests.should_receive(:open).with{|x,y|x=~/TEST_ENV_NUMBER= /}.and_return mocked_process
|
42
|
+
ParallelTests.run_tests(['xxx'],0,{})
|
43
|
+
end
|
44
|
+
|
45
|
+
it "uses TEST_ENV_NUMBER=2 when called for process 1" do
|
46
|
+
ParallelTests.should_receive(:open).with{|x,y| x=~/TEST_ENV_NUMBER=2/}.and_return mocked_process
|
47
|
+
ParallelTests.run_tests(['xxx'],1,{})
|
48
|
+
end
|
49
|
+
|
50
|
+
it "uses options" do
|
51
|
+
ParallelTests.should_receive(:open).with{|x,y| x=~ %r{ruby -Itest .* -- -v}}.and_return mocked_process
|
52
|
+
ParallelTests.run_tests(['xxx'],1,:test_options => '-v')
|
53
|
+
end
|
54
|
+
|
55
|
+
it "returns the output" do
|
56
|
+
io = open('spec/spec_helper.rb')
|
57
|
+
ParallelTests.stub!(:print)
|
58
|
+
ParallelTests.should_receive(:open).and_return io
|
59
|
+
ParallelTests.run_tests(['xxx'],1,{})[:stdout].should =~ /\$LOAD_PATH << File/
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe :test_in_groups do
|
64
|
+
it "does not sort when passed false do_sort option" do
|
65
|
+
ParallelTests.should_not_receive(:smallest_first)
|
66
|
+
ParallelTests.tests_in_groups [], 1, :no_sort => true
|
67
|
+
end
|
68
|
+
|
69
|
+
it "does sort when not passed do_sort option" do
|
70
|
+
ParallelTests.stub!(:tests_with_runtime).and_return([])
|
71
|
+
ParallelTests::Grouper.should_receive(:largest_first).and_return([])
|
72
|
+
ParallelTests.tests_in_groups [], 1
|
73
|
+
end
|
74
|
+
|
75
|
+
it "groups by single_process pattern and then via size" do
|
76
|
+
ParallelTests.should_receive(:with_runtime_info).and_return([['aaa',5],['aaa2',5],['bbb',2],['ccc',1],['ddd',1]])
|
77
|
+
result = ParallelTests.tests_in_groups [], 3, :single_process => [/^a.a/]
|
78
|
+
result.should == [["aaa", "aaa2"], ["bbb"], ["ccc", "ddd"]]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe :find_results do
|
83
|
+
it "finds multiple results in test output" do
|
84
|
+
output = <<EOF
|
85
|
+
Loaded suite /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/rake-0.8.4/lib/rake/rake_test_loader
|
86
|
+
Started
|
87
|
+
..............
|
88
|
+
Finished in 0.145069 seconds.
|
89
|
+
|
90
|
+
10 tests, 20 assertions, 0 failures, 0 errors
|
91
|
+
Loaded suite /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/rake-0.8.4/lib/rake/rake_test_loader
|
92
|
+
Started
|
93
|
+
..............
|
94
|
+
Finished in 0.145069 seconds.
|
95
|
+
|
96
|
+
14 tests, 20 assertions, 0 failures, 0 errors
|
97
|
+
|
98
|
+
EOF
|
99
|
+
|
100
|
+
ParallelTests.find_results(output).should == ['10 tests, 20 assertions, 0 failures, 0 errors','14 tests, 20 assertions, 0 failures, 0 errors']
|
101
|
+
end
|
102
|
+
|
103
|
+
it "is robust against scrambled output" do
|
104
|
+
output = <<EOF
|
105
|
+
Loaded suite /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/rake-0.8.4/lib/rake/rake_test_loader
|
106
|
+
Started
|
107
|
+
..............
|
108
|
+
Finished in 0.145069 seconds.
|
109
|
+
|
110
|
+
10 tests, 20 assertions, 0 failures, 0 errors
|
111
|
+
Loaded suite /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/rake-0.8.4/lib/rake/rake_test_loader
|
112
|
+
Started
|
113
|
+
..............
|
114
|
+
Finished in 0.145069 seconds.
|
115
|
+
|
116
|
+
14 te.dsts, 20 assertions, 0 failures, 0 errors
|
117
|
+
EOF
|
118
|
+
|
119
|
+
ParallelTests.find_results(output).should == ['10 tests, 20 assertions, 0 failures, 0 errors','14 tedsts, 20 assertions, 0 failures, 0 errors']
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe :bundler_enabled? do
|
124
|
+
before do
|
125
|
+
Object.stub!(:const_defined?).with(:Bundler).and_return false
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should return false" do
|
129
|
+
use_temporary_directory_for do
|
130
|
+
ParallelTests.send(:bundler_enabled?).should == false
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should return true when there is a constant called Bundler" do
|
135
|
+
use_temporary_directory_for do
|
136
|
+
Object.stub!(:const_defined?).with(:Bundler).and_return true
|
137
|
+
ParallelTests.send(:bundler_enabled?).should == true
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should be true when there is a Gemfile" do
|
142
|
+
use_temporary_directory_for do
|
143
|
+
FileUtils.touch("Gemfile")
|
144
|
+
ParallelTests.send(:bundler_enabled?).should == true
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should be true when there is a Gemfile in the parent directory" do
|
149
|
+
use_temporary_directory_for do
|
150
|
+
FileUtils.touch(File.join("..", "Gemfile"))
|
151
|
+
ParallelTests.send(:bundler_enabled?).should == true
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
describe :find_tests do
|
157
|
+
it "returns if root is an array" do
|
158
|
+
ParallelTests.send(:find_tests, [1]).should == [1]
|
159
|
+
end
|
160
|
+
|
161
|
+
it "finds all test files" do
|
162
|
+
begin
|
163
|
+
root = "/tmp/test-find_tests-#{rand(999)}"
|
164
|
+
`mkdir #{root}`
|
165
|
+
`mkdir #{root}/a`
|
166
|
+
`mkdir #{root}/b`
|
167
|
+
`touch #{root}/x_test.rb`
|
168
|
+
`touch #{root}/a/x_test.rb`
|
169
|
+
`touch #{root}/a/test.rb`
|
170
|
+
`touch #{root}/b/y_test.rb`
|
171
|
+
`touch #{root}/b/test.rb`
|
172
|
+
`ln -s #{root}/b #{root}/c`
|
173
|
+
`ln -s #{root}/b #{root}/a/`
|
174
|
+
ParallelTests.send(:find_tests, root).sort.should == [
|
175
|
+
"#{root}/a/b/y_test.rb",
|
176
|
+
"#{root}/a/x_test.rb",
|
177
|
+
"#{root}/b/y_test.rb",
|
178
|
+
"#{root}/c/y_test.rb",
|
179
|
+
"#{root}/x_test.rb"
|
180
|
+
]
|
181
|
+
ensure
|
182
|
+
`rm -rf #{root}`
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
it "finds files by pattern" do
|
187
|
+
begin
|
188
|
+
root = "/tmp/test-find_tests-#{rand(999)}"
|
189
|
+
`mkdir #{root}`
|
190
|
+
`mkdir #{root}/a`
|
191
|
+
`touch #{root}/a/x_test.rb`
|
192
|
+
`touch #{root}/a/y_test.rb`
|
193
|
+
`touch #{root}/a/z_test.rb`
|
194
|
+
ParallelTests.send(:find_tests, root, :pattern => '^a/(y|z)_test').sort.should == [
|
195
|
+
"#{root}/a/y_test.rb",
|
196
|
+
"#{root}/a/z_test.rb",
|
197
|
+
]
|
198
|
+
ensure
|
199
|
+
`rm -rf #{root}`
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
describe :summarize_results do
|
205
|
+
it "adds results" do
|
206
|
+
ParallelTests.summarize_results(['1 foo 3 bar','2 foo 5 bar']).should == '8 bars, 3 foos'
|
207
|
+
end
|
208
|
+
|
209
|
+
it "adds results with braces" do
|
210
|
+
ParallelTests.summarize_results(['1 foo(s) 3 bar(s)','2 foo 5 bar']).should == '8 bars, 3 foos'
|
211
|
+
end
|
212
|
+
|
213
|
+
it "adds same results with plurals" do
|
214
|
+
ParallelTests.summarize_results(['1 foo 3 bar','2 foos 5 bar']).should == '8 bars, 3 foos'
|
215
|
+
end
|
216
|
+
|
217
|
+
it "adds non-similar results" do
|
218
|
+
ParallelTests.summarize_results(['1 xxx 2 yyy','1 xxx 2 zzz']).should == '2 xxxs, 2 yyys, 2 zzzs'
|
219
|
+
end
|
220
|
+
|
221
|
+
it "does not pluralize 1" do
|
222
|
+
ParallelTests.summarize_results(['1 xxx 2 yyy']).should == '1 xxx, 2 yyys'
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
it "has a version" do
|
227
|
+
ParallelTests::VERSION.should =~ /^\d+\.\d+\.\d+$/
|
228
|
+
end
|
229
|
+
end
|