mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Add method coverage
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59888 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
a5641cdf7a
commit
78cf46078e
4 changed files with 83 additions and 2 deletions
14
compile.c
14
compile.c
|
@ -277,6 +277,19 @@ struct iseq_compile_data_ensure_node_stack {
|
|||
ADD_INSN2((seq), (line), trace2, INT2FIX(RUBY_EVENT_COVERAGE), INT2FIX(counter_idx * 16 + COVERAGE_INDEX_BRANCHES)); \
|
||||
} \
|
||||
} while (0)
|
||||
#define ADD_TRACE_METHOD_COVERAGE(seq, line, method_name) \
|
||||
do { \
|
||||
if (ISEQ_COVERAGE(iseq) && \
|
||||
ISEQ_METHOD_COVERAGE(iseq) && \
|
||||
(line) > 0) { \
|
||||
VALUE methods = ISEQ_METHOD_COVERAGE(iseq); \
|
||||
long counter_idx = RARRAY_LEN(methods) / 3; \
|
||||
rb_ary_push(methods, ID2SYM(method_name)); \
|
||||
rb_ary_push(methods, INT2FIX(line)); \
|
||||
rb_ary_push(methods, INT2FIX(0)); \
|
||||
ADD_INSN2((seq), (line), trace2, INT2FIX(RUBY_EVENT_COVERAGE), INT2FIX(counter_idx * 16 + COVERAGE_INDEX_METHODS)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define ADD_TRACE(seq, line, event) \
|
||||
do { \
|
||||
|
@ -637,6 +650,7 @@ rb_iseq_compile_node(rb_iseq_t *iseq, NODE *node)
|
|||
case ISEQ_TYPE_METHOD:
|
||||
{
|
||||
ADD_TRACE(ret, FIX2INT(iseq->body->location.first_lineno), RUBY_EVENT_CALL);
|
||||
ADD_TRACE_METHOD_COVERAGE(ret, FIX2INT(iseq->body->location.first_lineno), rb_intern_str(iseq->body->location.label));
|
||||
CHECK(COMPILE(ret, "scoped node", node->nd_body));
|
||||
ADD_TRACE(ret, nd_line(node), RUBY_EVENT_RETURN);
|
||||
break;
|
||||
|
|
|
@ -92,6 +92,22 @@ branch_coverage(VALUE branches)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
method_coverage(VALUE methods)
|
||||
{
|
||||
VALUE ret = rb_hash_new();
|
||||
int i, id;
|
||||
|
||||
for (i = 0; i < RARRAY_LEN(methods); ) {
|
||||
VALUE method_name = RARRAY_AREF(methods, i++);
|
||||
VALUE lineno = RARRAY_AREF(methods, i++);
|
||||
VALUE counter = RARRAY_AREF(methods, i++);
|
||||
rb_hash_aset(ret, rb_ary_new_from_args(3, method_name, INT2FIX(id++), lineno), counter);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
coverage_peek_result_i(st_data_t key, st_data_t val, st_data_t h)
|
||||
{
|
||||
|
@ -121,7 +137,7 @@ coverage_peek_result_i(st_data_t key, st_data_t val, st_data_t h)
|
|||
}
|
||||
|
||||
if (methods) {
|
||||
rb_hash_aset(h, ID2SYM(rb_intern("methods")), methods);
|
||||
rb_hash_aset(h, ID2SYM(rb_intern("methods")), method_coverage(methods));
|
||||
}
|
||||
|
||||
rb_hash_freeze(h);
|
||||
|
|
|
@ -280,4 +280,29 @@ class TestCoverage < Test::Unit::TestCase
|
|||
}
|
||||
}
|
||||
end
|
||||
|
||||
def test_method_coverage
|
||||
Dir.mktmpdir {|tmp|
|
||||
Dir.chdir(tmp) {
|
||||
File.open("test.rb", "w") do |f|
|
||||
f.puts 'def foo; end'
|
||||
f.puts 'def bar'
|
||||
f.puts 'end'
|
||||
f.puts 'def baz; end'
|
||||
f.puts ''
|
||||
f.puts 'foo'
|
||||
f.puts 'foo'
|
||||
f.puts 'bar'
|
||||
end
|
||||
|
||||
assert_in_out_err(%w[-W0 -rcoverage], <<-"end;", ["{:methods=>{[:foo, 0, 1]=>2, [:bar, 1, 2]=>1, [:baz, 2, 4]=>0}}"], [])
|
||||
ENV["COVERAGE_EXPERIMENTAL_MODE"] = "true"
|
||||
Coverage.start(methods: true)
|
||||
tmp = Dir.pwd
|
||||
require tmp + '/test.rb'
|
||||
p Coverage.result[tmp + "/test.rb"]
|
||||
end;
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
28
thread.c
28
thread.c
|
@ -4094,6 +4094,7 @@ clear_coverage_i(st_data_t key, st_data_t val, st_data_t dummy)
|
|||
VALUE coverage = (VALUE)val;
|
||||
VALUE lines = RARRAY_AREF(coverage, COVERAGE_INDEX_LINES);
|
||||
VALUE branches = RARRAY_AREF(coverage, COVERAGE_INDEX_BRANCHES);
|
||||
VALUE methods = RARRAY_AREF(coverage, COVERAGE_INDEX_METHODS);
|
||||
|
||||
if (lines) {
|
||||
for (i = 0; i < RARRAY_LEN(lines); i++) {
|
||||
|
@ -4108,6 +4109,11 @@ clear_coverage_i(st_data_t key, st_data_t val, st_data_t dummy)
|
|||
RARRAY_ASET(counters, i, INT2FIX(0));
|
||||
}
|
||||
}
|
||||
if (methods) {
|
||||
for (i = 2; i < RARRAY_LEN(methods); i += 3) {
|
||||
RARRAY_ASET(methods, i, INT2FIX(0));
|
||||
}
|
||||
}
|
||||
|
||||
return ST_CONTINUE;
|
||||
}
|
||||
|
@ -5016,6 +5022,19 @@ update_coverage(VALUE data, const rb_trace_arg_t *trace_arg)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case COVERAGE_INDEX_METHODS: {
|
||||
VALUE methods = RARRAY_AREF(coverage, COVERAGE_INDEX_METHODS);
|
||||
if (methods) {
|
||||
long count;
|
||||
long idx = arg / 16 * 3 + 2;
|
||||
VALUE num = RARRAY_AREF(methods, idx);
|
||||
count = FIX2LONG(num) + 1;
|
||||
if (POSFIXABLE(count)) {
|
||||
RARRAY_ASET(methods, idx, LONG2FIX(count));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5088,7 +5107,14 @@ rb_default_coverage(int n)
|
|||
RARRAY_ASET(coverage, COVERAGE_INDEX_BRANCHES, branches);
|
||||
|
||||
if (mode & COVERAGE_TARGET_METHODS) {
|
||||
/* not implemented yet */
|
||||
methods = rb_ary_tmp_new(0);
|
||||
/* internal data structures for method coverage:
|
||||
*
|
||||
* [symbol_of_method_name, lineno_of_method_head, counter,
|
||||
* ...]
|
||||
*
|
||||
* Example: [:foobar, 1, 0, ...]
|
||||
*/
|
||||
}
|
||||
RARRAY_ASET(coverage, COVERAGE_INDEX_METHODS, methods);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue