parallel_tests 2.21.3 → 4.2.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 +4 -4
- data/Readme.md +73 -39
- data/bin/parallel_cucumber +2 -1
- data/bin/parallel_rspec +2 -1
- data/bin/parallel_spinach +2 -1
- data/bin/parallel_test +2 -1
- data/lib/parallel_tests/cli.rb +188 -100
- data/lib/parallel_tests/cucumber/failures_logger.rb +1 -1
- data/lib/parallel_tests/cucumber/features_with_steps.rb +32 -0
- data/lib/parallel_tests/cucumber/runner.rb +10 -7
- data/lib/parallel_tests/cucumber/scenario_line_logger.rb +18 -15
- data/lib/parallel_tests/cucumber/scenarios.rb +34 -36
- data/lib/parallel_tests/gherkin/io.rb +2 -3
- data/lib/parallel_tests/gherkin/listener.rb +10 -12
- data/lib/parallel_tests/gherkin/runner.rb +29 -35
- data/lib/parallel_tests/gherkin/runtime_logger.rb +13 -12
- data/lib/parallel_tests/grouper.rb +88 -28
- data/lib/parallel_tests/pids.rb +6 -5
- data/lib/parallel_tests/railtie.rb +1 -0
- data/lib/parallel_tests/rspec/failures_logger.rb +2 -2
- data/lib/parallel_tests/rspec/logger_base.rb +9 -7
- data/lib/parallel_tests/rspec/runner.rb +32 -24
- data/lib/parallel_tests/rspec/runtime_logger.rb +12 -11
- data/lib/parallel_tests/rspec/summary_logger.rb +2 -3
- data/lib/parallel_tests/spinach/runner.rb +6 -2
- data/lib/parallel_tests/tasks.rb +153 -65
- data/lib/parallel_tests/test/runner.rb +114 -49
- data/lib/parallel_tests/test/runtime_logger.rb +18 -47
- data/lib/parallel_tests/version.rb +2 -1
- data/lib/parallel_tests.rb +14 -19
- metadata +15 -11
@@ -1,17 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'shellwords'
|
1
3
|
require 'parallel_tests'
|
2
4
|
|
3
5
|
module ParallelTests
|
4
6
|
module Test
|
5
7
|
class Runner
|
6
|
-
|
8
|
+
RuntimeLogTooSmallError = Class.new(StandardError)
|
7
9
|
|
8
10
|
class << self
|
9
11
|
# --- usually overwritten by other runners
|
10
12
|
|
11
|
-
def name
|
12
|
-
NAME
|
13
|
-
end
|
14
|
-
|
15
13
|
def runtime_log
|
16
14
|
'tmp/parallel_runtime_test.log'
|
17
15
|
end
|
@@ -20,13 +18,24 @@ module ParallelTests
|
|
20
18
|
/_(test|spec).rb$/
|
21
19
|
end
|
22
20
|
|
21
|
+
def default_test_folder
|
22
|
+
"test"
|
23
|
+
end
|
24
|
+
|
23
25
|
def test_file_name
|
24
26
|
"test"
|
25
27
|
end
|
26
28
|
|
27
29
|
def run_tests(test_files, process_number, num_processes, options)
|
28
|
-
require_list = test_files.map { |file| file.
|
29
|
-
cmd =
|
30
|
+
require_list = test_files.map { |file| file.gsub(" ", "\\ ") }.join(" ")
|
31
|
+
cmd = [
|
32
|
+
*executable,
|
33
|
+
'-Itest',
|
34
|
+
'-e',
|
35
|
+
"%w[#{require_list}].each { |f| require %{./\#{f}} }",
|
36
|
+
'--',
|
37
|
+
*options[:test_options]
|
38
|
+
]
|
30
39
|
execute_command(cmd, process_number, num_processes, options)
|
31
40
|
end
|
32
41
|
|
@@ -38,7 +47,7 @@ module ParallelTests
|
|
38
47
|
# --- usually used by other runners
|
39
48
|
|
40
49
|
# finds all tests and partitions them into groups
|
41
|
-
def tests_in_groups(tests, num_groups, options={})
|
50
|
+
def tests_in_groups(tests, num_groups, options = {})
|
42
51
|
tests = tests_with_size(tests, options)
|
43
52
|
Grouper.in_even_groups_by_size(tests, num_groups, options)
|
44
53
|
end
|
@@ -52,12 +61,19 @@ module ParallelTests
|
|
52
61
|
when :filesize
|
53
62
|
sort_by_filesize(tests)
|
54
63
|
when :runtime
|
55
|
-
sort_by_runtime(
|
64
|
+
sort_by_runtime(
|
65
|
+
tests, runtimes(tests, options),
|
66
|
+
options.merge(allowed_missing: (options[:allowed_missing_percent] || 50) / 100.0)
|
67
|
+
)
|
56
68
|
when nil
|
57
69
|
# use recorded test runtime if we got enough data
|
58
|
-
runtimes =
|
70
|
+
runtimes = begin
|
71
|
+
runtimes(tests, options)
|
72
|
+
rescue StandardError
|
73
|
+
[]
|
74
|
+
end
|
59
75
|
if runtimes.size * 1.5 > tests.size
|
60
|
-
puts "Using recorded test runtime"
|
76
|
+
puts "Using recorded test runtime" unless options[:quiet]
|
61
77
|
sort_by_runtime(tests, runtimes)
|
62
78
|
else
|
63
79
|
sort_by_filesize(tests)
|
@@ -70,31 +86,44 @@ module ParallelTests
|
|
70
86
|
end
|
71
87
|
|
72
88
|
def execute_command(cmd, process_number, num_processes, options)
|
89
|
+
number = test_env_number(process_number, options).to_s
|
73
90
|
env = (options[:env] || {}).merge(
|
74
|
-
"TEST_ENV_NUMBER" =>
|
91
|
+
"TEST_ENV_NUMBER" => number,
|
75
92
|
"PARALLEL_TEST_GROUPS" => num_processes.to_s,
|
76
|
-
"PARALLEL_PID_FILE" => ParallelTests.pid_file_path
|
93
|
+
"PARALLEL_PID_FILE" => ParallelTests.pid_file_path
|
77
94
|
)
|
78
|
-
cmd = "nice
|
79
|
-
cmd = "#{cmd} 2>&1" if options[:combine_stderr]
|
95
|
+
cmd = ["nice", *cmd] if options[:nice]
|
80
96
|
|
81
|
-
|
97
|
+
# being able to run with for example `-output foo-$TEST_ENV_NUMBER` worked originally and is convenient
|
98
|
+
cmd = cmd.map { |c| c.gsub("$TEST_ENV_NUMBER", number).gsub("${TEST_ENV_NUMBER}", number) }
|
99
|
+
|
100
|
+
print_command(cmd, env) if report_process_command?(options) && !options[:serialize_stdout]
|
82
101
|
|
83
102
|
execute_command_and_capture_output(env, cmd, options)
|
84
103
|
end
|
85
104
|
|
105
|
+
def print_command(command, env)
|
106
|
+
env_str = ['TEST_ENV_NUMBER', 'PARALLEL_TEST_GROUPS'].map { |e| "#{e}=#{env[e]}" }.join(' ')
|
107
|
+
puts [env_str, Shellwords.shelljoin(command)].compact.join(' ')
|
108
|
+
end
|
109
|
+
|
86
110
|
def execute_command_and_capture_output(env, cmd, options)
|
111
|
+
popen_options = {} # do not add `pgroup: true`, it will break `binding.irb` inside the test
|
112
|
+
popen_options[:err] = [:child, :out] if options[:combine_stderr]
|
113
|
+
|
87
114
|
pid = nil
|
88
|
-
output = IO.popen(env, cmd) do |io|
|
115
|
+
output = IO.popen(env, cmd, popen_options) do |io|
|
89
116
|
pid = io.pid
|
90
117
|
ParallelTests.pids.add(pid)
|
91
118
|
capture_output(io, env, options)
|
92
119
|
end
|
93
120
|
ParallelTests.pids.delete(pid) if pid
|
94
121
|
exitstatus = $?.exitstatus
|
95
|
-
seed = output[/seed (\d+)/,1]
|
122
|
+
seed = output[/seed (\d+)/, 1]
|
96
123
|
|
97
|
-
|
124
|
+
output = "#{Shellwords.shelljoin(cmd)}\n#{output}" if report_process_command?(options) && options[:serialize_stdout]
|
125
|
+
|
126
|
+
{ env: env, stdout: output, exit_status: exitstatus, command: cmd, seed: seed }
|
98
127
|
end
|
99
128
|
|
100
129
|
def find_results(test_output)
|
@@ -106,7 +135,7 @@ module ParallelTests
|
|
106
135
|
end.compact
|
107
136
|
end
|
108
137
|
|
109
|
-
def test_env_number(process_number, options={})
|
138
|
+
def test_env_number(process_number, options = {})
|
110
139
|
if process_number == 0 && !options[:first_is_1]
|
111
140
|
''
|
112
141
|
else
|
@@ -116,39 +145,42 @@ module ParallelTests
|
|
116
145
|
|
117
146
|
def summarize_results(results)
|
118
147
|
sums = sum_up_results(results)
|
119
|
-
sums.sort.map{|word, number|
|
148
|
+
sums.sort.map { |word, number| "#{number} #{word}#{'s' if number != 1}" }.join(', ')
|
120
149
|
end
|
121
150
|
|
122
151
|
# remove old seed and add new seed
|
123
152
|
def command_with_seed(cmd, seed)
|
124
|
-
clean = cmd
|
125
|
-
|
153
|
+
clean = remove_command_arguments(cmd, '--seed')
|
154
|
+
[*clean, '--seed', seed]
|
126
155
|
end
|
127
156
|
|
128
157
|
protected
|
129
158
|
|
130
159
|
def executable
|
131
|
-
ENV['PARALLEL_TESTS_EXECUTABLE']
|
160
|
+
if (executable = ENV['PARALLEL_TESTS_EXECUTABLE'])
|
161
|
+
[executable]
|
162
|
+
else
|
163
|
+
determine_executable
|
164
|
+
end
|
132
165
|
end
|
133
166
|
|
134
167
|
def determine_executable
|
135
|
-
"ruby"
|
168
|
+
["ruby"]
|
136
169
|
end
|
137
170
|
|
138
171
|
def sum_up_results(results)
|
139
|
-
results = results.join(' ').gsub(/s\b/,'') # combine and singularize results
|
172
|
+
results = results.join(' ').gsub(/s\b/, '') # combine and singularize results
|
140
173
|
counts = results.scan(/(\d+) (\w+)/)
|
141
|
-
counts.
|
174
|
+
counts.each_with_object(Hash.new(0)) do |(number, word), sum|
|
142
175
|
sum[word] += number.to_i
|
143
|
-
sum
|
144
176
|
end
|
145
177
|
end
|
146
178
|
|
147
179
|
# read output of the process and print it in chunks
|
148
|
-
def capture_output(out, env, options={})
|
149
|
-
result = ""
|
150
|
-
|
151
|
-
|
180
|
+
def capture_output(out, env, options = {})
|
181
|
+
result = +""
|
182
|
+
begin
|
183
|
+
loop do
|
152
184
|
read = out.readpartial(1000000) # read whatever chunk we can get
|
153
185
|
if Encoding.default_internal
|
154
186
|
read = read.force_encoding(Encoding.default_internal)
|
@@ -161,11 +193,13 @@ module ParallelTests
|
|
161
193
|
$stdout.flush
|
162
194
|
end
|
163
195
|
end
|
164
|
-
|
196
|
+
rescue EOFError
|
197
|
+
nil
|
198
|
+
end
|
165
199
|
result
|
166
200
|
end
|
167
201
|
|
168
|
-
def sort_by_runtime(tests, runtimes, options={})
|
202
|
+
def sort_by_runtime(tests, runtimes, options = {})
|
169
203
|
allowed_missing = options[:allowed_missing] || 1.0
|
170
204
|
allowed_missing = tests.size * allowed_missing
|
171
205
|
|
@@ -175,20 +209,14 @@ module ParallelTests
|
|
175
209
|
allowed_missing -= 1 unless time = runtimes[test]
|
176
210
|
if allowed_missing < 0
|
177
211
|
log = options[:runtime_log] || runtime_log
|
178
|
-
raise "Runtime log file '#{log}' does not
|
212
|
+
raise RuntimeLogTooSmallError, "Runtime log file '#{log}' does not contain sufficient data to sort #{tests.size} test files, please update or remove it."
|
179
213
|
end
|
180
214
|
[test, time]
|
181
215
|
end
|
182
216
|
|
183
|
-
if options[:verbose]
|
184
|
-
puts "Runtime found for #{tests.count(&:last)} of #{tests.size} tests"
|
185
|
-
end
|
217
|
+
puts "Runtime found for #{tests.count(&:last)} of #{tests.size} tests" if options[:verbose]
|
186
218
|
|
187
|
-
|
188
|
-
known, unknown = tests.partition(&:last)
|
189
|
-
average = (known.any? ? known.map!(&:last).inject(:+) / known.size : 1)
|
190
|
-
unknown_runtime = options[:unknown_runtime] || average
|
191
|
-
unknown.each { |set| set[1] = unknown_runtime }
|
219
|
+
set_unknown_runtime tests, options
|
192
220
|
end
|
193
221
|
|
194
222
|
def runtimes(tests, options)
|
@@ -196,7 +224,7 @@ module ParallelTests
|
|
196
224
|
lines = File.read(log).split("\n")
|
197
225
|
lines.each_with_object({}) do |line, times|
|
198
226
|
test, _, time = line.rpartition(':')
|
199
|
-
next unless test
|
227
|
+
next unless test && time
|
200
228
|
times[test] = time.to_f if tests.include?(test)
|
201
229
|
end
|
202
230
|
end
|
@@ -207,17 +235,23 @@ module ParallelTests
|
|
207
235
|
end
|
208
236
|
|
209
237
|
def find_tests(tests, options = {})
|
210
|
-
|
238
|
+
suffix_pattern = options[:suffix] || test_suffix
|
239
|
+
include_pattern = options[:pattern] || //
|
240
|
+
exclude_pattern = options[:exclude_pattern]
|
241
|
+
|
242
|
+
(tests || []).flat_map do |file_or_folder|
|
211
243
|
if File.directory?(file_or_folder)
|
212
244
|
files = files_in_folder(file_or_folder, options)
|
213
|
-
files.grep(
|
245
|
+
files = files.grep(suffix_pattern).grep(include_pattern)
|
246
|
+
files -= files.grep(exclude_pattern) if exclude_pattern
|
247
|
+
files
|
214
248
|
else
|
215
249
|
file_or_folder
|
216
250
|
end
|
217
|
-
end.
|
251
|
+
end.uniq
|
218
252
|
end
|
219
253
|
|
220
|
-
def files_in_folder(folder, options={})
|
254
|
+
def files_in_folder(folder, options = {})
|
221
255
|
pattern = if options[:symlinks] == false # not nil or true
|
222
256
|
"**/*"
|
223
257
|
else
|
@@ -225,7 +259,38 @@ module ParallelTests
|
|
225
259
|
# http://stackoverflow.com/questions/357754/can-i-traverse-symlinked-directories-in-ruby-with-a-glob
|
226
260
|
"**{,/*/**}/*"
|
227
261
|
end
|
228
|
-
Dir[File.join(folder, pattern)].uniq
|
262
|
+
Dir[File.join(folder, pattern)].uniq.sort
|
263
|
+
end
|
264
|
+
|
265
|
+
def remove_command_arguments(command, *args)
|
266
|
+
remove_next = false
|
267
|
+
command.select do |arg|
|
268
|
+
if remove_next
|
269
|
+
remove_next = false
|
270
|
+
false
|
271
|
+
elsif args.include?(arg)
|
272
|
+
remove_next = true
|
273
|
+
false
|
274
|
+
else
|
275
|
+
true
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
private
|
281
|
+
|
282
|
+
# fill gaps with unknown-runtime if given, average otherwise
|
283
|
+
# NOTE: an optimization could be doing runtime by average runtime per file size, but would need file checks
|
284
|
+
def set_unknown_runtime(tests, options)
|
285
|
+
known, unknown = tests.partition(&:last)
|
286
|
+
return if unknown.empty?
|
287
|
+
unknown_runtime = options[:unknown_runtime] ||
|
288
|
+
(known.empty? ? 1 : known.map!(&:last).sum / known.size) # average
|
289
|
+
unknown.each { |set| set[1] = unknown_runtime }
|
290
|
+
end
|
291
|
+
|
292
|
+
def report_process_command?(options)
|
293
|
+
options[:verbose] || options[:verbose_command]
|
229
294
|
end
|
230
295
|
end
|
231
296
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'parallel_tests'
|
2
3
|
require 'parallel_tests/test/runner'
|
3
4
|
|
@@ -22,7 +23,7 @@ module ParallelTests
|
|
22
23
|
separator = "\n"
|
23
24
|
groups = logfile.read.split(separator).map { |line| line.split(":") }.group_by(&:first)
|
24
25
|
lines = groups.map do |file, times|
|
25
|
-
time = "%.2f" % times.map(&:last).map(&:to_f).
|
26
|
+
time = "%.2f" % times.map(&:last).map(&:to_f).sum
|
26
27
|
"#{file}:#{time}"
|
27
28
|
end
|
28
29
|
logfile.rewind
|
@@ -34,7 +35,7 @@ module ParallelTests
|
|
34
35
|
private
|
35
36
|
|
36
37
|
def with_locked_log
|
37
|
-
File.open(logfile, File::RDWR|File::CREAT) do |logfile|
|
38
|
+
File.open(logfile, File::RDWR | File::CREAT) do |logfile|
|
38
39
|
logfile.flock(File::LOCK_EX)
|
39
40
|
yield logfile
|
40
41
|
end
|
@@ -59,7 +60,7 @@ module ParallelTests
|
|
59
60
|
end
|
60
61
|
|
61
62
|
def message(test, delta)
|
62
|
-
return unless method = test.public_instance_methods(true).detect { |
|
63
|
+
return unless method = test.public_instance_methods(true).detect { |m| m =~ /^test_/ }
|
63
64
|
filename = test.instance_method(method).source_location.first.sub("#{Dir.pwd}/", "")
|
64
65
|
"#{filename}:#{delta}"
|
65
66
|
end
|
@@ -74,56 +75,26 @@ end
|
|
74
75
|
|
75
76
|
if defined?(Minitest::Runnable) # Minitest 5
|
76
77
|
class << Minitest::Runnable
|
77
|
-
prepend(
|
78
|
-
|
79
|
-
|
80
|
-
|
78
|
+
prepend(
|
79
|
+
Module.new do
|
80
|
+
def run(*)
|
81
|
+
ParallelTests::Test::RuntimeLogger.log_test_run(self) do
|
82
|
+
super
|
83
|
+
end
|
81
84
|
end
|
82
85
|
end
|
83
|
-
|
86
|
+
)
|
84
87
|
end
|
85
88
|
|
86
89
|
class << Minitest
|
87
|
-
prepend(
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
end)
|
94
|
-
end
|
95
|
-
elsif defined?(MiniTest::Unit) # Minitest 4
|
96
|
-
MiniTest::Unit.class_eval do
|
97
|
-
alias_method :_run_suite_without_runtime_log, :_run_suite
|
98
|
-
def _run_suite(*args)
|
99
|
-
ParallelTests::Test::RuntimeLogger.log_test_run(args.first) do
|
100
|
-
_run_suite_without_runtime_log(*args)
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
alias_method :_run_suites_without_runtime_log, :_run_suites
|
105
|
-
def _run_suites(*args)
|
106
|
-
result = _run_suites_without_runtime_log(*args)
|
107
|
-
ParallelTests::Test::RuntimeLogger.unique_log
|
108
|
-
result
|
109
|
-
end
|
110
|
-
end
|
111
|
-
else # Test::Unit
|
112
|
-
require 'test/unit/testsuite'
|
113
|
-
class ::Test::Unit::TestSuite
|
114
|
-
alias_method :run_without_timing, :run
|
115
|
-
|
116
|
-
def run(result, &block)
|
117
|
-
test = tests.first
|
118
|
-
|
119
|
-
if test.is_a? ::Test::Unit::TestSuite # all tests ?
|
120
|
-
run_without_timing(result, &block)
|
121
|
-
ParallelTests::Test::RuntimeLogger.unique_log
|
122
|
-
else
|
123
|
-
ParallelTests::Test::RuntimeLogger.log_test_run(test.class) do
|
124
|
-
run_without_timing(result, &block)
|
90
|
+
prepend(
|
91
|
+
Module.new do
|
92
|
+
def run(*args)
|
93
|
+
result = super
|
94
|
+
ParallelTests::Test::RuntimeLogger.unique_log
|
95
|
+
result
|
125
96
|
end
|
126
97
|
end
|
127
|
-
|
98
|
+
)
|
128
99
|
end
|
129
100
|
end
|
data/lib/parallel_tests.rb
CHANGED
@@ -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|
|
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
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
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
|
-
|
59
|
+
previous = current
|
60
|
+
current = File.expand_path("..", current)
|
61
61
|
end
|
62
62
|
|
63
63
|
false
|
@@ -76,7 +76,7 @@ module ParallelTests
|
|
76
76
|
end
|
77
77
|
|
78
78
|
def with_ruby_binary(command)
|
79
|
-
WINDOWS ?
|
79
|
+
WINDOWS ? [RUBY_BINARY, '--', command] : [command]
|
80
80
|
end
|
81
81
|
|
82
82
|
def wait_for_other_processes_to_finish
|
@@ -88,13 +88,8 @@ module ParallelTests
|
|
88
88
|
pids.count
|
89
89
|
end
|
90
90
|
|
91
|
-
# real time even if someone messed with timecop in tests
|
92
91
|
def now
|
93
|
-
|
94
|
-
Time.now_without_mock_time
|
95
|
-
else
|
96
|
-
Time.now
|
97
|
-
end
|
92
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
98
93
|
end
|
99
94
|
|
100
95
|
def delta
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: parallel_tests
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 4.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Grosser
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-05-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parallel
|
@@ -24,7 +24,7 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
-
description:
|
27
|
+
description:
|
28
28
|
email: michael@grosser.it
|
29
29
|
executables:
|
30
30
|
- parallel_spinach
|
@@ -42,6 +42,7 @@ files:
|
|
42
42
|
- lib/parallel_tests.rb
|
43
43
|
- lib/parallel_tests/cli.rb
|
44
44
|
- lib/parallel_tests/cucumber/failures_logger.rb
|
45
|
+
- lib/parallel_tests/cucumber/features_with_steps.rb
|
45
46
|
- lib/parallel_tests/cucumber/runner.rb
|
46
47
|
- lib/parallel_tests/cucumber/scenario_line_logger.rb
|
47
48
|
- lib/parallel_tests/cucumber/scenarios.rb
|
@@ -62,11 +63,15 @@ files:
|
|
62
63
|
- lib/parallel_tests/test/runner.rb
|
63
64
|
- lib/parallel_tests/test/runtime_logger.rb
|
64
65
|
- lib/parallel_tests/version.rb
|
65
|
-
homepage:
|
66
|
+
homepage: https://github.com/grosser/parallel_tests
|
66
67
|
licenses:
|
67
68
|
- MIT
|
68
|
-
metadata:
|
69
|
-
|
69
|
+
metadata:
|
70
|
+
bug_tracker_uri: https://github.com/grosser/parallel_tests/issues
|
71
|
+
documentation_uri: https://github.com/grosser/parallel_tests/blob/v4.2.1/Readme.md
|
72
|
+
source_code_uri: https://github.com/grosser/parallel_tests/tree/v4.2.1
|
73
|
+
wiki_uri: https://github.com/grosser/parallel_tests/wiki
|
74
|
+
post_install_message:
|
70
75
|
rdoc_options: []
|
71
76
|
require_paths:
|
72
77
|
- lib
|
@@ -74,16 +79,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
74
79
|
requirements:
|
75
80
|
- - ">="
|
76
81
|
- !ruby/object:Gem::Version
|
77
|
-
version: 2.
|
82
|
+
version: 2.7.0
|
78
83
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
84
|
requirements:
|
80
85
|
- - ">="
|
81
86
|
- !ruby/object:Gem::Version
|
82
87
|
version: '0'
|
83
88
|
requirements: []
|
84
|
-
|
85
|
-
|
86
|
-
signing_key:
|
89
|
+
rubygems_version: 3.3.3
|
90
|
+
signing_key:
|
87
91
|
specification_version: 4
|
88
92
|
summary: Run Test::Unit / RSpec / Cucumber / Spinach in parallel
|
89
93
|
test_files: []
|