class Summary
Generates a detailed terminal coverage report.
Definitions
def initialize(threshold: 1.0)
Initialize the report with an optional coverage threshold.
Signature
-
parameter
thresholdNumeric | Nil The minimum ratio a file must meet to be omitted from the detailed output.
Implementation
def initialize(threshold: 1.0)
@threshold = threshold
end
def terminal(output)
Build a styled terminal for the given output.
Signature
-
parameter
outputIO The output stream.
-
returns
Console::Terminal The styled terminal wrapper.
Implementation
def terminal(output)
require "console/terminal"
Console::Terminal.for(output).tap do |terminal|
terminal[:path] ||= terminal.style(nil, nil, :bold, :underline)
terminal[:brief_path] ||= terminal.style(:yellow)
terminal[:uncovered_prefix] ||= terminal.style(:red)
terminal[:covered_prefix] ||= terminal.style(:green)
terminal[:ignored_prefix] ||= terminal.style(nil, nil, :faint)
terminal[:header_prefix] ||= terminal.style(nil, nil, :faint)
terminal[:uncovered_code] ||= terminal.style(:red)
terminal[:covered_code] ||= terminal.style(:green)
terminal[:ignored_code] ||= terminal.style(nil, nil, :faint)
terminal[:annotations] ||= terminal.style(:blue)
terminal[:error] ||= terminal.style(:red)
end
end
def each(wrapper)
Enumerate coverage below the threshold and return aggregate statistics.
Signature
-
parameter
wrapperCovered::Base The coverage wrapper to enumerate.
-
yields
{|coverage| ...} Coverage whose ratio is below the configured threshold.
-
parameter
coverageCovered::Coverage The coverage object below the threshold.
-
parameter
-
returns
Covered::Statistics Statistics for all coverage objects, including omitted ones.
Implementation
def each(wrapper)
statistics = Statistics.new
wrapper.each do |coverage|
statistics << coverage
if @threshold.nil? or coverage.ratio < @threshold
yield coverage
end
end
return statistics
end
def print_annotations(terminal, coverage, line, line_offset)
Print any annotations for the given line.
Signature
-
parameter
terminalConsole::Terminal The terminal to write to.
-
parameter
coverageCovered::Coverage The coverage being rendered.
-
parameter
lineString The source line.
-
parameter
line_offsetInteger The current line number.
Implementation
def print_annotations(terminal, coverage, line, line_offset)
if annotations = coverage.annotations[line_offset]
prefix = "#{line_offset}|".rjust(8) + "*|".rjust(8)
terminal.write prefix, style: :ignored_prefix
terminal.write line.match(/^\s+/)
terminal.puts "\# #{annotations.join(", ")}", style: :annotations
end
end
def print_line_header(terminal)
Print the line and hit-count header.
Signature
-
parameter
terminalConsole::Terminal The terminal to write to.
Implementation
def print_line_header(terminal)
prefix = "Line|".rjust(8) + "Hits|".rjust(8)
terminal.puts prefix, style: :header_prefix
end
def print_line(terminal, line, line_offset, count)
Print a single source line with coverage styling.
Signature
-
parameter
terminalConsole::Terminal The terminal to write to.
-
parameter
lineString The source line.
-
parameter
line_offsetInteger The current line number.
-
parameter
countInteger | Nil The execution count for the line.
Implementation
def print_line(terminal, line, line_offset, count)
prefix = "#{line_offset}|".rjust(8) + "#{count}|".rjust(8)
if count == nil
terminal.write prefix, style: :ignored_prefix
terminal.write line, style: :ignored_code
elsif count == 0
terminal.write prefix, style: :uncovered_prefix
terminal.write line, style: :uncovered_code
else
terminal.write prefix, style: :covered_prefix
terminal.write line, style: :covered_code
end
# If there was no newline at end of file, we add one:
unless line.end_with? $/
terminal.puts
end
end
def print_coverage(terminal, coverage)
Print line-by-line coverage for one source file.
Signature
-
parameter
terminalConsole::Terminal The terminal to write to.
-
parameter
coverageCovered::Coverage The coverage to render.
Implementation
def print_coverage(terminal, coverage)
line_offset = 1
counts = coverage.counts
coverage.read do |file|
print_line_header(terminal)
file.each_line do |line|
count = counts[line_offset]
print_annotations(terminal, coverage, line, line_offset)
print_line(terminal, line, line_offset, count)
line_offset += 1
end
end
end
def print_error(terminal, error)
Print an error raised while rendering coverage.
Signature
-
parameter
terminalConsole::Terminal The terminal to write to.
-
parameter
errorException The rendering error.
Implementation
def print_error(terminal, error)
terminal.puts "Error: #{error.message}", style: :error
terminal.puts error.backtrace
end
def call(wrapper, output = $stdout, **options)
Print the detailed coverage report.
A coverage array gives, for each line, the number of line executions by the interpreter. A nil value means coverage is finished for this line (lines like else and end).
Signature
-
parameter
wrapperCovered::Base The coverage wrapper to report.
-
parameter
outputIO The output stream.
-
parameter
optionsHash Options forwarded to
Covered::Summary#print_coverage.
Implementation
def call(wrapper, output = $stdout, **options)
terminal = self.terminal(output)
statistics = self.each(wrapper) do |coverage|
path = wrapper.relative_path(coverage.path)
terminal.puts ""
terminal.puts path, style: :path
begin
print_coverage(terminal, coverage, **options)
rescue => error
print_error(terminal, error)
end
coverage.print(output)
end
terminal.puts
statistics.print(output)
end