coverage 0.3

Sign up to get free protection for your applications and to get access to all the features.
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: []