rspec-tracer 0.9.3 → 1.0.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.
@@ -22,8 +22,6 @@ module RSpecTracer
22
22
  @reporter = RSpecTracer::Reporter.new
23
23
  @filtered_examples = {}
24
24
 
25
- return if @cache.run_id.nil?
26
-
27
25
  @cache.load_cache_for_run
28
26
  filter_examples_to_run
29
27
  end
@@ -72,7 +70,6 @@ module RSpecTracer
72
70
  @reporter.register_deleted_examples(@cache.all_examples)
73
71
  end
74
72
 
75
- # rubocop:disable Metrics/AbcSize
76
73
  def generate_missed_coverage
77
74
  missed_coverage = Hash.new do |files_coverage, file_path|
78
75
  files_coverage[file_path] = Hash.new do |strength, line_number|
@@ -99,7 +96,6 @@ module RSpecTracer
99
96
 
100
97
  missed_coverage
101
98
  end
102
- # rubocop:enable Metrics/AbcSize
103
99
 
104
100
  def register_dependency(examples_coverage)
105
101
  filtered_files = Set.new
@@ -145,25 +141,6 @@ module RSpecTracer
145
141
  @reporter.register_examples_coverage(examples_coverage)
146
142
  end
147
143
 
148
- def generate_report
149
- @reporter.generate_last_run_report
150
- generate_examples_status_report
151
-
152
- %i[all_files all_examples dependency examples_coverage reverse_dependency].each do |report_type|
153
- starting = Process.clock_gettime(Process::CLOCK_MONOTONIC)
154
-
155
- send("generate_#{report_type}_report")
156
-
157
- ending = Process.clock_gettime(Process::CLOCK_MONOTONIC)
158
- elpased = RSpecTracer::TimeFormatter.format_time(ending - starting)
159
-
160
- puts "RSpec tracer generated #{report_type.to_s.tr('_', ' ')} report (took #{elpased})" if RSpecTracer.verbose?
161
- end
162
-
163
- @reporter.write_reports
164
- @reporter.print_duplicate_examples
165
- end
166
-
167
144
  def non_zero_exit_code?
168
145
  !@reporter.duplicate_examples.empty? &&
169
146
  ENV.fetch('RSPEC_TRACER_FAIL_ON_DUPLICATES', 'true') == 'true'
@@ -183,9 +160,9 @@ module RSpecTracer
183
160
  filter_by_files_changed
184
161
 
185
162
  ending = Process.clock_gettime(Process::CLOCK_MONOTONIC)
186
- elpased = RSpecTracer::TimeFormatter.format_time(ending - starting)
163
+ elapsed = RSpecTracer::TimeFormatter.format_time(ending - starting)
187
164
 
188
- puts "RSpec tracer processed cache (took #{elpased})" if RSpecTracer.verbose?
165
+ puts "RSpec tracer processed cache (took #{elapsed})" if RSpecTracer.verbose?
189
166
  end
190
167
 
191
168
  def filter_by_example_status
@@ -311,92 +288,5 @@ module RSpecTracer
311
288
 
312
289
  true
313
290
  end
314
-
315
- def generate_examples_status_report
316
- starting = Process.clock_gettime(Process::CLOCK_MONOTONIC)
317
-
318
- generate_flaky_examples_report
319
- generate_failed_examples_report
320
- generate_pending_examples_report
321
-
322
- ending = Process.clock_gettime(Process::CLOCK_MONOTONIC)
323
- elpased = RSpecTracer::TimeFormatter.format_time(ending - starting)
324
-
325
- puts "RSpec tracer generated flaky, failed, and pending examples report (took #{elpased})" if RSpecTracer.verbose?
326
- end
327
-
328
- def generate_all_files_report
329
- @cache.all_files.each_pair do |file_name, data|
330
- next if @reporter.all_files.key?(file_name) ||
331
- @reporter.file_deleted?(file_name)
332
-
333
- @reporter.all_files[file_name] = data
334
- end
335
- end
336
-
337
- def generate_all_examples_report
338
- @cache.all_examples.each_pair do |example_id, data|
339
- next if @reporter.all_examples.key?(example_id) ||
340
- @reporter.example_deleted?(example_id)
341
-
342
- @reporter.all_examples[example_id] = data
343
- end
344
- end
345
-
346
- def generate_flaky_examples_report
347
- @reporter.possibly_flaky_examples.each do |example_id|
348
- next if @reporter.example_deleted?(example_id)
349
- next unless @cache.flaky_examples.include?(example_id) ||
350
- @reporter.example_passed?(example_id)
351
-
352
- @reporter.register_flaky_example(example_id)
353
- end
354
- end
355
-
356
- def generate_failed_examples_report
357
- @cache.failed_examples.each do |example_id|
358
- next if @reporter.example_deleted?(example_id) ||
359
- @reporter.all_examples.key?(example_id)
360
-
361
- @reporter.register_failed_example(example_id)
362
- end
363
- end
364
-
365
- def generate_pending_examples_report
366
- @cache.pending_examples.each do |example_id|
367
- next if @reporter.example_deleted?(example_id) ||
368
- @reporter.all_examples.key?(example_id)
369
-
370
- @reporter.register_pending_example(example_id)
371
- end
372
- end
373
-
374
- def generate_dependency_report
375
- @cache.dependency.each_pair do |example_id, data|
376
- next if @reporter.dependency.key?(example_id) ||
377
- @reporter.example_deleted?(example_id)
378
-
379
- @reporter.dependency[example_id] = data.reject do |file_name|
380
- @reporter.file_deleted?(file_name)
381
- end
382
- end
383
-
384
- @reporter.dependency.transform_values!(&:to_a)
385
- end
386
-
387
- def generate_examples_coverage_report
388
- @cache.cached_examples_coverage.each_pair do |example_id, data|
389
- next if @reporter.examples_coverage.key?(example_id) ||
390
- @reporter.example_deleted?(example_id)
391
-
392
- @reporter.examples_coverage[example_id] = data.reject do |file_name|
393
- @reporter.file_deleted?(file_name)
394
- end
395
- end
396
- end
397
-
398
- def generate_reverse_dependency_report
399
- @reporter.generate_reverse_dependency_report
400
- end
401
291
  end
402
292
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RSpecTracer
4
- VERSION = '0.9.3'
4
+ VERSION = '1.0.0'
5
5
  end
data/lib/rspec_tracer.rb CHANGED
@@ -13,11 +13,16 @@ require 'set'
13
13
  require_relative 'rspec_tracer/configuration'
14
14
  RSpecTracer.extend RSpecTracer::Configuration
15
15
 
16
+ require_relative 'rspec_tracer/coverage_merger'
16
17
  require_relative 'rspec_tracer/coverage_reporter'
18
+ require_relative 'rspec_tracer/coverage_writer'
17
19
  require_relative 'rspec_tracer/defaults'
18
20
  require_relative 'rspec_tracer/example'
19
21
  require_relative 'rspec_tracer/html_reporter/reporter'
20
22
  require_relative 'rspec_tracer/remote_cache/cache'
23
+ require_relative 'rspec_tracer/report_generator'
24
+ require_relative 'rspec_tracer/report_merger'
25
+ require_relative 'rspec_tracer/report_writer'
21
26
  require_relative 'rspec_tracer/rspec_reporter'
22
27
  require_relative 'rspec_tracer/rspec_runner'
23
28
  require_relative 'rspec_tracer/ruby_coverage'
@@ -34,10 +39,12 @@ module RSpecTracer
34
39
  RSpecTracer.running = false
35
40
  RSpecTracer.pid = Process.pid
36
41
 
37
- puts 'Started RSpec tracer'
42
+ return if RUBY_ENGINE == 'jruby' && !valid_jruby_opts?
38
43
 
39
- configure(&block) if block
44
+ puts "Started RSpec tracer (pid: #{RSpecTracer.pid})"
40
45
 
46
+ parallel_tests_setup
47
+ configure(&block) if block
41
48
  initial_setup
42
49
  end
43
50
 
@@ -80,6 +87,8 @@ module RSpecTracer
80
87
 
81
88
  ::Kernel.exit(1) if runner.non_zero_exit_code?
82
89
  ensure
90
+ FileUtils.rm_f(RSpecTracer.parallel_tests_lock_file) if parallel_tests_last_process?
91
+
83
92
  RSpecTracer.running = false
84
93
  end
85
94
 
@@ -109,6 +118,14 @@ module RSpecTracer
109
118
  return @coverage_reporter if defined?(@coverage_reporter)
110
119
  end
111
120
 
121
+ def coverage_merger
122
+ return @coverage_merger if defined?(@coverage_merger)
123
+ end
124
+
125
+ def report_merger
126
+ return @report_merger if defined?(@report_merger)
127
+ end
128
+
112
129
  def trace_point
113
130
  return @trace_point if defined?(@trace_point)
114
131
  end
@@ -125,8 +142,28 @@ module RSpecTracer
125
142
  return @simplecov if defined?(@simplecov)
126
143
  end
127
144
 
145
+ def parallel_tests?
146
+ return @parallel_tests if defined?(@parallel_tests)
147
+ end
148
+
128
149
  private
129
150
 
151
+ def valid_jruby_opts?
152
+ require 'jruby'
153
+
154
+ return true if Java::OrgJruby::RubyInstanceConfig.FULL_TRACE_ENABLED &&
155
+ JRuby.runtime.object_space_enabled?
156
+
157
+ puts <<-WARN.strip.gsub(/\s+/, ' ')
158
+ RSpec Tracer is not running as it requires debug and object space enabled. Use
159
+ command line options "--debug" and "-X+O" or set the "debug.fullTrace=true" and
160
+ "objectspace.enabled=true" options in your .jrubyrc file. You can also use
161
+ JRUBY_OPTS="--debug -X+O".
162
+ WARN
163
+
164
+ false
165
+ end
166
+
130
167
  def initial_setup
131
168
  unless setup_rspec
132
169
  puts 'Could not find a running RSpec process'
@@ -141,6 +178,36 @@ module RSpecTracer
141
178
  @coverage_reporter = RSpecTracer::CoverageReporter.new
142
179
  end
143
180
 
181
+ def parallel_tests_setup
182
+ @parallel_tests = !(ENV['TEST_ENV_NUMBER'] && ENV['PARALLEL_TEST_GROUPS']).nil?
183
+
184
+ return unless parallel_tests?
185
+
186
+ require 'parallel_tests' unless defined?(ParallelTests)
187
+
188
+ @coverage_merger = RSpecTracer::CoverageMerger.new
189
+ @report_merger = RSpecTracer::ReportMerger.new
190
+ rescue LoadError => e
191
+ puts "Failed to load parallel tests (Error: #{e.message})"
192
+ ensure
193
+ track_parallel_tests_test_env_number
194
+ end
195
+
196
+ def track_parallel_tests_test_env_number
197
+ return unless parallel_tests?
198
+
199
+ File.open(RSpecTracer.parallel_tests_lock_file, File::RDWR | File::CREAT, 0o644) do |f|
200
+ f.flock(File::LOCK_EX)
201
+
202
+ test_num = [f.read.to_i, ENV['TEST_ENV_NUMBER'].to_i].max
203
+
204
+ f.rewind
205
+ f.write("#{test_num}\n")
206
+ f.flush
207
+ f.truncate(f.pos)
208
+ end
209
+ end
210
+
144
211
  def setup_rspec
145
212
  runners = ObjectSpace.each_object(::RSpec::Core::Runner) do |runner|
146
213
  runner_clazz = runner.singleton_class
@@ -184,15 +251,23 @@ module RSpecTracer
184
251
  end
185
252
 
186
253
  simplecov? ? run_simplecov_exit_task : run_coverage_exit_task
254
+
255
+ run_parallel_tests_exit_tasks
187
256
  end
188
257
 
189
258
  def generate_reports
190
- puts 'RSpec tracer is generating reports'
259
+ puts "RSpec tracer is generating reports (pid: #{RSpecTracer.pid})"
191
260
 
192
261
  process_dependency
193
262
  process_coverage
