turbo_tests2 3.1.8 → 3.1.9

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: 896b2cd3a1a1e517516e76797c8a6a9783d1883d43a215086c165ecb72eea59c
4
- data.tar.gz: ce168afe9a512e7ab9d10cc165d034e2a9d0e8cbe735583ea0c4d7742134ff4b
3
+ metadata.gz: fabbd1aadd354e11840e0aaf2ce278c209eb3600f58b8a2ed9eadca74b1428bc
4
+ data.tar.gz: 75ee010bc491d4e4a5b77c0ede26bc748eeba35d89fafdab64e5acd2deb10df2
5
5
  SHA512:
6
- metadata.gz: 24ec7b6ddde8980013440ccdc0792ba033698470f73469dd726028778bcfc2afaf29e146c421ec924475b1937c2a7253e43bc8e193fb2cdd695ad953e3a009ad
7
- data.tar.gz: f26102397a81ae27a5518451a8be811d4346674e7b98c3cbfb692a45f58422ce5a2c4090bf3aa13d0a52d7000f654848295e37a3e0ef73987ddcc2383bd7a5e8
6
+ metadata.gz: 649dc4a8ac38f52c4773432cb404e43b16cbf9a4197c20bb49c01b8774b88b82a5921544e450541e61ffb3ceef3466c65536317c415a8ecd9d07acd05a547b38
7
+ data.tar.gz: c23d6a3c468aee9b3d32879dd8eeaf01b2801b2bad965fb406e4539407cf3f29f4548f377318155d7e8e0dde6e9fa4e879852b3bb8235d161ee7e9d23f8b8025
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -28,11 +28,23 @@ Please file a bug if you notice a violation of semantic versioning.
28
28
 
29
29
  ### Fixed
30
30
 
31
+ ### Security
32
+
33
+ ## [3.1.9] - 2026-07-14
34
+
35
+ - TAG: [v3.1.9][3.1.9t]
36
+ - COVERAGE: 97.60% -- 692/709 lines in 10 files
37
+ - BRANCH COVERAGE: 89.13% -- 164/184 branches in 10 files
38
+ - 37.08% documented
39
+
40
+ ### Fixed
41
+
42
+ - Buffered non-RSpec worker stdout/stderr so successful parallel runs no longer
43
+ leak interleaved coverage formatter output, while still reporting a single
44
+ concise coverage summary.
31
45
  - Prevented invalid UTF-8 bytes in worker output from crashing the parent
32
46
  runner on JRuby after the underlying RSpec examples pass.
33
47
 
34
- ### Security
35
-
36
48
  ## [3.1.8] - 2026-07-14
37
49
 
38
50
  - TAG: [v3.1.8][3.1.8t]
@@ -223,7 +235,9 @@ Please file a bug if you notice a violation of semantic versioning.
223
235
 
224
236
  - Initial release
225
237
 
226
- [Unreleased]: https://github.com/galtzo-floss/turbo_tests2/compare/v3.1.8...HEAD
238
+ [Unreleased]: https://github.com/galtzo-floss/turbo_tests2/compare/v3.1.9...HEAD
239
+ [3.1.9]: https://github.com/galtzo-floss/turbo_tests2/compare/v3.1.8...v3.1.9
240
+ [3.1.9t]: https://github.com/galtzo-floss/turbo_tests2/releases/tag/v3.1.9
227
241
  [3.1.8]: https://github.com/galtzo-floss/turbo_tests2/compare/v3.1.7...v3.1.8
228
242
  [3.1.8t]: https://github.com/galtzo-floss/turbo_tests2/releases/tag/v3.1.8
229
243
  [3.1.7]: https://github.com/galtzo-floss/turbo_tests2/compare/v3.1.6...v3.1.7
data/README.md CHANGED
@@ -666,7 +666,7 @@ Thanks for RTFM. ☺️
666
666
  [📌gitmoji]: https://gitmoji.dev
