Module: Ruby::Coverage
- Defined in:
- lib/ruby/coverage.rb,
lib/ruby/coverage/version.rb,
ext/ruby/coverage/coverage.c
Defined Under Namespace
Classes: Tracer
Constant Summary collapse
- VERSION =
"0.0.1"
Class Method Summary collapse
-
.executable_lines(iseq) ⇒ Object
Walk the instruction sequence to find which lines carry a RUBY_EVENT_LINE event — these are the executable lines.
-
.peek_result ⇒ Object
Return the current line-count data without stopping the tracer.
-
.result(stop: true, clear: false) ⇒ Object
Return coverage results, optionally stopping or clearing the tracer.
-
.running? ⇒ Boolean
Whether coverage is currently being tracked.
-
.start ⇒ Object
Start coverage tracking.
Class Method Details
.executable_lines(iseq) ⇒ Object
Walk the instruction sequence to find which lines carry a RUBY_EVENT_LINE event — these are the executable lines.
Lines without this event (comments, ‘else`, `end`, blank lines) remain nil in the counts array, matching the nil/0 distinction used by Ruby’s built-in Coverage module.
Recurses into child ISeqs (methods, blocks, lambdas) via ‘each_child` so that all executable lines across the entire compilation unit are collected.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/ruby/coverage.rb', line 43 def executable_lines(iseq) lines = [] current_line = nil iseq.to_a[13].each do |element| case element when Integer then current_line = element when :RUBY_EVENT_LINE then lines << current_line end end iseq.each_child{|child| lines.concat(executable_lines(child))} lines.sort! lines.uniq! lines end |
.peek_result ⇒ Object
Return the current line-count data without stopping the tracer.
The returned hash has the same shape as ‘::Coverage.peek_result`:
{ "/absolute/path.rb" => { lines: [nil, 0, 3, nil, ...] }, ... }
99 100 101 |
# File 'lib/ruby/coverage.rb', line 99 def peek_result @files.transform_values{|counts| {lines: counts}} end |
.result(stop: true, clear: false) ⇒ Object
Return coverage results, optionally stopping or clearing the tracer.
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/ruby/coverage.rb', line 110 def result(stop: true, clear: false) result = peek_result if stop @tracer&.stop @tracer = nil @files = {} elsif clear @tracer&.stop @files = {} @tracer = Tracer.new do |path, iseq| @files[path] ||= begin counts = [] executable_lines(iseq).each{|line| counts[line] = 0} counts end end @tracer.start end result end |
.running? ⇒ Boolean
Whether coverage is currently being tracked.
89 90 91 |
# File 'lib/ruby/coverage.rb', line 89 def running? !@tracer.nil? end |
.start ⇒ Object
Start coverage tracking.
The callback receives (path, iseq) for each newly compiled file and must return a Ruby Array to use as the line-count store for that file, or nil to skip it. Executable lines are pre-initialised to 0; non-executable lines remain nil.
Safe to call multiple times; subsequent calls are no-ops. Returns self.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/ruby/coverage.rb', line 70 def start return self if @tracer @files = {} @tracer = Tracer.new do |path, iseq| @files[path] ||= begin counts = [] executable_lines(iseq).each{|line| counts[line] = 0} counts end end @tracer.start self end |