parallel_tests 3.4.0 → 3.5.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fd8878310c757d2a906bbf5ca62b68e21941cc79472a9833944f88087449c229
4
- data.tar.gz: d55a5ac186f1c16d9568b8f6bb145e0016bafc1c2fb9748593e96997eaf2034c
3
+ metadata.gz: 296e1e8f85f982a03a1b03882cdb265518add4b7a426defa0e393248dab74c0c
4
+ data.tar.gz: '09ca0aaa70fbf4ad7d73ce91c83d1c16b69fdc1612931ee1e6f71dd87cb1bbb9'
5
5
  SHA512:
6
- metadata.gz: f01821e38506525feaafb8a9ff5a480ab1f6f2b0bed849088d72682a699f82ae50bb2a78b94526f243a65c2474ff8f2d3a06c204b44431a7687d877cbbc91dd8
7
- data.tar.gz: 2823702fc7e5d047a69c57d3ee4c0b72afbb51603d58e34a3656899d0026a4b749e94494b9edf234fdcc5fd81bae59dfba55f920d777f5f7d1f7c21fb5219552
6
+ metadata.gz: 5f627a0bf28e53045281f616cecdc57c70da160c525e62e2425ccd431f7ac1f0c70f54ca72661e84a2ace1a9bdbb59cd54f602ad71c0df178f00e01c275ef4fa
7
+ data.tar.gz: 28119c3ec31c49c22e01c6c737fd9cfb7fa922e5bbfbfc3e90260c5714a6a1cabfbcaff2e1e91377d33811362ee038d4bbee21027fb98208e44485aaa863e89d
data/Readme.md CHANGED
@@ -37,6 +37,9 @@ test:
37
37
  ### Copy development schema (repeat after migrations)
38
38
  rake parallel:prepare
39
39
 
40
+ ### Run migrations in additional database(s) (repeat after migrations)
41
+ rake parallel:migrate
42
+
40
43
  ### Setup environment from scratch (create db and loads schema, useful for CI)
41
44
  rake parallel:setup
42
45
 
@@ -142,17 +145,19 @@ Add the following to your `.rspec_parallel` (or `.rspec`) :
142
145
  RSpec: FailuresLogger
143
146
  -----------------------
144
147
 
145
- Produce pasteable command-line snippets for each failed example.
148
+ Produce pastable command-line snippets for each failed example. For example:
146
149
 
147
- E.g.
150
+ ```bash
151
+ rspec /path/to/my_spec.rb:123 # should do something
152
+ ```
148
153
 
149
- rspec /path/to/my_spec.rb:123 # should do something
150
-
151
- Add the following to your `.rspec_parallel` (or `.rspec`) :
154
+ Add to `.rspec_parallel` or use as CLI flag:
152
155
 
153
156
  --format progress
154
157
  --format ParallelTests::RSpec::FailuresLogger --out tmp/failing_specs.log
155
158
 
159
+ (Not needed to retry failures, for that pass [--only-failures](https://relishapp.com/rspec/rspec-core/docs/command-line/only-failures) to rspec)
160
+
156
161
  Cucumber: FailuresLogger
157
162
  -----------------------
158
163
 
@@ -208,7 +213,16 @@ Options are:
208
213
  -i, --isolate Do not run any other tests in the group used by --single(-s).
209
214
  Automatically turned on if --isolate-n is set above 0.
210
215
  --isolate-n Number of processes for isolated groups. Default to 1 when --isolate is on.
211
- --only-group INT[, INT]
216
+ --specify-groups [SPECS] Use 'specify-groups' if you want to specify multiple specs running in multiple
217
+ processes in a specific formation. Commas indicate specs in the same process,
218
+ pipes indicate specs in a new process. Cannot use with --single, --isolate, or
219
+ --isolate-n. Ex.
220
+ Ex.
221
+ $ parallel_tests -n 3 . --specify-groups '1_spec.rb,2_spec.rb|3_spec.rb'
222
+ Process 1 will contain 1_spec.rb and 2_spec.rb
223
+ Process 2 will contain 3_spec.rb
224
+ Process 3 will contain all other specs
225
+ --only-group INT[,INT]
212
226
  -e, --exec [COMMAND] execute this code parallel and with ENV['TEST_ENV_NUMBER']
213
227
  -o, --test-options '[OPTIONS]' execute test commands with those options
214
228
  -t, --type [TYPE] test(default) / rspec / cucumber / spinach
@@ -282,7 +296,7 @@ TIPS
282
296
  `export PARALLEL_TEST_FIRST_IS_1=true` will provide the same result
283
297
  - [email_spec and/or action_mailer_cache_delivery](https://github.com/grosser/parallel_tests/wiki)
284
298
  - [zeus-parallel_tests](https://github.com/sevos/zeus-parallel_tests)
285
- - [Distributed parallel test (e.g. Travis Support)](https://github.com/grosser/parallel_tests/wiki/Distributed-Parallel-Tests-and-Travis-Support)
299
+ - [Distributed Parallel Tests on CI systems)](https://github.com/grosser/parallel_tests/wiki/Distributed-Parallel-Tests-on-CI-systems) learn how `parallel_tests` can run on distributed servers such as Travis and GitLab-CI. Also shows you how to use parallel_tests without adding `TEST_ENV_NUMBER`-backends
286
300
  - [Capybara setup](https://github.com/grosser/parallel_tests/wiki)
287
301
  - [Sphinx setup](https://github.com/grosser/parallel_tests/wiki)
288
302
  - [Capistrano setup](https://github.com/grosser/parallel_tests/wiki/Remotely-with-capistrano) let your tests run on a big box instead of your laptop
@@ -379,6 +393,7 @@ inspired by [pivotal labs](https://blog.pivotal.io/labs/labs/parallelize-your-rs
379
393
  - [alboyadjian](https://github.com/alboyadjian)
380
394
  - [Nathan Broadbent](https://github.com/ndbroadbent)
381
395
  - [Vikram B Kumar](https://github.com/v-kumar)
396
+ - [Joshua Pinter](https://github.com/joshuapinter)
382
397
 
383
398
  [Michael Grosser](http://grosser.it)<br/>
384
399
  michael@grosser.it<br/>
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  # enable local usage from cloned repo
4
- root = File.expand_path("../..", __FILE__)
5
+ root = File.expand_path('..', __dir__)
5
6
  $LOAD_PATH << "#{root}/lib" if File.exist?("#{root}/Gemfile")
6
7
 
7
8
  require "parallel_tests"
data/bin/parallel_rspec CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  # enable local usage from cloned repo
4
- root = File.expand_path("../..", __FILE__)
5
+ root = File.expand_path('..', __dir__)
5
6
  $LOAD_PATH << "#{root}/lib" if File.exist?("#{root}/Gemfile")
6
7
 
7
8
  require "parallel_tests"
data/bin/parallel_spinach CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  # enable local usage from cloned repo
4
- root = File.expand_path("../..", __FILE__)
5
+ root = File.expand_path('..', __dir__)
5
6
  $LOAD_PATH << "#{root}/lib" if File.exist?("#{root}/Gemfile")
6
7
 
7
8
  require "parallel_tests"
data/bin/parallel_test CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  # enable local usage from cloned repo
4
- root = File.expand_path("../..", __FILE__)
5
+ root = File.expand_path('..', __dir__)
5
6
  $LOAD_PATH << "#{root}/lib" if File.exist?("#{root}/Gemfile")
6
7
 
7
8
  require "parallel_tests"
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require "parallel"
2
3
  require "parallel_tests/railtie" if defined? Rails::Railtie
3
4
  require "rbconfig"
@@ -17,7 +18,7 @@ module ParallelTests
17
18
  count,
18
19
  ENV["PARALLEL_TEST_PROCESSORS"],
19
20
  Parallel.processor_count
20
- ].detect{|c| not c.to_s.strip.empty? }.to_i
21
+ ].detect { |c| !c.to_s.strip.empty? }.to_i
21
22
  end
22
23
 
23
24
  def with_pid_file
@@ -57,7 +58,8 @@ module ParallelTests
57
58
  until !File.directory?(current) || current == previous
58
59
  filename = File.join(current, "Gemfile")
59
60
  return true if File.exist?(filename)
60
- current, previous = File.expand_path("..", current), current
61
+ previous = current
62
+ current = File.expand_path("..", current)
61
63
  end
62
64
 
63
65
  false
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'optparse'
2
3
  require 'tempfile'
3
4
  require 'parallel_tests'
@@ -14,7 +15,7 @@ module ParallelTests
14
15
  ENV['DISABLE_SPRING'] ||= '1'
15
16
 
16
17
  num_processes = ParallelTests.determine_number_of_processes(options[:count])
17
- num_processes = num_processes * (options[:multiply] || 1)
18
+ num_processes *= (options[:multiply] || 1)
18
19
 
19
20
  options[:first_is_1] ||= first_is_1?
20
21
 
@@ -56,12 +57,12 @@ module ParallelTests
56
57
  def run_tests_in_parallel(num_processes, options)
57
58
  test_results = nil
58
59
 
59
- run_tests_proc = -> {
60
+ run_tests_proc = -> do
60
61
  groups = @runner.tests_in_groups(options[:files], num_processes, options)
61
- groups.reject! &:empty?
62
+ groups.reject!(&:empty?)
62
63
 
63
64
  test_results = if options[:only_group]
64
- groups_to_run = options[:only_group].collect{|i| groups[i - 1]}.compact
65
+ groups_to_run = options[:only_group].map { |i| groups[i - 1] }.compact
65
66
  report_number_of_tests(groups_to_run) unless options[:quiet]
66
67
  execute_in_parallel(groups_to_run, groups_to_run.size, options) do |group|
67
68
  run_tests(group, groups_to_run.index(group), 1, options)
@@ -75,7 +76,7 @@ module ParallelTests
75
76
  end
76
77
 
77
78
  report_results(test_results, options) unless options[:quiet]
78
- }
79
+ end
79
80
 
80
81
  if options[:quiet]
81
82
  run_tests_proc.call
@@ -88,7 +89,7 @@ module ParallelTests
88
89
 
89
90
  def run_tests(group, process_number, num_processes, options)
90
91
  if group.empty?
91
- {:stdout => '', :exit_status => 0, :command => '', :seed => nil}
92
+ { stdout: '', exit_status: 0, command: '', seed: nil }
92
93
  else
93
94
  @runner.run_tests(group, process_number, num_processes, options)
94
95
  end
@@ -115,7 +116,7 @@ module ParallelTests
115
116
  end
116
117
 
117
118
  def report_results(test_results, options)
118
- results = @runner.find_results(test_results.map { |result| result[:stdout] }*"")
119
+ results = @runner.find_results(test_results.map { |result| result[:stdout] } * "")
119
120
  puts ""
120
121
  puts @runner.summarize_results(results)
121
122
 
@@ -140,20 +141,31 @@ module ParallelTests
140
141
  def report_number_of_tests(groups)
141
142
  name = @runner.test_file_name
142
143
  num_processes = groups.size
143
- num_tests = groups.map(&:size).inject(0, :+)
144
+ num_tests = groups.map(&:size).sum
144
145
  tests_per_process = (num_processes == 0 ? 0 : num_tests / num_processes)
145
- puts "#{num_processes} processes for #{num_tests} #{name}s, ~ #{tests_per_process} #{name}s per process"
146
+ puts "#{pluralize(num_processes, 'process')} for #{pluralize(num_tests, name)}, ~ #{pluralize(tests_per_process, name)} per process"
147
+ end
148
+
149
+ def pluralize(n, singular)
150
+ if n == 1
151
+ "1 #{singular}"
152
+ elsif singular.end_with?('s', 'sh', 'ch', 'x', 'z')
153
+ "#{n} #{singular}es"
154
+ else
155
+ "#{n} #{singular}s"
156
+ end
146
157
  end
147
158
 
148
- #exit with correct status code so rake parallel:test && echo 123 works
159
+ # exit with correct status code so rake parallel:test && echo 123 works
149
160
  def any_test_failed?(test_results)
150
161
  test_results.any? { |result| result[:exit_status] != 0 }
151
162
  end
152
163
 
153
164
  def parse_options!(argv)
165
+ newline_padding = " " * 37
154
166
  options = {}
155
167
  OptionParser.new do |opts|
156
- opts.banner = <<-BANNER.gsub(/^ /, '')
168
+ opts.banner = <<~BANNER
157
169
  Run all tests in parallel, giving each process ENV['TEST_ENV_NUMBER'] ('', '2', '3', ...)
158
170
 
159
171
  [optional] Only selected files & folders:
@@ -167,38 +179,51 @@ module ParallelTests
167
179
  opts.on("-n [PROCESSES]", Integer, "How many processes to use, default: available CPUs") { |n| options[:count] = n }
168
180
  opts.on("-p", "--pattern [PATTERN]", "run tests matching this regex pattern") { |pattern| options[:pattern] = /#{pattern}/ }
169
181
  opts.on("--exclude-pattern", "--exclude-pattern [PATTERN]", "exclude tests matching this regex pattern") { |pattern| options[:exclude_pattern] = /#{pattern}/ }
170
- opts.on("--group-by [TYPE]", <<-TEXT.gsub(/^ /, '')
171
- group tests by:
172
- found - order of finding files
173
- steps - number of cucumber/spinach steps
174
- scenarios - individual cucumber scenarios
175
- filesize - by size of the file
176
- runtime - info from runtime log
177
- default - runtime when runtime log is filled otherwise filesize
182
+ opts.on(
183
+ "--group-by [TYPE]",
184
+ <<~TEXT.rstrip.split("\n").join("\n#{newline_padding}")
185
+ group tests by:
186
+ found - order of finding files
187
+ steps - number of cucumber/spinach steps
188
+ scenarios - individual cucumber scenarios
189
+ filesize - by size of the file
190
+ runtime - info from runtime log
191
+ default - runtime when runtime log is filled otherwise filesize
178
192
  TEXT
179
- ) { |type| options[:group_by] = type.to_sym }
180
- opts.on("-m [FLOAT]", "--multiply-processes [FLOAT]", Float, "use given number as a multiplier of processes to run") { |multiply| options[:multiply] = multiply }
181
-
182
- opts.on("-s [PATTERN]", "--single [PATTERN]",
183
- "Run all matching files in the same process") do |pattern|
184
-
185
- options[:single_process] ||= []
186
- options[:single_process] << /#{pattern}/
193
+ ) { |type| options[:group_by] = type.to_sym }
194
+ opts.on("-m [FLOAT]", "--multiply-processes [FLOAT]", Float, "use given number as a multiplier of processes to run") do |multiply|
195
+ options[:multiply] = multiply
187
196
  end
188
197
 
189
- opts.on("-i", "--isolate",
190
- "Do not run any other tests in the group used by --single(-s)") do |pattern|
198
+ opts.on("-s [PATTERN]", "--single [PATTERN]", "Run all matching files in the same process") do |pattern|
199
+ (options[:single_process] ||= []) << /#{pattern}/
200
+ end
191
201
 
202
+ opts.on("-i", "--isolate", "Do not run any other tests in the group used by --single(-s)") do
192
203
  options[:isolate] = true
193
204
  end
194
205
 
195
- opts.on("--isolate-n [PROCESSES]",
206
+ opts.on(
207
+ "--isolate-n [PROCESSES]",
196
208
  Integer,
197
- "Use 'isolate' singles with number of processes, default: 1.") do |n|
198
- options[:isolate_count] = n
199
- end
209
+ "Use 'isolate' singles with number of processes, default: 1."
210
+ ) { |n| options[:isolate_count] = n }
211
+
212
+ opts.on(
213
+ "--specify-groups [SPECS]",
214
+ <<~TEXT.rstrip.split("\n").join("\n#{newline_padding}")
215
+ Use 'specify-groups' if you want to specify multiple specs running in multiple
216
+ processes in a specific formation. Commas indicate specs in the same process,
217
+ pipes indicate specs in a new process. Cannot use with --single, --isolate, or
218
+ --isolate-n. Ex.
219
+ $ parallel_tests -n 3 . --specify-groups '1_spec.rb,2_spec.rb|3_spec.rb'
220
+ Process 1 will contain 1_spec.rb and 2_spec.rb
221
+ Process 2 will contain 3_spec.rb
222
+ Process 3 will contain all other specs
223
+ TEXT
224
+ ) { |groups| options[:specify_groups] = groups }
200
225
 
201
- opts.on("--only-group INT[, INT]", Array) { |groups| options[:only_group] = groups.map(&:to_i) }
226
+ opts.on("--only-group INT[,INT]", Array) { |groups| options[:only_group] = groups.map(&:to_i) }
202
227
 
203
228
  opts.on("-e", "--exec [COMMAND]", "execute this code parallel and with ENV['TEST_ENV_NUMBER']") { |path| options[:execute] = path }
204
229
  opts.on("-o", "--test-options '[OPTIONS]'", "execute test commands with those options") { |arg| options[:test_options] = arg.lstrip }
@@ -210,18 +235,20 @@ module ParallelTests
210
235
  abort
211
236
  end
212
237
  end
213
- opts.on("--suffix [PATTERN]", <<-TEXT.gsub(/^ /, '')
214
- override built in test file pattern (should match suffix):
215
- '_spec\.rb$' - matches rspec files
216
- '_(test|spec).rb$' - matches test or spec files
238
+ opts.on(
239
+ "--suffix [PATTERN]",
240
+ <<~TEXT.rstrip.split("\n").join("\n#{newline_padding}")
241
+ override built in test file pattern (should match suffix):
242
+ '_spec\.rb$' - matches rspec files
243
+ '_(test|spec).rb$' - matches test or spec files
217
244
  TEXT
218
- ) { |pattern| options[:suffix] = /#{pattern}/ }
245
+ ) { |pattern| options[:suffix] = /#{pattern}/ }
219
246
  opts.on("--serialize-stdout", "Serialize stdout output, nothing will be written until everything is done") { options[:serialize_stdout] = true }
220
247
  opts.on("--prefix-output-with-test-env-number", "Prefixes test env number to the output when not using --serialize-stdout") { options[:prefix_output_with_test_env_number] = true }
221
248
  opts.on("--combine-stderr", "Combine stderr into stdout, useful in conjunction with --serialize-stdout") { options[:combine_stderr] = true }
222
249
  opts.on("--non-parallel", "execute same commands but do not in parallel, needs --exec") { options[:non_parallel] = true }
223
250
  opts.on("--no-symlinks", "Do not traverse symbolic links to find test files") { options[:symlinks] = false }
224
- opts.on('--ignore-tags [PATTERN]', 'When counting steps ignore scenarios with tags that match this pattern') { |arg| options[:ignore_tag_pattern] = arg }
251
+ opts.on('--ignore-tags [PATTERN]', 'When counting steps ignore scenarios with tags that match this pattern') { |arg| options[:ignore_tag_pattern] = arg }
225
252
  opts.on("--nice", "execute test commands with low priority.") { options[:nice] = true }
226
253
  opts.on("--runtime-log [PATH]", "Location of previously recorded test runtimes") { |path| options[:runtime_log] = path }
227
254
  opts.on("--allowed-missing [INT]", Integer, "Allowed percentage of missing runtimes (default = 50)") { |percent| options[:allowed_missing_percent] = percent }
@@ -232,13 +259,17 @@ module ParallelTests
232
259
  opts.on("--verbose-process-command", "Displays only the command that will be executed by each process") { options[:verbose_process_command] = true }
233
260
  opts.on("--verbose-rerun-command", "When there are failures, displays the command executed by each process that failed") { options[:verbose_rerun_command] = true }
234
261
  opts.on("--quiet", "Print only tests output") { options[:quiet] = true }
235
- opts.on("-v", "--version", "Show Version") { puts ParallelTests::VERSION; exit }
236
- opts.on("-h", "--help", "Show this.") { puts opts; exit }
262
+ opts.on("-v", "--version", "Show Version") do
263
+ puts ParallelTests::VERSION
264
+ exit 0
265
+ end
266
+ opts.on("-h", "--help", "Show this.") do
267
+ puts opts
268
+ exit 0
269
+ end
237
270
  end.parse!(argv)
238
271
 
239
- if options[:verbose] && options[:quiet]
240
- raise "Both options are mutually exclusive: verbose & quiet"
241
- end
272
+ raise "Both options are mutually exclusive: verbose & quiet" if options[:verbose] && options[:quiet]
242
273
 
243
274
  if options[:count] == 0
244
275
  options.delete(:count)
@@ -255,12 +286,18 @@ module ParallelTests
255
286
 
256
287
  options[:group_by] ||= :filesize if options[:only_group]
257
288
 
258
- raise "--group-by found and --single-process are not supported" if options[:group_by] == :found and options[:single_process]
289
+ if options[:group_by] == :found && options[:single_process]
290
+ raise "--group-by found and --single-process are not supported"
291
+ end
259
292
  allowed = [:filesize, :runtime, :found]
260
293
  if !allowed.include?(options[:group_by]) && options[:only_group]
261
294
  raise "--group-by #{allowed.join(" or ")} is required for --only-group"
262
295
  end
263
296
 
297
+ if options[:specify_groups] && (options.keys & [:single_process, :isolate, :isolate_count]).any?
298
+ raise "Can't pass --specify-groups with any of these keys: --single, --isolate, or --isolate-n"
299
+ end
300
+
264
301
  options
265
302
  end
266
303
 
@@ -272,7 +309,7 @@ module ParallelTests
272
309
 
273
310
  def extract_test_options(argv)
274
311
  dash_index = argv.index("--") || -1
275
- argv[dash_index+1..-1]
312
+ argv[dash_index + 1..-1]
276
313
  end
277
314
 
278
315
  def append_test_options(options, argv)
@@ -292,7 +329,7 @@ module ParallelTests
292
329
 
293
330
  def execute_shell_command_in_parallel(command, num_processes, options)
294
331
  runs = if options[:only_group]
295
- options[:only_group].map{|g| g - 1}
332
+ options[:only_group].map { |g| g - 1 }
296
333
  else
297
334
  (0...num_processes).to_a
298
335
  end
@@ -311,13 +348,13 @@ module ParallelTests
311
348
  abort if results.any? { |r| r[:exit_status] != 0 }
312
349
  end
313
350
 
314
- def report_time_taken
315
- seconds = ParallelTests.delta { yield }.to_i
351
+ def report_time_taken(&block)
352
+ seconds = ParallelTests.delta(&block).to_i
316
353
  puts "\nTook #{seconds} seconds#{detailed_duration(seconds)}"
317
354
  end
318
355
 
319
356
  def detailed_duration(seconds)
320
- parts = [ seconds / 3600, seconds % 3600 / 60, seconds % 60 ].drop_while(&:zero?)
357
+ parts = [seconds / 3600, seconds % 3600 / 60, seconds % 60].drop_while(&:zero?)
321
358
  return if parts.size < 2
322
359
  parts = parts.map { |i| "%02d" % i }.join(':').sub(/^0/, '')
323
360
  " (#{parts})"
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'cucumber/formatter/rerun'
2
3
  require 'parallel_tests/gherkin/io'
3
4
 
@@ -21,7 +22,6 @@ module ParallelTests
21
22
  end
22
23
  end
23
24
  end
24
-
25
25
  end
26
26
  end
27
27
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  begin
2
3
  gem "cuke_modeler", "~> 3.0"
3
4
  require 'cuke_modeler'
@@ -12,7 +13,7 @@ module ParallelTests
12
13
  def all(tests, options)
13
14
  ignore_tag_pattern = options[:ignore_tag_pattern].nil? ? nil : Regexp.compile(options[:ignore_tag_pattern])
14
15
  # format of hash will be FILENAME => NUM_STEPS
15
- steps_per_file = tests.each_with_object({}) do |file,steps|
16
+ steps_per_file = tests.each_with_object({}) do |file, steps|
16
17
  feature = ::CukeModeler::FeatureFile.new(file).feature
17
18
 
18
19
  # skip feature if it matches tag regex
@@ -20,8 +21,8 @@ module ParallelTests
20
21
 
21
22
  # count the number of steps in the file
22
23
  # will only include a feature if the regex does not match
23
- all_steps = feature.scenarios.map{|a| a.steps.count if a.tags.grep(ignore_tag_pattern).empty? }.compact
24
- steps[file] = all_steps.inject(0,:+)
24
+ all_steps = feature.scenarios.map { |a| a.steps.count if a.tags.grep(ignore_tag_pattern).empty? }.compact
25
+ steps[file] = all_steps.sum
25
26
  end
26
27
  steps_per_file.sort_by { |_, value| -value }
27
28
  end