parallel_tests 3.1.0 → 3.5.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e0830430a73f9d4366617a98f2014e8b737b8f987a284ac959b0e83e8b0d7da1
4
- data.tar.gz: 358bd27a736baec67ef7775d16d8dd2b935f69f25ca71d7065e3343fea8feee6
3
+ metadata.gz: b8539140ebc96ac00552e9f1e51f63789f1007a997829d86e79a786a71400b7b
4
+ data.tar.gz: be0f3f0785cd3b05882f9928a9fe83a6e10203a95e931b40f89566f1398e0691
5
5
  SHA512:
6
- metadata.gz: 18e2aae47f9ceb0d933ac37bde90fda6936febcbd5381b48c70be9f923a347fc79116996f36c532ba9e3efc14bbf249dfd3eb697d89d80b85578bf9ebd9cb2ae
7
- data.tar.gz: a6768ac48b991d984475921f64e7a7262e530303f150e9ee3e5d5322a8a34ee2a660af8ab626eda535c1be593fbf422049ac423f6bdbe0ee6292c9efc5e1603f
6
+ metadata.gz: 3bd0cfd72dd3a48b491198a5d2be73bb353dbdd5d1cd23cfac58f2429d44fe6b1ce6121c2ba6caed76c4b3c4aa4646fde9ef030dfd1d0a38fe30499e1a2ea38d
7
+ data.tar.gz: 10493da0d865c2e3987c8c11edb8a8605349d23a754bcb70ba05e1579a5f9a8693e9e80730b5c8d601b66efe4406bdf14b50a3ec3ce305a339d07075f5c77d51
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
 
@@ -82,6 +85,8 @@ Running things once
82
85
  ===================
83
86
 
84
87
  ```Ruby
88
+ require "parallel_tests"
89
+
85
90
  # preparation:
86
91
  # affected by race-condition: first process may boot slower than the second
87
92
  # either sleep a bit or use a lock for example File.lock
@@ -97,7 +102,6 @@ at_exit do
97
102
  undo_something
98
103
  end
99
104
  end
100
-
101
105
  ```
102
106
 
103
107
  Even test group run-times
@@ -141,17 +145,19 @@ Add the following to your `.rspec_parallel` (or `.rspec`) :
141
145
  RSpec: FailuresLogger
142
146
  -----------------------
143
147
 
144
- Produce pasteable command-line snippets for each failed example.
145
-
146
- E.g.
148
+ Produce pastable command-line snippets for each failed example. For example:
147
149
 
148
- rspec /path/to/my_spec.rb:123 # should do something
150
+ ```bash
151
+ rspec /path/to/my_spec.rb:123 # should do something
152
+ ```
149
153
 
150
- Add the following to your `.rspec_parallel` (or `.rspec`) :
154
+ Add to `.rspec_parallel` or use as CLI flag:
151
155
 
152
156
  --format progress
153
157
  --format ParallelTests::RSpec::FailuresLogger --out tmp/failing_specs.log
154
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
+
155
161
  Cucumber: FailuresLogger
156
162
  -----------------------
157
163
 
@@ -204,8 +210,19 @@ Options are:
204
210
  default - runtime when runtime log is filled otherwise filesize
205
211
  -m, --multiply-processes [FLOAT] use given number as a multiplier of processes to run
206
212
  -s, --single [PATTERN] Run all matching files in the same process
207
- -i, --isolate Do not run any other tests in the group used by --single(-s)
208
- --only-group INT[, INT]
213
+ -i, --isolate Do not run any other tests in the group used by --single(-s).
214
+ Automatically turned on if --isolate-n is set above 0.
215
+ --isolate-n Number of processes for isolated groups. Default to 1 when --isolate is on.
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]
209
226
  -e, --exec [COMMAND] execute this code parallel and with ENV['TEST_ENV_NUMBER']
210
227
  -o, --test-options '[OPTIONS]' execute test commands with those options
211
228
  -t, --type [TYPE] test(default) / rspec / cucumber / spinach
