Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

option to disable line warnings with enable_coverage_for_eval and rails views #1057

Open
dgarwood opened this issue Apr 20, 2023 · 3 comments

Comments

@dgarwood
Copy link

Couldn't find an issue that was directly related to this, please forgive me if I've overlooked something.

Love enable_coverage_for_eval since that allows getting coverage metrics for rails views, which was something that until Ruby 3.2, you had to do without. However, turning it on results in a lot of warnings, relative to this method in lib/simplecov/source_file.rb:

# lib/simplecov/source_file.rb:250-253
    # Warning to identify condition from Issue #56
    def coverage_exceeding_source_warn
      warn "Warning: coverage data provided by Coverage [#{coverage_data['lines'].size}] exceeds number of lines in #{filename} [#{src.size}]"
    end

Reviewing Issue#56, it wasn't clear why this warning occurs, other than we know that we're getting more lines reported for a source file than the code in the file actually has. I have not been able to determine why this is, but suspect it might be due to erb inserting lines in the file.

Below is a copy of the patch I created to allow turning these warnings off with an ENV var. Granted this is a crude fix, but it helps to clean up our test output.

My request is getting the below patch or something like it included in simplecov. Ultimately, these warnings are not helpful in their current form for view specs, since it's not clear why this is an issue or what can be done to resolve it.

$ ruby -e "puts RUBY_DESCRIPTION"
ruby 3.2.0 (2022-12-25 revision a528908271) [x86_64-linux]

Rails 7.0.4.3
RSpec 3.12.0
SimpleCov 0.22.0

tests are run with bin/rspec spec manually or via guard.

# spec/spec_helper.rb
# frozen_string_literal: true

unless RSpec.configuration.files_to_run.one?
  require 'simplecov'
  require_relative 'support/simplecov_warnings_patch'
  SimpleCov.start 'rails' do
    enable_coverage :branch
    enable_coverage_for_eval
    # minimum_coverage line: 85, branch: 70
    # maximum_coverage_drop 5
  end
end

...
<more spec_helper>

# spec/support/simplecov_warnings_patch.rb
# frozen_string_literal: true

module SimpleCov
  class SourceFile
    # this is needed for SimpleCov Issue#56
    # it also shows up for views when we `enable_coverage_for_eval`
    # patching here so that we can turn this off via ENV VAR
    def coverage_exceeding_source_warn
      return unless ENV['SHOW_EXCESS_LINE_WARNING']

      message = "Warning: coverage data provided by Coverage [#{coverage_data['lines'].size}] "
      message += "exceeds number of lines in #{filename} [#{src.size}]"
      warn message
    end
  end
end

This is an example view spec for devise (v4.8.1) that reproduces the issue (remove the unless wrapper on SimpleCov config to get results from specs for a single file):

# spec/views/devise/registrations/new.html.erb_spec.rb
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe 'devise/registrations/new.html.erb' do
  let(:resource) { build_stubbed :user }
  let(:devise_mapping) { Devise.mappings[:user] }

  before do
    render template: 'devise/registrations/new', \
           locals: { resource:, resource_name: :user, devise_mapping: }
  end

  it 'accepts username' do
    expect(rendered).to have_css '#user_username'
  end

  it 'accepts email' do
    expect(rendered).to have_css '#user_email'
  end
end

Again, main focus here is to have an env var or config option added to simplecov that allows silencing the warnings from the coverage_exceeding_source_warn method.

@dnalbach
Copy link

I am experiencing this too and am in favor of the ENV var fix.

@joshuapinter
Copy link
Contributor

I'm also seeing this since enabling enable_coverage_for_eval.

Silencing them could work in the meantime but hopefully a better solution that correctly identifies the # of lines for erb files is possible as well.

@oniram88
Copy link

oniram88 commented Jun 7, 2023

I think that the problem is with only one line,
every erb to ruby compilation add a first line: #coding:UTF-8

require "erb"
example = "hello <%= 'world' %>"
compiler = ERB.new(example)
puts compiler.src

get =>

#coding:UTF-8
_erbout = +''; _erbout.<< "hello ".freeze; _erbout.<<(( 'world' ).to_s); _erbout

this will then be executed from eval, src is 2 lines, coverage 1

I suppose that if you have nested renders in the same view you will have one line per nested template added to the total count of lines that will be evalueted, but i'm not sure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants