Parent

Rcov::FileStatistics

A FileStatistics object associates a filename to:

  1. its source code

  2. the per-line coverage information after correction using rcov’s heuristics

  3. the per-line execution counts

A FileStatistics object can be therefore be built given the filename, the associated source code, and an array holding execution counts (i.e. how many times each line has been executed).

FileStatistics is relatively intelligent: it handles normal comments, =begin/=end, heredocs, many multiline-expressions... It uses a number of heuristics to determine what is code and what is a comment, and to refine the initial (incomplete) coverage information.

Basic usage is as follows:

sf = FileStatistics.new("foo.rb", ["puts 1", "if true &&", "   false", 
                               "puts 2", "end"],  [1, 1, 0, 0, 0])
sf.num_lines        # => 5
sf.num_code_lines   # => 5
sf.coverage[2]      # => true
sf.coverage[3]      # => :inferred
sf.code_coverage    # => 0.6

The array of strings representing the source code and the array of execution counts would normally be obtained from a Rcov::CodeCoverageAnalyzer.

Attributes

counts[R]
coverage[R]
lines[R]
name[R]

Public Class Methods

new(name, lines, counts, comments_run_by_default = false) click to toggle source
# File lib/rcov/file_statistics.rb, line 29
def initialize(name, lines, counts, comments_run_by_default = false)
  @name = name
  @lines = lines
  initial_coverage = counts.map{|x| (x || 0) > 0 ? true : false }
  @coverage = CoverageInfo.new initial_coverage
  @counts = counts
  @is_begin_comment = nil
  # points to the line defining the heredoc identifier
  # but only if it was marked (we don't care otherwise)
  @heredoc_start = Array.new(lines.size, false)
  @multiline_string_start = Array.new(lines.size, false)
  extend_heredocs
  find_multiline_strings
  precompute_coverage comments_run_by_default
end

Public Instance Methods

code_coverage() click to toggle source

Code coverage rate: fraction of lines of code executed, relative to the total amount of lines of code (loc). Returns a float from 0 to 1.0.

# File lib/rcov/file_statistics.rb, line 79
def code_coverage
  indices = (0...@lines.size).select{|i| is_code? i }
  return 0 if indices.size == 0
  count = 0
  indices.each {|i| count += 1 if @coverage[i] }
  1.0 * count / indices.size
end
code_coverage_for_report() click to toggle source
# File lib/rcov/file_statistics.rb, line 87
def code_coverage_for_report
  code_coverage * 100
end
is_code?(lineno) click to toggle source

Returns true if the given line number corresponds to code, as opposed to a comment (either # or =begin/=end blocks).

# File lib/rcov/file_statistics.rb, line 107
def is_code?(lineno)
  unless @is_begin_comment
    @is_begin_comment = Array.new(@lines.size, false)
    pending = []
    state = :code
    @lines.each_with_index do |line, index|
      line.force_encoding("utf-8") if line.respond_to?(:force_encoding)
      case state
      when :code
        if /^=begin\b/ =~ line
          state = :comment
          pending << index
        end
      when :comment
        pending << index
        if /^=end\b/ =~ line
          state = :code
          pending.each{|idx| @is_begin_comment[idx] = true}
          pending.clear
        end
      end
    end
  end
  @lines[lineno] && !@is_begin_comment[lineno] && @lines[lineno] !~ /^\s*(#|$)/ 
end
merge(lines, coverage, counts) click to toggle source

Merge code coverage and execution count information. As for code coverage, a line will be considered

  • covered for sure (true) if it is covered in either self or in the coverage array

  • considered :inferred if the neither self nor the coverage array indicate that it was definitely executed, but it was inferred in either one

  • not covered (false) if it was uncovered in both

Execution counts are just summated on a per-line basis.

# File lib/rcov/file_statistics.rb, line 55
def merge(lines, coverage, counts)
  coverage.each_with_index do |v, idx|
    case @coverage[idx]
    when :inferred 
      @coverage[idx] = v || @coverage[idx]
    when false 
      @coverage[idx] ||= v
    end
  end
  counts.each_with_index{|v, idx| @counts[idx] += v }
  precompute_coverage false
end
num_code_lines() click to toggle source

Number of lines of code (loc).

# File lib/rcov/file_statistics.rb, line 96
def num_code_lines
  (0...@lines.size).select{|i| is_code? i}.size
end
num_lines() click to toggle source

Total number of lines.

# File lib/rcov/file_statistics.rb, line 101
def num_lines
  @lines.size
end
total_coverage() click to toggle source

Total coverage rate if comments are also considered “executable”, given as a fraction, i.e. from 0 to 1.0. A comment is attached to the code following it (RDoc-style): it will be considered executed if the the next statement was executed.

# File lib/rcov/file_statistics.rb, line 72
def total_coverage
  return 0 if @coverage.size == 0
  @coverage.inject(0.0) {|s,a| s + (a ? 1:0) } / @coverage.size
end
total_coverage_for_report() click to toggle source
# File lib/rcov/file_statistics.rb, line 91
def total_coverage_for_report
  total_coverage * 100
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.