parallelized_specs 0.1.8 → 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -12,7 +12,7 @@ begin
12
12
  gem.email = "jake@instructure.com"
13
13
  gem.homepage = "http://github.com/jakesorce/#{gem.name}"
14
14
  gem.authors = "Jake Sorce, Bryan Madsen"
15
- gem.version = "0.1.8"
15
+ gem.version = "0.1.9"
16
16
  end
17
17
 
18
18
  Jeweler::GemcutterTasks.new
data/Readme.md CHANGED
@@ -58,22 +58,20 @@ ParallelizedSpecs uses 1 database per test-process, 2 processes will use `*_test
58
58
  ### 4: Run!
59
59
  rake parallel:spec # RSpec
60
60
 
61
- rake parallel:test[1] --> force 1 CPU --> 86 seconds
62
- rake parallel:test --> got 2 CPUs? --> 47 seconds
63
- rake parallel:test --> got 4 CPUs? --> 26 seconds
61
+ rake parallel:spec[1] --> force 1 CPU --> 86 seconds
62
+ rake parallel:spec --> got 2 CPUs? --> 47 seconds
63
+ rake parallel:spec --> got 4 CPUs? --> 26 seconds
64
64
  ...
65
65
 
66
66
  Test by pattern (e.g. use one integration server per subfolder / see if you broke any 'user'-related tests)
67
67
 
68
- rake parallel:test[^unit] # everything in test/spec folder (every test file matching /^spec/)
69
- rake parallel:test[user] # run users_controller + user_helper + user tests
70
- rake parallel:test['user|product'] # run user and product related tests
71
-
68
+ rake parallel:spec[4,user,] # force 4 CPU and run users specs
69
+ rake parallel:spec['user|product'] # run user and product related specs
72
70
 
73
71
  Example output
74
72
  --------------
75
73
  2 processes for 210 specs, ~ 105 specs per process
76
- ... test output ...
74
+ ... spec output ...
77
75
 
78
76
  843 examples, 0 failures, 1 pending
79
77
 
@@ -98,10 +96,6 @@ Rspec: Add to your `spec/parallelized_specs.opts` (or `spec/spec.opts`) :
98
96
  --format progress
99
97
  --format ParallelizedSpecs::SpecRuntimeLogger --out tmp/parallel_profile.log
100
98
 
101
- Test::Unit: Add to your `test_helper.rb`:
102
- require 'parallelized_specs/runtime_logger'
103
-
104
-
105
99
  SpecSummaryLogger
106
100
  --------------------
107
101
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.8
1
+ 0.1.9
@@ -85,181 +85,177 @@ class ParallelizedSpecs
85
85
 
86
86
  tests_folder = 'spec'
87
87
  tests_folder = File.join(options[:root], tests_folder) unless options[:root].to_s.empty?
88
- if tests.is_a?(Array)
89
- groups = tests_in_groups(tests || tests_folder, num_processes, options)
90
- else
88
+ if !tests.is_a?(Array)
91
89
  files_array = tests.split(/ /)
92
- groups = tests_in_groups(files_array || tests_folder, num_processes, options)
93
90
  end
94
- num_processes = groups.size
91
+ groups = tests_in_groups(files_array || tests || tests_folder, num_processes, options)
95
92
 
96
- #adjust processes to groups
97
- abort "no #{name}s found!" if groups.size == 0
93
+ num_processes = groups.size
98
94
 
99
- num_tests = groups.inject(0) { |sum, item| sum + item.size }
100
- puts "#{num_processes} processes for #{num_tests} #{name}s, ~ #{num_tests / groups.size} #{name}s per process"
95
+ #adjust processes to groups
96
+ abort "no #{name}s found!" if groups.size == 0
101
97
 
102
- test_results = Parallel.map(groups, :in_processes => num_processes) do |group|
103
- run_tests(group, groups.index(group), options)
104
- end
98
+ num_tests = groups.inject(0) { |sum, item| sum + item.size }
99
+ puts "#{num_processes} processes for #{num_tests} #{name}s, ~ #{num_tests / groups.size} #{name}s per process"
105
100
 
106
- #parse and print results
107
- results = find_results(test_results.map { |result| result[:stdout] }*"")
108
- puts ""
109
- puts summarize_results(results)
101
+ test_results = Parallel.map(groups, :in_processes => num_processes) do |group|
102
+ run_tests(group, groups.index(group), options)
103
+ end
110
104
 
111
- #report total time taken
112
- puts ""
113
- puts "Took #{Time.now - start} seconds"
105
+ #parse and print results
106
+ results = find_results(test_results.map { |result| result[:stdout] }*"")
107
+ puts ""
108
+ puts summarize_results(results)
114
109
 
115
- #exit with correct status code so rake parallel:test && echo 123 works
116
- failed = test_results.any? { |result| result[:exit_status] != 0 }
117
- abort "#{name.capitalize}s Failed" if failed
118
- end
110
+ #report total time taken
111
+ puts ""
112
+ puts "Took #{Time.now - start} seconds"
113
+
114
+ #exit with correct status code so rake parallel:test && echo 123 works
115
+ failed = test_results.any? { |result| result[:exit_status] != 0 }
116
+ abort "#{name.capitalize}s Failed" if failed
117
+ end
119
118
 
120
119
  # parallel:spec[:count, :pattern, :options]
121
- def self.parse_rake_args(args)
122
- # order as given by user
123
- args = [args[:count], args[:pattern], args[:options]]
124
-
125
- # count given or empty ?
126
- # parallel:spec[2,models,options]
127
- # parallel:spec[,models,options]
128
- count = args.shift if args.first.to_s =~ /^\d*$/
129
- num_processes = count.to_i unless count.to_s.empty?
130
- num_processes ||= ENV['PARALLEL_TEST_PROCESSORS'].to_i if ENV['PARALLEL_TEST_PROCESSORS']
131
- num_processes ||= Parallel.processor_count
132
-
133
- pattern = args.shift
134
- options = args.shift
135
-
136
- [num_processes.to_i, pattern.to_s, options.to_s]
137
- end
120
+ def self.parse_rake_args(args)
121
+ # order as given by user
122
+ args = [args[:count], args[:pattern]]
123
+
124
+ # count given or empty ?
125
+ count = args.shift if args.first.to_s =~ /^\d*$/
126
+ num_processes = count.to_i unless count.to_s.empty?
127
+ num_processes ||= ENV['PARALLEL_TEST_PROCESSORS'].to_i if ENV['PARALLEL_TEST_PROCESSORS']
128
+ num_processes ||= Parallel.processor_count
129
+
130
+ pattern = args.shift
131
+
132
+ [num_processes.to_i, pattern.to_s]
133
+ end
138
134
 
139
135
  # finds all tests and partitions them into groups
140
- def self.tests_in_groups(tests, num_groups, options)
141
- if options[:no_sort]
142
- Grouper.in_groups(tests, num_groups)
143
- else
144
- tests = with_runtime_info(tests)
145
- Grouper.in_even_groups_by_size(tests, num_groups, options)
146
- end
136
+ def self.tests_in_groups(tests, num_groups, options)
137
+ if options[:no_sort]
138
+ Grouper.in_groups(tests, num_groups)
139
+ else
140
+ tests = with_runtime_info(tests)
141
+ Grouper.in_even_groups_by_size(tests, num_groups, options)
147
142
  end
143
+ end
148
144
 
149
- def self.execute_command(cmd, process_number, options)
150
- cmd = "TEST_ENV_NUMBER=#{test_env_number(process_number)} ; export TEST_ENV_NUMBER; #{cmd}"
151
- f = open("|#{cmd}", 'r')
152
- output = fetch_output(f, options)
153
- f.close
154
- {:stdout => output, :exit_status => $?.exitstatus}
155
- end
145
+ def self.execute_command(cmd, process_number, options)
146
+ cmd = "TEST_ENV_NUMBER=#{test_env_number(process_number)} ; export TEST_ENV_NUMBER; #{cmd}"
147
+ f = open("|#{cmd}", 'r')
148
+ output = fetch_output(f, options)
149
+ f.close
150
+ {:stdout => output, :exit_status => $?.exitstatus}
151
+ end
156
152
 
157
- def self.find_results(test_output)
158
- test_output.split("\n").map { |line|
159
- line = line.gsub(/\.|F|\*/, '')
160
- next unless line_is_result?(line)
161
- line
162
- }.compact
163
- end
153
+ def self.find_results(test_output)
154
+ test_output.split("\n").map { |line|
155
+ line = line.gsub(/\.|F|\*/, '')
156
+ next unless line_is_result?(line)
157
+ line
158
+ }.compact
159
+ end
164
160
 
165
- def self.test_env_number(process_number)
166
- process_number == 0 ? '' : process_number + 1
167
- end
161
+ def self.test_env_number(process_number)
162
+ process_number == 0 ? '' : process_number + 1
163
+ end
168
164
 
169
- def self.runtime_log
170
- 'tmp/parallelized_runtime_test.log'
171
- end
165
+ def self.runtime_log
166
+ 'tmp/parallelized_runtime_test.log'
167
+ end
172
168
 
173
- def self.summarize_results(results)
174
- results = results.join(' ').gsub(/s\b/, '') # combine and singularize results
175
- counts = results.scan(/(\d+) (\w+)/)
176
- sums = counts.inject(Hash.new(0)) do |sum, (number, word)|
177
- sum[word] += number.to_i
178
- sum
179
- end
180
- sums.sort.map { |word, number| "#{number} #{word}#{'s' if number != 1}" }.join(', ')
169
+ def self.summarize_results(results)
170
+ results = results.join(' ').gsub(/s\b/, '') # combine and singularize results
171
+ counts = results.scan(/(\d+) (\w+)/)
172
+ sums = counts.inject(Hash.new(0)) do |sum, (number, word)|
173
+ sum[word] += number.to_i
174
+ sum
181
175
  end
176
+ sums.sort.map { |word, number| "#{number} #{word}#{'s' if number != 1}" }.join(', ')
177
+ end
182
178
 
183
- protected
179
+ protected
184
180
 
185
181
  # read output of the process and print in in chucks
186
- def self.fetch_output(process, options)
187
- all = ''
188
- buffer = ''
189
- timeout = options[:chunk_timeout] || 0.2
190
- flushed = Time.now.to_f
191
-
192
- while (char = process.getc)
193
- char = (char.is_a?(Fixnum) ? char.chr : char) # 1.8 <-> 1.9
194
- all << char
195
-
196
- # print in chunks so large blocks stay together
197
- now = Time.now.to_f
198
- buffer << char
199
- if flushed + timeout < now
200
- print buffer
201
- STDOUT.flush
202
- buffer = ''
203
- flushed = now
204
- end
182
+ def self.fetch_output(process, options)
183
+ all = ''
184
+ buffer = ''
185
+ timeout = options[:chunk_timeout] || 0.2
186
+ flushed = Time.now.to_f
187
+
188
+ while (char = process.getc)
189
+ char = (char.is_a?(Fixnum) ? char.chr : char) # 1.8 <-> 1.9
190
+ all << char
191
+
192
+ # print in chunks so large blocks stay together
193
+ now = Time.now.to_f
194
+ buffer << char
195
+ if flushed + timeout < now
196
+ print buffer
197
+ STDOUT.flush
198
+ buffer = ''
199
+ flushed = now
205
200
  end
201
+ end
206
202
 
207
- # print the remainder
208
- print buffer
209
- STDOUT.flush
203
+ # print the remainder
204
+ print buffer
205
+ STDOUT.flush
210
206
 
211
- all
212
- end
207
+ all
208
+ end
213
209
 
214
210
  # copied from http://github.com/carlhuda/bundler Bundler::SharedHelpers#find_gemfile
215
- def self.bundler_enabled?
216
- return true if Object.const_defined?(:Bundler)
211
+ def self.bundler_enabled?
212
+ return true if Object.const_defined?(:Bundler)
217
213
 
218
- previous = nil
219
- current = File.expand_path(Dir.pwd)
214
+ previous = nil
215
+ current = File.expand_path(Dir.pwd)
220
216
 
221
- until !File.directory?(current) || current == previous
222
- filename = File.join(current, "Gemfile")
223
- return true if File.exists?(filename)
224
- current, previous = File.expand_path("..", current), current
225
- end
226
-
227
- false
217
+ until !File.directory?(current) || current == previous
218
+ filename = File.join(current, "Gemfile")
219
+ return true if File.exists?(filename)
220
+ current, previous = File.expand_path("..", current), current
228
221
  end
229
222
 
230
- def self.line_is_result?(line)
231
- line =~ /\d+ failure/
232
- end
223
+ false
224
+ end
225
+
226
+ def self.line_is_result?(line)
227
+ line =~ /\d+ failure/
228
+ end
233
229
 
234
- def self.with_runtime_info(tests)
235
- lines = File.read(runtime_log).split("\n") rescue []
236
-
237
- # use recorded test runtime if we got enough data
238
- if lines.size * 1.5 > tests.size
239
- puts "Using recorded test runtime"
240
- times = Hash.new(1)
241
- lines.each do |line|
242
- test, time = line.split(":")
243
- next unless test and time
244
- times[File.expand_path(test)] = time.to_f
245
- end
246
- tests.sort.map { |test| [test, times[test]] }
247
- else # use file sizes
248
- tests.sort.map { |test| [test, File.stat(test).size] }
230
+ def self.with_runtime_info(tests)
231
+ lines = File.read(runtime_log).split("\n") rescue []
232
+
233
+ # use recorded test runtime if we got enough data
234
+ if lines.size * 1.5 > tests.size
235
+ puts "Using recorded test runtime"
236
+ times = Hash.new(1)
237
+ lines.each do |line|
238
+ test, time = line.split(":")
239
+ next unless test and time
240
+ times[File.expand_path(test)] = time.to_f
249
241
  end
242
+ tests.sort.map { |test| [test, times[test]] }
243
+ else # use file sizes
244
+ tests.sort.map { |test| [test, File.stat(test).size] }
250
245
  end
246
+ end
251
247
 
252
- def self.find_tests(root, options={})
253
- if root.is_a?(Array)
254
- root
255
- else
256
- # follow one symlink and direct children
257
- # http://stackoverflow.com/questions/357754/can-i-traverse-symlinked-directories-in-ruby-with-a-glob
258
- files = Dir["#{root}/**{,/*/**}/*#{test_suffix}"].uniq
259
- files = files.map { |f| f.sub(root+'/', '') }
260
- files = files.grep(/#{options[:pattern]}/)
261
- files.map { |f| "/#{f}" }
262
- end
248
+ def self.find_tests(root, options={})
249
+ if root.is_a?(Array)
250
+ root
251
+ else
252
+ # follow one symlink and direct children
253
+ # http://stackoverflow.com/questions/357754/can-i-traverse-symlinked-directories-in-ruby-with-a-glob
254
+ files = Dir["#{root}/**{,/*/**}/*#{test_suffix}"].uniq
255
+ files = files.map { |f| f.sub(root+'/', '') }
256
+ files = files.grep(/#{options[:pattern]}/)
257
+ files.map { |f| "/#{f}" }
263
258
  end
259
+ end
264
260
 
265
261
  end
@@ -13,19 +13,24 @@ namespace :parallel do
13
13
  ParallelizedSpecs.execute_parallel_db('rake db:drop RAILS_ENV=test', args)
14
14
  end
15
15
 
16
- desc "update test databases by dumping and loading --> parallel:prepare[num_cpus]"
17
- task(:prepare, [:count] => 'db:abort_if_pending_migrations') do |t, args|
16
+ desc "update test databases by dumping and loading --> parallel:dump_load[num_cpus]"
17
+ task(:dump_load, [:count] => 'db:abort_if_pending_migrations') do |t, args|
18
18
  if defined?(ActiveRecord) && ActiveRecord::Base.schema_format == :ruby
19
19
  # dump then load in parallel
20
20
  Rake::Task['db:schema:dump'].invoke
21
- Rake::Task['parallel:load_schema'].invoke(args[:count])
21
+ Rake::Task['parallel:load_schema'].invoke
22
22
  else
23
- # there is no separate dump / load for schema_format :sql -> do it safe and slow
23
+ # there is no separate dump / load for s(args[:count])chema_format :sql -> do it safe and slow
24
24
  args = args.to_hash.merge(:non_parallel => true) # normal merge returns nil
25
- ParallelizedSpecs.execute_parallel_db('rake db:test:prepare --trace', args)
25
+ ParallelizedSpecs.execute_parallel_db('rake db:test:dump_load', args)
26
26
  end
27
27
  end
28
28
 
29
+ desc "drop, create, migrate all in one --> parallel:prepare[num_cpus]"
30
+ task :prepare, :count do |t, args|
31
+ ParallelizedSpecs.execute_parallel_db('rake db:drop db:create db:migrate RAILS_ENV=test', args)
32
+ end
33
+
29
34
  # when dumping/resetting takes too long
30
35
  desc "update test databases via db:migrate --> parallel:migrate[num_cpus]"
31
36
  task :migrate, :count do |t, args|
@@ -40,7 +45,7 @@ namespace :parallel do
40
45
 
41
46
  desc "run spec in parallel with parallel:spec[num_cpus]"
42
47
  task 'spec', :count, :pattern, :options, :arguments do |t, args|
43
- count, pattern, options = ParallelizedSpecs.parse_rake_args(args)
48
+ count, pattern = ParallelizedSpecs.parse_rake_args(args)
44
49
  opts = {:count => count, :pattern => pattern, :root => Rails.root, :files => args[:arguments]}
45
50
  ParallelizedSpecs.execute_parallel_specs(opts)
46
51
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "parallelized_specs"
8
- s.version = "0.1.8"
8
+ s.version = "0.1.9"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Jake Sorce, Bryan Madsen"]
12
- s.date = "2012-05-03"
12
+ s.date = "2012-05-07"
13
13
  s.email = "jake@instructure.com"
14
14
  s.files = [
15
15
  "Gemfile",
@@ -31,6 +31,7 @@ Gem::Specification.new do |s|
31
31
  "lib/parallelized_specs/tasks.rb",
32
32
  "lib/tasks/parallelized_specs.rake",
33
33
  "parallelized_specs.gemspec",
34
+ "spec/integration_spec.rb",
34
35
  "spec/parallelized_specs/spec_failure_logger_spec.rb",
35
36
  "spec/parallelized_specs/spec_runtime_logger_spec.rb",
36
37
  "spec/parallelized_specs/spec_summary_logger_spec.rb",
@@ -0,0 +1,133 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'CLI' do
4
+ before do
5
+ `rm -rf #{folder}`
6
+ end
7
+
8
+ after do
9
+ `rm -rf #{folder}`
10
+ end
11
+
12
+ def folder
13
+ "/tmp/parallel_tests_tests"
14
+ end
15
+
16
+ def write(file, content)
17
+ path = "#{folder}/#{file}"
18
+ `mkdir -p #{File.dirname(path)}` unless File.exist?(File.dirname(path))
19
+ File.open(path, 'w'){|f| f.write content }
20
+ path
21
+ end
22
+
23
+ def bin_folder
24
+ "#{File.expand_path(File.dirname(__FILE__))}/../bin"
25
+ end
26
+
27
+ def executable
28
+ "#{bin_folder}/parallel_test"
29
+ end
30
+
31
+ def run_tests(options={})
32
+ `cd #{folder} && #{executable} --chunk-timeout 999 -t #{options[:type] || 'spec'} -n #{options[:processes]||2} #{options[:add]} 2>&1`
33
+ end
34
+
35
+ it "runs tests in parallel" do
36
+ write 'spec/xxx_spec.rb', 'describe("it"){it("should"){puts "TEST1"}}'
37
+ write 'spec/xxx2_spec.rb', 'describe("it"){it("should"){puts "TEST2"}}'
38
+ result = run_tests
39
+
40
+ # test ran and gave their puts
41
+ result.should include('TEST1')
42
+ result.should include('TEST2')
43
+
44
+ # all results present
45
+ result.scan('1 example, 0 failure').size.should == 2 # 2 results
46
+ result.scan('2 examples, 0 failures').size.should == 1 # 1 summary
47
+ result.scan(/Finished in \d+\.\d+ seconds/).size.should == 2
48
+ result.scan(/Took \d+\.\d+ seconds/).size.should == 1 # parallel summary
49
+ $?.success?.should == true
50
+ end
51
+
52
+ it "does not run any tests if there are none" do
53
+ write 'spec/xxx.rb', 'xxx'
54
+ result = run_tests
55
+ result.should include('No examples found')
56
+ result.should include('Took')
57
+ end
58
+
59
+ it "fails when tests fail" do
60
+ write 'spec/xxx_spec.rb', 'describe("it"){it("should"){puts "TEST1"}}'
61
+ write 'spec/xxx2_spec.rb', 'describe("it"){it("should"){1.should == 2}}'
62
+ result = run_tests
63
+
64
+ result.scan('1 example, 1 failure').size.should == 1
65
+ result.scan('1 example, 0 failure').size.should == 1
66
+ result.scan('2 examples, 1 failure').size.should == 1
67
+ $?.success?.should == false
68
+ end
69
+
70
+ it "can exec given commands with ENV['TEST_ENV_NUM']" do
71
+ result = `#{executable} -e 'ruby -e "print ENV[:TEST_ENV_NUMBER.to_s].to_i"' -n 4`
72
+ result.gsub('"','').split('').sort.should == %w[0 2 3 4]
73
+ end
74
+
75
+ it "can exec given command non-parallel" do
76
+ result = `#{executable} -e 'ruby -e "sleep(rand(10)/100.0); puts ENV[:TEST_ENV_NUMBER.to_s].inspect"' -n 4 --non-parallel`
77
+ result.split("\n").should == %w["" "2" "3" "4"]
78
+ end
79
+
80
+ it "exists with success if all sub-processes returned success" do
81
+ system("#{executable} -e 'cat /dev/null' -n 4").should == true
82
+ end
83
+
84
+ it "exists with failure if any sub-processes returned failure" do
85
+ system("#{executable} -e 'test -e xxxx' -n 4").should == false
86
+ end
87
+
88
+ it "can run through parallel_spec / parallel_cucumber" do
89
+ version = `#{executable} -v`
90
+ `#{bin_folder}/parallel_spec -v`.should == version
91
+ `#{bin_folder}/parallel_cucumber -v`.should == version
92
+ end
93
+
94
+ it "runs faster with more processes" do
95
+ 2.times{|i|
96
+ write "spec/xxx#{i}_spec.rb", 'describe("it"){it("should"){sleep 5}}; $stderr.puts ENV["TEST_ENV_NUMBER"]'
97
+ }
98
+ t = Time.now
99
+ run_tests(:processes => 2)
100
+ expected = 10
101
+ (Time.now - t).should <= expected
102
+ end
103
+
104
+ it "can can with given files" do
105
+ write "spec/x1_spec.rb", "puts '111'"
106
+ write "spec/x2_spec.rb", "puts '222'"
107
+ write "spec/x3_spec.rb", "puts '333'"
108
+ result = run_tests(:add => 'spec/x1_spec.rb spec/x3_spec.rb')
109
+ result.should include('111')
110
+ result.should include('333')
111
+ result.should_not include('222')
112
+ end
113
+
114
+ it "can run with test-options" do
115
+ write "spec/x1_spec.rb", ""
116
+ write "spec/x2_spec.rb", ""
117
+ result = run_tests(:add => "--test-options ' --version'", :processes => 2)
118
+ result.should =~ /\d+\.\d+\.\d+.*\d+\.\d+\.\d+/m # prints version twice
119
+ end
120
+
121
+ it "runs with test::unit" do
122
+ write "test/x1_test.rb", "require 'test/unit'; class XTest < Test::Unit::TestCase; def test_xxx; end; end"
123
+ result = run_tests(:type => :test)
124
+ result.should include('1 test')
125
+ $?.success?.should == true
126
+ end
127
+
128
+ it "passes test options to test::unit" do
129
+ write "test/x1_test.rb", "require 'test/unit'; class XTest < Test::Unit::TestCase; def test_xxx; end; end"
130
+ result = run_tests(:type => :test, :add => '--test-options "-v"')
131
+ result.should include('test_xxx') # verbose output of every test
132
+ end
133
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parallelized_specs
3
3
  version: !ruby/object:Gem::Version
4
- hash: 11
4
+ hash: 9
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 8
10
- version: 0.1.8
9
+ - 9
10
+ version: 0.1.9
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jake Sorce, Bryan Madsen
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-05-03 00:00:00 Z
18
+ date: 2012-05-07 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: parallel
@@ -59,6 +59,7 @@ files:
59
59
  - lib/parallelized_specs/tasks.rb
60
60
  - lib/tasks/parallelized_specs.rake
61
61
  - parallelized_specs.gemspec
62
+ - spec/integration_spec.rb
62
63
  - spec/parallelized_specs/spec_failure_logger_spec.rb
63
64
  - spec/parallelized_specs/spec_runtime_logger_spec.rb
64
65
  - spec/parallelized_specs/spec_summary_logger_spec.rb