parallel_tests 3.4.0 → 3.7.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: 52c2ebdfc604b9e238867ea3d7d78cb919d60c951ab45bd2ead93db8893352f4
4
+ data.tar.gz: 441cf2b41a814746e1704fd794cd147638dbd261f1b294fd74b49adb9bc6d0da
5
5
  SHA512:
6
- metadata.gz: f01821e38506525feaafb8a9ff5a480ab1f6f2b0bed849088d72682a699f82ae50bb2a78b94526f243a65c2474ff8f2d3a06c204b44431a7687d877cbbc91dd8
7
- data.tar.gz: 2823702fc7e5d047a69c57d3ee4c0b72afbb51603d58e34a3656899d0026a4b749e94494b9edf234fdcc5fd81bae59dfba55f920d777f5f7d1f7c21fb5219552
6
+ metadata.gz: a20853e2eac4f7b4260ea3ac3a9515b3d83fa3b47ff411a5f9567fcde257044825b2e9a81047e01f4d72722c02a6fdd2dbffba026dafb236cff8c2be2b712134
7
+ data.tar.gz: 4483fac06b11b0615b2bd39dcc5487713a02105cac547cf50177ec30805a8b17ebdbbac679e88a84f57da702235998cc0f67b80e382ea0bd27e784f4e89639a0
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
 
@@ -197,24 +202,32 @@ Options are:
197
202
  -p, --pattern [PATTERN] run tests matching this regex pattern
198
203
  --exclude-pattern [PATTERN] exclude tests matching this regex pattern
199
204
  --group-by [TYPE] group tests by:
200
- found - order of finding files
201
- steps - number of cucumber/spinach steps
202
- scenarios - individual cucumber scenarios
203
- filesize - by size of the file
204
- runtime - info from runtime log
205
- default - runtime when runtime log is filled otherwise filesize
205
+ found - order of finding files
206
+ steps - number of cucumber/spinach steps
207
+ scenarios - individual cucumber scenarios
208
+ filesize - by size of the file
209
+ runtime - info from runtime log
210
+ default - runtime when runtime log is filled otherwise filesize
206
211
  -m, --multiply-processes [FLOAT] use given number as a multiplier of processes to run
207
212
  -s, --single [PATTERN] Run all matching files in the same process
208
- -i, --isolate Do not run any other tests in the group used by --single(-s).
209
- Automatically turned on if --isolate-n is set above 0.
210
- --isolate-n Number of processes for isolated groups. Default to 1 when --isolate is on.
211
- --only-group INT[, INT]
213
+ -i, --isolate Do not run any other tests in the group used by --single(-s)
214
+ --isolate-n [PROCESSES] Use 'isolate' singles with number of processes, default: 1.
215
+ --highest-exit-status Exit with the highest exit status provided by test run(s)
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
+ $ parallel_tests -n 3 . --specify-groups '1_spec.rb,2_spec.rb|3_spec.rb'
221
+ Process 1 will contain 1_spec.rb and 2_spec.rb
222
+ Process 2 will contain 3_spec.rb
223
+ Process 3 will contain all other specs
224
+ --only-group INT[,INT]
212
225
  -e, --exec [COMMAND] execute this code parallel and with ENV['TEST_ENV_NUMBER']
213
226
  -o, --test-options '[OPTIONS]' execute test commands with those options
214
227
  -t, --type [TYPE] test(default) / rspec / cucumber / spinach
215
228
  --suffix [PATTERN] override built in test file pattern (should match suffix):
216
- '_spec.rb$' - matches rspec files
217
- '_(test|spec).rb$' - matches test or spec files
229
+ '_spec.rb$' - matches rspec files
230
+ '_(test|spec).rb$' - matches test or spec files
218
231
  --serialize-stdout Serialize stdout output, nothing will be written until everything is done
219
232
  --prefix-output-with-test-env-number
220
233
  Prefixes test env number to the output when not using --serialize-stdout
