spicycode-rcov 0.8.1.5.6 → 0.8.1.5.7

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -17,8 +17,7 @@ require 'rake/clean'
17
17
  ENV["RCOVPATH"] = "bin/rcov"
18
18
 
19
19
  # The following task is largely equivalent to:
20
- # Rcov::RcovTask.new
21
- # (really!)
20
+ # Rcov::RcovTask.new
22
21
  desc "Create a cross-referenced code coverage report."
23
22
  Rcov::RcovTask.new do |t|
24
23
  t.test_files = FileList['test/*_test.rb']
@@ -53,6 +52,7 @@ if RUBY_PLATFORM == 'java'
53
52
  end
54
53
  else
55
54
  Rake::TestTask.new(:test_rcovrt => ["ext/rcovrt/rcovrt.so"]) do |t|
55
+ system("cd ext/rcovrt && make clean && rm Makefile")
56
56
  t.libs << "ext/rcovrt"
57
57
  t.test_files = FileList['test/*_test.rb']
58
58
  t.verbose = true
@@ -73,122 +73,24 @@ end
73
73
 
74
74
  desc "Run the unit tests"
75
75
  task :test => [:test_rcovrt]
76
- #, :test_pure_ruby] disabled since 1.8.5 broke them
76
+
77
+ desc "install by setup.rb"
78
+ task :install do
79
+ sh "sudo ruby setup.rb install"
80
+ end
81
+
82
+ task :default => :test
77
83
 
78
84
  desc "Generate rdoc documentation for the rcov library"
79
85
  Rake::RDocTask.new("rdoc") { |rdoc|
80
86
  rdoc.rdoc_dir = 'doc'
81
87
  rdoc.title = "rcov"
82
88
  rdoc.options << "--line-numbers" << "--inline-source"
83
- rdoc.rdoc_files.include('readme_for_api')
84
- rdoc.rdoc_files.include('readme_for_rake')
85
- rdoc.rdoc_files.include('readme_for_rant')
86
- rdoc.rdoc_files.include('readme_for_vim')
89
+ rdoc.rdoc_files.include('doc/readme_for_api')
90
+ rdoc.rdoc_files.include('doc/readme_for_rake')
91
+ rdoc.rdoc_files.include('doc/readme_for_rant')
92
+ rdoc.rdoc_files.include('doc/readme_for_vim')
87
93
  rdoc.rdoc_files.include('lib/**/*.rb')
88
94
  }
89
95
 
90
- task :default => :test
91
-
92
- desc "install by setup.rb"
93
- task :install do
94
- sh "sudo ruby setup.rb install"
95
- end
96
-
97
-
98
- PKG_FILES = ["bin/rcov", "lib/rcov.rb", "lib/rcov/lowlevel.rb", "lib/rcov/xx.rb", "lib/rcov/version.rb", "lib/rcov/rant.rb", "lib/rcov/report.rb", "lib/rcov/rcovtask.rb", "ext/rcovrt/extconf.rb", "ext/rcovrt/rcovrt.c", "ext/rcovrt/callsite.c", "LEGAL", "LICENSE", "Rakefile", "Rantfile", "readme_for_rake", "readme_for_rant", "readme_for_vim", "readme_for_emacs", "readme_for_vim", "readme_for_api", "THANKS", "test/functional_test.rb", "test/file_statistics_test.rb", "test/assets/sample_03.rb", "test/assets/sample_05-new.rb", "test/code_coverage_analyzer_test.rb", "test/assets/sample_04.rb", "test/assets/sample_02.rb", "test/assets/sample_05-old.rb", "test/assets/sample_01.rb", "test/turn_off_rcovrt.rb", "test/call_site_analyzer_test.rb", "test/assets/sample_05.rb", "rcov.vim", "rcov.el", "setup.rb", "BLURB", "CHANGES"]
99
-
100
- # gem management tasks Use these to build the java code before creating the gem package
101
- # this code can also be used to generate the MRI gem. But I left the gemspec file in too.
102
- spec = Gem::Specification.new do |s|
103
- s.name = %q{rcov}
104
- s.version = Rcov::VERSION
105
-
106
- s.required_rubygems_version = nil if s.respond_to? :required_rubygems_version=
107
- s.authors = ["Mauricio Fernandez"]
108
- s.cert_chain = nil
109
- s.date = %q{2007-11-21}
110
- s.default_executable = %q{rcov}
111
- s.description = %q{rcov is a code coverage tool for Ruby. It is commonly used for viewing overall test unit coverage of target code. It features fast execution (20-300 times faster than previous tools), multiple analysis modes, XHTML and several kinds of text reports, easy automation with Rake via a RcovTask, fairly accurate coverage information through code linkage inference using simple heuristics, colorblind-friendliness...}
112
- s.email = %q{mfp@acm.org}
113
- s.executables = ["rcov"]
114
- s.extensions = ["ext/rcovrt/extconf.rb"]
115
- s.platform = Gem::Platform::RUBY
116
- s.extra_rdoc_files = ["readme_for_api", "readme_for_rake", "readme_for_rant", "readme_for_vim"]
117
- s.files = PKG_FILES
118
- s.has_rdoc = true
119
- s.homepage = %q{http://eigenclass.org/hiki.rb?rcov}
120
- s.rdoc_options = ["--main", "readme_for_api", "--title", "rcov code coverage tool"]
121
- s.require_paths = ["lib"]
122
- s.required_ruby_version = Gem::Requirement.new("> 0.0.0")
123
- s.rubygems_version = %q{1.2.0}
124
- s.summary = %q{Code coverage analysis tool for Ruby}
125
- s.test_files = ["test/functional_test.rb", "test/file_statistics_test.rb", "test/code_coverage_analyzer_test.rb", "test/call_site_analyzer_test.rb"]
126
-
127
- if s.respond_to? :specification_version then
128
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
129
- s.specification_version = 1
130
-
131
- if current_version >= 3 then
132
- else
133
- end
134
- else
135
- end
136
- end
137
-
138
- # tasks added in to support generating the JRuby gem.
139
- if RUBY_PLATFORM == 'java'
140
- spec.platform = "jruby"
141
- spec.extensions = []
142
- # add the jruby extension to the file list
143
- PKG_FILES << "lib/rcovrt.jar"
144
-
145
- def java_classpath_arg
146
- begin
147
- require 'java'
148
- classpath = java.lang.System.getProperty('java.class.path')
149
- rescue LoadError
150
- end
151
-
152
- if classpath.empty?
153
- classpath = FileList["#{ENV['JRUBY_HOME']}/lib/*.jar"].join(File::PATH_SEPARATOR)
154
- end
155
-
156
- classpath ? "-cp #{classpath}" : ""
157
- end
158
-
159
-
160
- CLEAN.include ["ext/java/classes", "lib/rcovrt.jar", "pkg"]
161
-
162
- def compile_java
163
- mkdir_p "ext/java/classes"
164
- sh "javac -g -target 1.5 -source 1.5 -d ext/java/classes #{java_classpath_arg} #{FileList['ext/java/src/**/*.java'].join(' ')}"
165
- end
166
-
167
- def make_jar
168
- require 'fileutils'
169
- lib = File.join(File.dirname(__FILE__), 'lib')
170
- FileUtils.mkdir(lib) unless File.exists? lib
171
- sh "jar cf lib/rcovrt.jar -C ext/java/classes/ ."
172
- end
173
-
174
- file 'lib/rcovrt.jar' => FileList["ext/java/src/*.java"] do
175
- compile_java
176
- make_jar
177
- end
178
-
179
- desc "compile the java extension and put it into the lib directory"
180
- task :java_compile => ["lib/rcovrt.jar"]
181
-
182
- end
183
-
184
- Rake::GemPackageTask.new(spec) do |p|
185
- p.need_tar = true
186
- p.gem_spec = spec
187
- end
188
-
189
- # extend the gem task to include the java_compile
190
- if RUBY_PLATFORM == 'java'
191
- Rake::Task["pkg"].enhance(["java_compile"])
192
- end
193
-
194
96
  # vim: set sw=2 ft=ruby:
data/bin/rcov CHANGED
@@ -265,7 +265,7 @@ EOF
265
265
  "method specified by SELECTOR",
266
266
  "(format: Foo::Bar#method, A::B.method)") do |selector|
