Does there exists a tool for Ruby which records which parts
of code (preferable the nodes in the AST) there has been reached?
Eventually with some statistics on how many times each part
has been executed?
···
–
Simon Strandgaard
Does there exists a tool for Ruby which records which parts
of code (preferable the nodes in the AST) there has been reached?
Eventually with some statistics on how many times each part
has been executed?
–
Simon Strandgaard
“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag
news:pan.2004.02.02.15.01.49.377820@adslhome.dk…
Does there exists a tool for Ruby which records which parts
of code (preferable the nodes in the AST) there has been reached?Eventually with some statistics on how many times each part
has been executed?
I don’t know such a tool but two things come to mind:
You can use the profiler for timings (alternatively use “benchmark”,
which has less performance overhead).
You can use set_trace_function() to build the statistics.
Regards
robert
Simon Strandgaard wrote:
Does there exists a tool for Ruby which records which parts
of code (preferable the nodes in the AST) there has been reached?Eventually with some statistics on how many times each part
has been executed?
There is coverage.rb in RAA. It’s very basic, but it works fine
“out of the box” and has been useful to me.
It doesn’t measure stats, but it does show what code has been
hit and what has not, and dumps it in ANSI.
Hal
Wew, this is really a short piece of code… amazing that it can be done in
only 45 lines of ruby code!
If I do “cat report.txt” then my terminal just scrolls for 10 seconds,
which is much larger than what my terminal history can remember.
If I pipe it into “less” then the coloring disappears. How do you view
ANSI files?
I think I will improve it (because I need it in conjunction with unittest)
Has this been done before?
Other ideas?
Eventually make a rubyforge project out of it?
On Tue, 03 Feb 2004 09:14:01 +0900, Hal Fulton wrote:
Simon Strandgaard wrote:
Does there exists a tool for Ruby which records which parts
of code (preferable the nodes in the AST) there has been reached?Eventually with some statistics on how many times each part
has been executed?There is coverage.rb in RAA. It’s very basic, but it works fine
“out of the box” and has been useful to me.It doesn’t measure stats, but it does show what code has been
hit and what has not, and dumps it in ANSI.
–
Simon Strandgaard
Hi,
At Wed, 4 Feb 2004 00:30:04 +0900, Simon Strandgaard wrote:
If I do “cat report.txt” then my terminal just scrolls for 10 seconds,
which is much larger than what my terminal history can remember.
If I pipe it into “less” then the coloring disappears. How do you view
ANSI files?
less -r
–
Nobu Nakada
Thanks…
I have done some improvements to the original ‘coverage.rb’, so that
HTML is now generated. For an example have a look at:
http://neoneye.dk/parser.rb.coverage.html
As you may notice comments/arrays appears as if they are not executed!
How can I fix this?
On Wed, 04 Feb 2004 00:46:20 +0900, nobu.nokad wrote:
At Wed, 4 Feb 2004 00:30:04 +0900, > Simon Strandgaard wrote:
If I do “cat report.txt” then my terminal just scrolls for 10 seconds,
which is much larger than what my terminal history can remember.
If I pipe it into “less” then the coloring disappears. How do you view
ANSI files?less -r
–
Simon Strandgaard
module PrettyCoverage
class HTML
def initialize
@files = {}
end
def execute
puts “execute”
@files.each{|file, line_marked|
create_file(file, line_marked)
}
create_file_index
end
def mk_filename(name)
name+“.coverage.html”
end
def create_file_index
output_filename = “index.html”
rows =
@files.each{|file, line_marked|
filename = mk_filename(file)
rows << “<a href="#{filename}">#{file}”
}
result = rows.join(“\n”)
body = “
filename | #{file} |
coverage | #{percent} |
#{result}" end def create_file(file, line_marked) output_filename = mk_filename(file) puts "outputting #{output_filename.inspect}" body = format_overview(file, line_marked) + format_lines(line_marked) title = file + " - coverage" css = <<EOCSS body { background-color: rgb(180, 180, 180); } div.marked { background-color: rgb(185, 200, 200); } div.overview { border-bottom: 8px solid black; } EOCSS html = <<EOHTML #{title} #{css} #{body} EOHTML File.open(output_filename, "w+") do |f| f.puts html end end end end
SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
module COVERAGE__
COVER = {}
def self.trace_func(event, file, line, id, binding, klass)
case event
when ‘c-call’, ‘c-return’, ‘class’
return
end
COVER[file] ||=
COVER[file][line] ||= 0
COVER[file][line] += 1
end
END {
set_trace_func(nil)
printer = PrettyCoverage::HTML.new
COVER.each do |file, lines|
next if SCRIPT_LINES__.has_key?(file) == false
lines = SCRIPT_LINES__[file]
covers = COVER[file]
line_status =
0.upto(lines.size - 1) do |c|
line = lines[c].chomp
marked = false
if covers[c + 1]
marked = true
elsif /^\s*(?:begin\s*(?:#.)?|ensure\s(?:#.)?|else\s(?:#.)?)$/ =~ line and covers[c + 1 + 1]
covers[c + 1] = covers[c + 1 + 1]
marked = true
elsif /^\s(?:end|})\s*$/ =~ line && covers[c + 1 - 1]
covers[c + 1] = covers[c + 1 - 1]
marked = true
end
line_status << [line, marked]
end
printer.add_file(file, line_status)
end
printer.execute
}
set_trace_func(COVERAGE__.method(:trace_func).to_proc)
end
“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag
news:pan.2004.02.04.09.26.42.335507@adslhome.dk…
If I do “cat report.txt” then my terminal just scrolls for 10
seconds,
which is much larger than what my terminal history can remember.
If I pipe it into “less” then the coloring disappears. How do you
view
ANSI files?less -r
Thanks…
I have done some improvements to the original ‘coverage.rb’, so that
HTML is now generated. For an example have a look at:
http://neoneye.dk/parser.rb.coverage.htmlAs you may notice comments/arrays appears as if they are not executed!
How can I fix this?
Dunno whether it’s worth the effort. I guess, comments could be fixed by
identifying regions of comment lines and marking them as reached if the
line above and below is reached. For arrays you could try to find the
matching “[” for a closing “]” and mark all lines in between if the line
of the closing “]” is marked.
Apart from that: nice output!
Regards
robert
–
Simon Strandgaardmodule PrettyCoverage
#{result}
class HTML
def initialize
@files = {}
end
def execute
puts “execute”
@files.each{|file, line_marked|
create_file(file, line_marked)
}
create_file_index
end
def mk_filename(name)
name+“.coverage.html”
end
def create_file_index
output_filename = “index.html”
rows =
@files.each{|file, line_marked|
filename = mk_filename(file)
rows << “<a href="#{filename}">#{file}”
}
result = rows.join(“\n”)
body = “”
title = “coverage”
css = <<EOCSS
body {
background-color: rgb(180, 180, 180);
}
div.marked {
background-color: rgb(185, 200, 200);
}
div.overview {
border-bottom: 8px solid black;
}
EOCSS
html = <<EOHTML #{title} #{css} #{body} EOHTML File.open(output_filename, "w+") do |f| f.puts html end end def add_file(file, line_marked) percent = calc_coverage(line_marked) printf("file=#{file} coverage=%02.1f%\n", percent) @files[file] = line_marked end def calc_coverage(line_marked) marked = line_marked.transpose[1] n = marked.inject(0) {|r, i| (i) ? (r+1) : r } percent = n.to_f * 100 / marked.size end def format_overview(file, line_marked) percent = "%02.1f" % calc_coverage(line_marked) html = <<EOHTMLEOHTML html end def format_lines(line_marked) result = "" last = nil end_of_div = "" format_line = "%#{line_marked.size.to_s.size}d" line_no = 1 line_marked.each {|(line, marked)| if marked != last result += end_of_div case marked when true result += "
filename #{file} coverage #{percent} " end_of_div = "" when false end_of_div = "" end end result += (format_line % line_no) + " " + line + "\n" last = marked line_no += 1 } result += end_of_div "#{result}" end def create_file(file, line_marked) output_filename = mk_filename(file) puts "outputting #{output_filename.inspect}" body = format_overview(file, line_marked) + format_lines(line_marked) title = file + " - coverage" css = <<EOCSS body { background-color: rgb(180, 180, 180); } div.marked { background-color: rgb(185, 200, 200); } div.overview { border-bottom: 8px solid black; } EOCSS html = <<EOHTML #{title} #{css} #{body} EOHTML File.open(output_filename, "w+") do |f| f.puts html end end end endSCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
module COVERAGE__
COVER = {}
def self.trace_func(event, file, line, id, binding, klass)
case event
when ‘c-call’, ‘c-return’, ‘class’
return
end
COVER[file] ||=
COVER[file][line] ||= 0
COVER[file][line] += 1
endEND {
set_trace_func(nil)
printer = PrettyCoverage::HTML.new
COVER.each do |file, lines|
next if SCRIPT_LINES__.has_key?(file) == false
lines = SCRIPT_LINES__[file]
covers = COVER[file]
line_status =
0.upto(lines.size - 1) do |c|
line = lines[c].chomp
marked = false
if covers[c + 1]
marked = true
elsif
/^\s*(?:begin\s*(?:#.)?|ensure\s(?:#.)?|else\s(?:#.*)?)$/ =~ line and
covers[c + 1 + 1]
On Wed, 04 Feb 2004 00:46:20 +0900, nobu.nokad wrote:
At Wed, 4 Feb 2004 00:30:04 +0900, > > Simon Strandgaard wrote:
covers[c + 1] = covers[c + 1 + 1]
marked = true
elsif /^\s*(?:end|})\s*$/ =~ line && covers[c + 1 - 1]
covers[c + 1] = covers[c + 1 - 1]
marked = true
end
line_status << [line, marked]
end
printer.add_file(file, line_status)
end
printer.execute
}set_trace_func(COVERAGE__.method(:trace_func).to_proc)
end
Ok… I now propagate the marked status to comments… output is much better
now. Still Arrays/Hashes/=begin=end needs to be fixed.
Try compare the new output agains the old:
http://neoneye.dk/parser.rb.coverage.ver2.html
Suggestions for improvements is welcome… also patches is welcome.
For the courius; try to execute the attached code by
requiring it on the commandline.
ruby -rcoverage helloworld.rb
That should output a ‘helloworld.rb.coverage.html’ file.
On Wed, 04 Feb 2004 11:22:05 +0100, Robert Klemme wrote:
“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag
news:pan.2004.02.04.09.26.42.335507@adslhome.dk…On Wed, 04 Feb 2004 00:46:20 +0900, nobu.nokad wrote:
At Wed, 4 Feb 2004 00:30:04 +0900, >> > Simon Strandgaard wrote:
If I do “cat report.txt” then my terminal just scrolls for 10
seconds,
which is much larger than what my terminal history can remember.
If I pipe it into “less” then the coloring disappears. How do you
view
ANSI files?less -r
Thanks…
I have done some improvements to the original ‘coverage.rb’, so that
HTML is now generated. For an example have a look at:
http://neoneye.dk/parser.rb.coverage.htmlAs you may notice comments/arrays appears as if they are not executed!
How can I fix this?Dunno whether it’s worth the effort. I guess, comments could be fixed by
identifying regions of comment lines and marking them as reached if the
line above and below is reached. For arrays you could try to find the
matching “[” for a closing “]” and mark all lines in between if the line
of the closing “]” is marked.Apart from that: nice output!
–
Simon Strandgaard
module PrettyCoverage
class HTML
def initialize
@files = {}
end
def execute
puts “execute”
create_file_index
@files.each{|file, line_marked|
create_file(file, line_marked)
}
end
def mk_filename(name)
name+“.coverage.html”
end
def create_file_index
output_filename = “index.html”
rows =
@files.each{|file, line_marked|
filename = mk_filename(file)
rows << “<a href="#{filename}">#{file}”
}
result = rows.join(“\n”)
body = “
# comments and empty lines.. we must
# propagate marked-value backwards
line_marked << ["", false]
(line_marked.size).downto(1) do |index|
line, marked = line_marked[index-1]
next_line, next_marked = line_marked[index]
if line =~ /^\s*(#|$)/ and marked == false
marked = next_marked
#line = "hest" + line
line_marked[index-1] = [line, marked]
end
end
line_marked.pop
@files[file] = line_marked
end
def calc_coverage(line_marked)
marked = line_marked.transpose[1]
n = marked.inject(0) {|r, i| (i) ? (r+1) : r }
percent = n.to_f * 100 / marked.size
end
def format_overview(file, line_marked)
percent = "%02.1f" % calc_coverage(line_marked)
html = <<EOHTML
filename | #{file} |
coverage | #{percent} |
#{result}" end def create_file(file, line_marked) output_filename = mk_filename(file) puts "outputting #{output_filename.inspect}" body = format_overview(file, line_marked) + format_lines(line_marked) title = file + " - coverage" css = <<EOCSS body { background-color: rgb(180, 180, 180); } div.marked { background-color: rgb(185, 200, 200); } div.overview { border-bottom: 8px solid black; } EOCSS html = <<EOHTML #{title} #{css} #{body} EOHTML File.open(output_filename, "w+") do |f| f.puts html end end end end
SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
module COVERAGE__
COVER = {}
def self.trace_func(event, file, line, id, binding, klass)
case event
when ‘c-call’, ‘c-return’, ‘class’
return
end
COVER[file] ||=
COVER[file][line] ||= 0
COVER[file][line] += 1
end
END {
set_trace_func(nil)
printer = PrettyCoverage::HTML.new
COVER.each do |file, lines|
next if SCRIPT_LINES__.has_key?(file) == false
lines = SCRIPT_LINES__[file]
covers = COVER[file]
line_status =
0.upto(lines.size - 1) do |c|
line = lines[c].chomp
marked = false
if covers[c + 1]
marked = true
elsif /^\s*(?:begin\s*(?:#.)?|ensure\s(?:#.)?|else\s(?:#.)?)$/ =~ line and covers[c + 1 + 1]
covers[c + 1] = covers[c + 1 + 1]
marked = true
elsif /^\s(?:end|})\s*$/ =~ line && covers[c + 1 - 1]
covers[c + 1] = covers[c + 1 - 1]
marked = true
end
line_status << [line, marked]
end
printer.add_file(file, line_status)
end
printer.execute
}
set_trace_func(COVERAGE__.method(:trace_func).to_proc)
end
“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag
news:pan.2004.02.04.12.36.20.824346@adslhome.dk…
“Simon Strandgaard” neoneye@adslhome.dk schrieb im Newsbeitrag
news:pan.2004.02.04.09.26.42.335507@adslhome.dk…If I do “cat report.txt” then my terminal just scrolls for 10
seconds,
which is much larger than what my terminal history can remember.
If I pipe it into “less” then the coloring disappears. How do you
view
ANSI files?less -r
Thanks…
I have done some improvements to the original ‘coverage.rb’, so that
HTML is now generated. For an example have a look at:
http://neoneye.dk/parser.rb.coverage.htmlAs you may notice comments/arrays appears as if they are not
executed!
How can I fix this?Dunno whether it’s worth the effort. I guess, comments could be fixed
by
identifying regions of comment lines and marking them as reached if
the
line above and below is reached. For arrays you could try to find the
matching “[” for a closing “]” and mark all lines in between if the
line
of the closing “]” is marked.Apart from that: nice output!
Ok… I now propagate the marked status to comments… output is much
better
now. Still Arrays/Hashes/=begin=end needs to be fixed.Try compare the new output agains the old:
http://neoneye.dk/parser.rb.coverage.ver2.htmlSuggestions for improvements is welcome… also patches is welcome.
Apparently “end” lines are not reported so the comment is marked “not
reached” in line 72. Maybe it’s better to check the reached status of the
last line before a comment region. This should also be easier to do.
Regards
robert
For the courius; try to execute the attached code by
requiring it on the commandline.
ruby -rcoverage helloworld.rb
That should output a ‘helloworld.rb.coverage.html’ file.–
Simon Strandgaardmodule PrettyCoverage
#{result}
class HTML
def initialize
@files = {}
end
def execute
puts “execute”
create_file_index
@files.each{|file, line_marked|
create_file(file, line_marked)
}
end
def mk_filename(name)
name+“.coverage.html”
end
def create_file_index
output_filename = “index.html”
rows =
@files.each{|file, line_marked|
filename = mk_filename(file)
rows << “<a href="#{filename}">#{file}”
}
result = rows.join(“\n”)
body = “”
title = “coverage”
css = <<EOCSS
body {
background-color: rgb(180, 180, 180);
}
div.marked {
background-color: rgb(185, 200, 200);
}
div.overview {
border-bottom: 8px solid black;
}
EOCSS
html = <<EOHTML #{title} #{css} #{body} EOHTML File.open(output_filename, "w+") do |f| f.puts html end end def add_file(file, line_marked) percent = calc_coverage(line_marked) printf("file=#{file} coverage=%02.1f%\n", percent)# comments and empty lines.. we must # propagate marked-value backwards line_marked << ["", false] (line_marked.size).downto(1) do |index| line, marked = line_marked[index-1] next_line, next_marked = line_marked[index] if line =~ /^\s*(#|$)/ and marked == false marked = next_marked #line = "hest" + line line_marked[index-1] = [line, marked] end end line_marked.pop @files[file] = line_marked end def calc_coverage(line_marked) marked = line_marked.transpose[1] n = marked.inject(0) {|r, i| (i) ? (r+1) : r } percent = n.to_f * 100 / marked.size end def format_overview(file, line_marked) percent = "%02.1f" % calc_coverage(line_marked) html = <<EOHTML
EOHTML html end def format_lines(line_marked) result = "" last = nil end_of_div = "" format_line = "%#{line_marked.size.to_s.size}d" line_no = 1 line_marked.each {|(line, marked)| if marked != last result += end_of_div case marked when true result += "
filename #{file} coverage #{percent} " end_of_div = "" when false end_of_div = "" end end result += (format_line % line_no) + " " + line + "\n" last = marked line_no += 1 } result += end_of_div "#{result}" end def create_file(file, line_marked) output_filename = mk_filename(file) puts "outputting #{output_filename.inspect}" body = format_overview(file, line_marked) + format_lines(line_marked) title = file + " - coverage" css = <<EOCSS body { background-color: rgb(180, 180, 180); } div.marked { background-color: rgb(185, 200, 200); } div.overview { border-bottom: 8px solid black; } EOCSS html = <<EOHTML #{title} #{css} #{body} EOHTML File.open(output_filename, "w+") do |f| f.puts html end end end endSCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
module COVERAGE__
COVER = {}
def self.trace_func(event, file, line, id, binding, klass)
case event
when ‘c-call’, ‘c-return’, ‘class’
return
end
COVER[file] ||=
COVER[file][line] ||= 0
COVER[file][line] += 1
endEND {
set_trace_func(nil)
printer = PrettyCoverage::HTML.new
COVER.each do |file, lines|
next if SCRIPT_LINES__.has_key?(file) == false
lines = SCRIPT_LINES__[file]
covers = COVER[file]
line_status =
0.upto(lines.size - 1) do |c|
line = lines[c].chomp
marked = false
if covers[c + 1]
marked = true
elsif
/^\s*(?:begin\s*(?:#.)?|ensure\s(?:#.)?|else\s(?:#.*)?)$/ =~ line and
covers[c + 1 + 1]
On Wed, 04 Feb 2004 11:22:05 +0100, Robert Klemme wrote:
On Wed, 04 Feb 2004 00:46:20 +0900, nobu.nokad wrote:
At Wed, 4 Feb 2004 00:30:04 +0900, > >> > Simon Strandgaard wrote:
covers[c + 1] = covers[c + 1 + 1]
marked = true
elsif /^\s*(?:end|})\s*$/ =~ line && covers[c + 1 - 1]
covers[c + 1] = covers[c + 1 - 1]
marked = true
end
line_status << [line, marked]
end
printer.add_file(file, line_status)
end
printer.execute
}set_trace_func(COVERAGE__.method(:trace_func).to_proc)
end