parallelized_specs 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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