267
267
  case selector
268
- when /([^.]+)(#|\.)(.*)/: options.report_cov_bug_for = selector
268
+ when /([^.]+)(#|\.)(.*)/ then options.report_cov_bug_for = selector
269
269
  else
270
270
  raise OptionParser::InvalidArgument, selector
271
271
  end
File without changes
@@ -0,0 +1,64 @@
1
+
2
+ <tt>rcov.el</tt> allows you to use rcov from Emacs conveniently.
3
+ * Run unit tests and jump to uncovered code by <tt>C-x `</tt>.
4
+ * Run unit tests and save the current coverage status.
5
+ * Run unit tests and jump to uncovered code introduced since the last run.
6
+ * View cross-reference annotated code.
7
+
8
+ == Installation
9
+
10
+ Copy <tt>rcov.el</tt> to the appropriate directory, which is in load-path.
11
+ Then require it.
12
+ (require 'rcov)
13
+
14
+
15
+ == Usage
16
+
17
+ There are some commands to run rcov in Emacs.
18
+ All of them displays +rcov+ window, whose major-mode is compilation-mode.
19
+ Therefore you can jump to uncovered code by <tt>C-x `</tt>.
20
+
21
+ +rcov-command-line+, +rcovsave-command-line+, and +rcovdiff-command-line+ define
22
+ command line to run rcov.
23
+ If you do not use +rcov+ from Rake, you must modify them.
24
+
25
+ === Finding uncovered code
26
+
27
+ Type the following while editing your program:
28
+ M-x rcov
29
+
30
+ === Setting the reference point
31
+
32
+ +rcov+'s <tt>--text-coverage-diff</tt> mode compares the current coverage status against
33
+ the saved one. It therefore needs that information to be recorded
34
+ before you write new code (typically right after you perform a commit) in
35
+ order to have something to compare against.
36
+
37
+ You can save the current status with the <tt>--save</tt> option.
38
+
39
+ Type the following to save the current status in Emacs:
40
+ M-x rcovsave
41
+ If you do not use +rcov+ from Rake, you must modify +rcovsave-command-line+ variable.
42
+
43
+ === Finding new uncovered code
44
+
45
+ Type the following to save the current status in Emacs:
46
+ M-x rcovdiff
47
+
48
+ === Viewing cross-reference annotated code
49
+
50
+ If you read cross-reference annotated code, issue
51
+ rake rcov RCOVOPTS='-a'
52
+ at the beginning.
53
+ This command creates +coverage+ directory and many *.rb files in it.
54
+ Filenames of these Ruby scripts are converted from original path.
55
+ You can browse them by normally <tt>C-x C-f</tt>.
56
+ You can think of <tt>-a</tt> option as <tt>--xrefs</tt> option and output format is Ruby script.
57
+
58
+ After find-file-ed annotated script, the major-mode is rcov-xref-mode,
59
+ which is derived from ruby-mode and specializes navigation.
60
+
61
+ <tt>Tab</tt> and <tt>M-Tab</tt> goes forward/backward links.
62
+ <tt>Ret</tt> follows selected link.
63
+
64
+ This feature is useful to read third-party code or to follow control flow.
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,258 @@
1
+ #include <ruby.h>
2
+ #include <ruby/st.h>
3
+ #include <stdlib.h>
4
+
5
+ static char callsite_hook_set_p;
6
+
7
+ typedef struct {
8
+ const char *sourcefile;
9
+ unsigned int sourceline;
10
+ VALUE curr_meth;
11
+ } type_def_site;
12
+ static VALUE caller_info = 0;
13
+ static VALUE method_def_site_info = 0;
14
+
15
+ static int caller_stack_len = 1;
16
+
17
+ /*
18
+ *
19
+ * callsite hook and associated functions
20
+ *
21
+ * */
22
+
23
+ static VALUE
24
+ record_callsite_info(VALUE args)
25
+ {
26
+ VALUE caller_ary;
27
+ VALUE curr_meth;
28
+ VALUE count_hash;
29
+ VALUE count;
30
+ VALUE *pargs = (VALUE *)args;
31
+
32
+ caller_ary = pargs[0];
33
+ curr_meth = pargs[1];
34
+ count_hash = rb_hash_aref(caller_info, curr_meth);
35
+ if(TYPE(count_hash) != T_HASH) {
36
+ /* Qnil, anything else should be impossible unless somebody's been
37
+ * messing with ObjectSpace */
38
+ count_hash = rb_hash_new();
39
+ rb_hash_aset(caller_info, curr_meth, count_hash);
40
+ }
41
+ count = rb_hash_aref(count_hash, caller_ary);
42
+ if(count == Qnil)
43
+ count = INT2FIX(0);
44
+ count = INT2FIX(FIX2UINT(count) + 1);
45
+ rb_hash_aset(count_hash, caller_ary, count);
46
+ /* * /
47
+ printf("CALLSITE: %s -> %s %d\n", RSTRING_PTR(rb_inspect(curr_meth)),
48
+ RSTRING_PTR(rb_inspect(caller_ary)), FIX2INT(count));
49
+ / * */
50
+
51
+ return Qnil;
52
+ }
53
+
54
+
55
+ static VALUE
56
+ record_method_def_site(VALUE args)
57
+ {
58
+ type_def_site *pargs = (type_def_site *)args;
59
+ VALUE def_site_info;
60
+ // VALUE hash;
61
+
62
+ if( RTEST(rb_hash_aref(method_def_site_info, pargs->curr_meth)) )
63
+ return Qnil;
64
+ def_site_info = rb_ary_new();
65
+ rb_ary_push(def_site_info, rb_str_new2(pargs->sourcefile));
66
+ rb_ary_push(def_site_info, INT2NUM(pargs->sourceline+1));
67
+ rb_hash_aset(method_def_site_info, pargs->curr_meth, def_site_info);
68
+ /* * /
69
+ printf("DEFSITE: %s:%d for %s\n", pargs->sourcefile, pargs->sourceline+1,
70
+ RSTRING_PTR(rb_inspect(pargs->curr_meth)));
71
+ / * */
72
+
73
+ return Qnil;
74
+ }
75
+
76
+ static VALUE
77
+ callsite_custom_backtrace(int lev)
78
+ {
79
+ ID id;
80
+ VALUE klass;
81
+ VALUE klass_path;
82
+ VALUE eval_string;
83
+
84
+ rb_frame_method_id_and_class(&id, &klass);
85
+ if (id == ID_ALLOCATOR)
86
+ return Qnil;
87
+ if (klass) {
88
+ if (TYPE(klass) == T_ICLASS) {
89
+ klass = RBASIC(klass)->klass;
90
+ }
91
+ else if (FL_TEST(klass, FL_SINGLETON)) {
92
+ klass = rb_iv_get(klass, "__attached__");
93
+ }
94
+ }
95
+ // rb_sprintf("\"#<Class:%s>\"", RSTRING_PTR(klass_path))
96
+
97
+ /*
98
+ klass = class << klass; self end unless klass === eval("self", binding)
99
+ */
100
+
101
+ klass_path = rb_class_path(klass);
102
+ VALUE reciever = rb_funcall(rb_binding_new(), rb_intern("eval"), 1, rb_str_new2("self"));
103
+ if (rb_funcall(klass, rb_intern("=="), 1, reciever) == Qtrue) {
104
+ klass_path = rb_sprintf("\"#<Class:%s>\"", RSTRING_PTR(klass_path));
105
+ OBJ_FREEZE(klass_path);
106
+ }
107
+
108
+ 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));
109
+ return rb_eval_string(RSTRING_PTR(eval_string));
110
+ }
111
+
112
+ static void
113
+ coverage_event_callsite_hook(rb_event_flag_t event, VALUE node,
114
+ VALUE self, ID mid, VALUE klass)
115
+ {
116
+ VALUE caller_ary;
117
+ VALUE curr_meth;
118
+ VALUE args[2];
119
+ int status;
120
+
121
+ caller_ary = callsite_custom_backtrace(caller_stack_len);
122
+
123
+ VALUE klass_path;
124
+ curr_meth = rb_ary_new();
125
+
126
+ rb_frame_method_id_and_class(&mid, &klass);
127
+
128
+ if (mid == ID_ALLOCATOR)
129
+ return; //Qnil;
130
+ if (klass) {
131
+ if (TYPE(klass) == T_ICLASS) {
132
+ klass = RBASIC(klass)->klass;
133
+ }
134
+ else if (FL_TEST(klass, FL_SINGLETON)) {
135
+ klass = rb_iv_get(klass, "__attached__");
136
+ }
137
+ }
138
+
139
+ /*
140
+ klass = class << klass; self end unless klass === eval("self", binding)
141
+ */
142
+
143
+ klass_path = rb_class_path(klass);
144
+ VALUE reciever = rb_funcall(rb_binding_new(), rb_intern("eval"), 1, rb_str_new2("self"));
145
+ if (rb_funcall(klass, rb_intern("=="), 1, reciever) == Qtrue) {
146
+ klass_path = rb_sprintf("#<Class:%s>", RSTRING_PTR(klass_path));
147
+ OBJ_FREEZE(klass_path);
148
+ }
149
+
150
+ rb_ary_push(curr_meth, klass_path);
151
+ rb_ary_push(curr_meth, ID2SYM(mid));
152
+
153
+ args[0] = caller_ary;
154
+ args[1] = curr_meth;
155
+ rb_protect(record_callsite_info, (VALUE)args, &status);
156
+
157
+ if(!status) {
158
+ type_def_site args;
159
+
160
+ args.sourcefile = rb_sourcefile();
161
+ args.sourceline = rb_sourceline();
162
+ args.curr_meth = curr_meth;
163
+ rb_protect(record_method_def_site, (VALUE)&args, NULL);
164
+ }
165
+ if(status)
166
+ rb_gv_set("$!", Qnil);
167
+ }
168
+
169
+
170
+ static VALUE
171
+ cov_install_callsite_hook(VALUE self)
172
+ {
173
+ if(!callsite_hook_set_p) {
174
+ if(TYPE(caller_info) != T_HASH)
175
+ caller_info = rb_hash_new();
176
+ callsite_hook_set_p = 1;
177
+ VALUE something = 0;
178
+ rb_add_event_hook(coverage_event_callsite_hook,
179
+ RUBY_EVENT_CALL, something);
180
+ return Qtrue;
181
+ } else
182
+ return Qfalse;
183
+ }
184
+
185
+
186
+ static VALUE
187
+ cov_remove_callsite_hook(VALUE self)
188
+ {
189
+ if(!callsite_hook_set_p)
190
+ return Qfalse;
191
+ else {
192
+ rb_remove_event_hook(coverage_event_callsite_hook);
193
+ callsite_hook_set_p = 0;
194
+ return Qtrue;
195
+ }
196
+ }
197
+
198
+
199
+ static VALUE
200
+ cov_generate_callsite_info(VALUE self)
201
+ {
202
+ VALUE ret;
203
+
204
+ ret = rb_ary_new();
205
+ rb_ary_push(ret, caller_info);
206
+ rb_ary_push(ret, method_def_site_info);
207
+ return ret;
208
+ }
209
+
210
+
211
+ static VALUE
212
+ cov_reset_callsite(VALUE self)
213
+ {
214
+ if(callsite_hook_set_p) {
215
+ rb_raise(rb_eRuntimeError,
216
+ "Cannot reset the callsite info in the middle of a traced run.");
217
+ return Qnil;
218
+ }
219
+
220
+ caller_info = rb_hash_new();
221
+ method_def_site_info = rb_hash_new();
222
+ return Qnil;
223
+ }
224
+
225
+ void
226
+ Init_rcov_callsite()
227
+ {
228
+ VALUE mRcov;
229
+ VALUE mRCOV__;
230
+ ID id_rcov = rb_intern("Rcov");
231
+ ID id_coverage__ = rb_intern("RCOV__");
232
+ // ID id_script_lines__ = rb_intern("SCRIPT_LINES__");
233
+
234
+ if(rb_const_defined(rb_cObject, id_rcov))
235
+ mRcov = rb_const_get(rb_cObject, id_rcov);
236
+ else
237
+ mRcov = rb_define_module("Rcov");
238
+
239
+ if(rb_const_defined(mRcov, id_coverage__))
240
+ mRCOV__ = rb_const_get_at(mRcov, id_coverage__);
241
+ else
242
+ mRCOV__ = rb_define_module_under(mRcov, "RCOV__");
243
+
244
+ callsite_hook_set_p = 0;
245
+ caller_info = rb_hash_new();
246
+ method_def_site_info = rb_hash_new();
247
+ rb_gc_register_address(&caller_info);
248
+ rb_gc_register_address(&method_def_site_info);
249
+
250
+ rb_define_singleton_method(mRCOV__, "install_callsite_hook",
251
+ cov_install_callsite_hook, 0);
252
+ rb_define_singleton_method(mRCOV__, "remove_callsite_hook",
253
+ cov_remove_callsite_hook, 0);
254
+ rb_define_singleton_method(mRCOV__, "generate_callsite_info",
255
+ cov_generate_callsite_info, 0);
256
+ rb_define_singleton_method(mRCOV__, "reset_callsite", cov_reset_callsite, 0);
257
+ }
258
+ /* vim: set sw=8 expandtab: */
@@ -0,0 +1,315 @@
1
+ #include <ruby.h>
2
+ #include <ruby/st.h>
3
+ #include <stdlib.h>
4
+ #include <assert.h>
5
+
6
+ #define COVERAGE_DEBUG_EVENTS 0
7
+
8
+ #define RCOVRT_VERSION_MAJOR 2
9
+ #define RCOVRT_VERSION_MINOR 0
10
+ #define RCOVRT_VERSION_REV 0
11
+
12
+ static VALUE mRcov;
13
+ static VALUE mRCOV__;
14
+ static VALUE oSCRIPT_LINES__;
15
+ static ID id_cover;
16
+ static st_table* coverinfo = 0;
17
+ static char coverage_hook_set_p;
18
+
19
+ struct cov_array {
20
+ unsigned int len;
21
+ unsigned int *ptr;
22
+ };
23
+
24
+ static struct cov_array *cached_array = 0;
25
+ static char *cached_file = 0;
26
+
27
+ /*
28
+ *
29
+ * coverage hook and associated functions
30
+ *
31
+ * */
32
+ static struct cov_array *
33
+ coverage_increase_counter_uncached(char *sourcefile, unsigned int sourceline,
34
+ char mark_only)
35
+ {
36
+ struct cov_array *carray = NULL;
37
+
38
+ if(sourcefile == NULL) {
39
+ /* "can't happen", just ignore and avoid segfault */
40
+ return NULL;
41
+ } else if(!st_lookup(coverinfo, (st_data_t)sourcefile, (st_data_t*)&carray)) {
42
+ VALUE arr;
43
+
44
+ arr = rb_hash_aref(oSCRIPT_LINES__, rb_str_new2(sourcefile));
45
+ if(NIL_P(arr))
46
+ return 0;
47
+ rb_check_type(arr, T_ARRAY);
48
+ carray = calloc(1, sizeof(struct cov_array));
49
+ carray->ptr = calloc(RARRAY_LEN(arr), sizeof(unsigned int));
50
+ carray->len = RARRAY_LEN(arr);
51
+ st_insert(coverinfo, (st_data_t)strdup(sourcefile),
52
+ (st_data_t) carray);
53
+ } else {
54
+ /* recovered carray, sanity check */
55
+ assert(carray && "failed to create valid carray");
56
+ }
57
+
58
+ if(mark_only) {
59
+ if(!carray->ptr[sourceline])
60
+ carray->ptr[sourceline] = 1;
61
+ } else {
62
+ if (carray && carray->len > sourceline) {
63
+ carray->ptr[sourceline]++;
64
+ }
65
+ }
66
+
67
+ return carray;
68
+ }
69
+
70
+
71
+ static void
72
+ coverage_mark_caller()
73
+ {
74
+ // if @coverage_hook_activated
75
+ // COVER[file] ||= Array.new(SCRIPT_LINES__[file].size, 0)
76
+ // COVER[file][line - 1] ||= 0
77
+ // COVER[file][line - 1] += 1
78
+ // end
79
+
80
+ coverage_increase_counter_uncached(rb_sourcefile(), rb_sourceline(), 1);
81
+ }
82
+
83
+
84
+ static void
85
+ coverage_increase_counter_cached(char *sourcefile, int sourceline)
86
+ {
87
+ if(cached_file == sourcefile && cached_array && cached_array->len > sourceline) {
88
+ cached_array->ptr[sourceline]++;
89
+ return;
90
+ }
91
+ cached_file = sourcefile;
92
+ cached_array = coverage_increase_counter_uncached(sourcefile, sourceline, 0);
93
+ }
94
+
95
+ static void
96
+ coverage_event_coverage_hook(rb_event_flag_t event, VALUE node,
97
+ VALUE self, ID mid, VALUE klass)
98
+ {
99
+ char *sourcefile;
100
+ unsigned int sourceline;
101
+ static unsigned int in_hook = 0;
102
+
103
+ if(in_hook) {
104
+ return;
105
+ }
106
+
107
+ in_hook++;
108
+
109
+ #if COVERAGE_DEBUG_EVENTS
110
+ do {
111
+ int status;
112
+ VALUE old_exception;
113
+ old_exception = rb_gv_get("$!");
114
+ rb_protect(rb_inspect, klass, &status);
115
+ if(!status) {
116
+ printf("EVENT: %d %s %s %s %d\n", event,
117
+ klass ? RSTRING(rb_inspect(klass))->ptr : "",
118
+ mid ? (mid == ID_ALLOCATOR ? "ID_ALLOCATOR" : rb_id2name(mid))
119
+ : "unknown",
120
+ node ? node->nd_file : "", node ? nd_line(node) : 0);
121
+ } else {
122
+ printf("EVENT: %d %s %s %d\n", event,
123
+ mid ? (mid == ID_ALLOCATOR ? "ID_ALLOCATOR" : rb_id2name(mid))
124
+ : "unknown",
125
+ node ? node->nd_file : "", node ? nd_line(node) : 0);
126
+ }
127
+ rb_gv_set("$!", old_exception);
128
+ } while (0);
129
+ #endif
130
+
131
+ if(event & RUBY_EVENT_C_CALL) {
132
+ coverage_mark_caller();
133
+ }
134
+ if(event & (RUBY_EVENT_C_CALL | RUBY_EVENT_C_RETURN | RUBY_EVENT_CLASS)) {
135
+ in_hook--;
136
+ return;
137
+ }
138
+
139
+ // printf("NODE? %s , %s\n", rb_id2name(rb_frame_this_func()), RSTRING_PTR(rb_inspect(node)));
140
+
141
+ sourcefile = rb_sourcefile();
142
+ sourceline = rb_sourceline();
143
+
144
+ if (0 == sourceline || 0 == sourcefile) {
145
+ in_hook--;
146
+ return;
147
+ }
148
+
149
+ coverage_increase_counter_cached(sourcefile, sourceline);
150
+ if(event & RUBY_EVENT_CALL)
151
+ coverage_mark_caller();
152
+ in_hook--;
153
+ }
154
+
155
+
156
+ static VALUE
157
+ cov_install_coverage_hook(VALUE self)
158
+ {
159
+ if(!coverage_hook_set_p) {
160
+ if(!coverinfo)
161
+ coverinfo = st_init_strtable();
162
+ coverage_hook_set_p = 1;
163
+ /* TODO: allow C_CALL too, since it's supported already
164
+ * the overhead is around ~30%, tested on typo */
165
+ VALUE holder = 0;
166
+ rb_add_event_hook(coverage_event_coverage_hook,
167
+ RUBY_EVENT_ALL & ~RUBY_EVENT_C_CALL &
168
+ ~RUBY_EVENT_C_RETURN & ~RUBY_EVENT_CLASS, holder);
169
+ return Qtrue;
170
+ }
171
+ else
172
+ return Qfalse;
173
+ }
174
+
175
+
176
+ static int
177
+ populate_cover(st_data_t key, st_data_t value, st_data_t cover)
178
+ {
179
+ VALUE rcover;
180
+ VALUE rkey;
181
+ VALUE rval;
182
+ struct cov_array *carray;
183
+ unsigned int i;
184
+
185
+ rcover = (VALUE)cover;
186
+ carray = (struct cov_array *) value;
187
+ rkey = rb_str_new2((char*) key);
188
+ rval = rb_ary_new2(carray->len);
189
+ for(i = 0; i < carray->len; i++)
190
+ rb_ary_push(rval, UINT2NUM(carray->ptr[i]));
191
+
192
+ rb_hash_aset(rcover, rkey, rval);
193
+
194
+ return ST_CONTINUE;
195
+ }
196
+
197
+
198
+ static int
199
+ free_table(st_data_t key, st_data_t value, st_data_t ignored)
200
+ {
201
+ struct cov_array *carray;
202
+
203
+ carray = (struct cov_array *) value;
204
+ free((char *)key);
205
+ free(carray->ptr);
206
+ free(carray);
207
+
208
+ return ST_CONTINUE;
209
+ }
210
+
211
+
212
+ static VALUE
213
+ cov_remove_coverage_hook(VALUE self)
214
+ {
215
+ if(!coverage_hook_set_p)
216
+ return Qfalse;
217
+ else {
218
+ rb_remove_event_hook(coverage_event_coverage_hook);
219
+ coverage_hook_set_p = 0;
220
+ return Qtrue;
221
+ }
222
+ }
223
+
224
+
225
+ static VALUE
226
+ cov_generate_coverage_info(VALUE self)
227
+ {
228
+ VALUE cover;
229
+
230
+ if(rb_const_defined_at(mRCOV__, id_cover)) {
231
+ rb_mod_remove_const(mRCOV__, ID2SYM(id_cover));
232
+ }
233
+
234
+ cover = rb_hash_new();
235
+ if(coverinfo)
236
+ st_foreach(coverinfo, populate_cover, cover);
237
+ rb_define_const(mRCOV__, "COVER", cover);
238
+
239
+ return cover;
240
+ }
241
+
242
+
243
+ static VALUE
244
+ cov_reset_coverage(VALUE self)
245
+ {
246
+ if(coverage_hook_set_p) {
247
+ rb_raise(rb_eRuntimeError,
248
+ "Cannot reset the coverage info in the middle of a traced run.");
249
+ return Qnil;
250
+ }
251
+
252
+ cached_array = 0;
253
+ cached_file = 0;
254
+ st_foreach(coverinfo, free_table, Qnil);
255
+ st_free_table(coverinfo);
256
+ coverinfo = 0;
257
+
258
+ return Qnil;
259
+ }
260
+
261
+
262
+ static VALUE
263
+ cov_ABI(VALUE self)
264
+ {
265
+ VALUE ret;
266
+
267
+ ret = rb_ary_new();
268
+ rb_ary_push(ret, INT2FIX(RCOVRT_VERSION_MAJOR));
269
+ rb_ary_push(ret, INT2FIX(RCOVRT_VERSION_MINOR));
270
+ rb_ary_push(ret, INT2FIX(RCOVRT_VERSION_REV));
271
+
272
+ return ret;
273
+ }
274
+
275
+
276
+ void
277
+ Init_rcovrt()
278
+ {
279
+ ID id_rcov = rb_intern("Rcov");
280
+ ID id_coverage__ = rb_intern("RCOV__");
281
+ ID id_script_lines__ = rb_intern("SCRIPT_LINES__");
282
+
283
+ id_cover = rb_intern("COVER");
284
+
285
+ if(rb_const_defined(rb_cObject, id_rcov))
286
+ mRcov = rb_const_get(rb_cObject, id_rcov);
287
+ else
288
+ mRcov = rb_define_module("Rcov");
289
+
290
+ if(rb_const_defined(mRcov, id_coverage__))
291
+ mRCOV__ = rb_const_get_at(mRcov, id_coverage__);
292
+ else
293
+ mRCOV__ = rb_define_module_under(mRcov, "RCOV__");
294
+
295
+ if(rb_const_defined(rb_cObject, id_script_lines__))
296
+ oSCRIPT_LINES__ = rb_const_get(rb_cObject, rb_intern("SCRIPT_LINES__"));
297
+ else {
298
+ oSCRIPT_LINES__ = rb_hash_new();
299
+ rb_const_set(rb_cObject, id_script_lines__, oSCRIPT_LINES__);
300
+ }
301
+
302
+ coverage_hook_set_p = 0;
303
+
304
+ rb_define_singleton_method(mRCOV__, "install_coverage_hook",
305
+ cov_install_coverage_hook, 0);
306
+ rb_define_singleton_method(mRCOV__, "remove_coverage_hook",
307
+ cov_remove_coverage_hook, 0);
308
+ rb_define_singleton_method(mRCOV__, "generate_coverage_info",
309
+ cov_generate_coverage_info, 0);
310
+ rb_define_singleton_method(mRCOV__, "reset_coverage", cov_reset_coverage, 0);
311
+ rb_define_singleton_method(mRCOV__, "ABI", cov_ABI, 0);
312
+
313
+ Init_rcov_callsite();
314
+ }
315
+ /* vim: set sw=8 expandtab: */
@@ -6,8 +6,18 @@ unless RUBY_PLATFORM == 'java' then
6
6
  have_library("gcov", "__gcov_open")