667
667
  [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
668
668
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
669
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-0.653-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
669
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-0.709-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
670
670
  [🔐security]: https://github.com/galtzo-floss/turbo_tests2/blob/main/SECURITY.md
671
671
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
672
672
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
@@ -135,6 +135,8 @@ module TurboTests
135
135
  @threads = []
136
136
  @wait_threads = []
137
137
  @exited_process_ids = []
138
+ @worker_output = Hash.new { |hash, process_id| hash[process_id] = {stdout: +"", stderr: +""} }
139
+ @worker_output_mutex = Mutex.new
138
140
  @error = false
139
141
  @print_failed_group = opts[:print_failed_group]
140
142
  end
@@ -158,6 +160,9 @@ module TurboTests
158
160
  }
159
161
 
160
162
  ParallelTests.with_pid_file do
163
+ exit_status = nil
164
+ report_coverage = false
165
+
161
166
  @reporter.report(tests_in_groups) do |_reporter|
162
167
  old_signal = Signal.trap(:INT) { handle_interrupt }
163
168
 
@@ -174,13 +179,20 @@ module TurboTests
174
179
 
175
180
  Signal.trap(:INT, old_signal)
176
181
 
177
- if @reporter.failed_examples.empty? && @wait_threads.map(&:value).all?(&:success?)
178
- 0
182
+ statuses = @wait_threads.map(&:value)
183
+
184
+ if @reporter.failed_examples.empty? && statuses.all?(&:success?)
185
+ report_coverage = true
186
+ exit_status = 0
179
187
  else
188
+ flush_worker_output
180
189
  # From https://github.com/galtzo-floss/turbo_tests2/pull/20/
181
- @wait_threads.map { |thread| thread.value.exitstatus }.max
190
+ exit_status = statuses.map(&:exitstatus).max
182
191
  end
183
192
  end
193
+
194
+ flush_coverage_summary if report_coverage
195
+ exit_status
184
196
  end
185
197
  end
186
198
 
@@ -302,7 +314,7 @@ module TurboTests
302
314
  result = line.b.split(output_id)
303
315
 
304
316
  initial = result.shift
305
- print(initial) unless initial.empty?
317
+ append_worker_output(process_id, :stdout, initial) unless initial.empty?
306
318
 
307
319
  message = result.shift
308
320
  next unless message
@@ -322,14 +334,14 @@ module TurboTests
322
334
  # rubocop:enable ThreadSafety/NewThread
323
335
  @threads << stdout_thread
324
336
 
325
- stderr_thread = start_copy_thread(stderr, $stderr)
337
+ stderr_thread = start_copy_thread(stderr, process_id, :stderr)
326
338
  @threads << stderr_thread
327
339
 
328
340
  # rubocop:disable ThreadSafety/NewThread
329
341
  @threads << Thread.new do
330
342
  begin
331
343
  status = wait_thr.value
332
- @messages << {type: "error"} unless status.success?
344
+ @messages << {type: "error", process_id: process_id} unless status.success?
333
345
  @messages << {type: "exit", process_id: process_id}
334
346
  ensure
335
347
  stop_reader_thread(stdout_thread, stdout)
@@ -355,7 +367,7 @@ module TurboTests
355
367
  ParallelTests::Pids.new(pid_file_path).delete(pid) if pid && pid_file_path
356
368
  end
357
369
 
358
- def start_copy_thread(src, dst)
370
+ def start_copy_thread(src, process_id, stream)
359
371
  # rubocop:disable ThreadSafety/NewThread
360
372
  Thread.new do
361
373
  # rubocop:enable ThreadSafety/NewThread
@@ -368,12 +380,75 @@ module TurboTests
368
380
  rescue IOError
369
381
  break
370
382
  else
371
- dst.write(msg)
383
+ append_worker_output(process_id, stream, msg)
372
384
  end
373
385
  end
374
386
  end
375
387
  end
376
388
 
