relevance-rcov 0.9.3-java
Sign up to get free protection for your applications and to get access to all the features.
- data/BLURB +111 -0
- data/LICENSE +53 -0
- data/Rakefile +94 -0
- data/THANKS +110 -0
- data/bin/rcov +514 -0
- data/doc/readme_for_api.markdown +22 -0
- data/doc/readme_for_emacs.markdown +52 -0
- data/doc/readme_for_rake.markdown +51 -0
- data/doc/readme_for_vim.markdown +34 -0
- data/editor-extensions/rcov.el +131 -0
- data/editor-extensions/rcov.vim +38 -0
- data/ext/java/src/CallsiteHook.java +137 -0
- data/ext/java/src/CoverageHook.java +117 -0
- data/ext/java/src/RcovHook.java +9 -0
- data/ext/java/src/RcovrtService.java +130 -0
- data/lib/rcov.rb +33 -0
- data/lib/rcov/call_site_analyzer.rb +225 -0
- data/lib/rcov/code_coverage_analyzer.rb +268 -0
- data/lib/rcov/coverage_info.rb +36 -0
- data/lib/rcov/differential_analyzer.rb +116 -0
- data/lib/rcov/file_statistics.rb +334 -0
- data/lib/rcov/formatters.rb +13 -0
- data/lib/rcov/formatters/base_formatter.rb +173 -0
- data/lib/rcov/formatters/failure_report.rb +15 -0
- data/lib/rcov/formatters/full_text_report.rb +48 -0
- data/lib/rcov/formatters/html_coverage.rb +274 -0
- data/lib/rcov/formatters/html_erb_template.rb +62 -0
- data/lib/rcov/formatters/text_coverage_diff.rb +193 -0
- data/lib/rcov/formatters/text_report.rb +32 -0
- data/lib/rcov/formatters/text_summary.rb +11 -0
- data/lib/rcov/lowlevel.rb +146 -0
- data/lib/rcov/rcovtask.rb +155 -0
- data/lib/rcov/templates/detail.html.erb +64 -0
- data/lib/rcov/templates/index.html.erb +93 -0
- data/lib/rcov/templates/jquery-1.3.2.min.js +19 -0
- data/lib/rcov/templates/jquery.tablesorter.min.js +15 -0
- data/lib/rcov/templates/print.css +12 -0
- data/lib/rcov/templates/rcov.js +42 -0
- data/lib/rcov/templates/screen.css +270 -0
- data/lib/rcov/version.rb +10 -0
- data/lib/rcovrt.jar +0 -0
- data/setup.rb +1588 -0
- data/test/assets/sample_01.rb +7 -0
- data/test/assets/sample_02.rb +5 -0
- data/test/assets/sample_03.rb +20 -0
- data/test/assets/sample_04.rb +10 -0
- data/test/assets/sample_05-new.rb +17 -0
- data/test/assets/sample_05-old.rb +13 -0
- data/test/assets/sample_05.rb +17 -0
- data/test/assets/sample_06.rb +8 -0
- data/test/call_site_analyzer_test.rb +171 -0
- data/test/code_coverage_analyzer_test.rb +219 -0
- data/test/file_statistics_test.rb +471 -0
- data/test/functional_test.rb +91 -0
- data/test/turn_off_rcovrt.rb +4 -0
- metadata +115 -0
data/BLURB
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
Overview
|
2
|
+
========
|
3
|
+
rcov is a code coverage tool for Ruby. It is commonly used for viewing overall
|
4
|
+
test coverage of target code. It features:
|
5
|
+
* fast execution: 20-300 times faster than previous tools
|
6
|
+
* multiple analysis modes: standard, bogo-profile, "intentional testing",
|
7
|
+
dependency analysis...
|
8
|
+
* detection of uncovered code introduced since the last run ("differential
|
9
|
+
code coverage")
|
10
|
+
* fairly accurate coverage information through code linkage inference using
|
11
|
+
simple heuristics
|
12
|
+
* cross-referenced XHTML and several kinds of text reports
|
13
|
+
* support for easy automation with Rake
|
14
|
+
* colorblind-friendliness
|
15
|
+
|
16
|
+
How do I use it?
|
17
|
+
================
|
18
|
+
|
19
|
+
In the common scenario, your tests are under test/ and the target code
|
20
|
+
(whose coverage you want) is in lib/. In that case, all you have to do is
|
21
|
+
use rcov to run the tests (instead of testrb), and a number of XHTML files
|
22
|
+
with the code coverage information will be generated, e.g.
|
23
|
+
|
24
|
+
rcov -Ilib test/*.rb
|
25
|
+
|
26
|
+
will execute all the .rb files under test/ and generate the code coverage
|
27
|
+
report for the target code (i.e. for the files in lib/) under coverage/. The
|
28
|
+
target code needs not be under lib/; rcov will detect is as long as it is
|
29
|
+
require()d by the tests. rcov is smart enough to ignore "uninteresting"
|
30
|
+
files: the tests themselves, files installed in Ruby's standard locations,
|
31
|
+
etc. See rcov --help for the list of regexps rcov matches filenames
|
32
|
+
against.
|
33
|
+
|
34
|
+
rcov can also be used from Rake; see readme_for_rake or the RDoc documentation
|
35
|
+
for more information.
|
36
|
+
|
37
|
+
rcov can output information in several formats, and perform different kinds
|
38
|
+
of analyses in addition to plain code coverage. See rcov --help for a
|
39
|
+
description of the available options.
|
40
|
+
|
41
|
+
Sample output
|
42
|
+
=============
|
43
|
+
|
44
|
+
The text report (also used by default in RcovTasks) resembles
|
45
|
+
|
46
|
+
|
47
|
+
+-----------------------------------------------------+-------+-------+--------+
|
48
|
+
| File | Lines | LOC | COV |
|
49
|
+
+-----------------------------------------------------+-------+-------+--------+
|
50
|
+
|lib/rcov.rb | 572 | 358 | 91.3% |
|
51
|
+
+-----------------------------------------------------+-------+-------+--------+
|
52
|
+
|Total | 572 | 358 | 91.3% |
|
53
|
+
+-----------------------------------------------------+-------+-------+--------+
|
54
|
+
91.3% 1 file(s) 572 Lines 358 LOC
|
55
|
+
|
56
|
+
|
57
|
+
|
58
|
+
The (undecorated) textual output with execution count information looks like this:
|
59
|
+
|
60
|
+
$ rcov --no-html --text-counts b.rb
|
61
|
+
================================================================================
|
62
|
+
./b.rb
|
63
|
+
================================================================================
|
64
|
+
| 2
|
65
|
+
a, b, c = (1..3).to_a | 2
|
66
|
+
10.times do | 1
|
67
|
+
a += 1 | 10
|
68
|
+
20.times do |i| | 10
|
69
|
+
b += i | 200
|
70
|
+
b.times do | 200
|
71
|
+
c += (j = (b-a).abs) > 0 ? j : 0 | 738800
|
72
|
+
end | 0
|
73
|
+
end | 0
|
74
|
+
end | 0
|
75
|
+
|
76
|
+
|
77
|
+
rcov can detect when you've added code that was not covered by your unit
|
78
|
+
tests:
|
79
|
+
|
80
|
+
$ rcov --text-coverage-diff --no-color test/*.rb
|
81
|
+
Started
|
82
|
+
.......................................
|
83
|
+
Finished in 1.163085 seconds.
|
84
|
+
|
85
|
+
39 tests, 415 assertions, 0 failures, 0 errors
|
86
|
+
|
87
|
+
================================================================================
|
88
|
+
!!!!! Uncovered code introduced in lib/rcov.rb
|
89
|
+
|
90
|
+
### lib/rcov.rb:207
|
91
|
+
|
92
|
+
def precompute_coverage(comments_run_by_default = true)
|
93
|
+
changed = false
|
94
|
+
lastidx = lines.size - 1
|
95
|
+
if (!is_code?(lastidx) || /^__END__$/ =~ @lines[-1]) && !@coverage[lastidx]
|
96
|
+
!! # mark the last block of comments
|
97
|
+
!! @coverage[lastidx] ||= :inferred
|
98
|
+
!! (lastidx-1).downto(0) do |i|
|
99
|
+
!! break if is_code?(i)
|
100
|
+
!! @coverage[i] ||= :inferred
|
101
|
+
!! end
|
102
|
+
!! end
|
103
|
+
(0...lines.size).each do |i|
|
104
|
+
next if @coverage[i]
|
105
|
+
line = @lines[i]
|
106
|
+
|
107
|
+
|
108
|
+
|
109
|
+
License
|
110
|
+
-------
|
111
|
+
rcov is released under the terms of Ruby's license.
|
data/LICENSE
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
rcov is copyrighted free software by Mauricio Fernandez <mfp@acm.org>.
|
2
|
+
You can redistribute it and/or modify it under either the terms of the GPL,
|
3
|
+
or the conditions below:
|
4
|
+
|
5
|
+
1. You may make and give away verbatim copies of the source form of the
|
6
|
+
software without restriction, provided that you duplicate all of the
|
7
|
+
original copyright notices and associated disclaimers.
|
8
|
+
|
9
|
+
2. You may modify your copy of the software in any way, provided that
|
10
|
+
you do at least ONE of the following:
|
11
|
+
|
12
|
+
a) place your modifications in the Public Domain or otherwise
|
13
|
+
make them Freely Available, such as by posting said
|
14
|
+
modifications to Usenet or an equivalent medium, or by allowing
|
15
|
+
the author to include your modifications in the software.
|
16
|
+
|
17
|
+
b) use the modified software only within your corporation or
|
18
|
+
organization.
|
19
|
+
|
20
|
+
c) give non-standard binaries non-standard names, with
|
21
|
+
instructions on where to get the original software distribution.
|
22
|
+
|
23
|
+
d) make other distribution arrangements with the author.
|
24
|
+
|
25
|
+
3. You may distribute the software in object code or binary form,
|
26
|
+
provided that you do at least ONE of the following:
|
27
|
+
|
28
|
+
a) distribute the binaries and library files of the software,
|
29
|
+
together with instructions (in the manual page or equivalent)
|
30
|
+
on where to get the original distribution.
|
31
|
+
|
32
|
+
b) accompany the distribution with the machine-readable source of
|
33
|
+
the software.
|
34
|
+
|
35
|
+
c) give non-standard binaries non-standard names, with
|
36
|
+
instructions on where to get the original software distribution.
|
37
|
+
|
38
|
+
d) make other distribution arrangements with the author.
|
39
|
+
|
40
|
+
4. You may modify and include the part of the software into any other
|
41
|
+
software (possibly commercial). But some files in the distribution
|
42
|
+
are not written by the author, so that they are not under these terms.
|
43
|
+
|
44
|
+
5. The scripts and library files supplied as input to or produced as
|
45
|
+
output from the software do not automatically fall under the
|
46
|
+
copyright of the software, but belong to whomever generated them,
|
47
|
+
and may be sold commercially, and may be aggregated with this
|
48
|
+
software.
|
49
|
+
|
50
|
+
6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
51
|
+
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
52
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
53
|
+
PURPOSE.
|
data/Rakefile
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
$:.unshift "lib" if File.directory? "lib"
|
2
|
+
require 'rcov/rcovtask'
|
3
|
+
require 'rcov/version'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rake/rdoctask'
|
6
|
+
require 'rake/gempackagetask'
|
7
|
+
require 'rake/clean'
|
8
|
+
|
9
|
+
# Use the specified rcov executable instead of the one in $PATH
|
10
|
+
# (this way we get a sort of informal functional test).
|
11
|
+
# This could also be specified from the command like, e.g.
|
12
|
+
# rake rcov RCOVPATH=/path/to/myrcov
|
13
|
+
ENV["RCOVPATH"] = "bin/rcov"
|
14
|
+
|
15
|
+
# The following task is largely equivalent to:
|
16
|
+
# Rcov::RcovTask.new
|
17
|
+
desc "Create a cross-referenced code coverage report."
|
18
|
+
Rcov::RcovTask.new do |t|
|
19
|
+
t.test_files = FileList['test/*_test.rb']
|
20
|
+
t.ruby_opts << "-Ilib:ext/rcovrt" # in order to use this rcov
|
21
|
+
t.rcov_opts << "--xrefs" # comment to disable cross-references
|
22
|
+
t.verbose = true
|
23
|
+
end
|
24
|
+
|
25
|
+
desc "Analyze code coverage for the FileStatistics class."
|
26
|
+
Rcov::RcovTask.new(:rcov_sourcefile) do |t|
|
27
|
+
t.test_files = FileList['test/file_statistics_test.rb']
|
28
|
+
t.verbose = true
|
29
|
+
t.rcov_opts << "--test-unit-only"
|
30
|
+
t.ruby_opts << "-Ilib:ext/rcovrt" # in order to use this rcov
|
31
|
+
t.output_dir = "coverage.sourcefile"
|
32
|
+
end
|
33
|
+
|
34
|
+
Rcov::RcovTask.new(:rcov_ccanalyzer) do |t|
|
35
|
+
t.test_files = FileList['test/code_coverage_analyzer_test.rb']
|
36
|
+
t.verbose = true
|
37
|
+
t.rcov_opts << "--test-unit-only"
|
38
|
+
t.ruby_opts << "-Ilib:ext/rcovrt" # in order to use this rcov
|
39
|
+
t.output_dir = "coverage.ccanalyzer"
|
40
|
+
end
|
41
|
+
|
42
|
+
desc "Run the unit tests with rcovrt."
|
43
|
+
if RUBY_PLATFORM == 'java'
|
44
|
+
Rake::TestTask.new(:test_rcovrt => ["lib/rcovrt.jar"]) do |t|
|
45
|
+
t.libs << "lib"
|
46
|
+
t.ruby_opts << "--debug"
|
47
|
+
t.test_files = FileList['test/*_test.rb']
|
48
|
+
t.verbose = true
|
49
|
+
end
|
50
|
+
|
51
|
+
file "lib/rcovrt.jar" => FileList["ext/java/**/*.java"] do |t|
|
52
|
+
rm_f "lib/rcovrt.jar"
|
53
|
+
mkdir_p "pkg/classes"
|
54
|
+
sh "javac -classpath #{Java::JavaLang::System.getProperty('java.class.path')} -d pkg/classes #{t.prerequisites.join(' ')}"
|
55
|
+
sh "jar cf #{t.name} -C pkg/classes ."
|
56
|
+
end
|
57
|
+
else
|
58
|
+
Rake::TestTask.new(:test_rcovrt => ["ext/rcovrt/rcovrt.so"]) do |t|
|
59
|
+
system("cd ext/rcovrt && make clean && rm Makefile")
|
60
|
+
t.libs << "ext/rcovrt"
|
61
|
+
t.test_files = FileList['test/*_test.rb']
|
62
|
+
t.verbose = true
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
file "ext/rcovrt/rcovrt.so" => FileList["ext/rcovrt/*.c"] do
|
67
|
+
ruby "setup.rb config"
|
68
|
+
ruby "setup.rb setup"
|
69
|
+
end
|
70
|
+
|
71
|
+
desc "Run the unit tests in pure-Ruby mode ."
|
72
|
+
Rake::TestTask.new(:test_pure_ruby) do |t|
|
73
|
+
t.libs << "ext/rcovrt"
|
74
|
+
t.test_files = FileList['test/turn_off_rcovrt.rb', 'test/*_test.rb']
|
75
|
+
t.verbose = true
|
76
|
+
end
|
77
|
+
|
78
|
+
desc "Run the unit tests"
|
79
|
+
task :test => [:test_rcovrt]
|
80
|
+
|
81
|
+
desc "install by setup.rb"
|
82
|
+
task :install do
|
83
|
+
sh "sudo ruby setup.rb install"
|
84
|
+
end
|
85
|
+
|
86
|
+
task :default => :test
|
87
|
+
|
88
|
+
desc "Generate rdoc documentation for the rcov library"
|
89
|
+
Rake::RDocTask.new("rdoc") { |rdoc|
|
90
|
+
rdoc.rdoc_dir = 'doc'
|
91
|
+
rdoc.title = "rcov"
|
92
|
+
rdoc.options << "--line-numbers" << "--inline-source"
|
93
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
94
|
+
}
|
data/THANKS
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
Jay McGaffigan:
|
2
|
+
* JRuby support integrated from original rcov4j
|
3
|
+
|
4
|
+
Aaron Bedra:
|
5
|
+
* major refactoring
|
6
|
+
* added threshold testing
|
7
|
+
* Took on the task of keeping RCov going
|
8
|
+
|
9
|
+
Corey Ehmke (Bantik):
|
10
|
+
* redesigned index and detail XHTML
|
11
|
+
* added sortable columns in coverage table
|
12
|
+
* added file and coverage threshold filters to index XHTML
|
13
|
+
* added print-specific style sheet
|
14
|
+
* added support for custom CSS for XHTML output
|
15
|
+
|
16
|
+
Tom Dolbilin:
|
17
|
+
* identified and fixed backslash problem on win32 for generated filenames
|
18
|
+
|
19
|
+
Andrew Kreiling:
|
20
|
+
* made the index XHTML compliant
|
21
|
+
* consolidate multiple references to the same underlying .rb file
|
22
|
+
|
23
|
+
Robert Feldt:
|
24
|
+
* pointed me to dynamic uses of the tracing hooks, provided the inspiration
|
25
|
+
for RCOV__.run_hooked
|
26
|
+
* helped to refine the color scheme
|
27
|
+
|
28
|
+
Andre Nathan:
|
29
|
+
* identified a bug in the heuristics: missing propagation for lines
|
30
|
+
with only }, ), ]
|
31
|
+
|
32
|
+
David Roberts:
|
33
|
+
* reported confusing behavior when all files are ignored because they match
|
34
|
+
a regexp in the reject list
|
35
|
+
* tested the RubyGems package for win32
|
36
|
+
|
37
|
+
John-Mason Shackelford:
|
38
|
+
* reported an important bug in the pure-Ruby tracer module, which broke it
|
39
|
+
altogether in 0.4.0
|
40
|
+
* suggested a change in the CSS to make XHTML reports more readable under IE
|
41
|
+
|
42
|
+
Dave Burt:
|
43
|
+
* reported an issue with text reports under cmd.exe (should use < 80 cols)
|
44
|
+
|
45
|
+
Alex Wayne:
|
46
|
+
* reported problem with heredocs: they were not being marked as a whole if
|
47
|
+
the "header" wasn't reported by Ruby.
|
48
|
+
* reported problem with the last line of literal data structs not being
|
49
|
+
covered if there was stuff after the end delimiter
|
50
|
+
|
51
|
+
Coda Hale:
|
52
|
+
* reported problem with blocks were the first line is not being marked
|
53
|
+
and ditto for the last line when end/} is followed by more stuff
|
54
|
+
|
55
|
+
Tim Shadel:
|
56
|
+
* reported that the last comment block was not being marked even when
|
57
|
+
it was the last thing in the file
|
58
|
+
|
59
|
+
Thomas Leitner:
|
60
|
+
* reported that the SCRIPT_LINES__ workaround did not always work
|
61
|
+
* fixed the bug which broke differential reports for filenames with
|
62
|
+
special characters
|
63
|
+
|
64
|
+
Assaph Mehr:
|
65
|
+
* beta-tested 0.7.0 and found a bug in --aggregate (missing files)
|
66
|
+
|
67
|
+
Ryan Kinderman:
|
68
|
+
* suggested that -Ipath be passed to ruby instead of rcov in RcovTasks
|
69
|
+
|
70
|
+
Jan Svitok:
|
71
|
+
* reported typo in rcovtask.rb's RDoc
|
72
|
+
|
73
|
+
rubikitch:
|
74
|
+
* implemented --annotate mode
|
75
|
+
* implemented --gcc option
|
76
|
+
* superior emacs support
|
77
|
+
* testing, refactoring...
|
78
|
+
* many other things, see darcs changes
|
79
|
+
|
80
|
+
Zed A. Shaw:
|
81
|
+
* reported and fixed segfault triggered by rspec
|
82
|
+
|
83
|
+
Lee Marlow:
|
84
|
+
* patch allowing to run rcov against a data file with no input code
|
85
|
+
|
86
|
+
Kurt Stephens:
|
87
|
+
* patch to rethrow any exceptions generated by the traced scripts after
|
88
|
+
report generation; notably SystemExit, allowing to use the exit code from
|
89
|
+
test runners under rake.
|
90
|
+
|
91
|
+
Brian Candler:
|
92
|
+
* found compatibility issues with the REXML lib included in ruby-1.8.6-p110
|
93
|
+
and provided a workaround
|
94
|
+
|
95
|
+
Mat Schaffer:
|
96
|
+
* reported missing line colorization on Safari and probably other browsers,
|
97
|
+
owing to self-closing <a> not being handled properly despite being valid
|
98
|
+
XHTML 1.0.
|
99
|
+
|
100
|
+
Sam Granieri:
|
101
|
+
* tested workaround for REXML bug
|
102
|
+
|
103
|
+
Kosmas Schütz, Daniel Berger, François Beausoleil, Bil Kleb:
|
104
|
+
* provided information about the ruby-1.8.6-p11[01] REXML problems
|
105
|
+
|
106
|
+
Chad Humphries:
|
107
|
+
* indicated that Spec::DSL::Example has changed in RSpec trunk
|
108
|
+
|
109
|
+
Jeremy Hinegardner:
|
110
|
+
* more info about REXML's bugs in 1.8.6-p11[01]
|
data/bin/rcov
ADDED
@@ -0,0 +1,514 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: iso-8859-1 -*-
|
3
|
+
# rcov Copyright (c) 2004-2006 Mauricio Fernandez <mfp@acm.org>
|
4
|
+
#
|
5
|
+
# rcov originally based on
|
6
|
+
# module COVERAGE__ originally (c) NAKAMURA Hiroshi
|
7
|
+
# module PrettyCoverage originally (c) Simon Strandgaard
|
8
|
+
#
|
9
|
+
# rewritten & extended by Mauricio Fern�ndez <mfp@acm.org>
|
10
|
+
#
|
11
|
+
# See LEGAL and LICENSE for additional licensing information.
|
12
|
+
#
|
13
|
+
require 'cgi'
|
14
|
+
require 'rbconfig'
|
15
|
+
require 'optparse'
|
16
|
+
require 'ostruct'
|
17
|
+
|
18
|
+
SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
|
19
|
+
require 'rcov/version'
|
20
|
+
require 'rcov/formatters'
|
21
|
+
|
22
|
+
#{{{ "main" code
|
23
|
+
options = OpenStruct.new
|
24
|
+
options.color = true
|
25
|
+
options.range = 30.0
|
26
|
+
options.profiling = false
|
27
|
+
options.destdir = nil
|
28
|
+
options.loadpaths = []
|
29
|
+
options.textmode = false
|
30
|
+
options.skip = Rcov::BaseFormatter::DEFAULT_OPTS[:ignore]
|
31
|
+
options.include = []
|
32
|
+
options.html = true
|
33
|
+
options.css = nil
|
34
|
+
options.comments_run_by_default = false
|
35
|
+
options.test_unit_only = false
|
36
|
+
options.spec_only = false
|
37
|
+
options.sort = :name
|
38
|
+
options.sort_reverse = false
|
39
|
+
options.output_threshold = 101
|
40
|
+
options.failure_threshold = nil
|
41
|
+
options.replace_prog_name = false
|
42
|
+
options.callsites = false
|
43
|
+
options.crossrefs = false
|
44
|
+
options.coverage_diff_file = "coverage.info"
|
45
|
+
options.coverage_diff_mode = :compare
|
46
|
+
options.coverage_diff_save = false
|
47
|
+
options.diff_cmd = "diff"
|
48
|
+
options.report_cov_bug_for = nil
|
49
|
+
options.aggregate_file = nil
|
50
|
+
options.gcc_output = false
|
51
|
+
options.charset = nil
|
52
|
+
|
53
|
+
EXTRA_HELP = <<-EOF
|
54
|
+
|
55
|
+
You can run several programs at once:
|
56
|
+
rcov something.rb somethingelse.rb
|
57
|
+
|
58
|
+
The parameters to be passed to the program under inspection can be specified
|
59
|
+
after --:
|
60
|
+
|
61
|
+
rcov -Ilib -t something.rb -- --theseopts --are --given --to --something.rb
|
62
|
+
|
63
|
+
ARGV will be set to the specified parameters after --.
|
64
|
+
Keep in mind that all the programs are run under the same process
|
65
|
+
(i.e. they just get Kernel#load()'ed in sequence).
|
66
|
+
|
67
|
+
$PROGRAM_NAME (aka. $0) will be set before each file is load()ed if
|
68
|
+
--replace-progname is used.
|
69
|
+
EOF
|
70
|
+
|
71
|
+
def deprecated(opt)
|
72
|
+
puts "#{opt} is now depricated. Please remove it from you Rakefile or scripts. It will be removed in the next release."
|
73
|
+
end
|
74
|
+
|
75
|
+
#{{{ OptionParser
|
76
|
+
opts = OptionParser.new do |opts|
|
77
|
+
opts.banner = <<-EOF
|
78
|
+
rcov #{Rcov::VERSION} #{Rcov::RELEASE_DATE}
|
79
|
+
Usage: rcov [options] <script1.rb> [script2.rb] [-- --extra-options]
|
80
|
+
EOF
|
81
|
+
opts.separator ""
|
82
|
+
opts.separator "Options:"
|
83
|
+
|
84
|
+
opts.on("-o", "--output PATH", "Destination directory.") do |dir|
|
85
|
+
options.destdir = dir
|
86
|
+
end
|
87
|
+
|
88
|
+
opts.on("-I", "--include PATHS", "Prepend PATHS to $: (colon separated list)") do |paths|
|
89
|
+
options.loadpaths = paths.split(/:/)
|
90
|
+
end
|
91
|
+
|
92
|
+
opts.on("--[no-]comments", "Mark all comments by default.", "(default: --no-comments)") do |comments_run_p|
|
93
|
+
options.comments_run_by_default = comments_run_p
|
94
|
+
end
|
95
|
+
|
96
|
+
opts.on("--test-unit-only", "Only trace code executed inside TestCases.") do
|
97
|
+
deprecated("--test-unit-only")
|
98
|
+
end
|
99
|
+
|
100
|
+
opts.on("--spec-only", "Only trace code executed inside RSpec specs.") do
|
101
|
+
deprecated("--spec-only")
|
102
|
+
end
|
103
|
+
|
104
|
+
opts.on("-n", "--no-color", "Create colorblind-safe output.") do
|
105
|
+
options.color = false
|
106
|
+
end
|
107
|
+
|
108
|
+
opts.on("-i", "--include-file PATTERNS",
|
109
|
+
"Generate info for files matching a",
|
110
|
+
"pattern (comma-separated regexp list)") do |list|
|
111
|
+
begin
|
112
|
+
regexps = list.split(/,/).map{|x| Regexp.new(x) }
|
113
|
+
options.include += regexps
|
114
|
+
rescue RegexpError => e
|
115
|
+
raise OptionParser::InvalidArgument, e.message
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
opts.on("-x", "--exclude PATTERNS", "Don't generate info for files matching a","pattern (comma-separated regexp list)") do |list|
|
120
|
+
begin
|
121
|
+
regexps = list.split(/,/).map{|x| Regexp.new x}
|
122
|
+
options.skip += regexps
|
123
|
+
rescue RegexpError => e
|
124
|
+
raise OptionParser::InvalidArgument, e.message
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
opts.on("--exclude-only PATTERNS", "Skip info only for files matching the", "given patterns.") do |list|
|
129
|
+
begin
|
130
|
+
options.skip = list.split(/,/).map{|x| Regexp.new(x) }
|
131
|
+
rescue RegexpError => e
|
132
|
+
raise OptionParser::InvalidArgument, e.message
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
opts.on("--rails", "Skip config/, environment/ and vendor/.") do
|
137
|
+
options.skip.concat [%r{\bvendor/},%r{\bconfig/},%r{\benvironment/}]
|
138
|
+
end
|
139
|
+
|
140
|
+
opts.on("--[no-]callsites", "Show callsites in generated XHTML report.", "(somewhat slower; disabled by default)") do |val|
|
141
|
+
options.callsites = val
|
142
|
+
end
|
143
|
+
|
144
|
+
opts.on("--[no-]xrefs", "Generate fully cross-referenced report.", "(includes --callsites)") do |val|
|
145
|
+
options.crossrefs = val
|
146
|
+
options.callsites ||= val
|
147
|
+
end
|
148
|
+
|
149
|
+
opts.on("-p", "--profile", "Generate bogo-profiling info.") do
|
150
|
+
options.profiling = true
|
151
|
+
options.destdir ||= "profiling"
|
152
|
+
end
|
153
|
+
|
154
|
+
opts.on("-r", "--range RANGE", Float, "Color scale range for profiling info (dB).") do |val|
|
155
|
+
options.range = val
|
156
|
+
end
|
157
|
+
|
158
|
+
opts.on("-a", "--annotate", "Generate annotated source code.") do
|
159
|
+
options.html = false
|
160
|
+
options.textmode = :annotate
|
161
|
+
options.crossrefs = true
|
162
|
+
options.callsites = true
|
163
|
+
options.skip = [ %r!/test/unit/! ]
|
164
|
+
end
|
165
|
+
|
166
|
+
opts.on("-T", "--text-report", "Dump detailed plain-text report to stdout.", "(filename, LoC, total lines, coverage)") do
|
167
|
+
options.textmode = :report
|
168
|
+
end
|
169
|
+
|
170
|
+
opts.on("-t", "--text-summary", "Dump plain-text summary to stdout.") do
|
171
|
+
options.textmode = :summary
|
172
|
+
end
|
173
|
+
|
174
|
+
opts.on("--text-counts", "Dump execution counts in plaintext.") do
|
175
|
+
options.textmode = :counts
|
176
|
+
end
|
177
|
+
|
178
|
+
opts.on("--text-coverage", "Dump coverage info to stdout, using", "ANSI color sequences unless -n.") do
|
179
|
+
options.textmode = :coverage
|
180
|
+
end
|
181
|
+
|
182
|
+
opts.on("--gcc", "Dump uncovered line in GCC error format.") do
|
183
|
+
options.gcc_output = true
|
184
|
+
end
|
185
|
+
|
186
|
+
opts.on("--aggregate FILE", "Aggregate data from previous runs",
|
187
|
+
"in FILE. Overwrites FILE with the",
|
188
|
+
"merged data. FILE is created if",
|
189
|
+
"necessary.") do |file|
|
190
|
+
options.aggregate_file = file
|
191
|
+
end
|
192
|
+
|
193
|
+
opts.on("-D [FILE]", "--text-coverage-diff [FILE]",
|
194
|
+
"Compare code coverage with saved state",
|
195
|
+
"in FILE, defaults to coverage.info.",
|
196
|
+
"Implies --comments.") do |file|
|
197
|
+
options.textmode = :coverage_diff
|
198
|
+
options.comments_run_by_default = true
|
199
|
+
if options.coverage_diff_save
|
200
|
+
raise "You shouldn't use --save and --text-coverage-diff at a time."
|
201
|
+
end
|
202
|
+
options.coverage_diff_mode = :compare
|
203
|
+
options.coverage_diff_file = file if file && !file.empty?
|
204
|
+
end
|
205
|
+
|
206
|
+
opts.on("--save [FILE]", "Save coverage data to FILE,", "for later use with rcov -D.", "(default: coverage.info)") do |file|
|
207
|
+
options.coverage_diff_save = true
|
208
|
+
options.coverage_diff_mode = :record
|
209
|
+
if options.textmode == :coverage_diff
|
210
|
+
raise "You shouldn't use --save and --text-coverage-diff at a time."
|
211
|
+
end
|
212
|
+
options.coverage_diff_file = file if file && !file.empty?
|
213
|
+
end
|
214
|
+
|
215
|
+
opts.on("--[no-]html", "Generate HTML output.", "(default: --html)") do |val|
|
216
|
+
options.html = val
|
217
|
+
end
|
218
|
+
|
219
|
+
opts.on("--css relative/path/to/custom.css", "Use a custom CSS file for HTML output.", "Specified as a relative path.") do |val|
|
220
|
+
options.css = val
|
221
|
+
end
|
222
|
+
|
223
|
+
opts.on("--sort CRITERION", [:name, :loc, :coverage], "Sort files in the output by the specified", "field (name, loc, coverage)") do |criterion|
|
224
|
+
options.sort = criterion
|
225
|
+
end
|
226
|
+
|
227
|
+
opts.on("--sort-reverse", "Reverse files in the output.") do
|
228
|
+
options.sort_reverse = true
|
229
|
+
end
|
230
|
+
|
231
|
+
opts.on("--threshold INT", "Only list files with coverage < INT %.", "(default: 101)") do |threshold|
|
232
|
+
begin
|
233
|
+
threshold = Integer(threshold)
|
234
|
+
raise if threshold <= 0 || threshold > 101
|
235
|
+
rescue Exception
|
236
|
+
raise OptionParser::InvalidArgument, threshold
|
237
|
+
end
|
238
|
+
options.output_threshold = threshold
|
239
|
+
end
|
240
|
+
|
241
|
+
opts.on("--failure-threshold [INT]", "Fail if the coverage is below the threshold", "(default: 100)") do |threshold|
|
242
|
+
options.failure_threshold = (threshold || 100).to_i
|
243
|
+
options.textmode = :failure_report
|
244
|
+
end
|
245
|
+
|
246
|
+
opts.on("--charset CHARSET", "Charset used in Content-Type declaration of HTML reports.") do |c|
|
247
|
+
options.charset = c
|
248
|
+
end
|
249
|
+
|
250
|
+
opts.on("--only-uncovered", "Same as --threshold 100") do
|
251
|
+
options.output_threshold = 100
|
252
|
+
end
|
253
|
+
|
254
|
+
opts.on("--replace-progname", "Replace $0 when loading the .rb files.") do
|
255
|
+
options.replace_prog_name = true
|
256
|
+
end
|
257
|
+
|
258
|
+
opts.on("-w", "Turn warnings on (like ruby).") do
|
259
|
+
$VERBOSE = true
|
260
|
+
end
|
261
|
+
|
262
|
+
opts.on("--no-rcovrt", "Do not use the optimized C runtime.", "(will run 30-300 times slower)") do
|
263
|
+
$rcov_do_not_use_rcovrt = true
|
264
|
+
end
|
265
|
+
|
266
|
+
opts.on("--diff-cmd PROGNAME", "Use PROGNAME for --text-coverage-diff.",
|
267
|
+
"(default: diff)") do |cmd|
|
268
|
+
options.diff_cmd = cmd
|
269
|
+
end
|
270
|
+
|
271
|
+
opts.separator ""
|
272
|
+
|
273
|
+
opts.on_tail("-h", "--help", "Show extended help message") do
|
274
|
+
require 'pp'
|
275
|
+
puts opts
|
276
|
+
puts <<EOF
|
277
|
+
|
278
|
+
Files matching any of the following regexps will be omitted in the report(s):
|
279
|
+
#{PP.pp(options.skip, "").chomp}
|
280
|
+
EOF
|
281
|
+
puts EXTRA_HELP
|
282
|
+
exit
|
283
|
+
end
|
284
|
+
|
285
|
+
opts.on_tail("--report-cov-bug SELECTOR", "Report coverage analysis bug for the",
|
286
|
+
"method specified by SELECTOR", "(format: Foo::Bar#method, A::B.method)") do |selector|
|
287
|
+
case selector
|
288
|
+
when /([^.]+)(#|\.)(.*)/ then options.report_cov_bug_for = selector
|
289
|
+
else
|
290
|
+
raise OptionParser::InvalidArgument, selector
|
291
|
+
end
|
292
|
+
options.textmode = nil
|
293
|
+
options.html = false
|
294
|
+
options.callsites = true
|
295
|
+
end
|
296
|
+
opts.on_tail("--version", "Show version") do
|
297
|
+
puts "rcov " + Rcov::VERSION + " " + Rcov::RELEASE_DATE
|
298
|
+
exit
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
$ORIGINAL_ARGV = ARGV.clone
|
303
|
+
if (idx = ARGV.index("--"))
|
304
|
+
extra_args = ARGV[idx+1..-1]
|
305
|
+
ARGV.replace(ARGV[0,idx])
|
306
|
+
else
|
307
|
+
extra_args = []
|
308
|
+
end
|
309
|
+
|
310
|
+
begin
|
311
|
+
opts.parse! ARGV
|
312
|
+
rescue OptionParser::InvalidOption, OptionParser::InvalidArgument, OptionParser::MissingArgument => e
|
313
|
+
puts opts
|
314
|
+
puts
|
315
|
+
puts e.message
|
316
|
+
exit(-1)
|
317
|
+
end
|
318
|
+
|
319
|
+
options.destdir ||= "coverage"
|
320
|
+
unless ARGV[0] or options.aggregate_file && File.file?(options.aggregate_file)
|
321
|
+
puts opts
|
322
|
+
exit
|
323
|
+
end
|
324
|
+
|
325
|
+
# {{{ set loadpath
|
326
|
+
options.loadpaths.reverse_each{|x| $:.unshift x}
|
327
|
+
|
328
|
+
#{{{ require 'rcov': do it only now in order to be able to run rcov on itself
|
329
|
+
# since we need to set $: before.
|
330
|
+
|
331
|
+
require 'rcov'
|
332
|
+
|
333
|
+
options.callsites = true if options.report_cov_bug_for
|
334
|
+
options.textmode = :gcc if !options.textmode and options.gcc_output
|
335
|
+
|
336
|
+
def rcov_load_aggregate_data(file)
|
337
|
+
require 'zlib'
|
338
|
+
begin
|
339
|
+
old_data = nil
|
340
|
+
Zlib::GzipReader.open(file){|gz| old_data = Marshal.load(gz) }
|
341
|
+
rescue
|
342
|
+
old_data = {}
|
343
|
+
end
|
344
|
+
old_data || {}
|
345
|
+
end
|
346
|
+
|
347
|
+
def rcov_save_aggregate_data(file)
|
348
|
+
require 'zlib'
|
349
|
+
Zlib::GzipWriter.open(file) do |f|
|
350
|
+
Marshal.dump({:callsites => $rcov_callsite_analyzer, :coverage => $rcov_code_coverage_analyzer}, f)
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
if options.callsites
|
355
|
+
if options.aggregate_file
|
356
|
+
saved_aggregate_data = rcov_load_aggregate_data(options.aggregate_file)
|
357
|
+
if saved_aggregate_data[:callsites]
|
358
|
+
$rcov_callsite_analyzer = saved_aggregate_data[:callsites]
|
359
|
+
end
|
360
|
+
end
|
361
|
+
$rcov_callsite_analyzer ||= Rcov::CallSiteAnalyzer.new
|
362
|
+
$rcov_callsite_analyzer.install_hook
|
363
|
+
else
|
364
|
+
$rcov_callsite_analyzer = nil
|
365
|
+
end
|
366
|
+
|
367
|
+
# {{{ create formatters
|
368
|
+
formatters = []
|
369
|
+
make_formatter = lambda do |klass|
|
370
|
+
klass.new(:destdir => options.destdir, :color => options.color,
|
371
|
+
:fsr => options.range, :textmode => options.textmode,
|
372
|
+
:ignore => options.skip, :dont_ignore => options.include,
|
373
|
+
:sort => options.sort,
|
374
|
+
:sort_reverse => options.sort_reverse,
|
375
|
+
:output_threshold => options.output_threshold,
|
376
|
+
:callsite_analyzer => $rcov_callsite_analyzer,
|
377
|
+
:coverage_diff_mode => options.coverage_diff_mode,
|
378
|
+
:coverage_diff_file => options.coverage_diff_file,
|
379
|
+
:callsites => options.callsites,
|
380
|
+
:cross_references => options.crossrefs,
|
381
|
+
:diff_cmd => options.diff_cmd,
|
382
|
+
:comments_run_by_default => options.comments_run_by_default,
|
383
|
+
:gcc_output => options.gcc_output,
|
384
|
+
:charset => options.charset,
|
385
|
+
:css => options.css,
|
386
|
+
:failure_threshold => options.failure_threshold
|
387
|
+
)
|
388
|
+
end
|
389
|
+
|
390
|
+
if options.html
|
391
|
+
if options.profiling
|
392
|
+
formatters << make_formatter[Rcov::HTMLProfiling]
|
393
|
+
else
|
394
|
+
formatters << make_formatter[Rcov::HTMLCoverage]
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
textual_formatters = { :counts => Rcov::FullTextReport, :coverage => Rcov::FullTextReport,
|
399
|
+
:gcc => Rcov::FullTextReport, :annotate => Rcov::RubyAnnotation,
|
400
|
+
:summary => Rcov::TextSummary, :report => Rcov::TextReport,
|
401
|
+
:coverage_diff => Rcov::TextCoverageDiff, :failure_report => Rcov::FailureReport }
|
402
|
+
|
403
|
+
if textual_formatters[options.textmode]
|
404
|
+
formatters << make_formatter[textual_formatters[options.textmode]]
|
405
|
+
end
|
406
|
+
|
407
|
+
formatters << make_formatter[Rcov::TextCoverageDiff] if options.coverage_diff_save
|
408
|
+
|
409
|
+
if options.aggregate_file
|
410
|
+
saved_aggregate_data ||= rcov_load_aggregate_data(options.aggregate_file)
|
411
|
+
if saved_aggregate_data[:coverage]
|
412
|
+
$rcov_code_coverage_analyzer = saved_aggregate_data[:coverage]
|
413
|
+
end
|
414
|
+
end
|
415
|
+
|
416
|
+
$rcov_code_coverage_analyzer ||= Rcov::CodeCoverageAnalyzer.new
|
417
|
+
|
418
|
+
# must be registered before test/unit puts its own
|
419
|
+
|
420
|
+
|
421
|
+
# The exception to rethrow after reporting has been handled.
|
422
|
+
$__rcov_exit_exception = nil
|
423
|
+
|
424
|
+
END {
|
425
|
+
$rcov_code_coverage_analyzer.remove_hook
|
426
|
+
$rcov_callsite_analyzer.remove_hook if $rcov_callsite_analyzer
|
427
|
+
rcov_save_aggregate_data(options.aggregate_file) if options.aggregate_file
|
428
|
+
$rcov_code_coverage_analyzer.dump_coverage_info(formatters)
|
429
|
+
if options.report_cov_bug_for
|
430
|
+
defsite = $rcov_callsite_analyzer.defsite(options.report_cov_bug_for)
|
431
|
+
if !defsite
|
432
|
+
$stderr.puts <<-EOF
|
433
|
+
Couldn't find definition site of #{options.report_cov_bug_for}.
|
434
|
+
Was it executed at all?
|
435
|
+
EOF
|
436
|
+
exit(-1)
|
437
|
+
end
|
438
|
+
lines, mark_info, count_info = $rcov_code_coverage_analyzer.data(defsite.file)
|
439
|
+
puts <<EOF
|
440
|
+
|
441
|
+
Please fill in the blanks in the following report.
|
442
|
+
|
443
|
+
|
444
|
+
You can post bugs to
|
445
|
+
http://github.com/relevance/rcov/issues
|
446
|
+
|
447
|
+
Thank you!
|
448
|
+
|
449
|
+
=============================================================================
|
450
|
+
Bug report generated on #{Time.new}
|
451
|
+
|
452
|
+
Ruby version: #{RUBY_VERSION} (#{RUBY_RELEASE_DATE})
|
453
|
+
Platform: #{RUBY_PLATFORM}
|
454
|
+
rcov version: #{Rcov::VERSION}
|
455
|
+
rcovrt loaded? #{$".any?{|x| /\brcovrt\b/ =~ x} }
|
456
|
+
using RubyGems? #{$".any?{|x| /\brubygems\b/ =~ x} }
|
457
|
+
Command-line arguments: #{$ORIGINAL_ARGV.inspect}
|
458
|
+
Coverage analysis bug in: #{options.report_cov_bug_for}
|
459
|
+
|
460
|
+
Line(s) ____________ should be ______ (red/green).
|
461
|
+
|
462
|
+
Raw coverage information (feel free to remove useless data, but please leave
|
463
|
+
some context around the faulty lines):
|
464
|
+
|
465
|
+
EOF
|
466
|
+
defsite.line.upto(SCRIPT_LINES__[defsite.file].size) do |i|
|
467
|
+
puts "%7d:%5d:%s" % [count_info[i-1], i, lines[i-1]]
|
468
|
+
end
|
469
|
+
exit
|
470
|
+
end
|
471
|
+
if !formatters.empty? and formatters.all?{|formatter| formatter.sorted_file_pairs.empty? }
|
472
|
+
require 'pp'
|
473
|
+
$stderr.puts <<-EOF
|
474
|
+
|
475
|
+
No file to analyze was found. All the files loaded by rcov matched one of the
|
476
|
+
following expressions, and were thus ignored:
|
477
|
+
#{PP.pp(options.skip, "").chomp}
|
478
|
+
|
479
|
+
You can solve this by doing one or more of the following:
|
480
|
+
* rename the files not to be ignored so they don't match the above regexps
|
481
|
+
* use --include-file to give a list of patterns for files not to be ignored
|
482
|
+
* use --exclude-only to give the new list of regexps to match against
|
483
|
+
* structure your code as follows:
|
484
|
+
test/test_*.rb for the test cases
|
485
|
+
lib/**/*.rb for the target source code whose coverage you want
|
486
|
+
making sure that the test/test_*.rb files are loading from lib/, e.g. by
|
487
|
+
using the -Ilib command-line argument, adding
|
488
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
489
|
+
to test/test_*.rb, or running rcov via a Rakefile (read the RDoc
|
490
|
+
documentation or README.rake in the source distribution).
|
491
|
+
EOF
|
492
|
+
end
|
493
|
+
|
494
|
+
raise $__rcov_exit_exception if $__rcov_exit_exception
|
495
|
+
}
|
496
|
+
|
497
|
+
$rcov_code_coverage_analyzer.install_hook
|
498
|
+
|
499
|
+
#{{{ Load scripts
|
500
|
+
begin
|
501
|
+
pending_scripts = ARGV.clone
|
502
|
+
ARGV.replace extra_args
|
503
|
+
until pending_scripts.empty?
|
504
|
+
prog = pending_scripts.shift
|
505
|
+
if options.replace_prog_name
|
506
|
+
$0 = File.basename(File.expand_path(prog))
|
507
|
+
end
|
508
|
+
load prog
|
509
|
+
end
|
510
|
+
rescue Object => err
|
511
|
+
$__rcov_exit_exception = err
|
512
|
+
end
|
513
|
+
|
514
|
+
__END__
|