rcov 0.9.11 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
- }