123456789_123456789_123456789_123456789_123456789_

Class: SimpleCov::Formatter::JSONFormatter

Relationships & Source Files
Namespace Children
Classes:
Inherits: Object
Defined in: lib/simplecov/formatter/json_formatter.rb,
lib/simplecov/formatter/json_formatter/result_hash_formatter.rb

Overview

Writes coverage results as JSON to coverage/coverage.json. Used standalone, alongside the HTML formatter, or by external tools that consume ::SimpleCov output.

Constant Summary

Class Method Summary

Instance Method Summary

Constructor Details

.new(silent: false, output_dir: nil) ⇒ JSONFormatter

output_dir defaults to SimpleCov.coverage_path so the at_exit pipeline keeps working unchanged. Pass it explicitly to write somewhere else (handy for tests that don't want to clobber the project's coverage/ directory).

[ GitHub ]

  
# File 'lib/simplecov/formatter/json_formatter.rb', line 20

def initialize(silent: false, output_dir: nil)
  @silent = silent
  @output_dir = output_dir
end

Class Method Details

.build_hash(result)

[ GitHub ]

  
# File 'lib/simplecov/formatter/json_formatter.rb', line 25

def self.build_hash(result)
  ResultHashFormatter.new(result).format
end

Instance Method Details

#existing_timestamp(path) (private)

[ GitHub ]

  
# File 'lib/simplecov/formatter/json_formatter.rb', line 55

def existing_timestamp(path)
  return nil unless File.exist?(path)

  timestamp = JSON.parse(File.read(path), symbolize_names: true).dig(:meta, :timestamp)
  timestamp && Time.iso8601(timestamp)
rescue JSON::ParserError, ArgumentError
  nil
end

#format(result)

[ GitHub ]

  
# File 'lib/simplecov/formatter/json_formatter.rb', line 29

def format(result)
  FileUtils.mkdir_p(output_path)
  path = File.join(output_path, FILENAME)
  warn_if_concurrent_overwrite(path)
  File.write(path, JSON.pretty_generate(self.class.build_hash(result)))
  puts output_message(result) unless @silent
end

#output_message(result) (private)

[ GitHub ]

  
# File 'lib/simplecov/formatter/json_formatter.rb', line 64

def output_message(result)
  "JSON Coverage report generated for #{result.command_name} to #{output_path}. " \
    "#{result.covered_lines} / #{result.total_lines} LOC " \
    "(#{SimpleCov.round_coverage(result.covered_percent)}%) covered."
end

#output_path (private)

[ GitHub ]

  
# File 'lib/simplecov/formatter/json_formatter.rb', line 70

def output_path
  @output_dir || SimpleCov.coverage_path
end

#warn_if_concurrent_overwrite(path) (private)

Warns when the existing coverage.json has a timestamp newer than this process's start time — a strong signal that a sibling test process (e.g., parallel_tests) wrote it while we were running, and that our write is about to clobber their data.

[ GitHub ]

  
# File 'lib/simplecov/formatter/json_formatter.rb', line 43

def warn_if_concurrent_overwrite(path)
  start_time = SimpleCov.process_start_time or return
  existing_ts = existing_timestamp(path) or return
  return unless existing_ts > start_time

  warn "simplecov: #{path} was written at #{existing_ts.iso8601} — after " \
       "this process started at #{start_time.iso8601}. Overwriting " \
       "likely loses coverage data from a concurrent test run. For " \
       "parallel test setups, use SimpleCov::ResultMerger or run a single " \
       "collation step after all workers finish."
end