rcov 0.8.1.2.0 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. data/BLURB +2 -40
  2. data/LICENSE +2 -5
  3. data/Rakefile +32 -106
  4. data/THANKS +14 -0
  5. data/bin/rcov +277 -1090
  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/{rcov.el → editor-extensions/rcov.el} +0 -0
  11. data/{rcov.vim → editor-extensions/rcov.vim} +0 -0
  12. data/ext/rcovrt/1.8/callsite.c +216 -0
  13. data/ext/rcovrt/1.8/rcovrt.c +287 -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 +12 -2
  17. data/lib/rcov.rb +13 -968
  18. data/lib/rcov/call_site_analyzer.rb +225 -0
  19. data/lib/rcov/code_coverage_analyzer.rb +268 -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 +334 -0
  23. data/lib/rcov/formatters.rb +13 -0
  24. data/lib/rcov/formatters/base_formatter.rb +173 -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 +16 -17
  33. data/lib/rcov/rcovtask.rb +21 -22
  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 +5 -8
  42. data/setup.rb +5 -2
  43. data/test/{sample_01.rb → assets/sample_01.rb} +0 -0
  44. data/test/{sample_02.rb → assets/sample_02.rb} +0 -0
  45. data/test/{sample_03.rb → assets/sample_03.rb} +0 -0
  46. data/test/{sample_04.rb → assets/sample_04.rb} +0 -0
  47. data/test/{sample_05-new.rb → assets/sample_05-new.rb} +0 -0
  48. data/test/{sample_05-old.rb → assets/sample_05-old.rb} +0 -0
  49. data/test/{sample_05.rb → assets/sample_05.rb} +0 -0
  50. data/test/{test_CallSiteAnalyzer.rb → call_site_analyzer_test.rb} +57 -81
  51. data/test/{test_CodeCoverageAnalyzer.rb → code_coverage_analyzer_test.rb} +71 -35
  52. data/test/{test_FileStatistics.rb → file_statistics_test.rb} +34 -36
  53. data/test/{test_functional.rb → functional_test.rb} +21 -35
  54. metadata +91 -69
  55. data/CHANGES +0 -177
  56. data/LEGAL +0 -36
  57. data/README.API +0 -42
  58. data/README.emacs +0 -64
  59. data/README.en +0 -130
  60. data/README.rake +0 -62
  61. data/README.rant +0 -68
  62. data/README.vim +0 -47
  63. data/Rantfile +0 -76
  64. data/ext/rcovrt/callsite.c +0 -242
  65. data/ext/rcovrt/rcovrt.c +0 -329
  66. data/lib/rcov/rant.rb +0 -87
  67. data/lib/rcov/report.rb +0 -1236
  68. data/mingw-rbconfig.rb +0 -174
