Module: SimpleCov::CLI::Uncovered
- Extended by:
- CommandHelpers
- Defined in:
- lib/simplecov/cli/uncovered.rb
Overview
simplecov uncovered [--threshold N] [--top N] [--criterion C] — list
the lowest-coverage files (by the chosen criterion, ascending), so a
developer can answer "where should I add tests next?" without
opening a browser. Reads coverage.json directly.
Constant Summary
collapse
- DEFAULT_TOP =
10
CommandHelpers::STATS_ROW_FORMAT
Class Method Summary
collapse
-
.emit(stdout, files, opts) ⇒ Object
-
.emit_json(stdout, files) ⇒ Object
-
.emit_text(stdout, files, color) ⇒ Object
-
.empty_message(json) ⇒ Object
-
.format_row(fname, pct, covered, total, color) ⇒ Object
-
.parse(args) ⇒ Object
-
.rank(coverage_hash, threshold, keys) ⇒ Object
-
.report(opts, keys, stdout, stderr) ⇒ Object
-
.row_for(fname, payload, threshold, keys) ⇒ Object
-
.run(args, stdout:, stderr:) ⇒ Object
-
.unknown_criterion(criterion, stderr) ⇒ Object
-
.validate_top(value) ⇒ Object
A negative count would raise from Array#first; report it as the parse error it is (--top 0 is allowed and shows nothing).
command_name, common_options, error, parse_common, stats_row
Class Method Details
.emit(stdout, files, opts) ⇒ Object
44
45
46
|
# File 'lib/simplecov/cli/uncovered.rb', line 44
def emit(stdout, files, opts)
opts[:json] ? emit_json(stdout, files) : emit_text(stdout, files, SimpleCov::CLI.color_enabled?(opts, stdout))
end
|
.emit_json(stdout, files) ⇒ Object
71
72
73
74
75
76
|
# File 'lib/simplecov/cli/uncovered.rb', line 71
def emit_json(stdout, files)
rows = files.map do |fname, pct, covered, total|
{"file" => fname, "percent" => pct, "covered" => covered, "total" => total}
end
stdout.puts(JSON.pretty_generate(rows))
end
|
.emit_text(stdout, files, color) ⇒ Object
67
68
69
|
# File 'lib/simplecov/cli/uncovered.rb', line 67
def emit_text(stdout, files, color)
files.each { |fname, pct, covered, total| stdout.puts(format_row(fname, pct, covered, total, color)) }
end
|
.empty_message(json) ⇒ Object
78
79
80
|
# File 'lib/simplecov/cli/uncovered.rb', line 78
def empty_message(json)
json ? "[]" : "simplecov uncovered: nothing to report"
end
|
96
97
98
99
100
|
# File 'lib/simplecov/cli/uncovered.rb', line 96
def format_row(fname, pct, covered, total, color)
format("%<pct>s %<covered>d/%<total>d %<fname>s",
pct: SimpleCov::Color.colorize_percent(pct, format("%6.2f%%", pct), enabled: color),
covered: covered, total: total, fname: fname)
end
|
.parse(args) ⇒ Object
48
49
50
51
52
53
54
55
|
# File 'lib/simplecov/cli/uncovered.rb', line 48
def parse(args)
opts, = parse_common(args, threshold: 100.0, top: DEFAULT_TOP, criterion: :line) do |o, options|
o.on("--threshold N", Float) { |v| options[:threshold] = v }
o.on("--top N", Integer) { |v| options[:top] = validate_top(v) }
o.on("--criterion C") { |v| options[:criterion] = v.to_sym }
end
opts
end
|
.rank(coverage_hash, threshold, keys) ⇒ Object
82
83
84
85
|
# File 'lib/simplecov/cli/uncovered.rb', line 82
def rank(coverage_hash, threshold, keys)
rows = coverage_hash.filter_map { |fname, payload| row_for(fname, payload, threshold, keys) }
rows.sort_by { |_fname, pct, _c, _t| pct }
end
|
.report(opts, keys, stdout, stderr) ⇒ Object
28
29
30
31
32
33
34
35
36
37
|
# File 'lib/simplecov/cli/uncovered.rb', line 28
def report(opts, keys, stdout, stderr)
coverage = CoverageFile.load_coverage(opts[:input], command: "uncovered", stderr: stderr)
return 1 unless coverage
files = rank(coverage, opts[:threshold], keys).first(opts[:top])
return stdout.puts(empty_message(opts[:json])) || 0 if files.empty?
emit(stdout, files, opts)
0
end
|
.row_for(fname, payload, threshold, keys) ⇒ Object
87
88
89
90
91
92
93
94
|
# File 'lib/simplecov/cli/uncovered.rb', line 87
def row_for(fname, payload, threshold, keys)
return unless payload.is_a?(Hash) && payload[keys[:total]].to_i.positive?
pct = payload[keys[:percent]].to_f
return if pct >= threshold
[fname, pct, payload[keys[:covered]].to_i, payload[keys[:total]].to_i]
end
|
.run(args, stdout:, stderr:) ⇒ Object
20
21
22
23
24
25
26
|
# File 'lib/simplecov/cli/uncovered.rb', line 20
def run(args, stdout:, stderr:, **)
opts = parse(args)
keys = CoverageFile::CRITERIA[opts[:criterion]]
return unknown_criterion(opts[:criterion], stderr) unless keys
report(opts, keys, stdout, stderr)
end
|
.unknown_criterion(criterion, stderr) ⇒ Object
39
40
41
42
|
# File 'lib/simplecov/cli/uncovered.rb', line 39
def unknown_criterion(criterion, stderr)
stderr.puts("simplecov uncovered: unknown --criterion #{criterion.inspect} (expected line, branch, or method)")
1
end
|
.validate_top(value) ⇒ Object
A negative count would raise from Array#first; report it as
the parse error it is (--top 0 is allowed and shows nothing).
OptionParser prepends the offending option's name, so the raise
carries only the reason.
61
62
63
64
65
|
# File 'lib/simplecov/cli/uncovered.rb', line 61
def validate_top(value)
raise OptionParser::InvalidArgument, "must not be negative" if value.negative?
value
end
|