Class: SimpleCov::Formatter::HTMLFormatter

Inherits:
Base
  • Object
show all
Defined in:
lib/simplecov/formatter/html_formatter.rb,
lib/simplecov/formatter/html_formatter/viewer_data_validator.rb,
sig/simplecov.rbs

Overview

Writes the HTML report as a single self-contained index.html (the compiled template with the coverage JSON substituted at the data marker), and coverage.json as a side artifact (shared serialization via JSONFormatter.build_hash).

Defined Under Namespace

Modules: ViewerDataValidator

Constant Summary collapse

DATA_MARKER =

Placeholder in the compiled template where the report's data goes.

Returns:

  • ("<!-- SIMPLECOV_COVERAGE_DATA -->")
"<!-- SIMPLECOV_COVERAGE_DATA -->"
LEGACY_REPORT_FILES =

The sibling files a 1.0.0 through 1.0.3 report wrote next to index.html, removed by format when an earlier version left them.

Returns:

  • (Array[String])
%w[
  coverage_data.js application.js application.css
  favicon_green.png favicon_red.png favicon_yellow.png
].freeze

Instance Method Summary collapse

Methods inherited from Base

#displayable_output_path, #emit_status, #initialize, #message_prefix, #output_message, #output_path, #relative_or_absolute_output_path, #stats_line

Constructor Details

This class inherits a constructor from SimpleCov::Formatter::Base

Instance Method Details

#entry_point_filenameString

Returns:

  • (String)


60
61
62
# File 'lib/simplecov/formatter/html_formatter.rb', line 60

def entry_point_filename
  "index.html"
end

#format(result) ⇒ void

This method returns an undefined value.

Parameters:



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/simplecov/formatter/html_formatter.rb', line 31

def format(result)
  # The inlined report data feeds the client-side viewer, which
  # renders source from the embedded array — it always needs
  # `source`, regardless of `SimpleCov.source_in_json`. The
  # side-file `coverage.json` honors the setting so downstream
  # tools that read source from disk can opt into a smaller
  # payload. The embedded copy is serialized compactly (pretty
  # printing puts every element of every per-line coverage array
  # on its own indented line, roughly doubling the payload);
  # coverage.json stays pretty-printed for human readers.
  viewer_hash = JSONFormatter.build_hash(result, include_source: true)
  json_hash = SimpleCov.source_in_json ? viewer_hash : source_less_hash(viewer_hash)
  write_report_files(json_hash, viewer_hash, result)
  emit_status(result)
end

#format_from_json(json_path, output_dir) ⇒ void

This method returns an undefined value.

Generate HTML from a pre-existing coverage.json file without a live SimpleCov::Result or a running test suite.

Parameters:

  • json_path (String)
  • output_dir (String)


52
53
54
55
56
# File 'lib/simplecov/formatter/html_formatter.rb', line 52

def format_from_json(json_path, output_dir)
  data = ViewerDataValidator.call(SimpleCov::CoverageJSON.load(json_path))
  json = JSON.generate(data)
  AtomicFile.write(File.join(output_dir, "index.html"), render_report(json), binary: true)
end

#public_dirString

Returns:

  • (String)


96
97
98
99
100
# File 'lib/simplecov/formatter/html_formatter.rb', line 96

def public_dir
  # `.to_s` collapses `__dir__`'s nil arm (only possible under eval,
  # which can't happen for a file on disk) so the path is a String.
  File.join(__dir__.to_s, "html_formatter/public/")
end

#render_report(json) ⇒ String

Substitute the coverage JSON into the compiled template.

Parameters:

  • json (String)

Returns:

  • (String)


81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/simplecov/formatter/html_formatter.rb', line 81

def render_report(json)
  # UTF-8 explicitly, not the locale's `Encoding.default_external`:
  # the JSON payload is UTF-8, and substituting it into a template
  # tagged US-ASCII (or a Windows code page) raises
  # Encoding::CompatibilityError the moment either side carries a
  # non-ASCII character.
  template = File.read(File.join(public_dir, "index.html"), encoding: Encoding::UTF_8)
  unless template.include?(DATA_MARKER)
    raise "SimpleCov's HTML template is missing its #{DATA_MARKER.inspect} marker"
  end

  data_script = "<script>window.SIMPLECOV_DATA = #{json.gsub('<') { '\u003c' }};</script>"
  template.sub(DATA_MARKER) { data_script }
end

#source_less_hash(hash) ⇒ Hash[Symbol, untyped]

Parameters:

  • hash (Hash[Symbol, untyped])

Returns:

  • (Hash[Symbol, untyped])


64
65
66
67
# File 'lib/simplecov/formatter/html_formatter.rb', line 64

def source_less_hash(hash)
  coverage = hash.fetch(:coverage).transform_values { |file| file.except(:source) }
  hash.merge(coverage: coverage)
end

#write_report_files(json_hash, viewer_hash, result) ⇒ void

This method returns an undefined value.

Write coverage.json and index.html, then clear any legacy sibling files an earlier version left in the output directory.

Parameters:

  • json_hash (Hash[untyped, untyped])
  • viewer_hash (Hash[untyped, untyped])
  • result (SimpleCov::Result)


1441
1442
1443
1444
1445
# File 'sig/simplecov.rbs', line 1441

def write_report_files(json_hash, viewer_hash, result)
  CoverageJSONWriter.write(output_path, json_hash, result)
  AtomicFile.write(File.join(output_path, "index.html"), render_report(JSON.generate(viewer_hash)), binary: true)
  FileUtils.rm_f(LEGACY_REPORT_FILES.map { |name| File.join(output_path, name) })
end