coverage 0.3

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 (5) hide show
  1. data/CHANGES +23 -0
  2. data/README +76 -0
  3. data/TODO +13 -0
  4. data/lib/coverage.rb +275 -0
  5. metadata +45 -0
data/CHANGES ADDED
@@ -0,0 +1,23 @@
1
+ 29-december-2005 Neoneye
2
+ * Alex Pooley posted a patch to eliminate a warning.
3
+
4
+ 14-april-2004 Neoneye
5
+ * post-install notice added.
6
+
7
+ 30-march-2004 Neoneye
8
+ * better way to substitute into heredoc, while preserving whitespace.
9
+
10
+ 22-march-2004 Neoneye
11
+ * version 0.2 released.
12
+ * sidebar can be specified, by creating a file
13
+ named 'coverage.sidebar'.
14
+ * avoid absolute names.
15
+ * output to the local dir 'coverage'.
16
+ * XHTML1.0 strict.
17
+
18
+ 21-march-2004 Neoneye
19
+ * version 0.1 released.
20
+ * prepared to make a release of 'coverage.rb'
21
+ * While reading on the rubygems mailinglist I saw that batsman had
22
+ a patch to coverage. I have committed it. Thanks batsman.
23
+ It can now show percentages in the index.html file.
data/README ADDED
@@ -0,0 +1,76 @@
1
+ Ruby - Coverage
2
+
3
+
4
+ Purpose
5
+ =======
6
+
7
+ >> this package is outdated, rcov is way better <<
8
+
9
+ This tool helps identify those lines of code in your
10
+ program which didn't got executed while running.
11
+
12
+ NaHi is the author of the original 'coverage.rb',
13
+ 47 lines of Ruby code. Today it outputs nice HTML.
14
+
15
+
16
+
17
+ License
18
+ =======
19
+
20
+ Ruby's license
21
+
22
+
23
+ Install
24
+ =======
25
+
26
+ Follow these 3 steps in order to install
27
+
28
+ ruby install.rb config
29
+
30
+ ruby install.rb setup
31
+
32
+ ruby install.rb install
33
+
34
+
35
+ Usage
36
+ =====
37
+
38
+ Insert '-rcoverage' when you wish to make coverage output.
39
+ For instance:
40
+
41
+ ruby -rcoverage test_all.rb
42
+
43
+ It should generage an 'index.html' file, containing coverage info.
44
+
45
+
46
+ Credits
47
+ =======
48
+
49
+ NAKAMURA Hiroshi (NaHi) for the original coverage code.
50
+
51
+ Mauricio Julio Fern�ndez Pradier, lots of improvements.
52
+
53
+ Robert Feldt, for suggestions.
54
+
55
+ Alex Pooley, for eliminating warning(s).
56
+
57
+
58
+
59
+ Bugs reports (rubyforge account required)
60
+ =========================================
61
+
62
+ If you find any misbehavier, then please submit it here:
63
+ http://rubyforge.org/tracker/?atid=149&group_id=18&func=browse
64
+
65
+
66
+
67
+ Feature requests (rubyforge account required)
68
+ =============================================
69
+
70
+ If there is something you wish, then tell it so we can figure out
71
+ how to make 'coverage' capable of it.
72
+ http://rubyforge.org/tracker/?atid=152&group_id=18&func=browse
73
+
74
+
75
+
76
+ end of document
data/TODO ADDED
@@ -0,0 +1,13 @@
1
+ What needs to be done:
2
+
3
+ * 'end' statements isn't detected correct. I (Simon) has
4
+ only little insight how the original 'coverage.rb' works.
5
+ I don't know how to accomplish this. Please contribute
6
+ in case you know it.
7
+
8
+ * Have a Look at 'profiler.rb', how does it count which
9
+ pieces of code that has be executed.
10
+ When we have this information available, then produce
11
+ some nice HTML, so that you can browse that information.
12
+
13
+ * nicer html output.
@@ -0,0 +1,275 @@
1
+ # module COVERAGE__ originally (c) NAKAMURA Hiroshi, under Ruby's license
2
+ # module PrettyCoverage originally (c) Simon Strandgaard, under Ruby's license
3
+ # minor modifications by Mauricio Julio Fern�ndez Pradier
4
+
5
+ require 'fileutils'
6
+ require 'rbconfig'
7
+ include Config
8
+
9
+ module PrettyCoverage
10
+
11
+ class HTML
12
+ def write_page(body, title, css, filename)
13
+ html = <<-EOHTML.gsub(/^\s*/, '') % [title, css, body]
14
+ <?xml version="1.0" encoding="ISO-8859-1"?>
15
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
16
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
17
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
18
+ <head><title>%s</title>
19
+ <style type="text/css">%s</style></head>
20
+ <body>%s</body></html>
21
+ EOHTML
22
+ File.open(filename, "w+") {|f| f.write(html) }
23
+ end
24
+ def escape(text)
25
+ text.gsub(/&/, "&amp;").gsub(/\"/, "&quot;").gsub(/>/, "&gt;").gsub(/</, "&lt;")
26
+ end
27
+ def initialize
28
+ @files = {}
29
+ @files_codeonly = {}
30
+ @filenames = {}
31
+ @sidebar = ""
32
+ end
33
+ def output_dir(&block)
34
+ dir = "coverage"
35
+ if FileTest.directory?(dir)
36
+ FileUtils.rm_rf(dir)
37
+ end
38
+ FileUtils.mkdir(dir)
39
+ FileUtils.cd(dir) { block.call(dir) }
40
+ end
41
+ def load_sidebar
42
+ return unless FileTest.file?("coverage.sidebar")
43
+ data = nil
44
+ File.open("coverage.sidebar", "r") {|f| data = f.read}
45
+ @sidebar = "<div class=\"sidebar\">#{data}</div>"
46
+ end
47
+ def build_filenames
48
+ duplicates = Hash.new(0)
49
+ @files.keys.each do |filename, marked|
50
+ base = File.basename(filename)
51
+ absolute = File.expand_path(filename)
52
+ n = duplicates[base]
53
+ duplicates[base] += 1
54
+ if n > 0
55
+ base += n.to_s
56
+ end
57
+ @filenames[filename] = [base, absolute]
58
+ end
59
+ #p @filenames
60
+ end
61
+ def execute
62
+ puts "execute"
63
+ build_filenames
64
+ load_sidebar
65
+ output_dir do
66
+ create_file_index
67
+ @files.each do |file, line_marked|
68
+ create_file(file, line_marked, @files_codeonly[file])
69
+ end
70
+ end
71
+ end
72
+ def mk_filename(name)
73
+ base_absolute = @filenames[name]
74
+ raise "should not happen" unless base_absolute
75
+ base, absolute = base_absolute
76
+ return nil if absolute =~ /\A#{Regexp.escape(CONFIG["libdir"])}/
77
+ return nil if base =~ /test_/
78
+ [base + ".html", base, absolute]
79
+ end
80
+ def create_file_index
81
+ output_filename = "index.html"
82
+ rows = []
83
+ filestats = {}
84
+ filestats_code = {}
85
+ @files.sort_by{|k,v| k}.each do|file, line_marked|
86
+ url_filename = mk_filename(file)
87
+ next unless url_filename
88
+ percent = "%02.1f" % calc_coverage(line_marked)
89
+ percent2 = "%02.1f" % calc_coverage(@files_codeonly[file])
90
+ numlines = line_marked.transpose[1].size
91
+ filestats[file] = [calc_coverage(line_marked), numlines]
92
+ filestats_code[file] = [calc_coverage(@files_codeonly[file]),
93
+ numlines]
94
+ url, filename, abspath = url_filename
95
+ cells = [
96
+ "<a href=\"#{url}\">#{filename}</a>",
97
+ "<tt>#{numlines}</tt>",
98
+ "&nbsp;", "&nbsp;", "&nbsp;",
99
+ "<tt>#{percent}%</tt>",
100
+ "&nbsp;", "&nbsp;", "&nbsp;",
101
+ "<tt>#{percent2}%</tt>"
102
+ ]
103
+ rows << cells.map{|cell| "<td>#{cell}</td>"}
104
+ end
105
+ rows.map!{|row| "<tr>#{row}</tr>"}
106
+ table = "<table>#{rows.join}</table>"
107
+ total_cov = 1.0 *
108
+ filestats.inject(0){|a,(k,v)| a + v[0] * v[1]} /
109
+ filestats.inject(0){|a,(k,v)| a + v[1]}
110
+ total_code_cov = 1.0 *
111
+ filestats_code.inject(0) {|a,(k,v)| a + v[0] * v[1]} /
112
+ filestats_code.inject(0){|a,(k,v)| a + v[1]}
113
+ body = "<h1>Average (with comments): %02.1f%%</h1>" % total_cov
114
+ body << "<h1>Average (code only): %02.1f%%</h1>" % total_code_cov
115
+ body << @sidebar
116
+ body << table
117
+ title = "coverage"
118
+ css = <<-EOCSS.gsub(/^\s*/, '')
119
+ body {
120
+ background-color: rgb(180, 180, 180);
121
+ }
122
+ span.marked {
123
+ background-color: rgb(185, 200, 200);
124
+ display: block;
125
+ }
126
+ div.overview {
127
+ border-bottom: 8px solid black;
128
+ }
129
+ div.sidebar {
130
+ float: right;
131
+ width: 300px;
132
+ border: 2px solid black;
133
+ margin-left: 10px;
134
+ padding-left: 10px;
135
+ padding-right: 10px;
136
+ margin-right: -10px;
137
+ background-color: rgb(185, 200, 200);
138
+ }
139
+ EOCSS
140
+ write_page(body, title, css, output_filename)
141
+ end
142
+ def add_file(file, line_marked)
143
+ percent = calc_coverage(line_marked)
144
+ path = File.expand_path(file)
145
+ return nil if path =~ /\A#{Regexp.escape(CONFIG["rubylibdir"])}/
146
+ return nil if path =~ /\A#{Regexp.escape(CONFIG["sitelibdir"])}/
147
+ #printf("file #{file} coverage=%02.1f%\n", percent)
148
+
149
+ # comments and empty lines.. we must
150
+ # propagate marked-value backwards
151
+ line_marked << ["", false]
152
+ (line_marked.size).downto(1) do |index|
153
+ line, marked = line_marked[index-1]
154
+ next_line, next_marked = line_marked[index]
155
+ if line =~ /^\s*(#|$)/ and marked == false
156
+ marked = next_marked
157
+ line_marked[index-1] = [line, marked]
158
+ end
159
+ end
160
+ line_marked.pop
161
+ @files[file] = line_marked
162
+ @files_codeonly[file] = line_marked.select do |(line, marked)|
163
+ line !~ /^\s*(#|$)/
164
+ end
165
+ end
166
+ def calc_coverage(line_marked)
167
+ marked = line_marked.transpose[1]
168
+ n = marked.inject(0) {|r, i| (i) ? (r+1) : r }
169
+ percent = n.to_f * 100 / marked.size
170
+ end
171
+ def format_overview(file, line_marked, code_marked)
172
+ percent = "%02.1f" % calc_coverage(line_marked)
173
+ percent2 = "%02.1f" % calc_coverage(code_marked)
174
+ html = <<-EOHTML.gsub(/^\s*/, '')
175
+ <div class="overview">
176
+ <table>
177
+ <tr><td>filename</td><td><tt>#{file}</tt></td></tr>
178
+ <tr><td>total coverage</td><td>#{percent}%</td></tr>
179
+ <tr><td>code coverage</td><td>#{percent2}%</td></tr>
180
+ </table>
181
+ </div>
182
+ EOHTML
183
+ html
184
+ end
185
+ def format_lines(line_marked)
186
+ result = ""
187
+ last = nil
188
+ end_of_span = ""
189
+ format_line = "%#{line_marked.size.to_s.size}d"
190
+ line_no = 1
191
+ line_marked.each do |(line, marked)|
192
+ if marked != last
193
+ result += end_of_span
194
+ case marked
195
+ when true
196
+ result += "<span class=\"marked\">"
197
+ end_of_span = "</span>"
198
+ when false
199
+ end_of_span = ""
200
+ end
201
+ end
202
+ result += (format_line % line_no) + " " + escape(line) + "\n"
203
+ last = marked
204
+ line_no += 1
205
+ end
206
+ result += end_of_span
207
+ "<pre>#{result}</pre>"
208
+ end
209
+ def create_file(file, line_marked, code_marked)
210
+ url_filename = mk_filename(file)
211
+ return unless url_filename
212
+ output_filename, filename, abspath = url_filename
213
+ puts "outputting #{output_filename.inspect}"
214
+ body = format_overview(abspath, line_marked, code_marked) +
215
+ format_lines(line_marked)
216
+ title = filename + " - coverage"
217
+ css = <<-EOCSS.gsub(/^\s*/, '')
218
+ body {
219
+ background-color: rgb(180, 180, 180);
220
+ }
221
+ span.marked {
222
+ background-color: rgb(185, 200, 200);
223
+ display: block;
224
+ }
225
+ div.overview {
226
+ border-bottom: 8px solid black;
227
+ }
228
+ EOCSS
229
+ write_page(body, title, css, output_filename)
230
+ end
231
+ end # class HTML
232
+
233
+ end # module PrettyCoverage
234
+
235
+ SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
236
+
237
+ module COVERAGE__
238
+ COVER = {}
239
+ def self.trace_func(event, file, line, id, binding, klass)
240
+ case event
241
+ when 'c-call', 'c-return', 'class'
242
+ return
243
+ end
244
+ COVER[file] ||= []
245
+ COVER[file][line] ||= 0
246
+ COVER[file][line] += 1
247
+ end
248
+ END {
249
+ set_trace_func(nil)
250
+ printer = PrettyCoverage::HTML.new
251
+ COVER.each do |file, lines|
252
+ next if SCRIPT_LINES__.has_key?(file) == false
253
+ lines = SCRIPT_LINES__[file]
254
+ covers = COVER[file]
255
+ line_status = []
256
+ 0.upto(lines.size - 1) do |c|
257
+ line = lines[c].chomp
258
+ marked = false
259
+ if covers[c + 1]
260
+ marked = true
261
+ elsif /^\s*(?:begin\s*(?:#.*)?|ensure\s*(?:#.*)?|else\s*(?:#.*)?)$/ =~ line and covers[c + 1 + 1]
262
+ covers[c + 1] = covers[c + 1 + 1]
263
+ marked = true
264
+ elsif /^\s*(?:end|\})\s*$/ =~ line && covers[c + 1 - 1]
265
+ covers[c + 1] = covers[c + 1 - 1]
266
+ marked = true
267
+ end
268
+ line_status << [line, marked]
269
+ end
270
+ printer.add_file(file, line_status)
271
+ end
272
+ printer.execute
273
+ } # END
274
+ set_trace_func(COVERAGE__.method(:trace_func).to_proc)
275
+ end # module COVERAGE__
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.11
3
+ specification_version: 1
4
+ name: coverage
5
+ version: !ruby/object:Gem::Version
6
+ version: "0.3"
7
+ date: 2005-12-29 00:00:00 +01:00
8
+ summary: identifies inactive code
9
+ require_paths:
10
+ - lib
11
+ email: neoneye@gmail.com
12
+ homepage: http://aeditor.rubyforge.org
13
+ rubyforge_project: aeditor
14
+ description: "output-format is XHTML1.0 strict credit goes to NAKAMURA Hiroshi, which made
15
+ the original coverage in 47 lines of code! Mauricio Julio Fern�ndez Pradier,
16
+ lots of improvements. Robert Feldt, for suggestions. Alex Pooley, for
17
+ eliminating warnings."
18
+ autorequire: coverage
19
+ default_executable:
20
+ bindir: bin
21
+ has_rdoc: false
22
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
23
+ requirements:
24
+ -
25
+ - ">"
26
+ - !ruby/object:Gem::Version
27
+ version: 0.0.0
28
+ version:
29
+ platform: ruby
30
+ signing_key:
31
+ cert_chain:
32
+ authors:
33
+ - Simon Strandgaard
34
+ files:
35
+ - CHANGES
36
+ - README
37
+ - TODO
38
+ - lib/coverage.rb
39
+ test_files: []
40
+ rdoc_options: []
41
+ extra_rdoc_files: []
42
+ executables: []
43
+ extensions: []
44
+ requirements: []
45
+ dependencies: []