Module: Moult::Formatters::Table

Defined in:
lib/moult/formatters/table.rb

Overview

Human-readable ranked table. Renders from the same Report as the JSON formatter, so the two cannot disagree. Sorting already happened in Scoring; this layer owns limiting and column formatting only.

Constant Summary collapse

HEADERS =
["#", "SCORE", "COMPLEXITY", "CHURN", "FILE", "WORST METHOD"].freeze
RIGHT_ALIGNED =

Right-align the numeric columns; left-align file and method.

[0, 1, 2, 3].freeze
GUTTER =
"  "

Class Method Summary collapse

Class Method Details

.column_widths(rows) ⇒ Object



53
54
55
56
57
# File 'lib/moult/formatters/table.rb', line 53

def column_widths(rows)
  HEADERS.each_index.map do |col|
    ([HEADERS[col]] + rows.map { |r| r[col] }).map(&:length).max
  end
end

.format_row(cells, widths) ⇒ Object



59
60
61
62
63
# File 'lib/moult/formatters/table.rb', line 59

def format_row(cells, widths)
  cells.each_with_index.map { |cell, col|
    RIGHT_ALIGNED.include?(col) ? cell.rjust(widths[col]) : cell.ljust(widths[col])
  }.join(GUTTER).rstrip
end

.heading(report, shown) ⇒ Object



28
29
30
31
32
33
# File 'lib/moult/formatters/table.rb', line 28

def heading(report, shown)
  total = report.hotspots.size
  scope = (shown < total) ? "top #{shown} of #{total}" : total.to_s
  window = report.churn_window ? " — churn over #{report.churn_window}" : ""
  "Hotspots (complexity x churn): #{scope} files#{window}"
end

.num(value) ⇒ Object



65
66
67
# File 'lib/moult/formatters/table.rb', line 65

def num(value)
  format("%.1f", value)
end

.render(report, limit: nil) ⇒ String

Parameters:

  • report (Report)
  • limit (Integer, nil) (defaults to: nil)

    show only the top N hotspots

Returns:

  • (String)


19
20
21
22
23
24
25
26
# File 'lib/moult/formatters/table.rb', line 19

def render(report, limit: nil)
  hotspots = report.hotspots
  hotspots = hotspots.first(limit) if limit
  return "No hotspots found." if hotspots.empty?

  rows = hotspots.each_with_index.map { |h, i| row(h, i + 1) }
  [heading(report, hotspots.size), "", table(rows)].join("\n")
end

.row(hotspot, rank) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/moult/formatters/table.rb', line 35

def row(hotspot, rank)
  worst = hotspot.worst_method
  worst_cell = worst ? "#{worst.name} (#{num(worst.abc)})" : "-"
  [
    rank.to_s,
    num(hotspot.score),
    num(hotspot.complexity),
    hotspot.churn.to_s,
    hotspot.path,
    worst_cell
  ]
end

.table(rows) ⇒ Object



48
49
50
51
# File 'lib/moult/formatters/table.rb', line 48

def table(rows)
  widths = column_widths(rows)
  ([HEADERS] + rows).map { |cells| format_row(cells, widths) }.join("\n")
end