Enable coverage for eval.
This commit is contained in:
parent
4c37eaa979
commit
9434a7333c
Notes:
git
2022-09-22 19:19:45 +09:00
@ -2308,9 +2308,9 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
|
|||||||
if (ISEQ_COVERAGE(iseq)) {
|
if (ISEQ_COVERAGE(iseq)) {
|
||||||
if (ISEQ_LINE_COVERAGE(iseq) && (events & RUBY_EVENT_COVERAGE_LINE) &&
|
if (ISEQ_LINE_COVERAGE(iseq) && (events & RUBY_EVENT_COVERAGE_LINE) &&
|
||||||
!(rb_get_coverage_mode() & COVERAGE_TARGET_ONESHOT_LINES)) {
|
!(rb_get_coverage_mode() & COVERAGE_TARGET_ONESHOT_LINES)) {
|
||||||
int line = iobj->insn_info.line_no;
|
int line = iobj->insn_info.line_no - 1;
|
||||||
if (line >= 1) {
|
if (line >= 0 && line < RARRAY_LEN(ISEQ_LINE_COVERAGE(iseq))) {
|
||||||
RARRAY_ASET(ISEQ_LINE_COVERAGE(iseq), line - 1, INT2FIX(0));
|
RARRAY_ASET(ISEQ_LINE_COVERAGE(iseq), line, INT2FIX(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ISEQ_BRANCH_COVERAGE(iseq) && (events & RUBY_EVENT_COVERAGE_BRANCH)) {
|
if (ISEQ_BRANCH_COVERAGE(iseq) && (events & RUBY_EVENT_COVERAGE_BRANCH)) {
|
||||||
|
13
iseq.c
13
iseq.c
@ -697,7 +697,6 @@ prepare_iseq_build(rb_iseq_t *iseq,
|
|||||||
ISEQ_COMPILE_DATA(iseq)->ivar_cache_table = NULL;
|
ISEQ_COMPILE_DATA(iseq)->ivar_cache_table = NULL;
|
||||||
ISEQ_COMPILE_DATA(iseq)->builtin_function_table = GET_VM()->builtin_function_table;
|
ISEQ_COMPILE_DATA(iseq)->builtin_function_table = GET_VM()->builtin_function_table;
|
||||||
|
|
||||||
|
|
||||||
if (option->coverage_enabled) {
|
if (option->coverage_enabled) {
|
||||||
VALUE coverages = rb_get_coverages();
|
VALUE coverages = rb_get_coverages();
|
||||||
if (RTEST(coverages)) {
|
if (RTEST(coverages)) {
|
||||||
@ -928,6 +927,18 @@ rb_iseq_new_main(const rb_ast_body_t *ast, VALUE path, VALUE realpath, const rb_
|
|||||||
rb_iseq_t *
|
rb_iseq_t *
|
||||||
rb_iseq_new_eval(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath, VALUE first_lineno, const rb_iseq_t *parent, int isolated_depth)
|
rb_iseq_new_eval(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath, VALUE first_lineno, const rb_iseq_t *parent, int isolated_depth)
|
||||||
{
|
{
|
||||||
|
VALUE coverages = rb_get_coverages();
|
||||||
|
if (RTEST(coverages) && RTEST(path) && !RTEST(rb_hash_has_key(coverages, path))) {
|
||||||
|
int line_offset = RB_NUM2INT(first_lineno) - 1;
|
||||||
|
int line_count = line_offset + ast_line_count(ast);
|
||||||
|
|
||||||
|
if (line_count >= 0) {
|
||||||
|
int len = (rb_get_coverage_mode() & COVERAGE_TARGET_ONESHOT_LINES) ? 0 : line_count;
|
||||||
|
VALUE coverage = rb_default_coverage(len);
|
||||||
|
rb_hash_aset(coverages, path, coverage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return rb_iseq_new_with_opt(ast, name, path, realpath, first_lineno,
|
return rb_iseq_new_with_opt(ast, name, path, realpath, first_lineno,
|
||||||
parent, isolated_depth, ISEQ_TYPE_EVAL, &COMPILE_OPTION_DEFAULT);
|
parent, isolated_depth, ISEQ_TYPE_EVAL, &COMPILE_OPTION_DEFAULT);
|
||||||
}
|
}
|
||||||
|
@ -91,6 +91,7 @@ describe 'Coverage.result' do
|
|||||||
Coverage.result.should_not include(@config_file)
|
Coverage.result.should_not include(@config_file)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
ruby_version_is '3.1'...'3.2' do
|
||||||
it 'returns the correct results when eval is used' do
|
it 'returns the correct results when eval is used' do
|
||||||
Coverage.start
|
Coverage.start
|
||||||
require @eval_code_file.chomp('.rb')
|
require @eval_code_file.chomp('.rb')
|
||||||
@ -102,4 +103,19 @@ describe 'Coverage.result' do
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ruby_version_is '3.2' do
|
||||||
|
it 'returns the correct results when eval is used' do
|
||||||
|
Coverage.start
|
||||||
|
require @eval_code_file.chomp('.rb')
|
||||||
|
result = Coverage.result
|
||||||
|
|
||||||
|
result.should == {
|
||||||
|
@eval_code_file => [
|
||||||
|
1, nil, 1, nil, 1, 1, nil, nil, nil, nil, 1
|
||||||
|
]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -136,7 +136,7 @@ class TestCoverage < Test::Unit::TestCase
|
|||||||
f.puts 'REPEATS = 400'
|
f.puts 'REPEATS = 400'
|
||||||
f.puts 'def add_method(target)'
|
f.puts 'def add_method(target)'
|
||||||
f.puts ' REPEATS.times do'
|
f.puts ' REPEATS.times do'
|
||||||
f.puts ' target.class_eval(<<~RUBY, __FILE__, __LINE__ + 1)'
|
f.puts ' target.class_eval(<<~RUBY)'
|
||||||
f.puts ' def foo'
|
f.puts ' def foo'
|
||||||
f.puts ' #{"\n" * rand(REPEATS)}'
|
f.puts ' #{"\n" * rand(REPEATS)}'
|
||||||
f.puts ' end'
|
f.puts ' end'
|
||||||
@ -157,6 +157,21 @@ class TestCoverage < Test::Unit::TestCase
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_eval_coverage
|
||||||
|
assert_in_out_err(%w[-rcoverage], <<-"end;", ["[1, nil, 1, nil]"], [])
|
||||||
|
Coverage.start
|
||||||
|
|
||||||
|
eval(<<-RUBY, TOPLEVEL_BINDING, "test.rb")
|
||||||
|
s = String.new
|
||||||
|
begin
|
||||||
|
s << "foo
|
||||||
|
bar".freeze; end
|
||||||
|
RUBY
|
||||||
|
|
||||||
|
p Coverage.result["test.rb"]
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
|
||||||
def test_nocoverage_optimized_line
|
def test_nocoverage_optimized_line
|
||||||
assert_ruby_status(%w[], "#{<<-"begin;"}\n#{<<-'end;'}")
|
assert_ruby_status(%w[], "#{<<-"begin;"}\n#{<<-'end;'}")
|
||||||
begin;
|
begin;
|
||||||
|
@ -1672,6 +1672,8 @@ eval_make_iseq(VALUE src, VALUE fname, int line, const rb_binding_t *bind,
|
|||||||
rb_iseq_t *iseq = NULL;
|
rb_iseq_t *iseq = NULL;
|
||||||
rb_ast_t *ast;
|
rb_ast_t *ast;
|
||||||
int isolated_depth = 0;
|
int isolated_depth = 0;
|
||||||
|
int coverage_enabled = Qtrue;
|
||||||
|
|
||||||
{
|
{
|
||||||
int depth = 1;
|
int depth = 1;
|
||||||
const VALUE *ep = vm_block_ep(base_block);
|
const VALUE *ep = vm_block_ep(base_block);
|
||||||
@ -1703,11 +1705,17 @@ eval_make_iseq(VALUE src, VALUE fname, int line, const rb_binding_t *bind,
|
|||||||
rb_gc_register_mark_object(eval_default_path);
|
rb_gc_register_mark_object(eval_default_path);
|
||||||
}
|
}
|
||||||
fname = eval_default_path;
|
fname = eval_default_path;
|
||||||
|
coverage_enabled = Qfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
rb_parser_set_context(parser, parent, FALSE);
|
rb_parser_set_context(parser, parent, FALSE);
|
||||||
ast = rb_parser_compile_string_path(parser, fname, src, line);
|
ast = rb_parser_compile_string_path(parser, fname, src, line);
|
||||||
if (ast->body.root) {
|
if (ast->body.root) {
|
||||||
|
if (ast->body.compile_option == Qnil) {
|
||||||
|
ast->body.compile_option = rb_obj_hide(rb_ident_hash_new());
|
||||||
|
}
|
||||||
|
rb_hash_aset(ast->body.compile_option, rb_sym_intern_ascii_cstr("coverage_enabled"), coverage_enabled);
|
||||||
|
|
||||||
iseq = rb_iseq_new_eval(&ast->body,
|
iseq = rb_iseq_new_eval(&ast->body,
|
||||||
ISEQ_BODY(parent)->location.label,
|
ISEQ_BODY(parent)->location.label,
|
||||||
fname, Qnil, INT2FIX(line),
|
fname, Qnil, INT2FIX(line),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user