mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	Enable coverage for eval.
This commit is contained in:
		
							parent
							
								
									4c37eaa979
								
							
						
					
					
						commit
						9434a7333c
					
				
				
				Notes:
				
					git
				
				2022-09-22 19:19:45 +09:00 
				
			
			
			
		
		
					 5 changed files with 64 additions and 14 deletions
				
			
		| 
						 | 
				
			
			@ -2308,9 +2308,9 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
 | 
			
		|||
                if (ISEQ_COVERAGE(iseq)) {
 | 
			
		||||
                    if (ISEQ_LINE_COVERAGE(iseq) && (events & RUBY_EVENT_COVERAGE_LINE) &&
 | 
			
		||||
                        !(rb_get_coverage_mode() & COVERAGE_TARGET_ONESHOT_LINES)) {
 | 
			
		||||
                        int line = iobj->insn_info.line_no;
 | 
			
		||||
                        if (line >= 1) {
 | 
			
		||||
                            RARRAY_ASET(ISEQ_LINE_COVERAGE(iseq), line - 1, INT2FIX(0));
 | 
			
		||||
                        int line = iobj->insn_info.line_no - 1;
 | 
			
		||||
                        if (line >= 0 && line < RARRAY_LEN(ISEQ_LINE_COVERAGE(iseq))) {
 | 
			
		||||
                            RARRAY_ASET(ISEQ_LINE_COVERAGE(iseq), line, INT2FIX(0));
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    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)->builtin_function_table = GET_VM()->builtin_function_table;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    if (option->coverage_enabled) {
 | 
			
		||||
        VALUE coverages = rb_get_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_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,
 | 
			
		||||
                                parent, isolated_depth, ISEQ_TYPE_EVAL, &COMPILE_OPTION_DEFAULT);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -91,15 +91,31 @@ describe 'Coverage.result' do
 | 
			
		|||
    Coverage.result.should_not include(@config_file)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  it 'returns the correct results when eval is used' do
 | 
			
		||||
    Coverage.start
 | 
			
		||||
    require @eval_code_file.chomp('.rb')
 | 
			
		||||
    result = Coverage.result
 | 
			
		||||
  ruby_version_is '3.1'...'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, nil, nil, nil, nil, nil, 1
 | 
			
		||||
        ]
 | 
			
		||||
    }
 | 
			
		||||
      result.should == {
 | 
			
		||||
          @eval_code_file => [
 | 
			
		||||
              1, nil, 1, nil, 1, nil, nil, nil, nil, nil, 1
 | 
			
		||||
          ]
 | 
			
		||||
      }
 | 
			
		||||
    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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -136,7 +136,7 @@ class TestCoverage < Test::Unit::TestCase
 | 
			
		|||
          f.puts 'REPEATS = 400'
 | 
			
		||||
          f.puts 'def add_method(target)'
 | 
			
		||||
          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 '        #{"\n" * rand(REPEATS)}'
 | 
			
		||||
          f.puts '      end'
 | 
			
		||||
| 
						 | 
				
			
			@ -157,6 +157,21 @@ class TestCoverage < Test::Unit::TestCase
 | 
			
		|||
    }
 | 
			
		||||
  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
 | 
			
		||||
    assert_ruby_status(%w[], "#{<<-"begin;"}\n#{<<-'end;'}")
 | 
			
		||||
    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_ast_t *ast;
 | 
			
		||||
    int isolated_depth = 0;
 | 
			
		||||
    int coverage_enabled = Qtrue;
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        int depth = 1;
 | 
			
		||||
        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);
 | 
			
		||||
        }
 | 
			
		||||
        fname = eval_default_path;
 | 
			
		||||
        coverage_enabled = Qfalse;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rb_parser_set_context(parser, parent, FALSE);
 | 
			
		||||
    ast = rb_parser_compile_string_path(parser, fname, src, line);
 | 
			
		||||
    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_BODY(parent)->location.label,
 | 
			
		||||
                                fname, Qnil, INT2FIX(line),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue