Class: Rcov::CodeCoverageAnalyzer
- Inherits:
-
DifferentialAnalyzer
- Object
- DifferentialAnalyzer
- Rcov::CodeCoverageAnalyzer
- Defined in:
- lib/rcov.rb
Overview
A CodeCoverageAnalyzer is responsible for tracing code execution and returning code coverage and execution count information.
Note that you must require 'rcov'
before the code you want to analyze is parsed (i.e. before it gets loaded or required). You can do that by either invoking ruby with the -rrcov
command-line option or just:
require 'rcov'
require 'mycode'
# ....
Example
analyzer = Rcov::CodeCoverageAnalyzer.new
analyzer.run_hooked do
do_foo
# all the code executed as a result of this method call is traced
end
# ....
analyzer.run_hooked do
# the code coverage information generated in this run is aggregated
# to the previously recorded one
end
analyzer.analyzed_files # => ["foo.rb", "bar.rb", ... ]
lines, marked_info, count_info = analyzer.data("foo.rb")
In this example, two pieces of code are monitored, and the data generated in both runs are aggregated. lines
is an array of strings representing the source code of foo.rb
. marked_info
is an array holding false, true values indicating whether the corresponding lines of code were reported as executed by Ruby. count_info
is an array of integers representing how many times each line of code has been executed (more precisely, how many events where reported by Ruby — a single line might correspond to several events, e.g. many method calls).
You can have several CodeCoverageAnalyzer objects at a time, and it is possible to nest the #run_hooked / #install_hook/#remove_hook blocks: each analyzer will manage its data separately. Note however that no special provision is taken to ignore code executed “inside” the CodeCoverageAnalyzer class. At any rate this will not pose a problem since it’s easy to ignore it manually: just don’t do
lines, coverage, counts = analyzer.data("/path/to/lib/rcov.rb")
if you’re not interested in that information.
Class Method Summary collapse
-
.hook_level ⇒ Object
defined this way instead of attr_accessor so that it’s covered.
-
.hook_level=(x) ⇒ Object
:nodoc:.
Instance Method Summary collapse
-
#analyzed_files ⇒ Object
Return an array with the names of the files whose code was executed inside the block given to #run_hooked or between #install_hook and #remove_hook.
-
#data(filename) ⇒ Object
Return the available data about the requested file, or nil if none of its code was executed or it cannot be found.
-
#data_matching(filename_re) ⇒ Object
Data for the first file matching the given regexp.
-
#dump_coverage_info(formatters) ⇒ Object
:nodoc:.
-
#initialize ⇒ CodeCoverageAnalyzer
constructor
A new instance of CodeCoverageAnalyzer.
-
#install_hook ⇒ Object
Start monitoring execution to gather code coverage and execution count information.
-
#marshal_dump ⇒ Object
:nodoc:.
-
#marshal_load(ivs) ⇒ Object
:nodoc:.
-
#remove_hook ⇒ Object
Stop collecting code coverage and execution count information.
-
#reset ⇒ Object
Remove the data collected so far.
-
#run_hooked ⇒ Object
Execute the code in the given block, monitoring it in order to gather information about which code was executed.
Constructor Details
#initialize ⇒ CodeCoverageAnalyzer
Returns a new instance of CodeCoverageAnalyzer.
555 556 557 558 559 |
# File 'lib/rcov.rb', line 555 def initialize @script_lines__ = SCRIPT_LINES__ super(:install_coverage_hook, :remove_coverage_hook, :reset_coverage) end |
Class Method Details
.hook_level ⇒ Object
defined this way instead of attr_accessor so that it’s covered
548 549 550 |
# File 'lib/rcov.rb', line 548 def self.hook_level # :nodoc: @hook_level end |
.hook_level=(x) ⇒ Object
:nodoc:
551 552 553 |
# File 'lib/rcov.rb', line 551 def self.hook_level=(x) # :nodoc: @hook_level = x end |
Instance Method Details
#analyzed_files ⇒ Object
Return an array with the names of the files whose code was executed inside the block given to #run_hooked or between #install_hook and #remove_hook.
563 564 565 566 567 568 |
# File 'lib/rcov.rb', line 563 def analyzed_files update_script_lines__ raw_data_relative.select do |file, lines| @script_lines__.has_key?(file) end.map{|fname,| fname} end |
#data(filename) ⇒ Object
Return the available data about the requested file, or nil if none of its code was executed or it cannot be found. The return value is an array with three elements:
lines, marked_info, count_info = analyzer.data("foo.rb")
lines
is an array of strings representing the source code of foo.rb
. marked_info
is an array holding false, true values indicating whether the corresponding lines of code were reported as executed by Ruby. count_info
is an array of integers representing how many times each line of code has been executed (more precisely, how many events where reported by Ruby — a single line might correspond to several events, e.g. many method calls).
The returned data corresponds to the aggregation of all the statistics collected in each #run_hooked or #install_hook/#remove_hook runs. You can reset the data at any time with #reset to start from scratch.
585 586 587 588 589 590 591 592 593 |
# File 'lib/rcov.rb', line 585 def data(filename) raw_data = raw_data_relative update_script_lines__ unless @script_lines__.has_key?(filename) && raw_data.has_key?(filename) return nil end refine_coverage_info(@script_lines__[filename], raw_data[filename]) end |
#data_matching(filename_re) ⇒ Object
Data for the first file matching the given regexp. See #data.
597 598 599 600 601 602 603 604 605 |
# File 'lib/rcov.rb', line 597 def data_matching(filename_re) raw_data = raw_data_relative update_script_lines__ match = raw_data.keys.sort.grep(filename_re).first return nil unless match refine_coverage_info(@script_lines__[match], raw_data[match]) end |
#dump_coverage_info(formatters) ⇒ Object
:nodoc:
629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 |
# File 'lib/rcov.rb', line 629 def dump_coverage_info(formatters) # :nodoc: update_script_lines__ raw_data_relative.each do |file, lines| next if @script_lines__.has_key?(file) == false lines = @script_lines__[file] raw_coverage_array = raw_data_relative[file] line_info, marked_info, count_info = refine_coverage_info(lines, raw_coverage_array) formatters.each do |formatter| formatter.add_file(file, line_info, marked_info, count_info) end end formatters.each{|formatter| formatter.execute} end |
#install_hook ⇒ Object
Start monitoring execution to gather code coverage and execution count information. Such data will be collected until #remove_hook is called.
Use #run_hooked instead if possible.
615 |
# File 'lib/rcov.rb', line 615 def install_hook; super end |
#marshal_dump ⇒ Object
:nodoc:
751 752 753 754 755 756 757 758 |
# File 'lib/rcov.rb', line 751 def marshal_dump # :nodoc: # @script_lines__ is updated just before serialization so as to avoid # missing files in SCRIPT_LINES__ ivs = {} update_script_lines__ instance_variables.each{|iv| ivs[iv] = instance_variable_get(iv)} ivs end |
#marshal_load(ivs) ⇒ Object
:nodoc:
760 761 762 |
# File 'lib/rcov.rb', line 760 def marshal_load(ivs) # :nodoc: ivs.each_pair{|iv, val| instance_variable_set(iv, val)} end |
#remove_hook ⇒ Object
Stop collecting code coverage and execution count information. #remove_hook will also stop collecting info if it is run inside a #run_hooked block.
620 |
# File 'lib/rcov.rb', line 620 def remove_hook; super end |
#reset ⇒ Object
Remove the data collected so far. The coverage and execution count “history” will be erased, and further collection will start from scratch: no code is considered executed, and therefore all execution counts are 0. Right after #reset, #analyzed_files will return an empty array, and #data(filename) will return nil.
627 |
# File 'lib/rcov.rb', line 627 def reset; super end |
#run_hooked ⇒ Object
Execute the code in the given block, monitoring it in order to gather information about which code was executed.
609 |
# File 'lib/rcov.rb', line 609 def run_hooked; super end |