Class: Covered::Summary

Inherits:
Object
  • Object
show all
Defined in:
lib/covered/summary.rb

Overview

Generates a detailed terminal coverage report.

Direct Known Subclasses

BriefSummary, FullSummary, PartialSummary

Instance Method Summary collapse

Constructor Details

#initialize(threshold: 1.0) ⇒ Summary

Initialize the report with an optional coverage threshold.



14
15
16
# File 'lib/covered/summary.rb', line 14

def initialize(threshold: 1.0)
	@threshold = threshold
end

Instance Method Details

#call(wrapper, output = $stdout, **options) ⇒ Object

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).



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/covered/summary.rb', line 144

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

#each(wrapper) ⇒ Object

Enumerate coverage below the threshold and return aggregate statistics.



47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/covered/summary.rb', line 47

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

Print any annotations for the given line.



66
67
68
69
70
71
72
73
74
# File 'lib/covered/summary.rb', line 66

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

Print line-by-line coverage for one source file.



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/covered/summary.rb', line 112

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

Print an error raised while rendering coverage.



134
135
136
137
# File 'lib/covered/summary.rb', line 134

def print_error(terminal, error)
	terminal.puts "Error: #{error.message}", style: :error
	terminal.puts error.backtrace
end

Print a single source line with coverage styling.



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/covered/summary.rb', line 89

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

Print the line and hit-count header.



78
79
80
81
82
# File 'lib/covered/summary.rb', line 78

def print_line_header(terminal)
	prefix = "Line|".rjust(8) + "Hits|".rjust(8)
	
	terminal.puts prefix, style: :header_prefix
end

#terminal(output) ⇒ Object

Build a styled terminal for the given output.



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/covered/summary.rb', line 21

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