7
7
 
8
8
  $CFLAGS << " -fprofile-arcs -ftest-coverage"
9
- create_makefile("rcovrt")
9
+ if RUBY_VERSION =~ /1.9/
10
+ $CFLAGS << ' -DRUBY_19_COMPATIBILITY'
11
+ create_makefile("rcovrt", "1.9/")
12
+ else
13
+ create_makefile("rcovrt", "1.8/")
14
+ end
10
15
  else
11
- create_makefile("rcovrt")
16
+ if RUBY_VERSION =~ /1.9/
17
+ $CFLAGS << ' -DRUBY_19_COMPATIBILITY'
18
+ create_makefile("rcovrt", "1.9/")
19
+ else
20
+ create_makefile("rcovrt", "1.8/")
21
+ end
12
22
  end
13
23
  end
@@ -917,8 +917,8 @@ class CallSiteAnalyzer < DifferentialAnalyzer
917
917
  def expand_name(classname_or_fullname, methodname = nil)
918
918
  if methodname.nil?
919
919
  case classname_or_fullname
920
- when /(.*)#(.*)/: classname, methodname = $1, $2
921
- when /(.*)\.(.*)/: classname, methodname = "#<Class:#{$1}>", $2
920
+ when /(.*)#(.*)/ then classname, methodname = $1, $2
921
+ when /(.*)\.(.*)/ then classname, methodname = "#<Class:#{$1}>", $2
922
922
  else