194
- runner.generate_report
195
- RSpecTracer::HTMLReporter::Reporter.new.generate_report
263
+
264
+ RSpecTracer::ReportGenerator.new(runner.reporter, runner.cache).generate_report
265
+
266
+ report_writer = RSpecTracer::ReportWriter.new(RSpecTracer.cache_path, runner.reporter)
267
+ report_writer.write_report
268
+ report_writer.print_duplicate_examples
269
+
270
+ RSpecTracer::HTMLReporter::Reporter.new(RSpecTracer.report_path, runner.reporter).generate_report
196
271
  end
197
272
 
198
273
  def process_dependency
@@ -204,9 +279,9 @@ module RSpecTracer
204
279
  runner.register_untraced_dependency(@traced_files)
205
280
 
206
281
  ending = Process.clock_gettime(Process::CLOCK_MONOTONIC)
207
- elpased = RSpecTracer::TimeFormatter.format_time(ending - starting)
282
+ elapsed = RSpecTracer::TimeFormatter.format_time(ending - starting)
208
283
 
209
- puts "RSpec tracer processed dependency (took #{elpased})" if RSpecTracer.verbose?
284
+ puts "RSpec tracer processed dependency (took #{elapsed})" if RSpecTracer.verbose?
210
285
  end
211
286
 
212
287
  def process_coverage
@@ -217,9 +292,9 @@ module RSpecTracer
217
292
  runner.register_examples_coverage(coverage_reporter.examples_coverage)
218
293
 
219
294
  ending = Process.clock_gettime(Process::CLOCK_MONOTONIC)
220
- elpased = RSpecTracer::TimeFormatter.format_time(ending - starting)
295
+ elapsed = RSpecTracer::TimeFormatter.format_time(ending - starting)
221
296
 
222
- puts "RSpec tracer processed coverage (took #{elpased})" if RSpecTracer.verbose?
297
+ puts "RSpec tracer processed coverage (took #{elapsed})" if RSpecTracer.verbose?
223
298
  end
224
299
 
225
300
  def run_simplecov_exit_task
@@ -239,34 +314,129 @@ module RSpecTracer
239
314
  coverage_reporter.generate_final_coverage
240
315
 
241
316
  file_name = File.join(RSpecTracer.coverage_path, 'coverage.json')
317
+ coverage_writer = RSpecTracer::CoverageWriter.new(file_name, coverage_reporter)
318
+
319
+ coverage_writer.write_report
320
+
321
+ ending = Process.clock_gettime(Process::CLOCK_MONOTONIC)
322
+
323
+ coverage_writer.print_stats(ending - starting)
324
+ end
325
+
326
+ def run_parallel_tests_exit_tasks
327
+ return unless parallel_tests_executed?
328
+
329
+ merge_parallel_tests_reports
330
+ write_parallel_tests_merged_report
331
+ merge_parallel_tests_coverage_reports
332
+ write_parallel_tests_coverage_report
333
+ purge_parallel_tests_reports
334
+ end
335
+
336
+ def merge_parallel_tests_reports
337
+ return unless parallel_tests_executed?
338
+
339
+ starting = Process.clock_gettime(Process::CLOCK_MONOTONIC)
340
+ reports_dir = []
242
341
 
243
- write_coverage_report(file_name)
342
+ 1.upto(ENV['PARALLEL_TEST_GROUPS'].to_i) do |test_num|
343
+ cache_path = File.dirname(RSpecTracer.cache_path)
344
+ cache_dir = File.join(cache_path, "parallel_tests_#{test_num}")
345
+
346
+ next unless File.directory?(cache_dir)
347
+
348
+ run_id = JSON.parse(File.read(File.join(cache_dir, 'last_run.json')))['run_id']
349
+
350
+ reports_dir << File.join(cache_dir, run_id)
351
+ end
352
+
353
+ report_merger.merge(reports_dir)
244
354
 
245
355
  ending = Process.clock_gettime(Process::CLOCK_MONOTONIC)
246
- elpased = RSpecTracer::TimeFormatter.format_time(ending - starting)
356
+ elapsed = RSpecTracer::TimeFormatter.format_time(ending - starting)
247
357
 
