Class: RSpecTracer::Reporters::CoverageJsonReporter Private

Inherits:
Base
  • Object
show all
Defined in:
lib/rspec_tracer/reporters/coverage_json_reporter.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Single owner of ‘coverage.json` emission in 2.0. Replaces the legacy CoverageReporter + CoverageWriter + CoverageMerger + RubyCoverage quartet that 1.x carried. Output shape preserved byte-for-byte for downstream consumers (user CI dashboards parse this):

{ "RSpecTracer": {
    "coverage": { "<absolute_path>": [Integer|nil, ...], ... },
    "timestamp": <Integer>
} }

Cumulative coverage source: ‘::Coverage.peek_result` at finalize time, routed through `Tracker::CoverageAdapter#peek_unfiltered` so the lib/-wide peek_result call-site count stays at 3 (one each in coverage_adapter.rb, rspec/installation.rb, and tracker/loaded_files_tracker.rb).

Skipped-example contribution: ‘Engine#merge_skipped_coverage`, which replays 1.x’s CoverageReporter algorithm verbatim - per- skipped-example per-line strengths add into the cumulative map.

SimpleCov interop: when SimpleCov is loaded, this reporter does NOT write coverage.json. Instead it installs a small inner module via ‘::Coverage.singleton_class.prepend` so SimpleCov’s at_exit result-merge sees rspec-tracer’s filtered coverage. Matches 1.x behavior + the integration matrix convention.

Parallel_tests: per-worker emit happens through the Registry like every other reporter (each worker writes its own coverage.json under the per-worker coverage_path). The elected worker calls ‘merge_parallel` from `RSpec::ParallelTests` to union the per-worker files into the top-level coverage.json.

Defined Under Namespace

Modules: SimpleCovInterop

Constant Summary collapse

FILENAME =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Internal constant.

'coverage.json'

Instance Attribute Summary

Attributes inherited from Base

#logger, #options, #report_dir, #run_metadata, #snapshot

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#initialize

Constructor Details

This class inherits a constructor from RSpecTracer::Reporters::Base

Class Method Details

.merge_parallel(peer_paths:, output_path:, logger: nil) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Class-level rollup for parallel_tests. Unions per-line strengths across the per-worker coverage.json files written by ‘generate` on each worker, then writes the merged top-level coverage.json. Replaces 1.x’s ‘CoverageMerger.new + CoverageWriter.new(top_path, merger)`.



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/rspec_tracer/reporters/coverage_json_reporter.rb', line 81

def self.merge_parallel(peer_paths:, output_path:, logger: nil)
  merged = {}
  peer_paths.each do |peer|
    path = File.join(peer, FILENAME)
    next unless File.file?(path)

    data = JSON.parse(File.read(path, encoding: 'UTF-8'))
    peer_coverage = data.fetch('RSpecTracer').fetch('coverage')
    peer_coverage.each do |file_path, lines|
      if merged.key?(file_path)
        merge_line_arrays(merged[file_path], lines)
      else
        merged[file_path] = lines.dup
      end
    end
  end

  FileUtils.mkdir_p(File.dirname(output_path))
  payload = { RSpecTracer: { coverage: merged, timestamp: Time.now.utc.to_i } }
  File.write(output_path, JSON.pretty_generate(payload), encoding: 'UTF-8')
  logger&.debug("rspec-tracer: wrote merged coverage.json to #{output_path}")
  output_path
end

Instance Method Details

#generateString?

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Concrete implementation of Base#generate. Builds the cumulative coverage payload and writes ‘coverage.json` under Base#report_dir, except when SimpleCov owns the run (in which case the SimpleCov interop shim takes over).

Returns:

  • (String, nil)

    absolute path of the written file, or nil when the run wrote nothing (engine missing / SimpleCov interop).



57
58
59
60
61
62
63
64
65
# File 'lib/rspec_tracer/reporters/coverage_json_reporter.rb', line 57

def generate
  return nil unless RSpecTracer.engine
  return install_simplecov_interop if RSpecTracer.simplecov?

  coverage = build_coverage
  write_coverage_json(coverage)
  log_stats(coverage)
  target_path
end

#no_op?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Coverage emission fires unconditionally - even when no examples ran, 1.x writes coverage.json with whatever boot-time peek_result returned (plus filter + stub). Override Base#no_op? so the parent’s “snapshot has zero examples” early-return doesn’t gate this emitter.

Returns:

  • (Boolean)


72
73
74
# File 'lib/rspec_tracer/reporters/coverage_json_reporter.rb', line 72

def no_op?
  false
end