@@ -258,7 +275,7 @@ TIPS
258
275
  - Use [rspec-retry](https://github.com/NoRedInk/rspec-retry) (not rspec-rerun) to rerun failed tests.
259
276
  - [JUnit formatter configuration](https://github.com/grosser/parallel_tests/wiki#with-rspec_junit_formatter----by-jgarber)
260
277
  - Use [parallel_split_test](https://github.com/grosser/parallel_split_test) to run multiple scenarios in a single spec file, concurrently. (`parallel_tests` [works at the file-level and intends to stay that way](https://github.com/grosser/parallel_tests/issues/747#issuecomment-580216980))
261
-
278
+
262
279
  ### Cucumber
263
280
 
264
281
  - Add a `parallel: foo` profile to your `config/cucumber.yml` and it will be used to run parallel tests
@@ -279,7 +296,7 @@ TIPS
279
296
  `export PARALLEL_TEST_FIRST_IS_1=true` will provide the same result
280
297
  - [email_spec and/or action_mailer_cache_delivery](https://github.com/grosser/parallel_tests/wiki)
281
298
  - [zeus-parallel_tests](https://github.com/sevos/zeus-parallel_tests)
282
- - [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
283
300
  - [Capybara setup](https://github.com/grosser/parallel_tests/wiki)
284
301
  - [Sphinx setup](https://github.com/grosser/parallel_tests/wiki)
285
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
@@ -375,6 +392,8 @@ inspired by [pivotal labs](https://blog.pivotal.io/labs/labs/parallelize-your-rs
375
392
  - [Calaway](https://github.com/calaway)
376
393
  - [alboyadjian](https://github.com/alboyadjian)
377
394
  - [Nathan Broadbent](https://github.com/ndbroadbent)
395
+ - [Vikram B Kumar](https://github.com/v-kumar)
396
+ - [Joshua Pinter](https://github.com/joshuapinter)
378
397
 
379
398
  [Michael Grosser](http://grosser.it)<br/>
380
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,32 +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("--only-group INT[, INT]", Array) { |groups| options[:only_group] = groups.map(&:to_i) }
206
+ opts.on(
207
+ "--isolate-n [PROCESSES]",
208
+ Integer,
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 }
225
+
226
+ opts.on("--only-group INT[,INT]", Array) { |groups| options[:only_group] = groups.map(&:to_i) }
196
227
 
197
228
  opts.on("-e", "--exec [COMMAND]", "execute this code parallel and with ENV['TEST_ENV_NUMBER']") { |path| options[:execute] = path }
198
229
  opts.on("-o", "--test-options '[OPTIONS]'", "execute test commands with those options") { |arg| options[:test_options] = arg.lstrip }
@@ -204,18 +235,20 @@ module ParallelTests
204
235
  abort
205
236
  end
206
237
  end
207
- opts.on("--suffix [PATTERN]", <<-TEXT.gsub(/^ /, '')
208
- override built in test file pattern (should match suffix):
209
- '_spec\.rb$' - matches rspec files
210
- '_(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
211
244
  TEXT
212
- ) { |pattern| options[:suffix] = /#{pattern}/ }
245
+ ) { |pattern| options[:suffix] = /#{pattern}/ }
213
246
  opts.on("--serialize-stdout", "Serialize stdout output, nothing will be written until everything is done") { options[:serialize_stdout] = true }
214
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 }
215
248
  opts.on("--combine-stderr", "Combine stderr into stdout, useful in conjunction with --serialize-stdout") { options[:combine_stderr] = true }
216
249
  opts.on("--non-parallel", "execute same commands but do not in parallel, needs --exec") { options[:non_parallel] = true }
217
250
  opts.on("--no-symlinks", "Do not traverse symbolic links to find test files") { options[:symlinks] = false }
218
- 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 }
219
252
  opts.on("--nice", "execute test commands with low priority.") { options[:nice] = true }
220
253
  opts.on("--runtime-log [PATH]", "Location of previously recorded test runtimes") { |path| options[:runtime_log] = path }
221
254
  opts.on("--allowed-missing [INT]", Integer, "Allowed percentage of missing runtimes (default = 50)") { |percent| options[:allowed_missing_percent] = percent }
@@ -226,13 +259,17 @@ module ParallelTests
226
259
  opts.on("--verbose-process-command", "Displays only the command that will be executed by each process") { options[:verbose_process_command] = true }
227
260
  opts.on("--verbose-rerun-command", "When there are failures, displays the command executed by each process that failed") { options[:verbose_rerun_command] = true }
228
261
  opts.on("--quiet", "Print only tests output") { options[:quiet] = true }
229
- opts.on("-v", "--version", "Show Version") { puts ParallelTests::VERSION; exit }
230
- 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
231
270
  end.parse!(argv)
232
271
 
233
- if options[:verbose] && options[:quiet]
234
- raise "Both options are mutually exclusive: verbose & quiet"
235
- end
272
+ raise "Both options are mutually exclusive: verbose & quiet" if options[:verbose] && options[:quiet]
236
273
 
237
274
  if options[:count] == 0
238
275
  options.delete(:count)
@@ -249,12 +286,18 @@ module ParallelTests
249
286
 
250
287
  options[:group_by] ||= :filesize if options[:only_group]
251
288
 
252
- 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
253
292
  allowed = [:filesize, :runtime, :found]
254
293
  if !allowed.include?(options[:group_by]) && options[:only_group]
255
294
  raise "--group-by #{allowed.join(" or ")} is required for --only-group"
256
295
  end
257
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
+
258
301
  options
259
302
  end
260
303
 
@@ -266,7 +309,7 @@ module ParallelTests
266
309
 
267
310
  def extract_test_options(argv)
268
311
  dash_index = argv.index("--") || -1
269
- argv[dash_index+1..-1]
312
+ argv[dash_index + 1..-1]
270
313
  end
271
314
 
272
315
  def append_test_options(options, argv)
@@ -286,7 +329,7 @@ module ParallelTests
286
329
 
287
330
  def execute_shell_command_in_parallel(command, num_processes, options)
288
331
  runs = if options[:only_group]
289
- options[:only_group].map{|g| g - 1}
332
+ options[:only_group].map { |g| g - 1 }
290
333
  else
291
334
  (0...num_processes).to_a
292
335
  end
@@ -305,13 +348,13 @@ module ParallelTests
305
348
  abort if results.any? { |r| r[:exit_status] != 0 }
306
349
  end
307
350
 
308
- def report_time_taken
309
- seconds = ParallelTests.delta { yield }.to_i
351
+ def report_time_taken(&block)
352
+ seconds = ParallelTests.delta(&block).to_i
310
353
  puts "\nTook #{seconds} seconds#{detailed_duration(seconds)}"
311
354
  end
312
355
 
313
356
  def detailed_duration(seconds)
314
- parts = [ seconds / 3600, seconds % 3600 / 60, seconds % 60 ].drop_while(&:zero?)
357
+ parts = [seconds / 3600, seconds % 3600 / 60, seconds % 60].drop_while(&:zero?)
315
358
  return if parts.size < 2
316
359
  parts = parts.map { |i| "%02d" % i }.join(':').sub(/^0/, '')
317
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