248
- print_coverage_stats(file_name, elpased)
358
+ puts "\nRSpec tracer merged parallel tests reports (took #{elapsed})"
249
359
  end
250
360
 
251
- def write_coverage_report(file_name)
252
- report = {
253
- RSpecTracer: {
254
- coverage: coverage_reporter.coverage,
255
- timestamp: Time.now.utc.to_i
256
- }
257
- }
361
+ def write_parallel_tests_merged_report
362
+ return unless parallel_tests_executed?
363
+
364
+ report_dir = File.dirname(RSpecTracer.cache_path)
258
365
 
259
- File.write(file_name, JSON.pretty_generate(report))
366
+ RSpecTracer::ReportWriter.new(report_dir, report_merger).write_report
367
+
368
+ report_dir = File.dirname(RSpecTracer.report_path)
369
+
370
+ RSpecTracer::HTMLReporter::Reporter.new(report_dir, report_merger).generate_report
260
371
  end
261
372
 
262
- def print_coverage_stats(file_name, elpased)
263
- stat = coverage_reporter.coverage_stat
373
+ def merge_parallel_tests_coverage_reports
374
+ return unless parallel_tests_executed? && !simplecov?
375
+
376
+ starting = Process.clock_gettime(Process::CLOCK_MONOTONIC)
377
+ reports_dir = []
378
+
379
+ 1.upto(ENV['PARALLEL_TEST_GROUPS'].to_i) do |test_num|
380
+ coverage_path = File.dirname(RSpecTracer.coverage_path)
381
+ coverage_dir = File.join(coverage_path, "parallel_tests_#{test_num}")
382
+
383
+ reports_dir << coverage_dir if File.directory?(coverage_dir)
384
+ end
385
+
386
+ coverage_merger.merge(reports_dir)
387
+
388
+ ending = Process.clock_gettime(Process::CLOCK_MONOTONIC)
389
+ elapsed = RSpecTracer::TimeFormatter.format_time(ending - starting)
390
+
391
+ puts "RSpec tracer merged parallel tests coverage reports (took #{elapsed})"
392
+ end
393
+
394
+ def write_parallel_tests_coverage_report
395
+ return unless parallel_tests_executed? && !simplecov?
396
+
397
+ starting = Process.clock_gettime(Process::CLOCK_MONOTONIC)
398
+
399
+ coverage_path = File.dirname(RSpecTracer.coverage_path)
400
+ file_name = File.join(coverage_path, 'coverage.json')
401
+ coverage_writer = RSpecTracer::CoverageWriter.new(file_name, coverage_merger)
402
+
403
+ coverage_writer.write_report
404
+
405
+ ending = Process.clock_gettime(Process::CLOCK_MONOTONIC)
406
+
407
+ coverage_writer.print_stats(ending - starting)
408
+ end
409
+
410
+ def purge_parallel_tests_reports
411
+ return unless parallel_tests_executed?
412
+
413
+ 1.upto(ENV['PARALLEL_TEST_GROUPS'].to_i) do |test_num|
414
+ [RSpecTracer.cache_path, RSpecTracer.coverage_path, RSpecTracer.report_path].each do |path|
415
+ FileUtils.rm_rf(File.join(File.dirname(path), "parallel_tests_#{test_num}"))
416
+ end
417
+ end
418
+ end
419
+
420
+ def parallel_tests_executed?
421
+ return false unless parallel_tests? && parallel_tests_last_process?
422
+
423
+ ParallelTests.wait_for_other_processes_to_finish
424
+
425
+ true
426
+ end
427
+
428
+ def parallel_tests_last_process?
429
+ return false unless parallel_tests?
430
+
431
+ max_test_num = 0
432
+
433
+ File.open(RSpecTracer.parallel_tests_lock_file, 'r') do |f|
434
+ f.flock(File::LOCK_SH)
435
+
436
+ max_test_num = f.read.to_i
437
+ end
264
438
 
