Module: SimpleCov::CLI::Report

Extended by:
CommandHelpers, Report
Included in:
Report
Defined in:
lib/simplecov/cli/report.rb

Constant Summary collapse

TOTAL_LABEL =
"All Files"
SECTIONS =

: Array[[String, String]]

[%w[Line lines], %w[Branch branches], %w[Method methods]].freeze

Constants included from CommandHelpers

CommandHelpers::STATS_ROW_FORMAT

Instance Method Summary collapse

Methods included from CommandHelpers

build_parser, command_name, common_options, error, error_nil, on_help, one?, parse_common, quiet_option, recorded_contexts, stats_row

Instance Method Details

#collect_section(totals) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
# File 'lib/simplecov/cli/report.rb', line 78

def collect_section(totals)
  sections = {} #: Hash[String, untyped]
  SECTIONS.each_with_object(sections) do |(_, key), out|
    section = totals[key]
    next unless section.instance_of?(Hash) && section["total"].to_i.positive?

    out[key] = {
      "percent" => section["percent"], "covered" => section["covered"], "total" => section.fetch("total")
    }
  end
end

#emit_json(stdout, data) ⇒ Object



71
72
73
74
75
76
# File 'lib/simplecov/cli/report.rb', line 71

def emit_json(stdout, data)
  none = {} #: Hash[String, untyped]
  groups = data.fetch("groups", none).transform_values { |group| collect_section(group) }
  payload = {"total" => collect_section(data.fetch("total", none)), "groups" => groups}
  stdout.puts(JSON.pretty_generate(payload))
end

#emit_section(stdout, display, section, color) ⇒ Object



62
63
64
65
66
67
68
69
# File 'lib/simplecov/cli/report.rb', line 62

def emit_section(stdout, display, section, color)
  return unless section.instance_of?(Hash) && section["total"].to_i.positive?

  stdout.puts(stats_row(display,
    Color.colorize_percent(section["percent"].to_f, enabled: color),
    section["covered"],
    section.fetch("total")))
end

#emit_text(stdout, data, color) ⇒ Object



47
48
49
50
51
52
53
54
# File 'lib/simplecov/cli/report.rb', line 47

def emit_text(stdout, data, color)
  none = {} #: Hash[String, untyped]
  emit_totals(stdout, TOTAL_LABEL, data.fetch("total", none), color)
  data.fetch("groups", none).each do |name, group|
    label = name.eql?(TOTAL_LABEL) ? "#{name} (group)" : name
    emit_totals(stdout, label, group, color)
  end
end

#emit_totals(stdout, label, totals, color) ⇒ Object



56
57
58
59
60
# File 'lib/simplecov/cli/report.rb', line 56

def emit_totals(stdout, label, totals, color)
  stdout.puts(label)
  SECTIONS.each { |display, key| emit_section(stdout, display, totals[key], color) }
  stdout.puts
end

#load_data(input, stderr) ⇒ Object

Valid JSON isn't enough: a wrong-typed "total" or "groups" used to escape here and crash the emitters with a backtrace instead of the one-line error the sibling commands print.



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

def load_data(input, stderr)
  data = CoverageFile.load_document(input, command: "report", stderr: stderr)
  return unless data

  none = {} #: Hash[String, untyped]
  unless data.fetch("total", none).instance_of?(Hash)
    return CoverageFile.report_invalid(stderr, "report", input, '"total" must be an object')
  end

  groups = data.fetch("groups", none)
  return data if groups.instance_of?(Hash) && groups.each_value.all?(Hash)

  CoverageFile.report_invalid(stderr, "report", input, '"groups" must be an object of objects')
end

#run(args, stdout:, stderr:) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
# File 'lib/simplecov/cli/report.rb', line 17

def run(args, stdout:, stderr:)
  opts, = parse_common(args)
  return 1 unless (data = load_data(opts.fetch(:input), stderr))

  if opts.fetch(:json)
    emit_json(stdout, data)
  else
    emit_text(stdout, data, CLI.color_enabled?(opts, stdout))
  end
  0
end