Module: Moult::Formatters::DeadCodeTable
- Defined in:
- lib/moult/formatters/dead_code_table.rb
Overview
Human-readable table of dead-code candidates. Renders from the same DeadCodeReport as the JSON formatter so the two cannot disagree. Sorting already happened in DeadCode; this layer owns column formatting only.
The heading is deliberate: these are confidence-graded candidates, never certainties.
Constant Summary collapse
- RIGHT_ALIGNED =
Only the CONF column (col 0) is right-aligned.
[0].freeze
Class Method Summary collapse
- .columns(runtime) ⇒ Object
- .conf(value) ⇒ Object
- .heading(count) ⇒ Object
- .location(finding) ⇒ Object
- .render(report) ⇒ String
- .row(finding, runtime) ⇒ Object
-
.top_reason(finding) ⇒ Object
The most informative reason is the last applied non-base adjustment; fall back to the base reason for a bare candidate.
Class Method Details
.columns(runtime) ⇒ Object
31 32 33 34 35 |
# File 'lib/moult/formatters/dead_code_table.rb', line 31 def columns(runtime) cols = ["CONF", "KIND"] cols << "RUNTIME" if runtime cols + ["SYMBOL", "LOCATION", "TOP REASON"] end |
.conf(value) ⇒ Object
61 62 63 |
# File 'lib/moult/formatters/dead_code_table.rb', line 61 def conf(value) format("%.2f", value) end |
.heading(count) ⇒ Object
37 38 39 |
# File 'lib/moult/formatters/dead_code_table.rb', line 37 def heading(count) "Dead-code candidates (confidence-graded — not certainties): #{count} findings" end |
.location(finding) ⇒ Object
47 48 49 50 51 |
# File 'lib/moult/formatters/dead_code_table.rb', line 47 def location(finding) span = finding.span line = span&.start_line line ? "#{finding.path}:#{line}" : finding.path.to_s end |
.render(report) ⇒ String
19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/moult/formatters/dead_code_table.rb', line 19 def render(report) findings = report.findings return "No dead-code candidates found." if findings.empty? # The RUNTIME column only appears when coverage was merged, so output # without --coverage is byte-for-byte unchanged from Phase 2. runtime = findings.any? { |f| !f.runtime.nil? } headers = columns(runtime) rows = findings.map { |f| row(f, runtime) } [heading(findings.size), "", TextTable.render(headers, rows, right_aligned: RIGHT_ALIGNED)].join("\n") end |
.row(finding, runtime) ⇒ Object
41 42 43 44 45 |
# File 'lib/moult/formatters/dead_code_table.rb', line 41 def row(finding, runtime) cells = [conf(finding.confidence), finding.kind.to_s] cells << (finding.runtime&.to_s || "-") if runtime cells + [finding.name.to_s, location(finding), top_reason(finding)] end |
.top_reason(finding) ⇒ Object
The most informative reason is the last applied non-base adjustment; fall back to the base reason for a bare candidate.
55 56 57 58 59 |
# File 'lib/moult/formatters/dead_code_table.rb', line 55 def top_reason(finding) reasons = finding.reasons.reject { |r| r.rule == :base_score } chosen = reasons.last || finding.reasons.first chosen ? chosen.detail.to_s : "-" end |