Ruby::CoverageSourceRubyCoverageself

class << self

Definitions

def executable_lines(iseq)

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.

Signature

parameter iseq RubyVM::InstructionSequence
returns Array(Integer)

Sorted, deduplicated executable line numbers.

Implementation

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

def start

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.

Implementation

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

def running?

Whether coverage is currently being tracked.

Signature

returns Boolean

Implementation

def running?
	!@tracer.nil?
end

def peek_result

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, ...] , ... }

Signature

returns Hash

Implementation

def peek_result
	@files.transform_values{|counts| {lines: counts}}
end

def result(stop: true, clear: false)

Return coverage results, optionally stopping or clearing the tracer.

Signature

parameter stop Boolean

Stop tracking after returning results (default: true).

parameter clear Boolean

Clear accumulated data and restart without stopping (default: false).

returns Hash

Same shape as Ruby::Coverage::class#peek_result.

Implementation

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