@@ -282,7 +295,7 @@ TIPS
282
295
  `export PARALLEL_TEST_FIRST_IS_1=true` will provide the same result
283
296
  - [email_spec and/or action_mailer_cache_delivery](https://github.com/grosser/parallel_tests/wiki)
284
297
  - [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)
298
+ - [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
299
  - [Capybara setup](https://github.com/grosser/parallel_tests/wiki)
287
300
  - [Sphinx setup](https://github.com/grosser/parallel_tests/wiki)
288
301
  - [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 +392,7 @@ inspired by [pivotal labs](https://blog.pivotal.io/labs/labs/parallelize-your-rs
379
392
  - [alboyadjian](https://github.com/alboyadjian)
380
393
  - [Nathan Broadbent](https://github.com/ndbroadbent)
381
394
  - [Vikram B Kumar](https://github.com/v-kumar)
395
+ - [Joshua Pinter](https://github.com/joshuapinter)
382
396
 
383
397
  [Michael Grosser](http://grosser.it)<br/>
384
398
  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,21 +18,19 @@ 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
24
25
  Tempfile.open('parallel_tests-pidfile') do |f|
25
- begin
26
- ENV['PARALLEL_PID_FILE'] = f.path
27
- # Pids object should be created before threads will start adding pids to it
28
- # Otherwise we would have to use Mutex to prevent creation of several instances
29
- @pids = pids
30
- yield
31
- ensure
32
- ENV['PARALLEL_PID_FILE'] = nil
33
- @pids = nil
34
- end
26
+ ENV['PARALLEL_PID_FILE'] = f.path
27
+ # Pids object should be created before threads will start adding pids to it
28
+ # Otherwise we would have to use Mutex to prevent creation of several instances
29
+ @pids = pids
30
+ yield
31
+ ensure
32
+ ENV['PARALLEL_PID_FILE'] = nil
33
+ @pids = nil
35
34
  end
36
35
  end
37
36
 
@@ -57,7 +56,8 @@ module ParallelTests
57
56
  until !File.directory?(current) || current == previous
58
57
  filename = File.join(current, "Gemfile")
59
58
  return true if File.exist?(filename)
60
- current, previous = File.expand_path("..", current), current
59
+ previous = current
60
+ current = File.expand_path("..", current)
61
61
  end
62
62
 
63
63
  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
@@ -83,12 +84,23 @@ module ParallelTests
83
84
  report_time_taken(&run_tests_proc)
84
85
  end
85
86
 
86
- abort final_fail_message if any_test_failed?(test_results)
87
+ if any_test_failed?(test_results)
88
+ warn final_fail_message
89
+
90
+ # return the highest exit status to allow sub-processes to send things other than 1
91
+ exit_status = if options[:highest_exit_status]
92
+ test_results.map { |data| data.fetch(:exit_status) }.max
93
+ else
94
+ 1
95
+ end
96
+
97
+ exit exit_status
98
+ end
87
99
  end
88
100
 
89
101
  def run_tests(group, process_number, num_processes, options)
90
102
  if group.empty?
91
- {:stdout => '', :exit_status => 0, :command => '', :seed => nil}
103
+ { stdout: '', exit_status: 0, command: '', seed: nil }
92
104
  else
93
105
  @runner.run_tests(group, process_number, num_processes, options)
94
106
  end
@@ -104,18 +116,16 @@ module ParallelTests
104
116
 
105
117
  def lock(lockfile)
106
118
  File.open(lockfile) do |lock|
107
- begin
108
- lock.flock File::LOCK_EX
109
- yield
110
- ensure
111
- # This shouldn't be necessary, but appears to be
112
- lock.flock File::LOCK_UN
113
- end
119
+ lock.flock File::LOCK_EX
120
+ yield
121
+ ensure
122
+ # This shouldn't be necessary, but appears to be
123
+ lock.flock File::LOCK_UN
114
124
  end
115
125
  end
116
126
 
117
127
  def report_results(test_results, options)
118
- results = @runner.find_results(test_results.map { |result| result[:stdout] }*"")
128
+ results = @runner.find_results(test_results.map { |result| result[:stdout] } * "")
119
129
  puts ""
120
130
  puts @runner.summarize_results(results)
121
131
 
@@ -140,20 +150,31 @@ module ParallelTests
140
150
  def report_number_of_tests(groups)
141
151
  name = @runner.test_file_name
142
152
  num_processes = groups.size
143
- num_tests = groups.map(&:size).inject(0, :+)
153
+ num_tests = groups.map(&:size).sum
144
154
  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"
155
+ puts "#{pluralize(num_processes, 'process')} for #{pluralize(num_tests, name)}, ~ #{pluralize(tests_per_process, name)} per process"
146
156
  end
147
157
 
148
- #exit with correct status code so rake parallel:test && echo 123 works
158
+ def pluralize(n, singular)
159
+ if n == 1
160
+ "1 #{singular}"
161
+ elsif singular.end_with?('s', 'sh', 'ch', 'x', 'z')
162
+ "#{n} #{singular}es"
163
+ else
164
+ "#{n} #{singular}s"
165
+ end
166
+ end
167
+
168
+ # exit with correct status code so rake parallel:test && echo 123 works
149
169
  def any_test_failed?(test_results)
150
170
  test_results.any? { |result| result[:exit_status] != 0 }
151
171
  end
152
172
 
153
173
  def parse_options!(argv)
174
+ newline_padding = " " * 37
154
175
  options = {}
155
176
  OptionParser.new do |opts|
156
- opts.banner = <<-BANNER.gsub(/^ /, '')
177
+ opts.banner = <<~BANNER
157
178
  Run all tests in parallel, giving each process ENV['TEST_ENV_NUMBER'] ('', '2', '3', ...)
158
179
 
159
180
  [optional] Only selected files & folders:
@@ -167,61 +188,78 @@ module ParallelTests
167
188
  opts.on("-n [PROCESSES]", Integer, "How many processes to use, default: available CPUs") { |n| options[:count] = n }
168
189
  opts.on("-p", "--pattern [PATTERN]", "run tests matching this regex pattern") { |pattern| options[:pattern] = /#{pattern}/ }
169
190
  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
191
+ opts.on(
192
+ "--group-by [TYPE]",
193
+ <<~TEXT.rstrip.split("\n").join("\n#{newline_padding}")
194
+ group tests by:
195
+ found - order of finding files
196
+ steps - number of cucumber/spinach steps
197
+ scenarios - individual cucumber scenarios
198
+ filesize - by size of the file
199
+ runtime - info from runtime log
200
+ default - runtime when runtime log is filled otherwise filesize
178
201
  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}/
202
+ ) { |type| options[:group_by] = type.to_sym }
203
+ opts.on("-m [FLOAT]", "--multiply-processes [FLOAT]", Float, "use given number as a multiplier of processes to run") do |multiply|
204
+ options[:multiply] = multiply
187
205
  end
188
206
 
189
- opts.on("-i", "--isolate",
190
- "Do not run any other tests in the group used by --single(-s)") do |pattern|
207
+ opts.on("-s [PATTERN]", "--single [PATTERN]", "Run all matching files in the same process") do |pattern|
208
+ (options[:single_process] ||= []) << /#{pattern}/
209
+ end
191
210
 
211
+ opts.on("-i", "--isolate", "Do not run any other tests in the group used by --single(-s)") do
192
212
  options[:isolate] = true
193
213
  end
194
214
 
195
- opts.on("--isolate-n [PROCESSES]",
215
+ opts.on(
216
+ "--isolate-n [PROCESSES]",
196
217
  Integer,
197
- "Use 'isolate' singles with number of processes, default: 1.") do |n|
198
- options[:isolate_count] = n
218
+ "Use 'isolate' singles with number of processes, default: 1."
219
+ ) { |n| options[:isolate_count] = n }
220
+
221
+ opts.on("--highest-exit-status", "Exit with the highest exit status provided by test run(s)") do
222
+ options[:highest_exit_status] = true
199
223
  end
200
224
 
201
- opts.on("--only-group INT[, INT]", Array) { |groups| options[:only_group] = groups.map(&:to_i) }
225
+ opts.on(
226
+ "--specify-groups [SPECS]",
227
+ <<~TEXT.rstrip.split("\n").join("\n#{newline_padding}")
228
+ Use 'specify-groups' if you want to specify multiple specs running in multiple
229
+ processes in a specific formation. Commas indicate specs in the same process,
230
+ pipes indicate specs in a new process. Cannot use with --single, --isolate, or
231
+ --isolate-n. Ex.
232
+ $ parallel_tests -n 3 . --specify-groups '1_spec.rb,2_spec.rb|3_spec.rb'
233
+ Process 1 will contain 1_spec.rb and 2_spec.rb
234
+ Process 2 will contain 3_spec.rb
235
+ Process 3 will contain all other specs
236
+ TEXT
237
+ ) { |groups| options[:specify_groups] = groups }
238
+
239
+ opts.on("--only-group INT[,INT]", Array) { |groups| options[:only_group] = groups.map(&:to_i) }
202
240
 
203
241
  opts.on("-e", "--exec [COMMAND]", "execute this code parallel and with ENV['TEST_ENV_NUMBER']") { |path| options[:execute] = path }
204
242
  opts.on("-o", "--test-options '[OPTIONS]'", "execute test commands with those options") { |arg| options[:test_options] = arg.lstrip }
205
243
  opts.on("-t", "--type [TYPE]", "test(default) / rspec / cucumber / spinach") do |type|
206
- begin
207
- @runner = load_runner(type)
208
- rescue NameError, LoadError => e
209
- puts "Runner for `#{type}` type has not been found! (#{e})"
210
- abort
211
- end
244
+ @runner = load_runner(type)
245
+ rescue NameError, LoadError => e
246
+ puts "Runner for `#{type}` type has not been found! (#{e})"
247
+ abort
212
248
  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
249
+ opts.on(
250
+ "--suffix [PATTERN]",
251
+ <<~TEXT.rstrip.split("\n").join("\n#{newline_padding}")
252
+ override built in test file pattern (should match suffix):
253
+ '_spec\.rb$' - matches rspec files
254
+ '_(test|spec).rb$' - matches test or spec files
217
255
  TEXT
218
- ) { |pattern| options[:suffix] = /#{pattern}/ }
256
+ ) { |pattern| options[:suffix] = /#{pattern}/ }
219
257
  opts.on("--serialize-stdout", "Serialize stdout output, nothing will be written until everything is done") { options[:serialize_stdout] = true }
220
258
  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
259
  opts.on("--combine-stderr", "Combine stderr into stdout, useful in conjunction with --serialize-stdout") { options[:combine_stderr] = true }
222
260
  opts.on("--non-parallel", "execute same commands but do not in parallel, needs --exec") { options[:non_parallel] = true }
223
261
  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 }
262
+ opts.on('--ignore-tags [PATTERN]', 'When counting steps ignore scenarios with tags that match this pattern') { |arg| options[:ignore_tag_pattern] = arg }
225
263
  opts.on("--nice", "execute test commands with low priority.") { options[:nice] = true }
226
264
  opts.on("--runtime-log [PATH]", "Location of previously recorded test runtimes") { |path| options[:runtime_log] = path }
227
265
  opts.on("--allowed-missing [INT]", Integer, "Allowed percentage of missing runtimes (default = 50)") { |percent| options[:allowed_missing_percent] = percent }
@@ -232,13 +270,17 @@ module ParallelTests
232
270
  opts.on("--verbose-process-command", "Displays only the command that will be executed by each process") { options[:verbose_process_command] = true }
233
271
  opts.on("--verbose-rerun-command", "When there are failures, displays the command executed by each process that failed") { options[:verbose_rerun_command] = true }
234
272
  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 }
273
+ opts.on("-v", "--version", "Show Version") do
274
+ puts ParallelTests::VERSION
275
+ exit 0
276
+ end
277
+ opts.on("-h", "--help", "Show this.") do
278
+ puts opts
279
+ exit 0
280
+ end
237
281
  end.parse!(argv)
238
282
 
239
- if options[:verbose] && options[:quiet]
240
- raise "Both options are mutually exclusive: verbose & quiet"
241
- end
283
+ raise "Both options are mutually exclusive: verbose & quiet" if options[:verbose] && options[:quiet]
242
284
 
243
285
  if options[:count] == 0
244
286
  options.delete(:count)
@@ -247,7 +289,14 @@ module ParallelTests
247
289
 
248
290
  files, remaining = extract_file_paths(argv)
249
291
  unless options[:execute]
250
- abort "Pass files or folders to run" unless files.any?
292
+ if files.empty?
293
+ default_test_folder = @runner.default_test_folder
294
+ if File.directory?(default_test_folder)
295
+ files = [default_test_folder]
296
+ else
297
+ abort "Pass files or folders to run"
298
+ end
299
+ end
251
300
  options[:files] = files.map { |file_path| Pathname.new(file_path).cleanpath.to_s }
252
301
  end
253
302
 
@@ -255,12 +304,18 @@ module ParallelTests
255
304
 
256
305
  options[:group_by] ||= :filesize if options[:only_group]
257
306
 
258
- raise "--group-by found and --single-process are not supported" if options[:group_by] == :found and options[:single_process]
307
+ if options[:group_by] == :found && options[:single_process]
308
+ raise "--group-by found and --single-process are not supported"
309
+ end
259
310
  allowed = [:filesize, :runtime, :found]
260
311
  if !allowed.include?(options[:group_by]) && options[:only_group]
261
312
  raise "--group-by #{allowed.join(" or ")} is required for --only-group"
262
313
  end
263
314
 
315
+ if options[:specify_groups] && (options.keys & [:single_process, :isolate, :isolate_count]).any?
316
+ raise "Can't pass --specify-groups with any of these keys: --single, --isolate, or --isolate-n"
317
+ end
318
+
264
319
  options
265
320
  end
266
321
 
@@ -272,7 +327,7 @@ module ParallelTests
272
327
 
273
328
  def extract_test_options(argv)
274
329
  dash_index = argv.index("--") || -1
275
- argv[dash_index+1..-1]
330
+ argv[dash_index + 1..-1]
276
331
  end
277
332
 
278
333
  def append_test_options(options, argv)
@@ -292,7 +347,7 @@ module ParallelTests
292
347
 
293
348
  def execute_shell_command_in_parallel(command, num_processes, options)
294
349
  runs = if options[:only_group]
295
- options[:only_group].map{|g| g - 1}
350
+ options[:only_group].map { |g| g - 1 }
296
351
  else
297
352
  (0...num_processes).to_a
298
353
  end
@@ -311,13 +366,13 @@ module ParallelTests
311
366
  abort if results.any? { |r| r[:exit_status] != 0 }
312
367
  end
313
368
 
314
- def report_time_taken
315
- seconds = ParallelTests.delta { yield }.to_i
369
+ def report_time_taken(&block)
370
+ seconds = ParallelTests.delta(&block).to_i
316
371
  puts "\nTook #{seconds} seconds#{detailed_duration(seconds)}"
317
372
  end
318
373
 
319
374
  def detailed_duration(seconds)
320
- parts = [ seconds / 3600, seconds % 3600 / 60, seconds % 60 ].drop_while(&:zero?)
375
+ parts = [seconds / 3600, seconds % 3600 / 60, seconds % 60].drop_while(&:zero?)
321
376
  return if parts.size < 2
322
377
  parts = parts.map { |i| "%02d" % i }.join(':').sub(/^0/, '')
323
378
  " (#{parts})"