katsuya-rcov 0.9.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/BLURB +111 -0
  2. data/LICENSE +53 -0
  3. data/Rakefile +103 -0
  4. data/THANKS +110 -0
  5. data/bin/rcov +514 -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 +294 -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 +271 -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 +355 -0
  23. data/lib/rcov/formatters.rb +13 -0
  24. data/lib/rcov/formatters/base_formatter.rb +174 -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 +274 -0
  28. data/lib/rcov/formatters/html_erb_template.rb +62 -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 +64 -0
  35. data/lib/rcov/templates/index.html.erb +93 -0
  36. data/lib/rcov/templates/jquery-1.3.2.min.js +19 -0
  37. data/lib/rcov/templates/jquery.tablesorter.min.js +15 -0
  38. data/lib/rcov/templates/print.css +12 -0
  39. data/lib/rcov/templates/rcov.js +42 -0
  40. data/lib/rcov/templates/screen.css +270 -0
  41. data/lib/rcov/version.rb +10 -0
  42. data/setup.rb +1588 -0
  43. data/test/assets/sample_01.rb +7 -0
  44. data/test/assets/sample_02.rb +5 -0
  45. data/test/assets/sample_03.rb +20 -0
  46. data/test/assets/sample_04.rb +10 -0
  47. data/test/assets/sample_05-new.rb +17 -0
  48. data/test/assets/sample_05-old.rb +13 -0
  49. data/test/assets/sample_05.rb +17 -0
  50. data/test/assets/sample_06.rb +8 -0
  51. data/test/call_site_analyzer_test.rb +171 -0
  52. data/test/code_coverage_analyzer_test.rb +219 -0
  53. data/test/expected_coverage/diff-gcc-all.out +7 -0
  54. data/test/expected_coverage/diff-gcc-diff.out +11 -0
  55. data/test/expected_coverage/diff-gcc-original.out +5 -0
  56. data/test/expected_coverage/diff-no-color.out +12 -0
  57. data/test/expected_coverage/diff.out +12 -0
  58. data/test/expected_coverage/gcc-text.out +10 -0
  59. data/test/expected_coverage/sample_03_rb.html +651 -0
  60. data/test/expected_coverage/sample_03_rb.rb +28 -0
  61. data/test/expected_coverage/sample_04_rb.html +641 -0
  62. data/test/file_statistics_test.rb +471 -0
  63. data/test/functional_test.rb +91 -0
  64. data/test/test_helper.rb +4 -0
  65. data/test/turn_off_rcovrt.rb +4 -0
  66. metadata +126 -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,103 @@
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
+ begin
89
+ %w{sdoc sdoc-helpers rdiscount}.each { |name| gem name }
90
+ require 'sdoc_helpers'
91
+ rescue LoadError => ex
92
+ puts "sdoc support not enabled:"
93
+ puts ex.inspect
94
+ end
95
+
96
+ require 'rake/rdoctask'
97
+ Rake::RDocTask.new do |rdoc|
98
+ version = File.exist?('VERSION') ? File.read('VERSION') : ''
99
+ rdoc.rdoc_dir = 'rdoc'
100
+ rdoc.title = "rcov #{version}"
101
+ rdoc.rdoc_files.include('README*')
102
+ rdoc.rdoc_files.include('lib/**/*.rb')
103
+ end
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]
@@ -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__