389
+ def append_worker_output(process_id, stream, msg)
390
+ return if msg.empty?
391
+
392
+ msg = msg.dup.force_encoding(Encoding::UTF_8).scrub
393
+ @worker_output_mutex.synchronize do
394
+ @worker_output[process_id][stream] << msg
395
+ end
396
+
397
+ io = (stream == :stderr) ? $stderr : $stdout
398
+ io.write(msg) if @verbose
399
+ end
400
+
401
+ def flush_worker_output
402
+ output_by_process = @worker_output_mutex.synchronize do
403
+ @worker_output.transform_values(&:dup)
404
+ end
405
+
406
+ output_by_process.each do |process_id, streams|
407
+ streams.each do |stream, output|
408
+ next if output.empty?
409
+
410
+ io = (stream == :stderr) ? $stderr : $stdout
411
+ io.puts
412
+ io.puts("TurboTests worker #{process_id} #{stream}:")
413
+ io.write(output)
414
+ io.puts unless output.end_with?("\n")
415
+ end
416
+ end
417
+ end
418
+
419
+ def flush_coverage_summary
420
+ line_coverage = nil
421
+ branch_coverage = nil
422
+ @worker_output_mutex.synchronize do
423
+ @worker_output.each_value do |streams|
424
+ streams.each_value do |output|
425
+ output.each_line do |line|
426
+ stripped = line.strip
427
+ line_coverage = coverage_line("Line", stripped, line_coverage)
428
+ branch_coverage = coverage_line("Branch", stripped, branch_coverage)
429
+ end
430
+ end
431
+ end
432
+ end
433
+
434
+ return unless line_coverage || branch_coverage
435
+
436
+ puts
437
+ puts("Coverage:")
438
+ puts(line_coverage) if line_coverage
439
+ puts(branch_coverage) if branch_coverage
440
+ end
441
+
442
+ def coverage_line(kind, line, current)
443
+ return line if line.start_with?("#{kind} Coverage:")
444
+ return current if current&.start_with?("#{kind} Coverage:")
445
+
446
+ match = line.match(/\A#{kind} coverage:\s*(\d+)\s*\/\s*(\d+)\s*\(([^)]+)\)\z/i)
447
+ return current unless match
448
+
449
+ "#{kind} Coverage: #{match[3]} (#{match[1]} / #{match[2]})"
450
+ end
451
+
377
452
  def stop_reader_thread(thread, io)
378
453
  return if thread.join(0.1)
379
454
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module TurboTests
4
4
  module Version
5
- VERSION = "3.1.8"
5
+ VERSION = "3.1.9"
6
6
  end
7
7
  VERSION = Version::VERSION # Traditional Constant Location
8
8
  end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: turbo_tests2
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.8
4
+ version: 3.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Illia
@@ -312,10 +312,10 @@ licenses:
312
312
  - MIT
313
313
  metadata:
314
314
  homepage_uri: https://turbo-tests2.galtzo.com
315
- source_code_uri: https://github.com/galtzo-floss/turbo_tests2/tree/v3.1.8
316
- changelog_uri: https://github.com/galtzo-floss/turbo_tests2/blob/v3.1.8/CHANGELOG.md
315
+ source_code_uri: https://github.com/galtzo-floss/turbo_tests2/tree/v3.1.9
316
+ changelog_uri: https://github.com/galtzo-floss/turbo_tests2/blob/v3.1.9/CHANGELOG.md
317
317
  bug_tracker_uri: https://github.com/galtzo-floss/turbo_tests2/issues
318
- documentation_uri: https://www.rubydoc.info/gems/turbo_tests2/3.1.8
318
+ documentation_uri: https://www.rubydoc.info/gems/turbo_tests2/3.1.9
319
319
  funding_uri: https://github.com/sponsors/pboling
320
320
  wiki_uri: https://github.com/galtzo-floss/turbo_tests2/wiki
321
321
  news_uri: https://www.railsbling.com/tags/turbo_tests2
metadata.gz.sig CHANGED
Binary file