rcov 0.9.11 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/bin/rcov +26 -3
  2. data/ext/rcovrt/1.8/callsite.c +38 -53
  3. data/ext/rcovrt/1.8/rcovrt.c +84 -100
  4. data/ext/rcovrt/extconf.rb +7 -12
  5. data/lib/rcov/formatters/html_erb_template.rb +7 -7
  6. data/lib/rcov/formatters/html_profiling.rb +51 -0
  7. data/lib/rcov/formatters/ruby_annotation.rb +110 -0
  8. data/lib/rcov/templates/index.html.erb +18 -14
  9. data/lib/rcov/version.rb +2 -6
  10. metadata +35 -75
  11. data/BLURB +0 -111
  12. data/LICENSE +0 -53
  13. data/Rakefile +0 -103
  14. data/THANKS +0 -110
  15. data/doc/readme_for_api.markdown +0 -22
  16. data/doc/readme_for_emacs.markdown +0 -52
  17. data/doc/readme_for_rake.markdown +0 -51
  18. data/doc/readme_for_vim.markdown +0 -34
  19. data/editor-extensions/rcov.el +0 -131
  20. data/editor-extensions/rcov.vim +0 -38
  21. data/ext/rcovrt/1.9/callsite.c +0 -234
  22. data/ext/rcovrt/1.9/rcovrt.c +0 -264
  23. data/setup.rb +0 -1588
  24. data/test/assets/sample_01.rb +0 -7
  25. data/test/assets/sample_02.rb +0 -5
  26. data/test/assets/sample_03.rb +0 -20
  27. data/test/assets/sample_04.rb +0 -10
  28. data/test/assets/sample_05-new.rb +0 -17
  29. data/test/assets/sample_05-old.rb +0 -13
  30. data/test/assets/sample_05.rb +0 -17
  31. data/test/assets/sample_06.rb +0 -8
  32. data/test/call_site_analyzer_test.rb +0 -171
  33. data/test/code_coverage_analyzer_test.rb +0 -220
  34. data/test/expected_coverage/diff-gcc-all.out +0 -7
  35. data/test/expected_coverage/diff-gcc-diff.out +0 -11
  36. data/test/expected_coverage/diff-gcc-original.out +0 -5
  37. data/test/expected_coverage/diff-no-color.out +0 -12
  38. data/test/expected_coverage/diff.out +0 -12
  39. data/test/expected_coverage/gcc-text.out +0 -10
  40. data/test/expected_coverage/sample_03_rb.html +0 -651
  41. data/test/expected_coverage/sample_03_rb.rb +0 -28
  42. data/test/expected_coverage/sample_04_rb.html +0 -641
  43. data/test/file_statistics_test.rb +0 -471
  44. data/test/functional_test.rb +0 -91
  45. data/test/test_helper.rb +0 -4
  46. data/test/turn_off_rcovrt.rb +0 -4
