gigpark-rcov 0.8.6

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