parallelized_specs 0.1.8 → 0.1.9

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