parallelized_specs 0.0.1

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.
@@ -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