Class: SimpleCovMcp::CoverageModel

Inherits:
Object
  • Object
show all
Defined in:
lib/simplecov_mcp/model.rb

Constant Summary collapse

RELATIVIZER_SCALAR_KEYS =
%w[file file_path].freeze
RELATIVIZER_ARRAY_KEYS =
%w[newer_files missing_files deleted_files].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(root: '.', resultset: nil, staleness: :off, tracked_globs: nil) ⇒ CoverageModel

Create a CoverageModel

Params:

  • root: project root directory (default ‘.’)

  • resultset: path or directory to .resultset.json

  • staleness: :off or :error (default :off). When :error, raises stale errors if sources are newer than coverage or line counts mismatch.

  • tracked_globs: only used for all_files project-level staleness.



28
29
30
31
32
33
34
35
36
37
38
# File 'lib/simplecov_mcp/model.rb', line 28

def initialize(root: '.', resultset: nil, staleness: :off, tracked_globs: nil)
  @root = File.absolute_path(root || '.')
  @resultset = resultset
  @relativizer = PathRelativizer.new(
    root: @root,
    scalar_keys: RELATIVIZER_SCALAR_KEYS,
    array_keys: RELATIVIZER_ARRAY_KEYS
  )

  load_coverage_data(resultset, staleness, tracked_globs)
end

Instance Attribute Details

#relativizerObject (readonly)

Returns the value of attribute relativizer.



18
19
20
# File 'lib/simplecov_mcp/model.rb', line 18

def relativizer
  @relativizer
end

Instance Method Details

#all_files(sort_order: :descending, check_stale: [email protected]?,, tracked_globs: nil) ⇒ Object

Returns [ { ‘file’ =>, ‘covered’ =>, ‘total’ =>, ‘percentage’ =>, ‘stale’ => }, … ]



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/simplecov_mcp/model.rb', line 77

def all_files(sort_order: :descending, check_stale: !@checker.off?, tracked_globs: nil)
  stale_checker = build_staleness_checker(mode: :off, tracked_globs: tracked_globs)

  rows = @cov.map do |abs_path, _data|
    begin
      coverage_lines = CovUtil.lookup_lines(@cov, abs_path)
    rescue FileError
      next
    end

    s = CovUtil.summary(coverage_lines)
    stale = stale_checker.stale_for_file?(abs_path, coverage_lines)
    {
      'file' => abs_path,
      'covered' => s['covered'],
      'total' => s['total'],
      'percentage' => s['percentage'],
      'stale' => stale
    }
  end.compact

  rows = filter_rows_by_globs(rows, tracked_globs)

  if check_stale
    build_staleness_checker(mode: :error, tracked_globs: tracked_globs).check_project!(@cov)
  end

  sort_rows(rows, sort_order: sort_order)
end

#detailed_for(path) ⇒ Object

Returns { ‘file’ => <absolute_path>, ‘lines’ => [‘line’=>,‘hits’=>,‘covered’=>,…], ‘summary’ => … }



67
68
69
70
71
72
73
74
# File 'lib/simplecov_mcp/model.rb', line 67

def detailed_for(path)
  file_abs, coverage_lines = coverage_data_for(path)
  {
    'file' => file_abs,
    'lines' => CovUtil.detailed(coverage_lines),
    'summary' => CovUtil.summary(coverage_lines)
  }
end

#format_table(rows = nil, sort_order: :descending, check_stale: [email protected]?,, tracked_globs: nil) ⇒ Object

Returns formatted table string for all files coverage data



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/simplecov_mcp/model.rb', line 123

def format_table(rows = nil, sort_order: :descending, check_stale: !@checker.off?,
  tracked_globs: nil)
  rows = prepare_rows(rows, sort_order: sort_order, check_stale: check_stale,
    tracked_globs: tracked_globs)
  return 'No coverage data found' if rows.empty?

  widths = compute_table_widths(rows)
  lines = []
  lines << border_line(widths, '', '', '')
  lines << header_row(widths)
  lines << border_line(widths, '', '', '')
  rows.each { |file_data| lines << data_row(file_data, widths) }
  lines << border_line(widths, '', '', '')
  lines << summary_counts(rows)
  if rows.any? { |f| f['stale'] }
    lines <<
      'Staleness: M = Missing file, T = Timestamp (source newer), L = Line count mismatch'
  end
  lines.join("\n")
end

#project_totals(tracked_globs: nil, check_stale: [email protected]?)) ⇒ Object



107
108
109
110
111
# File 'lib/simplecov_mcp/model.rb', line 107

def project_totals(tracked_globs: nil, check_stale: !@checker.off?)
  rows = all_files(sort_order: :ascending, check_stale: check_stale,
    tracked_globs: tracked_globs)
  totals_from_rows(rows)
end

#raw_for(path) ⇒ Object

Returns { ‘file’ => <absolute_path>, ‘lines’ => [hits|nil,…] }



41
42
43
44
# File 'lib/simplecov_mcp/model.rb', line 41

def raw_for(path)
  file_abs, coverage_lines = coverage_data_for(path)
  { 'file' => file_abs, 'lines' => coverage_lines }
end

#relativize(payload) ⇒ Object



46
47
48
# File 'lib/simplecov_mcp/model.rb', line 46

def relativize(payload)
  relativizer.relativize(payload)
end

#staleness_for(path) ⇒ Object



113
114
115
116
117
118
119
120
# File 'lib/simplecov_mcp/model.rb', line 113

def staleness_for(path)
  file_abs = File.absolute_path(path, @root)
  coverage_lines = CovUtil.lookup_lines(@cov, file_abs)
  @checker.stale_for_file?(file_abs, coverage_lines)
rescue => e
  CovUtil.safe_log("Failed to check staleness for #{path}: #{e.message}")
  false
end

#summary_for(path) ⇒ Object

Returns { ‘file’ => <absolute_path>, ‘summary’ => ‘total’=>, ‘percentage’=> }



51
52
53
54
# File 'lib/simplecov_mcp/model.rb', line 51

def summary_for(path)
  file_abs, coverage_lines = coverage_data_for(path)
  { 'file' => file_abs, 'summary' => CovUtil.summary(coverage_lines) }
end

#uncovered_for(path) ⇒ Object

Returns { ‘file’ => <absolute_path>, ‘uncovered’ => [line,…], ‘summary’ => … }



57
58
59
60
61
62
63
64
# File 'lib/simplecov_mcp/model.rb', line 57

def uncovered_for(path)
  file_abs, coverage_lines = coverage_data_for(path)
  {
    'file' => file_abs,
    'uncovered' => CovUtil.uncovered(coverage_lines),
    'summary' => CovUtil.summary(coverage_lines)
  }
end