Class: Teek::MethodCoverageService Private
- Inherits:
-
Object
- Object
- Teek::MethodCoverageService
- Defined in:
- lib/teek/method_coverage_service.rb
Overview
This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.
Transforms SimpleCov line coverage data into per-method coverage.
Merges coverage data from all test suite result files, uses Prism to parse Ruby source files and find method definitions, then maps SimpleCov line coverage to calculate per-method percentages.
Defined Under Namespace
Classes: MethodVisitor
Instance Attribute Summary collapse
- #coverage_dir ⇒ Object readonly private
- #output_path ⇒ Object readonly private
- #source_dirs ⇒ Object readonly private
Instance Method Summary collapse
- #call ⇒ Object private
-
#initialize(coverage_dir:, source_dirs: ["lib"], output_path: nil) ⇒ MethodCoverageService
constructor
private
A new instance of MethodCoverageService.
Constructor Details
#initialize(coverage_dir:, source_dirs: ["lib"], output_path: nil) ⇒ MethodCoverageService
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns a new instance of MethodCoverageService.
25 26 27 28 29 |
# File 'lib/teek/method_coverage_service.rb', line 25 def initialize(coverage_dir:, source_dirs: ["lib"], output_path: nil) @coverage_dir = coverage_dir @source_dirs = source_dirs @output_path = output_path || File.join(coverage_dir, "method_coverage.json") end |
Instance Attribute Details
#coverage_dir ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
23 24 25 |
# File 'lib/teek/method_coverage_service.rb', line 23 def coverage_dir @coverage_dir end |
#output_path ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
23 24 25 |
# File 'lib/teek/method_coverage_service.rb', line 23 def output_path @output_path end |
#source_dirs ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
23 24 25 |
# File 'lib/teek/method_coverage_service.rb', line 23 def source_dirs @source_dirs end |
Instance Method Details
#call ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/teek/method_coverage_service.rb', line 31 def call coverage_files = Dir.glob(File.join(coverage_dir, "results", "*", "coverage.json")) resultset_files = Dir.glob(File.join(coverage_dir, "results", "*", ".resultset.json")) if coverage_files.empty? && resultset_files.empty? warn "No coverage files found in #{coverage_dir}/results/" return nil end coverage_data = load_and_merge_coverage(coverage_files) result = {} # Collect all methods from all files all_methods = [] source_files.each do |file| all_methods.concat(extract_methods(file)) end # Group by class path and calculate coverage all_methods.group_by { |m| m[:class_path] }.each do |class_path, methods| class_result = { "class_methods" => {}, "instance_methods" => {} } total_covered = 0 total_relevant = 0 methods.each do |method| file_coverage = coverage_data[method[:file]] next unless file_coverage cov = calculate_coverage(file_coverage, method[:start_line], method[:end_line]) next unless cov # Store [percent, lines_string] - compact format method_data = [cov[:percent], cov[:lines]] if method[:scope] == :class class_result["class_methods"][method[:name]] = method_data else class_result["instance_methods"][method[:name]] = method_data end total_covered += cov[:covered] total_relevant += cov[:relevant] end next if class_result["class_methods"].empty? && class_result["instance_methods"].empty? if total_relevant > 0 class_result["total"] = (total_covered.to_f / total_relevant * 100).round(1) end result[class_path] = class_result end File.write(output_path, JSON.pretty_generate(result)) puts "Generated method coverage: #{output_path} (#{result.size} classes/modules)" result end |