data/README.rake DELETED
@@ -1,62 +0,0 @@
1
-
2
- == Code coverage analysis automation with Rake
3
-
4
- Since 0.4.0, <tt>rcov</tt> features a <tt>Rcov::RcovTask</tt> task for rake
5
- which can be used to automate test coverage analysis. Basic usage is as
6
- follows:
7
-
8
- require 'rcov/rcovtask'
9
- Rcov::RcovTask.new do |t|
10
- t.test_files = FileList['test/test*.rb']
11
- # t.verbose = true # uncomment to see the executed command
12
- end
13
-
14
- This will create by default a task named <tt>rcov</tt>, and also a task to
15
- remove the output directory where the XHTML report is generated.
16
- The latter will be named <tt>clobber_rcob</tt>, and will be added to the main
17
- <tt>clobber</tt> target.
18
-
19
- === Passing command line options to <tt>rcov</tt>
20
-
21
- You can provide a description, change the name of the generated tasks (the
22
- one used to generate the report(s) and the clobber_ one) and pass options to
23
- <tt>rcov</tt>:
24
-
25
- desc "Analyze code coverage of the unit tests."
26
- Rcov::RcovTask.new(:coverage) do |t|
27
- t.test_files = FileList['test/test*.rb']
28
- t.verbose = true
29
- ## get a text report on stdout when rake is run:
30
- t.rcov_opts << "--text-report"
31
- ## only report files under 80% coverage
32
- t.rcov_opts << "--threshold 80"
33
- end
34
-
35
- That will generate a <tt>coverage</tt> task and the associated
36
- <tt>clobber_coverage</tt> task to remove the directory the report is dumped
37
- to ("<tt>coverage</tt>" by default).
38
-
39
- You can specify a different destination directory, which comes handy if you
40
- have several <tt>RcovTask</tt>s; the <tt>clobber_*</tt> will take care of
41
- removing that directory:
42
-
43
- desc "Analyze code coverage for the FileStatistics class."
44
- Rcov::RcovTask.new(:rcov_sourcefile) do |t|
45
- t.test_files = FileList['test/test_FileStatistics.rb']
46
- t.verbose = true
47
- t.rcov_opts << "--test-unit-only"
48
- t.output_dir = "coverage.sourcefile"
49
- end
50
-
51
- Rcov::RcovTask.new(:rcov_ccanalyzer) do |t|
52
- t.test_files = FileList['test/test_CodeCoverageAnalyzer.rb']
53
- t.verbose = true
54
- t.rcov_opts << "--test-unit-only"
55
- t.output_dir = "coverage.ccanalyzer"
56
- end
57
-
58
- === Options passed through the <tt>rake</tt> command line
59
-
60
- You can override the options defined in the RcovTask by passing the new
61
- options at the time you invoke rake.
62
- The documentation for the Rcov::RcovTask explains how this can be done.
data/README.rant DELETED
@@ -1,68 +0,0 @@
1
-
2
- == Code coverage analysis automation with Rant
3
-
4
- Since 0.5.0, <tt>rcov</tt> features a <tt>Rcov</tt> generator for eant
5
- which can be used to automate test coverage analysis. Basic usage is as
6
- follows:
7
-
8
- require 'rcov/rant'
9
-
10
- desc "Create a cross-referenced code coverage report."
11
- gen Rcov do |g|
12
- g.test_files = sys['test/test*.rb']
13
- end
14
-
15
- This will create by default a task named <tt>rcov</tt>.
16
-
17
- === Passing command line options to <tt>rcov</tt>
18
-
19
- You can provide a description, change the name of the generated tasks (the
20
- one used to generate the report(s) and the clobber_ one) and pass options to
21
- <tt>rcov</tt>:
22
-
23
- desc "Create cross-referenced code coverage report."
24
- gen Rcov, :coverage do |g|
25
- g.test_files = sys['test/test*.rb']
26
- g.rcov_opts << "--threshold 80" << "--callsites"
27
- end
28
-
29
- That will generate a <tt>coverage</tt> task.
30
-
31
- You can specify a different destination directory, which comes handy if you
32
- have several rcov tasks:
33
-
34
- desc "Analyze code coverage for the FileStatistics class."
35
- gen Rcov, :rcov_sourcefile do |g|
36
- g.libs << "ext/rcovrt"
37
- g.test_files = sys['test/test_FileStatistics.rb']
38
- g.rcov_opts << "--test-unit-only"
39
- g.output_dir = "coverage.sourcefile"
40
- end
41
-
42
- desc "Analyze code coverage for CodeCoverageAnalyzer."
43
- gen Rcov, :rcov_ccanalyzer do |g|
44
- g.libs << "ext/rcovrt"
45
- g.test_files = sys['test/test_CodeCoverageAnalyzer.rb']
46
- g.rcov_opts << "--test-unit-only"
47
- g.output_dir = "coverage.ccanalyzer"
48
- end
49
-
50
- === Options specified passed to the generator
51
-
52
- The +Rcov+ generator recognizes the following options:
53
- +libs+:: directories to be added to the <tt>$LOAD_PATH</tt>
54
- +rcov_opts+:: array of options to be passed to rcov
55
- +test_files+:: files to execute
56
- +test_dirs+:: directories where to look for test files automatically
57
- +pattern+:: pattern for automatic discovery of unit tests to be executed
58
- +output_dir+:: directory where to leave the generated reports
59
-
60
- +test_files+ overrides the combination of +test_dirs+ and +pattern+.
61
-
62
-
63
- === Options passed through the <tt>rake</tt> command line
64
-
65
- You can override the options defined in the Rcov tasks by specifying them
66
- using environment variables at the time rant is executed.
67
- RCOVPATH=/my/modified/rcov rant rcov # use the specified rcov executable
68
- RCOVOPTS="--no-callsites -x foo" rant rcov # pass those options to rcov
data/README.vim DELETED
@@ -1,47 +0,0 @@
1
-
2
- <tt>rcov.vim</tt> allows you to run unit tests from vim and enter quickfix mode in
3
- order to jump to uncovered code introduced since the last run.
4
-
5
- == Installation
6
- Copy <tt>rcov.vim</tt> to the appropriate "compiler" directory (typically
7
- <tt>$HOME/.vim/compiler</tt>).
8
-
9
- == Usage
10
-
11
- === Setting the reference point
12
-
13
- +rcov+'s <tt>--text-coverage-diff</tt> mode compares the current coverage status against
14
- the saved one. It therefore needs that information to be recorded
15
- before you write new code (typically right after you perform a commit) in
16
- order to have something to compare against.
17
-
18
- You can save the current status with the <tt>--save</tt> option.
19
- If you're running +rcov+ from Rake, you can do something like
20
- rake rcov_units RCOVOPTS="-T --save --rails"
21
- in order to take the current status as the reference point.
22
-
23
- === Finding new uncovered code
24
-
25
- Type the following in command mode while editing your program:
26
- :compiler rcov
27
-
28
- rcov.vim assumes +rcov+ can be invoked with a rake task (see
29
- README.rake[link:files/README_rake.html] for
30
- information on how to create it).
31
-
32
- You can then execute +rcov+ and enter quickfix mode by typing
33
-
34
- :make <taskname>
35
-
36
- where taskname is the +rcov+ task you want to use; if you didn't override the
37
- default name in the Rakefile, just
38
-
39
- :make rcov
40
-
41
- will do.
42
-
43
- vim will then enter quickfix mode, allowing you to jump to the areas that were
44
- not covered since the last time you saved the coverage data.
45
-
46
- --------
47
- # vim: ft=text :
data/Rantfile DELETED
@@ -1,76 +0,0 @@
1
- # This Rantfile serves as an example of how to use the Rcov generator.
2
- # Take a look at the RDoc documentation (or README.rant) for further
3
- # information.
4
-
5
- $:.unshift "lib" if File.directory? "lib"
6
-
7
- import %w(rubytest rubydoc autoclean)
8
- require 'rcov/rant'
9
-
10
- task :default => :test
11
-
12
- # Use the specified rcov executable instead of the one in $PATH
13
- # (this way we get a sort of informal functional test).
14
- # This could also be specified from the command like, e.g.
15
- # rake rcov RCOVPATH=/path/to/myrcov
16
- ENV["RCOVPATH"] = "bin/rcov"
17
-
18
- desc "Create a cross-referenced code coverage report."
19
- gen Rcov do |g|
20
- g.libs << "ext/rcovrt"
21
- g.test_files = sys['test/test*.rb']
22
- g.rcov_opts << "--callsites" # comment to disable cross-references
23
- end
24
-
25
- desc "Analyze code coverage for the FileStatistics class."
26
- gen Rcov, :rcov_sourcefile do |g|
27
- g.libs << "ext/rcovrt"
28
- g.test_files = sys['test/test_FileStatistics.rb']
29
- g.rcov_opts << "--test-unit-only"
30
- g.output_dir = "coverage.sourcefile"
31
- end
32
-
33
- desc "Analyze code coverage for CodeCoverageAnalyzer."
34
- gen Rcov, :rcov_ccanalyzer do |g|
35
- g.libs << "ext/rcovrt"
36
- g.test_files = sys['test/test_CodeCoverageAnalyzer.rb']
37
- g.rcov_opts << "--test-unit-only"
38
- g.output_dir = "coverage.ccanalyzer"
39
- end
40
-
41
- desc "Run the unit tests, both rcovrt and pure-Ruby modes"
42
- task :test => [:test_rcovrt, :test_pure_ruby]
43
-
44
- desc "Run the unit tests with rcovrt."
45
- gen RubyTest, :test_rcovrt => %w[ext/rcovrt/rcovrt.so] do |g|
46
- g.libs << "ext/rcovrt"
47
- g.test_files = sys['test/test*.rb']
48
- g.verbose = true
49
- end
50
-
51
- file "ext/rcovrt/rcovrt.so" => "ext/rcovrt/rcov.c" do
52
- sys "ruby setup.rb config"
53
- sys "ruby setup.rb setup"
54
- end
55
-
56
- desc "Run the unit tests in pure-Ruby mode."
57
- gen RubyTest, :test_pure_ruby do |g|
58
- g.libs << "ext/rcovrt"
59
- g.test_files = sys['test/turn_off_rcovrt.rb', 'test/test*.rb']
60
- g.verbose = true
61
- end
62
-
63
- desc "Generate documentation."
64
- gen RubyDoc, :rdoc do |g|
65
- g.verbose = true
66
- g.dir = "doc"
67
- g.files = sys["README.API", "README.rake", "README.rant", "README.vim",
68
- "lib/**/*.rb"]
69
- g.opts = %w(--line-numbers --inline-source --title rcov --main README.API)
70
- end
71
-
72
- desc "Remove autogenerated files."
73
- gen AutoClean, :clean
74
- var[:clean].include %w(InstalledFiles .config coverage coverage.* )
75
-
76
- # vim: set sw=2 ft=ruby:
@@ -1,242 +0,0 @@
1
- #include <ruby.h>
2
- #include <env.h>
3
- #include <node.h>
4
- #include <st.h>
5
- #include <stdlib.h>
6
-
7
-
8
- static char callsite_hook_set_p;
9
-
10
- typedef struct {
11
- char *sourcefile;
12
- unsigned int sourceline;
13
- VALUE curr_meth;
14
- } type_def_site;
15
- static VALUE caller_info = 0;
16
- static VALUE method_def_site_info = 0;
17
-
18
- static caller_stack_len = 1;
19
-
20
- /*
21
- *
22
- * callsite hook and associated functions
23
- *
24
- * */
25
-
26
- static VALUE
27
- record_callsite_info(VALUE args)
28
- {
29
- VALUE caller_ary;
30
- VALUE curr_meth;
31
- VALUE count_hash;
32
- VALUE count;
33
- VALUE *pargs = (VALUE *)args;
34
-
35
- caller_ary = pargs[0];
36
- curr_meth = pargs[1];
37
- count_hash = rb_hash_aref(caller_info, curr_meth);
38
- if(TYPE(count_hash) != T_HASH) {
39
- /* Qnil, anything else should be impossible unless somebody's been
40
- * messing with ObjectSpace */
41
- count_hash = rb_hash_new();
42
- rb_hash_aset(caller_info, curr_meth, count_hash);
43
- }
44
- count = rb_hash_aref(count_hash, caller_ary);
45
- if(count == Qnil)
46
- count = INT2FIX(0);
47
- count = INT2FIX(FIX2UINT(count) + 1);
48
- rb_hash_aset(count_hash, caller_ary, count);
49
- /*
50
- printf("CALLSITE: %s -> %s %d\n", RSTRING(rb_inspect(curr_meth))->ptr,
51
- RSTRING(rb_inspect(caller_ary))->ptr, FIX2INT(count));
52
- */
53
-
54
- return Qnil;
55
- }
56
-
57
-
58
- static VALUE
59
- record_method_def_site(VALUE args)
60
- {
61
- type_def_site *pargs = (type_def_site *)args;
62
- VALUE def_site_info;
63
- VALUE hash;
64
-
65
- if( RTEST(rb_hash_aref(method_def_site_info, pargs->curr_meth)) )
66
- return Qnil;
67
- def_site_info = rb_ary_new();
68
- rb_ary_push(def_site_info, rb_str_new2(pargs->sourcefile));
69
- rb_ary_push(def_site_info, INT2NUM(pargs->sourceline+1));
70
- rb_hash_aset(method_def_site_info, pargs->curr_meth, def_site_info);
71
- /*
72
- printf("DEFSITE: %s:%d for %s\n", pargs->sourcefile, pargs->sourceline+1,
73
- RSTRING(rb_inspect(pargs->curr_meth))->ptr);
74
- */
75
-
76
- return Qnil;
77
- }
78
-
79
- static VALUE
80
- callsite_custom_backtrace(int lev)
81
- {
82
- struct FRAME *frame = ruby_frame;
83
- VALUE ary;
84
- NODE *n;
85
- VALUE level;
86
- VALUE klass;
87
-
88
- ary = rb_ary_new();
89
- if (frame->last_func == ID_ALLOCATOR) {
90
- frame = frame->prev;
91
- }
92
- for (; frame && (n = frame->node); frame = frame->prev) {
93
- if (frame->prev && frame->prev->last_func) {
94
- if (frame->prev->node == n) continue;
95
- level = rb_ary_new();
96
- klass = frame->prev->last_class ? frame->prev->last_class : Qnil;
97
- if(TYPE(klass) == T_ICLASS) {
98
- klass = CLASS_OF(klass);
99
- }
100
- rb_ary_push(level, klass);
101
- rb_ary_push(level, ID2SYM(frame->prev->last_func));
102
- rb_ary_push(level, rb_str_new2(n->nd_file));
103
- rb_ary_push(level, INT2NUM(nd_line(n)));
104
- }
105
- else {
106
- level = rb_ary_new();
107
- rb_ary_push(level, Qnil);
108
- rb_ary_push(level, Qnil);
109
- rb_ary_push(level, rb_str_new2(n->nd_file));
110
- rb_ary_push(level, INT2NUM(nd_line(n)));
111
- }
112
- rb_ary_push(ary, level);
113
- if(--lev == 0)
114
- break;
115
- }
116
-
117
- return ary;
118
- }
119
-
120
- static void
121
- coverage_event_callsite_hook(rb_event_t event, NODE *node, VALUE self,
122
- ID mid, VALUE klass)
123
- {
124
- VALUE caller_ary;
125
- VALUE curr_meth;
126
- VALUE args[2];
127
- int status;
128
-
129
- caller_ary = callsite_custom_backtrace(caller_stack_len);
130
-
131
- if(TYPE(klass) == T_ICLASS) {
132
- klass = CLASS_OF(klass);
133
- }
134
- curr_meth = rb_ary_new();
135
- rb_ary_push(curr_meth, klass);
136
- rb_ary_push(curr_meth, ID2SYM(mid));
137
-
138
- args[0] = caller_ary;
139
- args[1] = curr_meth;
140
- rb_protect(record_callsite_info, (VALUE)args, &status);
141
- if(!status && node) {
142
- type_def_site args;
143
-
144
- args.sourcefile = node->nd_file;
145
- args.sourceline = nd_line(node) - 1;
146
- args.curr_meth = curr_meth;
147
- rb_protect(record_method_def_site, (VALUE)&args, NULL);
148
- }
149
- if(status)
150
- rb_gv_set("$!", Qnil);
151
- }
152
-
153
-
154
- static VALUE
155
- cov_install_callsite_hook(VALUE self)
156
- {
157
- if(!callsite_hook_set_p) {
158
- if(TYPE(caller_info) != T_HASH)
159
- caller_info = rb_hash_new();
160
- callsite_hook_set_p = 1;
161
- rb_add_event_hook(coverage_event_callsite_hook,
162
- RUBY_EVENT_CALL);
163
-
164
- return Qtrue;
165
- } else
166
- return Qfalse;
167
- }
168
-
169
-
170
- static VALUE
171
- cov_remove_callsite_hook(VALUE self)
172
- {
173
- if(!callsite_hook_set_p)
174
- return Qfalse;
175
- else {
176
- rb_remove_event_hook(coverage_event_callsite_hook);
177
- callsite_hook_set_p = 0;
178
- return Qtrue;
179
- }
180
- }
181
-
182
-
183
- static VALUE
184
- cov_generate_callsite_info(VALUE self)
185
- {
186
- VALUE ret;
187
-
188
- ret = rb_ary_new();
189
- rb_ary_push(ret, caller_info);
190
- rb_ary_push(ret, method_def_site_info);
191
- return ret;
192
- }
193
-
194
-
195
- static VALUE
196
- cov_reset_callsite(VALUE self)
197
- {
198
- if(callsite_hook_set_p) {
199
- rb_raise(rb_eRuntimeError,
200
- "Cannot reset the callsite info in the middle of a traced run.");
201
- return Qnil;
202
- }
203
-
204
- caller_info = rb_hash_new();
205
- method_def_site_info = rb_hash_new();
206
- return Qnil;
207
- }
208
-
209
- void
210
- Init_rcov_callsite()
211
- {
212
- VALUE mRcov;
213
- VALUE mRCOV__;
214
- ID id_rcov = rb_intern("Rcov");
215
- ID id_coverage__ = rb_intern("RCOV__");
216
- ID id_script_lines__ = rb_intern("SCRIPT_LINES__");
217
-
218
- if(rb_const_defined(rb_cObject, id_rcov))
219
- mRcov = rb_const_get(rb_cObject, id_rcov);
220
- else
221
- mRcov = rb_define_module("Rcov");
222
-
223
- if(rb_const_defined(mRcov, id_coverage__))
224
- mRCOV__ = rb_const_get_at(mRcov, id_coverage__);
225
- else
226
- mRCOV__ = rb_define_module_under(mRcov, "RCOV__");
227
-
228
- callsite_hook_set_p = 0;
229
- caller_info = rb_hash_new();
230
- method_def_site_info = rb_hash_new();
231
- rb_gc_register_address(&caller_info);
232
- rb_gc_register_address(&method_def_site_info);
233
-
234
- rb_define_singleton_method(mRCOV__, "install_callsite_hook",
235
- cov_install_callsite_hook, 0);
236
- rb_define_singleton_method(mRCOV__, "remove_callsite_hook",
237
- cov_remove_callsite_hook, 0);
238
- rb_define_singleton_method(mRCOV__, "generate_callsite_info",
239
- cov_generate_callsite_info, 0);
240
- rb_define_singleton_method(mRCOV__, "reset_callsite", cov_reset_callsite, 0);
241
- }
242
- /* vim: set sw=8 expandtab: */