insurance 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/railscov +85 -0
- data/extconf.rb +3 -0
- data/insurance_tracer.c +99 -0
- data/lib/insurance.rb +9 -0
- data/lib/insurance/analyzer.rb +82 -0
- data/lib/insurance/formatter.rb +42 -0
- data/lib/insurance/generators/rails/insurance/insurance_generator.rb +12 -0
- data/lib/insurance/generators/rails/insurance/templates/insurance.rake +7 -0
- data/lib/insurance/generators/rails/loader.rb +17 -0
- data/lib/insurance/source_file.rb +35 -0
- data/lib/insurance/templates/code-page.rhtml +73 -0
- data/lib/insurance/templates/index.rhtml +72 -0
- data/test/test_settracefunc.rb +140 -0
- metadata +67 -0
data/bin/railscov
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'insurance'
|
5
|
+
rescue LoadError
|
6
|
+
require 'rubygems'
|
7
|
+
require 'insurance'
|
8
|
+
end
|
9
|
+
require 'optparse'
|
10
|
+
|
11
|
+
options = {}
|
12
|
+
opts = OptionParser.new do |opts|
|
13
|
+
opts.banner = <<-EOF
|
14
|
+
Insurance Rails Runner #{Insurance::VERSION}, #{Insurance::RELEASE_DATE}
|
15
|
+
Usage: railscov [options]
|
16
|
+
EOF
|
17
|
+
|
18
|
+
opts.separator ''
|
19
|
+
opts.on('-A', '--apply-to DIRECTORY',
|
20
|
+
'Create a Rake task for running the ',
|
21
|
+
'Insurance analyzer.',
|
22
|
+
'Currently only works with Rails apps.'
|
23
|
+
) { |value| options[:apply_to] = value }
|
24
|
+
|
25
|
+
opts.separator ''
|
26
|
+
opts.on_tail('-h', '--help', 'Show this message') do
|
27
|
+
puts opts
|
28
|
+
exit
|
29
|
+
end
|
30
|
+
opts.on_tail('--version', 'Show version') do
|
31
|
+
puts "Insurance #{Insurance::VERSION}, #{Insurance::RELEASE_DATE}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
opts.parse! ARGV
|
35
|
+
|
36
|
+
if options[:apply_to]
|
37
|
+
require 'insurance/generators/rails/loader'
|
38
|
+
InsuranceLoader::Generators::RailsLoader.load! options
|
39
|
+
exit
|
40
|
+
end
|
41
|
+
|
42
|
+
unless File.exist?('config/environment.rb')
|
43
|
+
puts 'Please run railscov from your RAILS_ROOT'
|
44
|
+
exit
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
# We modify Test::Unit::TestCase so that tracing is only turned on
|
49
|
+
# when executing a test. This avoids tracing framework loading
|
50
|
+
# and speeds things up by a great deal.
|
51
|
+
|
52
|
+
require 'test/unit'
|
53
|
+
module Test
|
54
|
+
module Unit
|
55
|
+
include Assertions
|
56
|
+
class TestCase
|
57
|
+
def run(result)
|
58
|
+
yield(STARTED, name)
|
59
|
+
@_result = result
|
60
|
+
begin
|
61
|
+
setup
|
62
|
+
Insurance.set_trace_func Insurance::RailsAnalyzer.method(:line_trace_func).to_proc
|
63
|
+
__send__(@method_name)
|
64
|
+
rescue AssertionFailedError => e
|
65
|
+
add_failure(e.message, e.backtrace)
|
66
|
+
rescue StandardError, ScriptError
|
67
|
+
add_error($!)
|
68
|
+
ensure
|
69
|
+
Insurance.set_trace_func nil
|
70
|
+
begin
|
71
|
+
teardown
|
72
|
+
rescue AssertionFailedError => e
|
73
|
+
add_failure(e.message, e.backtrace)
|
74
|
+
rescue StandardError, ScriptError
|
75
|
+
add_error($!)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
result.add_run
|
79
|
+
yield(FINISHED, name)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
Insurance::RailsAnalyzer.run(Dir['test/unit/*.rb'] + Dir['test/functional/*.rb'])
|
data/extconf.rb
ADDED
data/insurance_tracer.c
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include <node.h>
|
3
|
+
#include <env.h>
|
4
|
+
|
5
|
+
static int tracing = 0;
|
6
|
+
static int am_tracing = 0;
|
7
|
+
|
8
|
+
static char *
|
9
|
+
get_event_name(rb_event_t event)
|
10
|
+
{
|
11
|
+
switch (event) {
|
12
|
+
case RUBY_EVENT_LINE:
|
13
|
+
return "line";
|
14
|
+
case RUBY_EVENT_CLASS:
|
15
|
+
return "class";
|
16
|
+
case RUBY_EVENT_END:
|
17
|
+
return "end";
|
18
|
+
case RUBY_EVENT_CALL:
|
19
|
+
return "call";
|
20
|
+
case RUBY_EVENT_RETURN:
|
21
|
+
return "return";
|
22
|
+
case RUBY_EVENT_C_CALL:
|
23
|
+
return "c-call";
|
24
|
+
case RUBY_EVENT_C_RETURN:
|
25
|
+
return "c-return";
|
26
|
+
case RUBY_EVENT_RAISE:
|
27
|
+
return "raise";
|
28
|
+
default:
|
29
|
+
return "unknown";
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
static VALUE cov_tracer = 0;
|
34
|
+
|
35
|
+
static void
|
36
|
+
insurance_trace_func(event, node, self, id, klass)
|
37
|
+
rb_event_t event;
|
38
|
+
NODE *node;
|
39
|
+
VALUE self;
|
40
|
+
ID id;
|
41
|
+
VALUE klass;
|
42
|
+
{
|
43
|
+
int state, raised;
|
44
|
+
NODE *node_save;
|
45
|
+
VALUE srcfile;
|
46
|
+
struct FRAME *prev;
|
47
|
+
static int counting = 0;
|
48
|
+
|
49
|
+
if (tracing) return;
|
50
|
+
if (id == ID_ALLOCATOR) return;
|
51
|
+
tracing = 1;
|
52
|
+
if (node) {
|
53
|
+
ruby_current_node = node;
|
54
|
+
ruby_frame->node = node;
|
55
|
+
ruby_sourcefile = node->nd_file;
|
56
|
+
ruby_sourceline = nd_line(node);
|
57
|
+
}
|
58
|
+
|
59
|
+
srcfile = rb_str_new2(ruby_sourcefile?ruby_sourcefile:"(ruby)");
|
60
|
+
rb_funcall(cov_tracer, rb_intern("call"), 3, rb_str_new2(get_event_name(event)), srcfile, INT2FIX(ruby_sourceline));
|
61
|
+
tracing = 0;
|
62
|
+
}
|
63
|
+
|
64
|
+
static VALUE
|
65
|
+
is_tracing()
|
66
|
+
{
|
67
|
+
if (am_tracing == 0) {
|
68
|
+
return Qfalse;
|
69
|
+
}
|
70
|
+
return Qtrue;
|
71
|
+
}
|
72
|
+
|
73
|
+
static VALUE
|
74
|
+
set_insurance_trace_func(obj, trace)
|
75
|
+
VALUE obj, trace;
|
76
|
+
{
|
77
|
+
if (NIL_P(trace)) {
|
78
|
+
cov_tracer = 0;
|
79
|
+
am_tracing = 0;
|
80
|
+
rb_remove_event_hook(insurance_trace_func);
|
81
|
+
return Qnil;
|
82
|
+
}
|
83
|
+
|
84
|
+
cov_tracer = trace;
|
85
|
+
am_tracing = 1;
|
86
|
+
rb_add_event_hook(insurance_trace_func, RUBY_EVENT_LINE);
|
87
|
+
return trace;
|
88
|
+
}
|
89
|
+
|
90
|
+
|
91
|
+
void
|
92
|
+
Init_insurance_tracer()
|
93
|
+
{
|
94
|
+
VALUE mProf;
|
95
|
+
|
96
|
+
mProf = rb_define_module("Insurance");
|
97
|
+
rb_define_module_function(mProf, "set_trace_func", set_insurance_trace_func, 1);
|
98
|
+
rb_define_module_function(mProf, "is_tracing?", is_tracing, 0);
|
99
|
+
}
|
data/lib/insurance.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
module Insurance
|
3
|
+
FILELIST = {}
|
4
|
+
|
5
|
+
END {
|
6
|
+
Insurance.set_trace_func nil
|
7
|
+
|
8
|
+
Dir.mkdir('insurance') unless File.exist?('insurance')
|
9
|
+
|
10
|
+
Insurance::Formatter.run(Insurance::FILELIST)
|
11
|
+
}
|
12
|
+
|
13
|
+
class Analyzer
|
14
|
+
def self.line_trace_func(event, file, line)
|
15
|
+
# case event
|
16
|
+
# when 'c-call', 'c-return'
|
17
|
+
# return
|
18
|
+
# end
|
19
|
+
|
20
|
+
if (full_path = self.filter(file))
|
21
|
+
FILELIST[full_path] ||= SourceFile.new(full_path)
|
22
|
+
FILELIST[full_path] << line
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.filter(file)
|
27
|
+
file
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.run(files)
|
31
|
+
Insurance.set_trace_func self.method(:line_trace_func).to_proc
|
32
|
+
files.each { |f| load f }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class RailsAnalyzer < Analyzer
|
37
|
+
@@dir_regexp = Regexp.new("^#{Dir.pwd}/(?:lib|app/(?:models|controllers))/")
|
38
|
+
@@_path_cache = {}
|
39
|
+
|
40
|
+
def self.filter(file)
|
41
|
+
begin
|
42
|
+
full_path = @@_path_cache[file] || (@@_path_cache[file] = File.expand_path(file))
|
43
|
+
if @@dir_regexp =~ full_path
|
44
|
+
pwd = Dir.pwd
|
45
|
+
return full_path[(full_path.index(pwd)+pwd.length+1)..-1]
|
46
|
+
else
|
47
|
+
return false
|
48
|
+
end
|
49
|
+
rescue
|
50
|
+
return false
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.run(files)
|
55
|
+
# The rails analyzer does not need to set the trace func, because that is
|
56
|
+
# done in the perversion of Test::Unit::TestCase.
|
57
|
+
|
58
|
+
# Since we flip tracing on only right before a test is executed, to avoid
|
59
|
+
# tracing the entire framework at all times (very slow), we need to pre-load
|
60
|
+
# all of the application's models and controllers so that we can trace things
|
61
|
+
# at the class level. This is just easier to do than to try and figure out
|
62
|
+
# what should really be marked as hit in the output stage.
|
63
|
+
|
64
|
+
pipe = IO.popen('-', 'w+')
|
65
|
+
if pipe
|
66
|
+
Insurance::FILELIST.merge!(YAML::load(pipe.read))
|
67
|
+
files.each { |f| load f }
|
68
|
+
else
|
69
|
+
at_exit {
|
70
|
+
Insurance.set_trace_func nil
|
71
|
+
puts Insurance::FILELIST.to_yaml
|
72
|
+
exit!
|
73
|
+
}
|
74
|
+
|
75
|
+
require 'config/environment'
|
76
|
+
Insurance.set_trace_func self.method(:line_trace_func).to_proc
|
77
|
+
require 'application'
|
78
|
+
(Dir['app/models/*.rb'] + Dir['app/controllers/*.rb']).each { |f| load f }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'syntax'
|
3
|
+
require 'syntax/convertors/html'
|
4
|
+
|
5
|
+
module Insurance
|
6
|
+
class Formatter
|
7
|
+
include ERB::Util
|
8
|
+
|
9
|
+
def self.run(filelist)
|
10
|
+
files = filelist.keys.sort
|
11
|
+
|
12
|
+
project_name = File.basename Dir.pwd
|
13
|
+
|
14
|
+
File.open("insurance/index.html", 'w') do |f|
|
15
|
+
f.write ERB.new(File.read("#{File.dirname(__FILE__)}/templates/index.rhtml")).result(binding)
|
16
|
+
puts "Wrote insurance/index.html"
|
17
|
+
end
|
18
|
+
|
19
|
+
filelist.each do |file, sf|
|
20
|
+
sf.post_analyze!
|
21
|
+
|
22
|
+
file_under_test = sf.name
|
23
|
+
percentage = sf.coverage_percent
|
24
|
+
|
25
|
+
File.open("insurance/#{sf.name.gsub('/', '-')}.html", 'w') do |f|
|
26
|
+
contents = File.open(sf.name, 'r').readlines
|
27
|
+
body = "<pre class=\"ruby\">\n"
|
28
|
+
contents.each_with_index do |line, num|
|
29
|
+
unless sf.lines.include?(num + 1)
|
30
|
+
body << "#{'%3s' % (num + 1).to_s} <span class=\"unhit\">#{Syntax::Convertors::HTML.for_syntax('ruby').convert(line.chomp, false)}</span>\n"
|
31
|
+
else
|
32
|
+
body << "#{'%3s' % (num + 1).to_s} #{Syntax::Convertors::HTML.for_syntax('ruby').convert(line, false)}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
body << "</pre>"
|
36
|
+
f.write ERB.new(File.read("#{File.dirname(__FILE__)}/templates/code-page.rhtml")).result(binding)
|
37
|
+
puts "Wrote insurance/#{sf.name.gsub('/', '-')}.html"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class InsuranceGenerator < Rails::Generator::NamedBase
|
2
|
+
def initialize(runtime_args, runtime_options={})
|
3
|
+
super
|
4
|
+
end
|
5
|
+
|
6
|
+
def manifest
|
7
|
+
record do |m|
|
8
|
+
m.directory 'lib/tasks'
|
9
|
+
m.template 'insurance.rake', File.join('lib', 'tasks', 'insurance.rake')
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module InsuranceLoader
|
2
|
+
module Generators
|
3
|
+
class RailsLoader
|
4
|
+
def self.load!(options)
|
5
|
+
require "#{options[:apply_to]}/config/environment"
|
6
|
+
require "rails_generator"
|
7
|
+
require "rails_generator/scripts/generate"
|
8
|
+
|
9
|
+
Rails::Generator::Base.sources << Rails::Generator::PathSource.new(
|
10
|
+
:insurance, File.dirname(__FILE__))
|
11
|
+
|
12
|
+
args = ['insurance', 'insurance', 'insurance']
|
13
|
+
Rails::Generator::Scripts::Generate.new.run(args)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Insurance
|
2
|
+
class SourceFile
|
3
|
+
attr_reader :name
|
4
|
+
attr_reader :lines
|
5
|
+
attr_reader :coverage_percent
|
6
|
+
|
7
|
+
def initialize(name)
|
8
|
+
@name = name
|
9
|
+
@lines = []
|
10
|
+
@coverage_percent = 0
|
11
|
+
end
|
12
|
+
|
13
|
+
def <<(line)
|
14
|
+
@lines << line unless @lines.include?(line)
|
15
|
+
end
|
16
|
+
|
17
|
+
# This marks crufty crap that isn't important, like 'end', and whitespace.
|
18
|
+
def post_analyze!
|
19
|
+
contents = File.open(self.name, 'r').readlines
|
20
|
+
contents.each_with_index do |line, num|
|
21
|
+
sline = line.strip
|
22
|
+
lines << num + 1 if sline.empty?
|
23
|
+
lines << num + 1 if sline =~ /^#/
|
24
|
+
lines << num + 1 if sline =~ /^\s*(?:end|\})\s*(?:#.*)?$/
|
25
|
+
lines << num + 1 if sline =~ /^(public|private|protected)/
|
26
|
+
lines << num + 1 if sline =~ /^(?:begin\s*(?:#.*)?|ensure\s*(?:#.*)?|else\s*(?:#.*)?)$/
|
27
|
+
lines << num + 1 if sline =~ /^(?:rescue)/
|
28
|
+
lines << num + 1 if sline =~ /^case\s*(?:#.*)?$/
|
29
|
+
lines << num + 1 if sline =~ /^(\)|\]|\})(?:#.*)?$/
|
30
|
+
end
|
31
|
+
|
32
|
+
@coverage_percent = (@lines.size.to_f / contents.size.to_f) * 100.0
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
3
|
+
<html>
|
4
|
+
<head>
|
5
|
+
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
|
6
|
+
<title><%= file_under_test %></title>
|
7
|
+
<style type="text/css" media="screen">
|
8
|
+
/* <![CDATA[ */
|
9
|
+
body {
|
10
|
+
font-size: small;
|
11
|
+
}
|
12
|
+
|
13
|
+
th { text-align: left; }
|
14
|
+
|
15
|
+
.ruby .normal {}
|
16
|
+
.ruby .comment { color: #bfbfbf; }
|
17
|
+
.ruby .keyword { color: #FF5600; font-weight: bold; }
|
18
|
+
.ruby .method { color: #21439C; }
|
19
|
+
.ruby .class { color: #21439C; }
|
20
|
+
.ruby .module { color: #21439C; }
|
21
|
+
.ruby .punct { color: #21439C; font-weight: bold; }
|
22
|
+
.ruby .symbol { color: #21439C; }
|
23
|
+
.ruby .string { color: #00A33F; }
|
24
|
+
.ruby .char { color: #00A33F; }
|
25
|
+
.ruby .ident { color: #21439C; }
|
26
|
+
.ruby .constant { color: #A535AE; }
|
27
|
+
.ruby .regex { color: #990000; }
|
28
|
+
.ruby .number { }
|
29
|
+
.ruby .attribute { }
|
30
|
+
.ruby .global { }
|
31
|
+
.ruby .expr { }
|
32
|
+
|
33
|
+
.unhit { background: #FFC6C6; }
|
34
|
+
|
35
|
+
.right { text-align: right; }
|
36
|
+
|
37
|
+
#code-tree {
|
38
|
+
float: left;
|
39
|
+
width: 30%;
|
40
|
+
}
|
41
|
+
|
42
|
+
#graph, #code {
|
43
|
+
margin-left: 30%;
|
44
|
+
}
|
45
|
+
|
46
|
+
#graph {
|
47
|
+
padding-left: 35px;
|
48
|
+
}
|
49
|
+
|
50
|
+
/* ]]> */
|
51
|
+
</style>
|
52
|
+
|
53
|
+
</head>
|
54
|
+
<body>
|
55
|
+
<div id="header">
|
56
|
+
<h1>Insurance - <%= project_name %></h1>
|
57
|
+
</div>
|
58
|
+
<div id="code-tree">
|
59
|
+
<table>
|
60
|
+
<% files.each do |f| %>
|
61
|
+
<tr>
|
62
|
+
<td><a href="<%= "#{f.gsub('/', '-')}.html" %>"><%= f %></a></td>
|
63
|
+
<td></td>
|
64
|
+
</tr>
|
65
|
+
<% end %>
|
66
|
+
</table>
|
67
|
+
</div>
|
68
|
+
<div id="code">
|
69
|
+
<h2><%= file_under_test %></h2>
|
70
|
+
<%= body %>
|
71
|
+
</div>
|
72
|
+
</body>
|
73
|
+
</html>
|
@@ -0,0 +1,72 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
3
|
+
<html>
|
4
|
+
<head>
|
5
|
+
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
|
6
|
+
<title>Insurance - <%= project_name %></title>
|
7
|
+
<style type="text/css" media="screen">
|
8
|
+
/* <![CDATA[ */
|
9
|
+
body {
|
10
|
+
font-size: small;
|
11
|
+
}
|
12
|
+
|
13
|
+
th { text-align: left; }
|
14
|
+
|
15
|
+
.ruby .normal {}
|
16
|
+
.ruby .comment { color: #bfbfbf; }
|
17
|
+
.ruby .keyword { color: #FF5600; font-weight: bold; }
|
18
|
+
.ruby .method { color: #21439C; }
|
19
|
+
.ruby .class { color: #21439C; }
|
20
|
+
.ruby .module { color: #21439C; }
|
21
|
+
.ruby .punct { color: #21439C; font-weight: bold; }
|
22
|
+
.ruby .symbol { color: #21439C; }
|
23
|
+
.ruby .string { color: #00A33F; }
|
24
|
+
.ruby .char { color: #00A33F; }
|
25
|
+
.ruby .ident { color: #21439C; }
|
26
|
+
.ruby .constant { color: #A535AE; }
|
27
|
+
.ruby .regex { color: #990000; }
|
28
|
+
.ruby .number { }
|
29
|
+
.ruby .attribute { }
|
30
|
+
.ruby .global { }
|
31
|
+
.ruby .expr { }
|
32
|
+
|
33
|
+
.unhit { background: #FFC6C6; }
|
34
|
+
|
35
|
+
.right { text-align: right; }
|
36
|
+
|
37
|
+
#code-tree {
|
38
|
+
float: left;
|
39
|
+
width: 30%;
|
40
|
+
}
|
41
|
+
|
42
|
+
#graph, #code {
|
43
|
+
margin-left: 30%;
|
44
|
+
}
|
45
|
+
|
46
|
+
#graph {
|
47
|
+
padding-left: 35px;
|
48
|
+
}
|
49
|
+
|
50
|
+
/* ]]> */
|
51
|
+
</style>
|
52
|
+
|
53
|
+
</head>
|
54
|
+
<body>
|
55
|
+
<div id="header">
|
56
|
+
<h1>Insurance - <%= project_name %></h1>
|
57
|
+
</div>
|
58
|
+
<div id="code-tree">
|
59
|
+
<table>
|
60
|
+
<% files.each do |f| %>
|
61
|
+
<tr>
|
62
|
+
<td><a href="<%= "#{f.gsub('/', '-')}.html" %>"><%= f %></a></td>
|
63
|
+
<td></td>
|
64
|
+
</tr>
|
65
|
+
<% end %>
|
66
|
+
</table>
|
67
|
+
</div>
|
68
|
+
<div id="code">
|
69
|
+
The next release will have much more information here. I promise!
|
70
|
+
</div>
|
71
|
+
</body>
|
72
|
+
</html>
|
@@ -0,0 +1,140 @@
|
|
1
|
+
# Taken from Ruby 1.8.3's test_settracefunc.rb
|
2
|
+
require 'test/unit'
|
3
|
+
require 'insurance'
|
4
|
+
|
5
|
+
class TestSetTraceFunc < Test::Unit::TestCase
|
6
|
+
def foo; end;
|
7
|
+
|
8
|
+
def bar
|
9
|
+
events = []
|
10
|
+
Insurance.set_trace_func(Proc.new { |event, file, lineno|
|
11
|
+
events << [event, lineno]
|
12
|
+
})
|
13
|
+
return events
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_event
|
17
|
+
events = []
|
18
|
+
Insurance.set_trace_func(Proc.new { |event, file, lineno|
|
19
|
+
events << [event, lineno]
|
20
|
+
})
|
21
|
+
a = 1
|
22
|
+
foo
|
23
|
+
a
|
24
|
+
b = 1 + 2
|
25
|
+
if b == 3
|
26
|
+
case b
|
27
|
+
when 2
|
28
|
+
c = "b == 2"
|
29
|
+
when 3
|
30
|
+
c = "b == 3"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
begin
|
34
|
+
raise "error"
|
35
|
+
rescue
|
36
|
+
end
|
37
|
+
eval("class Foo; end")
|
38
|
+
Insurance.set_trace_func nil
|
39
|
+
|
40
|
+
assert_equal(["line", 21],
|
41
|
+
events.shift) # a = 1
|
42
|
+
assert_equal(["line", 22],
|
43
|
+
events.shift) # foo
|
44
|
+
assert_equal(["call", 6],
|
45
|
+
events.shift) # foo
|
46
|
+
assert_equal(["return", 6],
|
47
|
+
events.shift) # foo
|
48
|
+
assert_equal(["line", 23],
|
49
|
+
events.shift) # a
|
50
|
+
assert_equal(["line", 24],
|
51
|
+
events.shift) # b = 1 + 2
|
52
|
+
assert_equal(["c-call", 24],
|
53
|
+
events.shift) # 1 + 2
|
54
|
+
assert_equal(["c-return", 24],
|
55
|
+
events.shift) # 1 + 2
|
56
|
+
assert_equal(["line", 25],
|
57
|
+
events.shift) # if b == 3
|
58
|
+
assert_equal(["line", 25],
|
59
|
+
events.shift) # if b == 3
|
60
|
+
assert_equal(["c-call", 25],
|
61
|
+
events.shift) # b == 3
|
62
|
+
assert_equal(["c-return", 25],
|
63
|
+
events.shift) # b == 3
|
64
|
+
assert_equal(["line", 26],
|
65
|
+
events.shift) # case b
|
66
|
+
assert_equal(["line", 27],
|
67
|
+
events.shift) # when 2
|
68
|
+
assert_equal(["c-call", 27],
|
69
|
+
events.shift) # when 2
|
70
|
+
assert_equal(["c-call", 27],
|
71
|
+
events.shift) # when 2
|
72
|
+
assert_equal(["c-return", 27],
|
73
|
+
events.shift) # when 2
|
74
|
+
assert_equal(["c-return", 27],
|
75
|
+
events.shift) # when 2
|
76
|
+
assert_equal(["line", 29],
|
77
|
+
events.shift) # when 3
|
78
|
+
assert_equal(["c-call", 29],
|
79
|
+
events.shift) # when 3
|
80
|
+
assert_equal(["c-return", 29],
|
81
|
+
events.shift) # when 3
|
82
|
+
assert_equal(["line", 30],
|
83
|
+
events.shift) # c = "b == 3"
|
84
|
+
assert_equal(["line", 33],
|
85
|
+
events.shift) # begin
|
86
|
+
assert_equal(["line", 34],
|
87
|
+
events.shift) # raise "error"
|
88
|
+
assert_equal(["c-call", 34],
|
89
|
+
events.shift) # raise "error"
|
90
|
+
assert_equal(["c-call", 34],
|
91
|
+
events.shift) # raise "error"
|
92
|
+
assert_equal(["c-call", 34],
|
93
|
+
events.shift) # raise "error"
|
94
|
+
assert_equal(["c-return", 34],
|
95
|
+
events.shift) # raise "error"
|
96
|
+
assert_equal(["c-return", 34],
|
97
|
+
events.shift) # raise "error"
|
98
|
+
assert_equal(["c-call", 34],
|
99
|
+
events.shift) # raise "error"
|
100
|
+
assert_equal(["c-return", 34],
|
101
|
+
events.shift) # raise "error"
|
102
|
+
assert_equal(["c-call", 34],
|
103
|
+
events.shift) # raise "error"
|
104
|
+
assert_equal(["c-return", 34],
|
105
|
+
events.shift) # raise "error"
|
106
|
+
assert_equal(["raise", 34],
|
107
|
+
events.shift) # raise "error"
|
108
|
+
assert_equal(["c-return", 34],
|
109
|
+
events.shift) # raise "error"
|
110
|
+
assert_equal(["line", 37],
|
111
|
+
events.shift) # eval(<<EOF)
|
112
|
+
assert_equal(["c-call", 37],
|
113
|
+
events.shift) # eval(<<EOF)
|
114
|
+
assert_equal(["line", 1],
|
115
|
+
events.shift) # class Foo
|
116
|
+
assert_equal(["c-call", 1],
|
117
|
+
events.shift) # class Foo
|
118
|
+
assert_equal(["c-return", 1],
|
119
|
+
events.shift) # class Foo
|
120
|
+
assert_equal(["class", 1],
|
121
|
+
events.shift) # class Foo
|
122
|
+
assert_equal(["end", 1],
|
123
|
+
events.shift) # class Foo
|
124
|
+
assert_equal(["c-return", 37],
|
125
|
+
events.shift) # eval(<<EOF)
|
126
|
+
assert_equal(["line", 38],
|
127
|
+
events.shift) # set_trace_func nil
|
128
|
+
assert_equal(["c-call", 38],
|
129
|
+
events.shift) # set_trace_func nil
|
130
|
+
assert_equal([], events)
|
131
|
+
|
132
|
+
events = bar
|
133
|
+
Insurance.set_trace_func(nil)
|
134
|
+
assert_equal(["line", 13], events.shift)
|
135
|
+
assert_equal(["return", 9], events.shift)
|
136
|
+
assert_equal(["line", 133], events.shift)
|
137
|
+
assert_equal(["c-call", 133], events.shift)
|
138
|
+
assert_equal([], events)
|
139
|
+
end
|
140
|
+
end
|
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.6
|
3
|
+
specification_version: 1
|
4
|
+
name: insurance
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: "0.1"
|
7
|
+
date: 2005-10-28
|
8
|
+
summary: Code coverage analysis package.
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: scott@elitists.net
|
12
|
+
homepage: http://lunchboxsoftware.com/insurance
|
13
|
+
rubyforge_project: insurance
|
14
|
+
description: Insurance is a code coverage analysis utility.
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: false
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
-
|
22
|
+
- ">"
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 0.0.0
|
25
|
+
version:
|
26
|
+
platform: ruby
|
27
|
+
authors:
|
28
|
+
- Scott Barron
|
29
|
+
files:
|
30
|
+
- extconf.rb
|
31
|
+
- insurance_tracer.c
|
32
|
+
- bin/railscov
|
33
|
+
- lib/insurance
|
34
|
+
- lib/insurance.rb
|
35
|
+
- lib/insurance/analyzer.rb
|
36
|
+
- lib/insurance/formatter.rb
|
37
|
+
- lib/insurance/generators
|
38
|
+
- lib/insurance/source_file.rb
|
39
|
+
- lib/insurance/templates
|
40
|
+
- lib/insurance/generators/rails
|
41
|
+
- lib/insurance/generators/rails/insurance
|
42
|
+
- lib/insurance/generators/rails/loader.rb
|
43
|
+
- lib/insurance/generators/rails/insurance/insurance_generator.rb
|
44
|
+
- lib/insurance/generators/rails/insurance/templates
|
45
|
+
- lib/insurance/generators/rails/insurance/templates/insurance.rake
|
46
|
+
- lib/insurance/templates/code-page.rhtml
|
47
|
+
- lib/insurance/templates/index.rhtml
|
48
|
+
- test/test_settracefunc.rb
|
49
|
+
test_files: []
|
50
|
+
rdoc_options: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
executables:
|
53
|
+
- railscov
|
54
|
+
extensions:
|
55
|
+
- extconf.rb
|
56
|
+
requirements: []
|
57
|
+
dependencies:
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: syntax
|
60
|
+
version_requirement:
|
61
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
62
|
+
requirements:
|
63
|
+
-
|
64
|
+
- ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: 1.0.0
|
67
|
+
version:
|