923
923
  raise ArgumentError, "Incorrect method name"
924
924
  end
@@ -99,8 +99,8 @@ class Formatter # :nodoc:
99
99
  @ignore_files = options[:ignore]
100
100
  @dont_ignore_files = options[:dont_ignore]
101
101
  @sort_criterium = case options[:sort]
102
- when :loc : lambda{|fname, finfo| finfo.num_code_lines}
103
- when :coverage : lambda{|fname, finfo| finfo.code_coverage}
102
+ when :loc then lambda{|fname, finfo| finfo.num_code_lines}
103
+ when :coverage then lambda{|fname, finfo| finfo.code_coverage}
104
104
  else lambda{|fname, finfo| fname}
105
105
  end
106
106
  @sort_reverse = options[:sort_reverse]
@@ -773,7 +773,7 @@ EOS
773
773
  tr_(:class => color_classes[color_class_index]) {
774
774
  td_ {
775
775
  case f.name
776
- when "TOTAL":
776
+ when "TOTAL" then
777
777
  t_ { "TOTAL" }
778
778
  else
779
779
  a_(:href => mangle_filename(f.name)){ t_ { f.name } }
@@ -73,37 +73,25 @@ class TestCallSiteAnalyzer < Test::Unit::TestCase
73
73
 
74
74
  def test_basic_defsite_recording
75
75
  @a.run_hooked{ @o.f1 }
76
- verify_defsite_equal(["./test/assets/sample_03.rb", 3],
77
- @a.defsite("Rcov::Test::Temporary::Sample03", "f1"))
78
- verify_defsite_equal(["./test/assets/sample_03.rb", 7],
79
- @a.defsite("Rcov::Test::Temporary::Sample03", "f2"))
80
- verify_defsite_equal(["./test/assets/sample_03.rb", 7],
81
- @a.defsite("Rcov::Test::Temporary::Sample03#f2"))
76
+ verify_defsite_equal(["./test/assets/sample_03.rb", 3], @a.defsite("Rcov::Test::Temporary::Sample03", "f1"))
77
+ verify_defsite_equal(["./test/assets/sample_03.rb", 7], @a.defsite("Rcov::Test::Temporary::Sample03", "f2"))
78
+ verify_defsite_equal(["./test/assets/sample_03.rb", 7], @a.defsite("Rcov::Test::Temporary::Sample03#f2"))
82
79
  end
83
80
 
84
81
  def test_basic_callsite_recording
85
82
  @a.run_hooked{ @o.f1 }
86
83
  assert(@a.analyzed_classes.include?("Rcov::Test::Temporary::Sample03"))
87
84
  assert_equal(%w[f1 f2], @a.analyzed_methods("Rcov::Test::Temporary::Sample03"))
88
- verify_callsites_equal({[[Rcov::Test::Temporary::Sample03, :f1, "./test/assets/sample_03.rb", 4]] => 10},
89
- @a.callsites("Rcov::Test::Temporary::Sample03", "f2"))
90
- verify_callsites_equal({[[Rcov::Test::Temporary::Sample03, :f1, "./test/assets/sample_03.rb", 4]] => 10},
91
- @a.callsites("Rcov::Test::Temporary::Sample03#f2"))
92
- #verify_callsites_equal({["./test/sample_03.rb:4:in `f1'"] => 10},
93
- # @a.callsites("Rcov::Test::Temporary::Sample03", "f2"))
94
- #verify_callsites_equal({["./test/sample_03.rb:4:in `f1'"] => 10},
95
- # @a.callsites("Rcov::Test::Temporary::Sample03#f2"))
85
+ verify_callsites_equal({[[Rcov::Test::Temporary::Sample03, :f1, "./test/assets/sample_03.rb", 4]] => 10}, @a.callsites("Rcov::Test::Temporary::Sample03", "f2"))
86
+ verify_callsites_equal({[[Rcov::Test::Temporary::Sample03, :f1, "./test/assets/sample_03.rb", 4]] => 10}, @a.callsites("Rcov::Test::Temporary::Sample03#f2"))
96
87
  end
97
88
 
98
89
  def test_basic_callsite_recording_API
99
90
  @a.run_hooked{ @o.f1 }
100
91
  assert(@a.analyzed_classes.include?("Rcov::Test::Temporary::Sample03"))
101
92
  assert_equal(%w[f1 f2], @a.analyzed_methods("Rcov::Test::Temporary::Sample03"))
102
- verify_callsites_equal({[[Rcov::Test::Temporary::Sample03, :f1,
103
- "./test/assets/sample_03.rb", 4]] => 10},
104
- @a.callsites("Rcov::Test::Temporary::Sample03", "f2"))
105
- verify_callsites_equal({[[Rcov::Test::Temporary::Sample03, :f1, "./test/assets/sample_03.rb", 4]] => 10},
106
- @a.callsites("Rcov::Test::Temporary::Sample03", "f2"))
93
+ verify_callsites_equal({[[Rcov::Test::Temporary::Sample03, :f1, "./test/assets/sample_03.rb", 4]] => 10}, @a.callsites("Rcov::Test::Temporary::Sample03", "f2"))
94
+ verify_callsites_equal({[[Rcov::Test::Temporary::Sample03, :f1, "./test/assets/sample_03.rb", 4]] => 10}, @a.callsites("Rcov::Test::Temporary::Sample03", "f2"))
107
95
  callsites = @a.callsites("Rcov::Test::Temporary::Sample03", "f2")
108
96
  callsite = callsites.keys[0]
109
97
  #expand path is used here to compensate for differences between JRuby and MRI
@@ -117,12 +105,8 @@ class TestCallSiteAnalyzer < Test::Unit::TestCase
117
105
  @a.run_hooked{ @o.class.g1 }
118
106
  assert(@a.analyzed_classes.include?("#<Class:Rcov::Test::Temporary::Sample03>"))
119
107
  assert_equal(%w[g1 g2], @a.analyzed_methods("#<Class:Rcov::Test::Temporary::Sample03>"))
120
- verify_callsites_equal({[[class << Rcov::Test::Temporary::Sample03; self end,
121
- :g1, "./test/assets/sample_03.rb", 15]] => 10},
122
- @a.callsites("Rcov::Test::Temporary::Sample03.g2"))
123
- verify_callsites_equal({[[class << Rcov::Test::Temporary::Sample03; self end,
124
- :g1, "./test/assets/sample_03.rb", 15]] => 10},
125
- @a.callsites("#<Class:Rcov::Test::Temporary::Sample03>","g2"))
108
+ verify_callsites_equal({[[class << Rcov::Test::Temporary::Sample03; self end, :g1, "./test/assets/sample_03.rb", 15]] => 10}, @a.callsites("Rcov::Test::Temporary::Sample03.g2"))
109
+ verify_callsites_equal({[[class << Rcov::Test::Temporary::Sample03; self end, :g1, "./test/assets/sample_03.rb", 15]] => 10}, @a.callsites("#<Class:Rcov::Test::Temporary::Sample03>","g2"))
126
110
  end
127
111
 
128
112
 
@@ -130,24 +114,17 @@ class TestCallSiteAnalyzer < Test::Unit::TestCase
130
114
  @a.run_hooked{ @o.f1 }
131
115
  assert(@a.analyzed_classes.include?("Rcov::Test::Temporary::Sample03"))
132
116
  assert_equal(%w[f1 f2], @a.analyzed_methods("Rcov::Test::Temporary::Sample03"))
133
- verify_callsites_equal({[[Rcov::Test::Temporary::Sample03, :f1,
134
- "./test/assets/sample_03.rb", 4]] => 10},
135
- @a.callsites("Rcov::Test::Temporary::Sample03", "f2"))
117
+ verify_callsites_equal({[[Rcov::Test::Temporary::Sample03, :f1, "./test/assets/sample_03.rb", 4]] => 10}, @a.callsites("Rcov::Test::Temporary::Sample03", "f2"))
136
118
 
137
119
  @a.run_hooked{ @o.f1 }
138
120
  assert(@a.analyzed_classes.include?("Rcov::Test::Temporary::Sample03"))
139
121
  assert_equal(%w[f1 f2], @a.analyzed_methods("Rcov::Test::Temporary::Sample03"))
140
- verify_callsites_equal({[[Rcov::Test::Temporary::Sample03, :f1,
141
- "./test/assets/sample_03.rb", 4]] => 20},
142
- @a.callsites("Rcov::Test::Temporary::Sample03", "f2"))
122
+ verify_callsites_equal({[[Rcov::Test::Temporary::Sample03, :f1, "./test/assets/sample_03.rb", 4]] => 20}, @a.callsites("Rcov::Test::Temporary::Sample03", "f2"))
143
123
 
144
124
  @a.run_hooked{ @o.f3 }
145
125
  assert_equal(%w[f1 f2 f3], @a.analyzed_methods("Rcov::Test::Temporary::Sample03"))
146
- verify_callsites_equal({[[Rcov::Test::Temporary::Sample03, :f1,
147
- "./test/assets/sample_03.rb", 4]] => 120,
148
- [[Rcov::Test::Temporary::Sample03, :f3,
149
- "./test/assets/sample_03.rb", 11]]=>100 },
150
- @a.callsites("Rcov::Test::Temporary::Sample03", "f2"))
126
+ verify_callsites_equal({[[Rcov::Test::Temporary::Sample03, :f1, "./test/assets/sample_03.rb", 4]] => 120,
127
+ [[Rcov::Test::Temporary::Sample03, :f3, "./test/assets/sample_03.rb", 11]] => 100 }, @a.callsites("Rcov::Test::Temporary::Sample03", "f2"))
151
128
  end
152
129
 
153
130
  def test_reset
@@ -158,10 +135,7 @@ class TestCallSiteAnalyzer < Test::Unit::TestCase
158
135
  end
159
136
  assert(@a.analyzed_classes.include?("Rcov::Test::Temporary::Sample03"))
160
137
  assert_equal(%w[f1 f2], @a.analyzed_methods("Rcov::Test::Temporary::Sample03"))
161
- verify_callsites_equal({[[Rcov::Test::Temporary::Sample03, :f1,
162
- "./test/assets/sample_03.rb", 4]] => 10},
163
- @a.callsites("Rcov::Test::Temporary::Sample03", "f2"))
164
-
138
+ verify_callsites_equal({[[Rcov::Test::Temporary::Sample03, :f1, "./test/assets/sample_03.rb", 4]] => 10}, @a.callsites("Rcov::Test::Temporary::Sample03", "f2"))
165
139
  end
166
140
 
167
141
  def test_nested_callsite_recording
@@ -171,37 +145,27 @@ class TestCallSiteAnalyzer < Test::Unit::TestCase
171
145
  b.run_hooked { @o.f1 }
172
146
  assert(b.analyzed_classes.include?("Rcov::Test::Temporary::Sample03"))
173
147
  assert_equal(%w[f1 f2], b.analyzed_methods("Rcov::Test::Temporary::Sample03"))
174
- verify_callsites_equal({[[Rcov::Test::Temporary::Sample03, :f1,
175
- "./test/assets/sample_03.rb", 4]] => 10},
176
- b.callsites("Rcov::Test::Temporary::Sample03", "f2"))
148
+ verify_callsites_equal({[[Rcov::Test::Temporary::Sample03, :f1, "./test/assets/sample_03.rb", 4]] => 10}, b.callsites("Rcov::Test::Temporary::Sample03", "f2"))
177
149
 
178
150
  @o.f1
179
151
  assert_equal(%w[f1 f2], b.analyzed_methods("Rcov::Test::Temporary::Sample03"))
180
- verify_callsites_equal({[[Rcov::Test::Temporary::Sample03, :f1,
181
- "./test/assets/sample_03.rb", 4]] => 10},
182
- b.callsites("Rcov::Test::Temporary::Sample03", "f2"))
152
+ verify_callsites_equal({[[Rcov::Test::Temporary::Sample03, :f1, "./test/assets/sample_03.rb", 4]] => 10}, b.callsites("Rcov::Test::Temporary::Sample03", "f2"))
183
153
 
184
154
  assert(a.analyzed_classes.include?("Rcov::Test::Temporary::Sample03"))
185
155
  assert_equal(%w[f1 f2], a.analyzed_methods("Rcov::Test::Temporary::Sample03"))
186
- verify_callsites_equal({[[Rcov::Test::Temporary::Sample03, :f1,
187
- "./test/assets/sample_03.rb", 4]] => 20},
188
- a.callsites("Rcov::Test::Temporary::Sample03", "f2"))
156
+ verify_callsites_equal({[[Rcov::Test::Temporary::Sample03, :f1, "./test/assets/sample_03.rb", 4]] => 20}, a.callsites("Rcov::Test::Temporary::Sample03", "f2"))
189
157
  end
158
+
190
159
  b.run_hooked{ @o.f3 }
191
160
  assert_equal(%w[f1 f2 f3], b.analyzed_methods("Rcov::Test::Temporary::Sample03"))
192
- verify_callsites_equal({[[Rcov::Test::Temporary::Sample03, :f1,
193
- "./test/assets/sample_03.rb", 4]] => 110,
194
- [[Rcov::Test::Temporary::Sample03, :f3,
195
- "./test/assets/sample_03.rb", 11]]=>100 },
196
- b.callsites("Rcov::Test::Temporary::Sample03", "f2"))
161
+ verify_callsites_equal({[[Rcov::Test::Temporary::Sample03, :f1, "./test/assets/sample_03.rb", 4]] => 110,
162
+ [[Rcov::Test::Temporary::Sample03, :f3, "./test/assets/sample_03.rb", 11]]=>100 }, b.callsites("Rcov::Test::Temporary::Sample03", "f2"))
197
163
  end
198
164
 
199
165
  def test_expand_name
200
166
  assert_equal(["Foo", "foo"], @a.instance_eval{ expand_name("Foo#foo") })
201
167
  assert_equal(["Foo", "foo"], @a.instance_eval{ expand_name("Foo", "foo") })
202
- assert_equal(["#<Class:Foo>", "foo"],
203
- @a.instance_eval{ expand_name("Foo.foo") })
204
- assert_equal(["#<Class:Foo>", "foo"],
205
- @a.instance_eval{ expand_name("#<Class:Foo>", "foo") })
168
+ assert_equal(["#<Class:Foo>", "foo"], @a.instance_eval{ expand_name("Foo.foo") })
169
+ assert_equal(["#<Class:Foo>", "foo"], @a.instance_eval{ expand_name("#<Class:Foo>", "foo") })
206
170
  end
207
171
  end
@@ -1,7 +1,7 @@
1
1
  require File.dirname(__FILE__) + '/test_helper'
2
2
 
3
3
  class TestCodeCoverageAnalyzer < Test::Unit::TestCase
4
- LINES = <<-EOF.to_a
4
+ LINES = <<-EOF.split "\n"
5
5
  puts 1
6
6
  if foo
7
7
  bar
@@ -88,9 +88,9 @@ EOF
88
88
  analyzer = Rcov::CodeCoverageAnalyzer.new
89
89
  analyzer.run_hooked{ load sample_file }
90
90
  line_info, cov_info, count_info = analyzer.data(sample_file)
91
- assert_equal([1, 2, 0, 0, 1, 0, 11], count_info) unless PLATFORM =~ /java/
91
+ assert_equal([1, 2, 0, 0, 1, 0, 11], count_info) unless (defined? PLATFORM && PLATFORM =~ /java/) || RUBY_VERSION =~ /1.9/
92
92
  # JRUBY reports an if x==blah as hitting this type of line once, JRUBY also optimizes this stuff so you'd have to run with --debug to get "extra" information. MRI hits it twice.
93
- assert_equal([1, 1, 0, 0, 1, 0, 11], count_info) if PLATFORM =~ /java/
93
+ assert_equal([1, 2, 0, 0, 1, 0, 11], count_info) if RUBY_VERSION =~ /1.9/
94
94
 
95
95
  analyzer.reset
96
96
  #set_trace_func proc { |event, file, line, id, binding, classname| printf "%8s %s:%-2d %10s %8s\n", event, file, line, id, classname if (file =~ /sample_02.rb/) }
@@ -98,13 +98,15 @@ EOF
98
98
  sample_file = File.join(File.dirname(__FILE__), "assets/sample_02.rb")
99
99
  analyzer.run_hooked{ load sample_file }
100
100
  line_info, cov_info, count_info = analyzer.data(sample_file)
101
- assert_equal([8, 1, 0, 0, 0], count_info)
101
+ assert_equal([8, 1, 0, 0, 0], count_info) unless RUBY_VERSION =~ /1.9/
102
+ assert_equal([4, 1, 0, 0, 4], count_info) if RUBY_VERSION =~ /1.9/
102
103
 
103
104
  analyzer.reset
104
105
  assert_equal([], analyzer.analyzed_files)
105
106
  analyzer.run_hooked{ Rcov::Test::Temporary::Sample02.foo(1, 1) }
106
107
  line_info, cov_info, count_info = analyzer.data(sample_file)
107
- assert_equal([0, 1, 1, 1, 0], count_info)
108
+ assert_equal([0, 1, 1, 1, 0], count_info) unless RUBY_VERSION =~ /1.9/
109
+ assert_equal([0, 2, 1, 0, 0], count_info) if RUBY_VERSION =~ /1.9/
108
110
  analyzer.run_hooked do
109
111
  10.times{ Rcov::Test::Temporary::Sample02.foo(1, 1) }
110
112
  end
metadata CHANGED
@@ -1,14 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spicycode-rcov
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1.5.6
4
+ version: 0.8.1.5.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mauricio Fernandez
8
+ - Chad Humphries
9
+ - Aaron Bedra
8
10
  autorequire:
9
11
  bindir: bin
10
12
  cert_chain:
11
- date: 2008-08-29 00:00:00 -07:00
13
+ date: 2009-03-17 00:00:00 -07:00
12
14
  default_executable: rcov
13
15
  dependencies: []
14
16
 
@@ -19,10 +21,10 @@ executables:
19
21
  extensions:
20
22
  - ext/rcovrt/extconf.rb
21
23
  extra_rdoc_files:
22
- - readme_for_api
23
- - readme_for_rake
24
- - readme_for_rant
25
- - readme_for_vim
24
+ - doc/readme_for_api
25
+ - doc/readme_for_rake
26
+ - doc/readme_for_rant
27
+ - doc/readme_for_vim
26
28
  files:
27
29
  - bin/rcov
28
30
  - lib/rcov.rb
@@ -31,19 +33,21 @@ files:
31
33
  - lib/rcov/version.rb
32
34
  - lib/rcov/rant.rb
33
35
  - lib/rcov/report.rb
34
- - lib/rcov/rexml_extensions.rb
35
36
  - lib/rcov/rcovtask.rb
36
37
  - ext/rcovrt/extconf.rb
37
- - ext/rcovrt/rcovrt.c
38
- - ext/rcovrt/callsite.c
38
+ - ext/rcovrt/1.8/rcovrt.c
39
+ - ext/rcovrt/1.9/rcovrt.c
40
+ - ext/rcovrt/1.8/callsite.c
41
+ - ext/rcovrt/1.9/callsite.c
39
42
  - LEGAL
40
43
  - LICENSE
41
44
  - Rakefile
42
45
  - Rantfile
43
- - readme_for_rake
44
- - readme_for_rant
45
- - readme_for_vim
46
- - readme_for_api
46
+ - doc/readme_for_rake
47
+ - doc/readme_for_rant
48
+ - doc/readme_for_vim
49
+ - doc/readme_for_emacs
50
+ - doc/readme_for_api
47
51
  - THANKS
48
52
  - test/functional_test.rb
49
53
  - test/file_statistics_test.rb
@@ -57,14 +61,13 @@ files:
57
61
  - test/turn_off_rcovrt.rb
58
62
  - test/call_site_analyzer_test.rb
59
63
  - test/assets/sample_05.rb
60
- - test/rexml_test.rb
61
- - rcov.vim
62
- - rcov.el
64
+ - editor-extensions/rcov.vim
65
+ - editor-extensions/rcov.el
63
66
  - setup.rb
64
67
  - BLURB
65
68
  - CHANGES
66
69
  has_rdoc: true
67
- homepage: http://eigenclass.org/hiki.rb?rcov
70
+ homepage: http://github.com/spicycode/rcov
68
71
  post_install_message:
69
72
  rdoc_options:
70
73
  - --main
@@ -1,44 +0,0 @@
1
- require 'rexml/document'
2
- require 'rexml/formatters/pretty'
3
-
4
- module Rcov
5
- module REXMLExtensions
6
-
7
- def self.fix_pretty_formatter_wrap
8
- REXML::Formatters::Pretty.class_eval do
9
- include PrettyFormatterWrapFix
10
- end
11
- end
12
-
13
- # Fix for this bug: http://clint-hill.com/2008/10/02/a-bug-in-ruby-did-i-just-find-that/
14
- # Also known from this fun exception:
15
- #
16
- # /usr/local/ruby/lib/ruby/1.8/rexml/formatters/pretty.rb:131:in
17
- # `[]': no implicit conversion from nil to integer (TypeError)
18
- #
19
- # This bug was fixed in Ruby with this changeset http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=19487
20
- # ...which should mean that this bug only affects Ruby 1.8.6. The latest stable version of 1.8.7 (and up) should be fine.
21
- module PrettyFormatterWrapFix
22
-
23
- def self.included(base)
24
- base.class_eval do
25
- def wrap(string, width)
26
- # Recursively wrap string at width.
27
- return string if string.length <= width
28
- place = string.rindex(' ', width) # Position in string with last ' ' before cutoff
29
- return string if place.nil?
30
- return string[0,place] + "\n" + wrap(string[place+1..-1], width)
31
- end
32
- end
33
- end
34
-
35
- end
36
-
37
- def self.init!
38
- if RUBY_VERSION == "1.8.6"
39
- fix_pretty_formatter_wrap
40
- end
41
- end
42
- end
43
-
44
- end
@@ -1,23 +0,0 @@
1
- require File.dirname(__FILE__) + '/test_helper'
2
- require 'rcov/rexml_extensions'
3
-
4
- class TestRexml < Test::Unit::TestCase
5
-
6
- def test_wrap_with_long_lines_without_spaces_should_not_break_wrap
7
- Rcov::REXMLExtensions.fix_pretty_formatter_wrap
8
- pretty_formatter = ::REXML::Formatters::Pretty.new
9
- long_string = "this-is-a-long-string-without-any-spaces-to-try-to-break-rexml-formatter-and-it-is-over-100-characters-long"
10
- pretty_formatter.instance_eval { wrap(long_string, 100) } # avoid send, it can't bypass private methods in ruby19
11
- end
12
-
13
- def test_wrap_original_behavior_should_be_preserved
14
- pretty_formatter = REXML::Formatters::Pretty.new
15
- str = "This string should be wrapped at 40 characters"
16
- pretty_formatter.instance_eval do
17
- str = wrap(str, 40)
18
- end # avoid send, it can't bypass private methods in ruby19
19
- assert_equal("This string should be wrapped at 40\ncharacters", str)
20
-
21
- end
22
-
23
- end