265
- puts <<-REPORT.strip.gsub(/\s+/, ' ')
266
- Coverage report generated for RSpecTracer to #{file_name}. #{stat[:covered_lines]}
267
- / #{stat[:total_lines]} LOC (#{stat[:covered_percent]}%) covered
268
- (took #{elpased})
269
- REPORT
439
+ ENV['TEST_ENV_NUMBER'].to_i == max_test_num
270
440
  end
271
441
  end
272
442
  end
metadata CHANGED
@@ -1,55 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-tracer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.3
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Abhimanyu Singh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-03 00:00:00.000000000 Z
11
+ date: 2021-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: docile
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '1.1'
20
17
  - - ">="
21
18
  - !ruby/object:Gem::Version
22
19
  version: 1.1.0
20
+ - - "~>"
21
+ - !ruby/object:Gem::Version
22
+ version: '1.1'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
- - - "~>"
28
- - !ruby/object:Gem::Version
29
- version: '1.1'
30
27
  - - ">="
31
28
  - !ruby/object:Gem::Version
32
29
  version: 1.1.0
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '1.1'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: rspec-core
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
- - - "~>"
38
- - !ruby/object:Gem::Version
39
- version: '3.6'
40
37
  - - ">="
41
38
  - !ruby/object:Gem::Version
42
39
  version: 3.6.0
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: '3.6'
43
43
  type: :runtime
44
44
  prerelease: false
45
45
  version_requirements: !ruby/object:Gem::Requirement
46
46
  requirements:
47
- - - "~>"
48
- - !ruby/object:Gem::Version
49
- version: '3.6'
50
47
  - - ">="
51
48
  - !ruby/object:Gem::Version
52
49
  version: 3.6.0
50
+ - - "~>"
51
+ - !ruby/object:Gem::Version
52
+ version: '3.6'
53
53
  description: RSpec Tracer is a specs dependency analyzer, flaky tests detector, tests
54
54
  accelerator, and coverage reporter tool for RSpec. It maintains a list of files
55
55
  for each test, enabling itself to skip tests in the subsequent runs if none of the
@@ -67,7 +67,9 @@ files:
67
67
  - lib/rspec_tracer.rb
68
68
  - lib/rspec_tracer/cache.rb
69
69
  - lib/rspec_tracer/configuration.rb
70
+ - lib/rspec_tracer/coverage_merger.rb
70
71
  - lib/rspec_tracer/coverage_reporter.rb
72
+ - lib/rspec_tracer/coverage_writer.rb
71
73
  - lib/rspec_tracer/defaults.rb
72
74
  - lib/rspec_tracer/example.rb
73
75
  - lib/rspec_tracer/filter.rb
@@ -101,6 +103,9 @@ files:
101
103
  - lib/rspec_tracer/remote_cache/cache.rb
102
104
  - lib/rspec_tracer/remote_cache/repo.rb
103
105
  - lib/rspec_tracer/remote_cache/validator.rb
106
+ - lib/rspec_tracer/report_generator.rb
107
+ - lib/rspec_tracer/report_merger.rb
108
+ - lib/rspec_tracer/report_writer.rb
104
109
  - lib/rspec_tracer/reporter.rb
105
110
  - lib/rspec_tracer/rspec_reporter.rb
106
111
  - lib/rspec_tracer/rspec_runner.rb
@@ -114,7 +119,7 @@ licenses:
114
119
  - MIT
115
120
  metadata:
116
121
  homepage_uri: https://github.com/avmnu-sng/rspec-tracer
117
- source_code_uri: https://github.com/avmnu-sng/rspec-tracer/tree/v0.9.3
122
+ source_code_uri: https://github.com/avmnu-sng/rspec-tracer/tree/v1.0.0
118
123
  changelog_uri: https://github.com/avmnu-sng/rspec-tracer/blob/main/CHANGELOG.md
119
124
  bug_tracker_uri: https://github.com/avmnu-sng/rspec-tracer/issues
120
125
  post_install_message:
@@ -132,7 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
132
137
  - !ruby/object:Gem::Version
133
138
  version: '0'
134
139
  requirements: []
135
- rubygems_version: 3.2.26
140
+ rubygems_version: 3.0.9
136
141
  signing_key:
137
142
  specification_version: 4
138
143
  summary: RSpec Tracer is a specs dependency analyzer, flaky tests detector, tests