@@ -1,51 +0,0 @@
1
- # Code coverage analysis automation with Rake
2
-
3
- Since 0.4.0, RCov features a `Rcov::RcovTask` task for rake
4
- which can be used to automate test coverage analysis. Basic usage is as
5
- follows:
6
- <pre><code>
7
- require 'rcov/rcovtask'
8
- Rcov::RcovTask.new do |t|
9
- t.test_files = FileList['test/test*.rb']
10
- # t.verbose = true # uncomment to see the executed command
11
- end
12
- </pre></code>
13
-
14
- This will create by default a task named `rcov`, and also a task to remove the output directory where the XHTML report is generated. The latter will be named `clobber_rcov`, and will be added to the main `clobber` target.
15
-
16
- ## Passing command line options to RCov
17
-
18
- You can provide a description, change the name of the generated tasks (the one used to generate the report(s) and the `clobber_` one) and pass options to RCov:
19
- <pre><code>
20
- desc "Analyze code coverage of the unit tests."
21
- Rcov::RcovTask.new(:coverage) do |t|
22
- t.test_files = FileList['test/test*.rb']
23
- t.verbose = true
24
- ## get a text report on stdout when rake is run:
25
- t.rcov_opts << "--text-report"
26
- ## only report files under 80% coverage
27
- t.rcov_opts << "--threshold 80"
28
- end
29
- </pre></code>
30
-
31
- This will generate a `coverage` task and the associated `clobber_coverage` task to remove the directory the report is dumped to (`coverage` by default). You can specify a different destination directory, which comes handy if you have several `RcovTask`s; the `clobber_*` will take care of removing that directory:
32
- <pre><code>
33
- desc "Analyze code coverage for the FileStatistics class."
34
- Rcov::RcovTask.new(:rcov_sourcefile) do |t|
35
- t.test_files = FileList['test/test_FileStatistics.rb']
36
- t.verbose = true
37
- t.rcov_opts << "--test-unit-only"
38
- t.output_dir = "coverage.sourcefile"
39
- end
40
-
41
- Rcov::RcovTask.new(:rcov_ccanalyzer) do |t|
42
- t.test_files = FileList['test/test_CodeCoverageAnalyzer.rb']
43
- t.verbose = true
44
- t.rcov_opts << "--test-unit-only"
45
- t.output_dir = "coverage.ccanalyzer"
46
- end
47
- </pre></code>
48
-
49
- ## Options passed through the `rake` command line
50
-
51
- You can override the options defined in the RcovTask by passing the new options at the time you invoke rake. The documentation for the `Rcov::RcovTask` explains how this can be done.
@@ -1,34 +0,0 @@
1
- # rcov.vim
2
-
3
- `rcov.vim` allows you to run unit tests from vim and enter quickfix mode in order to jump to uncovered code introduced since the last run.
4
-
5
- ## Installation
6
- Copy `rcov.vim` to the appropriate `compiler` directory (typically `$HOME/.vim/compiler`).
7
-
8
- ### Usage
9
-
10
- #### Setting the reference point
11
-
12
- RCov's `--text-coverage-diff` mode compares the current coverage status against the saved one. It therefore needs that information to be recorded before you write new code (typically right after you perform a commit) in order to have something to compare against. You can save the current status with the `--save` option. If you're running RCov from Rake, you can do something like
13
-
14
- `rake rcov_units RCOVOPTS="-T --save --rails"`
15
-
16
- in order to take the current status as the reference point.
17
-
18
- #### Finding new uncovered code
19
-
20
- Type the following in command mode while editing your program:
21
-
22
- `:compiler rcov`
23
-
24
- `rcov.vim` assumes RCov can be invoked with a rake task (see [readme for rake]("http://github.com/relevance/rcov/blob/master/doc/readme_for_rake.markdown") for information on how to create it).
25
-
26
- You can then execute +rcov+ and enter quickfix mode by typing
27
-
28
- `:make <taskname>`
29
-
30
- where taskname is the +rcov+ task you want to use; if you didn't override the default name in the Rakefile, just
31
-
32
- `:make rcov`
33
-
34
- will do. Vim will then enter quickfix mode, allowing you to jump to the areas that were not covered since the last time you saved the coverage data.
@@ -1,131 +0,0 @@
1
- ;;; rcov.el -- Ruby Coverage Analysis Tool
2
-
3
- ;;; Copyright (c) 2006 rubikitch <rubikitch@ruby-lang.org>
4
- ;;;
5
- ;;; Use and distribution subject to the terms of the rcov license.
6
-
7
- (defvar rcov-xref-before-visit-source-hook nil
8
- "Hook executed before jump.")
9
- (defvar rcov-xref-after-visit-source-hook nil
10
- "Hook executed after jump.")
11
- (defvar rcov-command-line "rake rcov RCOVOPTS='--gcc --no-html'"
12
- "Rcov command line to find uncovered code.
13
- It is good to use rcov with Rake because it `cd's appropriate directory.
14
- `--gcc' option is strongly recommended because `rcov' uses compilation-mode.")
15
- (defvar rcovsave-command-line "rake rcov RCOVOPTS='--gcc --no-html --save=coverage.info'"
16
- "Rcov command line to save coverage status. See also `rcov-command-line'.")
17
- (defvar rcovdiff-command-line "rake rcov RCOVOPTS='-D --gcc --no-html'"
18
- "Rcov command line to find new uncovered code. See also `rcov-command-line'.")
19
-
20
- ;;;; rcov-xref-mode
21
- (define-derived-mode rcov-xref-mode ruby-mode "Rxref"
22
- "Major mode for annotated Ruby scripts (coverage/*.rb) by rcov."
23
- (setq truncate-lines t)
24
- ;; ruby-electric-mode / pabbrev-mode hijacks TAB binding.
25
- (and ruby-electric-mode (ruby-electric-mode -1))
26
- (and (boundp 'pabbrev-mode) pabbrev-mode (pabbrev-mode -1))
27
- (suppress-keymap rcov-xref-mode-map)
28
- (define-key rcov-xref-mode-map "\C-i" 'rcov-xref-next-tag)
29
- (define-key rcov-xref-mode-map "\M-\C-i" 'rcov-xref-previous-tag)
30
- (define-key rcov-xref-mode-map "\C-m" 'rcov-xref-visit-source)
31
- (set (make-local-variable 'automatic-hscrolling) nil)
32
- )
33
-
34
- (defvar rcov-xref-tag-regexp "\\[\\[\\(.*?\\)\\]\\]")
35
-
36
- (defun rcov-xref-next-tag (n)
37
- "Go to next LINK."
38
- (interactive "p")
39
- (when (looking-at rcov-xref-tag-regexp)
40
- (goto-char (match-end 0)))
41
- (when (re-search-forward rcov-xref-tag-regexp nil t n)
42
- (goto-char (match-beginning 0)))
43
- (rcov-xref-show-link))
44
-
45
- (defun rcov-xref-previous-tag (n)
46
- "Go to previous LINK."
47
- (interactive "p")
48
- (re-search-backward rcov-xref-tag-regexp nil t n)
49
- (rcov-xref-show-link))
50
-
51
- (defvar rcov-xref-link-tempbuffer " *rcov-link*")
52
- (defun rcov-xref-show-link ()
53
- "Follow current LINK."
54
- (let ((link (match-string 1))
55
- (eol (point-at-eol)))
56
- (save-excursion
57
- (when (and link
58
- (re-search-backward "# \\(>>\\|<<\\) " (point-at-bol) t))
59
- (while (re-search-forward rcov-xref-tag-regexp eol t)
60
- (let ((matched (match-string 1)))
61
- (when (string= link matched)
62
- (add-text-properties 0 (length matched) '(face highlight) matched))
63
- (with-current-buffer (get-buffer-create rcov-xref-link-tempbuffer)
64
- (insert matched "\n"))))
65
- (let (message-log-max) ; inhibit *Messages*
66
- (message "%s" (with-current-buffer rcov-xref-link-tempbuffer
67
- (substring (buffer-string) 0 -1)))) ; chomp
68
- (kill-buffer rcov-xref-link-tempbuffer)))))
69
-
70
-
71
- ;; copied from jw-visit-source
72
- (defun rcov-xref-extract-file-lines (line)
73
- "Extract a list of file/line pairs from the given line of text."
74
- (let*
75
- ((unix_fn "[^ \t\n\r\"'([<{]+")
76
- (dos_fn "[a-zA-Z]:[^ \t\n\r\"'([<{]+")
77
- (flre (concat "\\(" unix_fn "\\|" dos_fn "\\):\\([0-9]+\\)"))
78
- (start nil)
79
- (result nil))
80
- (while (string-match flre line start)
81
- (setq start (match-end 0))
82
- (setq result
83
- (cons (list
84
- (substring line (match-beginning 1) (match-end 1))
85
- (string-to-int (substring line (match-beginning 2) (match-end 2))))
86
- result)))
87
- result))
88
-
89
- (defun rcov-xref-select-file-line (candidates)
90
- "Select a file/line candidate that references an existing file."
91
- (cond ((null candidates) nil)
92
- ((file-readable-p (caar candidates)) (car candidates))
93
- (t (rcov-xref-select-file-line (cdr candidates))) ))
94
-
95
- (defun rcov-xref-visit-source ()
96
- "If the current line contains text like '../src/program.rb:34', visit
97
- that file in the other window and position point on that line."
98
- (interactive)
99
- (let* ((line (progn (looking-at rcov-xref-tag-regexp) (match-string 1)))
100
- (candidates (rcov-xref-extract-file-lines line))
101
- (file-line (rcov-xref-select-file-line candidates)))
102
- (cond (file-line
103
- (run-hooks 'rcov-xref-before-visit-source-hook)
104
- (find-file (car file-line))
105
- (goto-line (cadr file-line))
106
- (run-hooks 'rcov-xref-after-visit-source-hook))
107
- (t
108
- (error "No source location on line.")) )))
109
-
110
- ;;;; Running rcov with various options.
111
- (defun rcov-internal (cmdline)
112
- "Run rcov with various options."
113
- (compile-internal cmdline ""
114
- nil nil nil (lambda (x) "*rcov*")))
115
-
116
- (defun rcov ()
117
- "Run rcov to find uncovered code."
118
- (interactive)
119
- (rcov-internal rcov-command-line))
120
-
121
- (defun rcovsave ()
122
- "Run rcov to save coverage status."
123
- (interactive)
124
- (rcov-internal rcovsave-command-line))
125
-
126
- (defun rcovdiff ()
127
- "Run rcov to find new uncovered code."
128
- (interactive)
129
- (rcov-internal rcovdiff-command-line))
130
-
131
- (provide 'rcov)
@@ -1,38 +0,0 @@
1
- " Vim compiler file
2
- " Language: Ruby
3
- " Function: Code coverage information with rcov
4
- " Maintainer: Mauricio Fernandez <mfp at acm dot org>
5
- " Info:
6
- " URL: http://eigenclass.org/hiki.rb?rcov
7
- " ----------------------------------------------------------------------------
8
- "
9
- " Changelog:
10
- " 0.1: initial version, shipped with rcov 0.6.0
11
- "
12
- " Comments:
13
- " Initial attempt.
14
- " ----------------------------------------------------------------------------
15
-
16
- if exists("current_compiler")
17
- finish
18
- endif
19
- let current_compiler = "rcov"
20
-
21
- if exists(":CompilerSet") != 2 " older Vim always used :setlocal
22
- command -nargs=* CompilerSet setlocal <args>
23
- endif
24
-
25
- let s:cpo_save = &cpo
26
- set cpo-=C
27
-
28
- CompilerSet makeprg=rake\ $*\ RCOVOPTS=\"-D\ --no-html\ --no-color\"\ $*
29
-
30
- CompilerSet errorformat=
31
- \%+W\#\#\#\ %f:%l\,
32
- \%-C\ \ \ ,
33
- \%-C!!\
34
-
35
- let &cpo = s:cpo_save
36
- unlet s:cpo_save
37
-
38
- " vim: nowrap sw=2 sts=2 ts=8 ff=unix :
@@ -1,234 +0,0 @@
1
- #include <ruby.h>
2
- #include <ruby/st.h>
3
- #include <stdlib.h>
4
-
5
- #define DEBUG 0
6
-
7
- static char callsite_hook_set_p;
8
-
9
- typedef struct {
10
- const char *sourcefile;
11
- unsigned int sourceline;
12
- VALUE curr_meth;
13
- } type_def_site;
14
-
15
- static VALUE caller_info = 0;
16
- static VALUE method_def_site_info = 0;
17
-
18
- static int caller_stack_len = 1;
19
-
20
- static VALUE record_callsite_info(VALUE args) {
21
- VALUE caller_ary;
22
- VALUE curr_meth;
23
- VALUE count_hash;
24
- VALUE count;
25
- VALUE *pargs = (VALUE *)args;
26
-
27
- caller_ary = pargs[0];
28
- curr_meth = pargs[1];
29
- count_hash = rb_hash_aref(caller_info, curr_meth);
30
-
31
- if(TYPE(count_hash) != T_HASH) {
32
- /* Qnil, anything else should be impossible unless somebody's been
33
- * messing with ObjectSpace */
34
- count_hash = rb_hash_new();
35
- rb_hash_aset(caller_info, curr_meth, count_hash);
36
- }
37
-
38
- count = rb_hash_aref(count_hash, caller_ary);
39
-
40
- if(count == Qnil)
41
- count = INT2FIX(0);
42
-
43
- count = INT2FIX(FIX2UINT(count) + 1);
44
- rb_hash_aset(count_hash, caller_ary, count);
45
-
46
- if(DEBUG == 1)
47
- printf("CALLSITE: %s -> %s %d\n", RSTRING_PTR(rb_inspect(curr_meth)), RSTRING_PTR(rb_inspect(caller_ary)), FIX2INT(count));
48
-
49
- return Qnil;
50
- }
51
-
52
- static VALUE record_method_def_site(VALUE args) {
53
- type_def_site *pargs = (type_def_site *)args;
54
- VALUE def_site_info;
55
-
56
- if( RTEST(rb_hash_aref(method_def_site_info, pargs->curr_meth)) )
57
- return Qnil;
58
-
59
- def_site_info = rb_ary_new();
60
- rb_ary_push(def_site_info, rb_str_new2(pargs->sourcefile));
61
- rb_ary_push(def_site_info, INT2NUM(pargs->sourceline+1));
62
- rb_hash_aset(method_def_site_info, pargs->curr_meth, def_site_info);
63
-
64
- if(DEBUG == 1)
65
- printf("DEFSITE: %s:%d for %s\n", pargs->sourcefile, pargs->sourceline+1, RSTRING_PTR(rb_inspect(pargs->curr_meth)));
66
-
67
- return Qnil;
68
- }
69
-
70
- static VALUE callsite_custom_backtrace(int lev) {
71
- ID id;
72
- VALUE klass;
73
- VALUE klass_path;
74
- VALUE eval_string;
75
-
76
- rb_frame_method_id_and_class(&id, &klass);
77
-
78
- if (id == ID_ALLOCATOR)
79
- return Qnil;
80
-
81
- if (klass) {
82
- if (TYPE(klass) == T_ICLASS) {
83
- klass = RBASIC(klass)->klass;
84
- }
85
- else if (FL_TEST(klass, FL_SINGLETON)) {
86
- klass = rb_iv_get(klass, "__attached__");
87
- }
88
- }
89
- // rb_sprintf("\"#<Class:%s>\"", RSTRING_PTR(klass_path))
90
-
91
- /*
92
- klass = class << klass; self end unless klass === eval("self", binding)
93
- */
94
-
95
- klass_path = rb_class_path(klass);
96
- VALUE reciever = rb_funcall(rb_binding_new(), rb_intern("eval"), 1, rb_str_new2("self"));
97
-
98
- if (rb_funcall(klass, rb_intern("=="), 1, reciever) == Qtrue) {
99
- klass_path = rb_sprintf("\"#<Class:%s>\"", RSTRING_PTR(klass_path));
100
- OBJ_FREEZE(klass_path);
101
- }
102
-
103
- eval_string = rb_sprintf("caller[%d, 1].map do |line|\nmd = /^([^:]*)(?::(\\d+)(?::in `(?:block in )?(.*)'))?/.match(line)\nraise \"Bad backtrace format\" unless md\n[%s, md[3] ? md[3].to_sym : nil, md[1], (md[2] || '').to_i]\nend", lev, RSTRING_PTR(klass_path));
104
- return rb_eval_string(RSTRING_PTR(eval_string));
105
- }
106
-
107
- static void coverage_event_callsite_hook(rb_event_flag_t event, VALUE node, VALUE self, ID mid, VALUE klass) {
108
- VALUE caller_ary;
109
- VALUE curr_meth;
110
- VALUE args[2];
111
- int status;
112
-
113
- caller_ary = callsite_custom_backtrace(caller_stack_len);
114
-
115
- VALUE klass_path;
116
- curr_meth = rb_ary_new();
117
-
118
- rb_frame_method_id_and_class(&mid, &klass);
119
-
120
- if (mid == ID_ALLOCATOR)
121
- return; //Qnil;
122
- if (klass) {
123
- if (TYPE(klass) == T_ICLASS) {
124
- klass = RBASIC(klass)->klass;
125
- }
126
- else if (FL_TEST(klass, FL_SINGLETON)) {
127
- klass = rb_iv_get(klass, "__attached__");
128
- }
129
- }
130
-
131
- /*
132
- klass = class << klass; self end unless klass === eval("self", binding)
133
- */
134
-
135
- klass_path = rb_class_path(klass);
136
- VALUE reciever = rb_funcall(rb_binding_new(), rb_intern("eval"), 1, rb_str_new2("self"));
137
-
138
- if (rb_funcall(klass, rb_intern("=="), 1, reciever) == Qtrue) {
139
- klass_path = rb_sprintf("#<Class:%s>", RSTRING_PTR(klass_path));
140
- OBJ_FREEZE(klass_path);
141
- }
142
-
143
- rb_ary_push(curr_meth, klass_path);
144
- rb_ary_push(curr_meth, ID2SYM(mid));
145
-
146
- args[0] = caller_ary;
147
- args[1] = curr_meth;
148
- rb_protect(record_callsite_info, (VALUE)args, &status);
149
-
150
- if(!status) {
151
- type_def_site args;
152
-
153
- args.sourcefile = rb_sourcefile();
154
- args.sourceline = rb_sourceline();
155
- args.curr_meth = curr_meth;
156
- rb_protect(record_method_def_site, (VALUE)&args, NULL);
157
- }
158
-
159
- if(status)
160
- rb_gv_set("$!", Qnil);
161
- }
162
-
163
- static VALUE cov_install_callsite_hook(VALUE self) {
164
- if(!callsite_hook_set_p) {
165
- if(TYPE(caller_info) != T_HASH)
166
- caller_info = rb_hash_new();
167
- callsite_hook_set_p = 1;
168
- VALUE something = 0;
169
- rb_add_event_hook(coverage_event_callsite_hook,
170
- RUBY_EVENT_CALL, something);
171
- return Qtrue;
172
- }
173
- else
174
- return Qfalse;
175
- }
176
-
177
- static VALUE cov_remove_callsite_hook(VALUE self) {
178
- if(!callsite_hook_set_p)
179
- return Qfalse;
180
- else {
181
- rb_remove_event_hook(coverage_event_callsite_hook);
182
- callsite_hook_set_p = 0;
183
- return Qtrue;
184
- }
185
- }
186
-
187
- static VALUE cov_generate_callsite_info(VALUE self) {
188
- VALUE ret;
189
-
190
- ret = rb_ary_new();
191
- rb_ary_push(ret, caller_info);
192
- rb_ary_push(ret, method_def_site_info);
193
- return ret;
194
- }
195
-
196
- static VALUE cov_reset_callsite(VALUE self) {
197
- if(callsite_hook_set_p) {
198
- rb_raise(rb_eRuntimeError, "Cannot reset the callsite info in the middle of a traced run.");
199
- return Qnil;
200
- }
201
-
202
- caller_info = rb_hash_new();
203
- method_def_site_info = rb_hash_new();
204
- return Qnil;
205
- }
206
-
207
- void Init_rcov_callsite() {
208
- VALUE mRcov;
209
- VALUE mRCOV__;
210
- ID id_rcov = rb_intern("Rcov");
211
- ID id_coverage__ = rb_intern("RCOV__");
212
- // ID id_script_lines__ = rb_intern("SCRIPT_LINES__");
213
-
214
- if(rb_const_defined(rb_cObject, id_rcov))
215
- mRcov = rb_const_get(rb_cObject, id_rcov);
216
- else
217
- mRcov = rb_define_module("Rcov");
218
-
219
- if(rb_const_defined(mRcov, id_coverage__))
220
- mRCOV__ = rb_const_get_at(mRcov, id_coverage__);
221
- else
222
- mRCOV__ = rb_define_module_under(mRcov, "RCOV__");
223
-
224
- callsite_hook_set_p = 0;
225
- caller_info = rb_hash_new();
226
- method_def_site_info = rb_hash_new();
227
- rb_gc_register_address(&caller_info);
228
- rb_gc_register_address(&method_def_site_info);
229
-
230
- rb_define_singleton_method(mRCOV__, "install_callsite_hook", cov_install_callsite_hook, 0);
231
- rb_define_singleton_method(mRCOV__, "remove_callsite_hook", cov_remove_callsite_hook, 0);
232
- rb_define_singleton_method(mRCOV__, "generate_callsite_info", cov_generate_callsite_info, 0);
233
- rb_define_singleton_method(mRCOV__, "reset_callsite", cov_reset_callsite, 0);
234
- }