Class: SimpleCov::Formatter::Base Private

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

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.

Shared scaffolding for formatters that write a coverage report to an output directory and emit a "Coverage report generated for X to Y" summary on stderr. Subclasses override format, and may override message_prefix.

Direct Known Subclasses

BaselineFormatter, HTMLFormatter, JSONFormatter

Instance Method Summary collapse

Constructor Details

#initialize(silent: false, output_dir: nil) ⇒ Base

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.

output_dir defaults to SimpleCov.coverage_path. Pass it explicitly to write somewhere else.

Parameters:

  • silent: (Boolean) (defaults to: false)
  • output_dir: (String, nil) (defaults to: nil)


16
17
18
19
# File 'lib/simplecov/formatter/base.rb', line 16

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

Instance Method Details

#displayable_output_pathString

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.

The path shown in the "Coverage report generated for X to Y" status line. Rendered relative to cwd when output_path lives inside cwd, with the formatter's entry_point_filename appended so the line points at a concrete file a terminal can hyperlink. Paths outside cwd stay absolute; a ../../../tmp/cov display would be more confusing (#197).

Returns:

  • (String)


51
52
53
54
55
# File 'lib/simplecov/formatter/base.rb', line 51

def displayable_output_path
  directory = relative_or_absolute_output_path
  entry_point = entry_point_filename
  entry_point ? File.join(directory, entry_point) : directory
end

#emit_status(result) ⇒ void

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.

This method returns an undefined value.

The one home of the "status lines go to stderr, not through warn" decision (#1225). stderr rather than stdout because this is a status message, not the program's output, so it stays out of pipelines like rspec -f json. And $stderr.puts rather than warn so the line neither reaches Warning.warn hooks nor vanishes under -W0.

Parameters:

  • result (Object)


28
29
30
31
32
33
34
# File 'lib/simplecov/formatter/base.rb', line 28

def emit_status(result)
  $stderr.puts output_message(result) unless @silent # rubocop:disable Style/StderrPuts
rescue IOError
  # A parallel runner can close a worker's stderr before its at_exit hooks
  # run (rspec-conductor does). Losing the status line must not abort the
  # exit tasks that follow report generation.
end

#entry_point_filenameString?

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.

Subclasses override to name the report's entry-point file, which gets appended to the directory in the status line. The empty body answers nil, which leaves the bare directory in place for any third-party formatter that has no single canonical entry point.

Returns:

  • (String, nil)


71
72
# File 'lib/simplecov/formatter/base.rb', line 71

def entry_point_filename
end

#message_prefixString

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.

Subclasses override to prepend a marker (e.g. "JSON ") to the summary line. Empty for the HTML formatter, historically the unmarked default.

Returns:

  • (String)


38
39
40
# File 'lib/simplecov/formatter/base.rb', line 38

def message_prefix
  ""
end

#output_message(result) ⇒ String

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.

One summary line per criterion the run actually measured, in the order of result.coverage_statistics, which reflects what the user enabled.

Parameters:

  • result (Object)

Returns:

  • (String)


76
77
78
79
80
# File 'lib/simplecov/formatter/base.rb', line 76

def output_message(result)
  header = "#{message_prefix}Coverage report generated for #{result.command_name} to #{displayable_output_path}"
  body = result.coverage_statistics.filter_map { |criterion, stat| stats_line(criterion, stat) }
  [header, *body].join("\n")
end

#output_pathString

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.

Returns:

  • (String)


42
43
44
# File 'lib/simplecov/formatter/base.rb', line 42

def output_path
  @output_dir || SimpleCov.coverage_path
end

#relative_or_absolute_output_pathString

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.

Returns:

  • (String)


57
58
59
60
61
62
63
64
65
# File 'lib/simplecov/formatter/base.rb', line 57

def relative_or_absolute_output_path
  absolute = output_path
  relative = Pathname.new(absolute).relative_path_from(Pathname.pwd).to_s
  relative.start_with?("..") ? absolute : relative
rescue ArgumentError
  # Pathname#relative_path_from raises across mixed absolute/relative
  # inputs, and across Windows drives.
  output_path
end

#stats_line(criterion, stat) ⇒ String?

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.

Returns nil for branch/method criteria that have nothing to measure. Showing "Branch coverage: 0 / 0 (100.00%)" is noise.

Parameters:

Returns:

  • (String, nil)


84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/simplecov/formatter/base.rb', line 84

def stats_line(criterion, stat)
  return if !criterion.equal?(:line) && !stat.total.positive?

  percent = SimpleCov.round_coverage(stat.percent)
  # `Symbol#capitalize` answers a Symbol, which `%<label>s` renders as its
  # capitalized name, so the label needs no `to_s` step of its own.
  Kernel.format(
    "%<label>s coverage: %<covered>d / %<total>d (%<percent>s)",
    label: criterion.capitalize,
    covered: stat.covered,
    total: stat.total,
    percent: Color.colorize_percent(percent)
  )
end