Module: SimpleCov::CLI::Coverage

Extended by:
CommandHelpers
Defined in:
lib/simplecov/cli/coverage.rb

Overview

simplecov coverage <path> — print per-criterion stats for one file from a JSONFormatter coverage.json.

Constant Summary

Constants included from CommandHelpers

SimpleCov::CLI::CommandHelpers::STATS_ROW_FORMAT

Class Method Summary collapse

Methods included from CommandHelpers

command_name, common_options, error, parse_common, stats_row

Class Method Details

.emit(match, opts, stdout) ⇒ Object



60
61
62
63
64
65
66
67
68
# File 'lib/simplecov/cli/coverage.rb', line 60

def emit(match, opts, stdout)
  filename, payload = match
  if opts[:json]
    entry = {filename => payload} #: Hash[untyped, untyped]
    stdout.puts(JSON.pretty_generate(entry))
  else
    print_human(filename, payload, stdout, SimpleCov::CLI.color_enabled?(opts, stdout))
  end
end

.emit_criterion(stdout, payload, criterion, color) ⇒ Object



75
76
77
78
79
80
81
82
83
# File 'lib/simplecov/cli/coverage.rb', line 75

def emit_criterion(stdout, payload, criterion, color)
  return unless payload.key?(criterion[:percent])

  pct = payload[criterion[:percent]].to_f
  stdout.puts(stats_row(criterion[:label],
                        SimpleCov::Color.colorize_percent(pct, enabled: color),
                        payload[criterion[:covered]],
                        payload[criterion[:total]]))
end

.locate_match(opts, stderr) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/simplecov/cli/coverage.rb', line 35

def locate_match(opts, stderr)
  coverage = CoverageFile.load_coverage(opts[:input], command: "coverage", stderr: stderr)
  return unless coverage

  match = lookup(coverage, opts[:path])
  if match.nil?
    stderr.puts("simplecov coverage: no entry for #{opts[:path]} in #{opts[:input]}")
    return nil
  end
  # A wrong-typed entry used to escape here and crash print_human.
  return match if match.last.is_a?(Hash)

  CoverageFile.report_invalid(stderr, "coverage", opts[:input], "entry for #{opts[:path]} must be an object")
end

.lookup(coverage_hash, path) ⇒ Object

Match either the absolute path, the literal string passed, or any coverage entry whose absolute filename ends with "/". That covers the three natural ways a user types a path: relative to project root ("app/foo.rb"), absolute, or basename-only.



54
55
56
57
58
# File 'lib/simplecov/cli/coverage.rb', line 54

def lookup(coverage_hash, path)
  absolute = File.expand_path(path)
  suffix   = "/#{path}"
  coverage_hash.find { |fname, _| fname == absolute || fname == path || fname.end_with?(suffix) }
end

.parse(args, stderr:) ⇒ Object



27
28
29
30
31
32
33
# File 'lib/simplecov/cli/coverage.rb', line 27

def parse(args, stderr:)
  opts, rest = parse_common(args)
  return stderr.puts("simplecov coverage: missing file argument") && nil if rest.empty?

  opts[:path] = rest.first
  opts
end


70
71
72
73
# File 'lib/simplecov/cli/coverage.rb', line 70

def print_human(filename, payload, stdout, color)
  stdout.puts(filename)
  CoverageFile::CRITERIA.each_value { |c| emit_criterion(stdout, payload, c, color) }
end

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



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

def run(args, stdout:, stderr:)
  opts = parse(args, stderr: stderr)
  return 1 unless opts

  match = locate_match(opts, stderr)
  return 1 unless match

  emit(match, opts, stdout)
  0
end