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

Restore 100% test coverage #3086

Merged
merged 14 commits into from
May 15, 2024
Merged

Restore 100% test coverage #3086

merged 14 commits into from
May 15, 2024

Conversation

nevinera
Copy link
Contributor

@nevinera nevinera commented May 13, 2024

This is mostly annotational, but there were a few minor tests missing from however long the coverage-check was busted.
The larger items:

  • Add :nocov: annotations to some version-specific code
  • Mark all SecurityError-related code as :nocov:, and conditionalize a few of the specs related to it based on RSpec::Support::RubyFeatures.supports_taint?. They were passing anyway, since they were just checking for "doesn't raise an error", but they weren't actually testing what they said they were testing, when run against anything after ruby-2.6
  • Mark the ForkRunner#run_specs method as :nocov: - it actually is fully covered, but it only executes in a forked process, when run by the integration/bisect_spec.rb, and the Coverage run in the main process doesn't hear about it. But I manually checked, and both conditional branches are getting exercised.
  • Mark the DidYouMean wrapper as :nocov:, since the gem isn't installed on CI - none of the code inside this file can be exercised there (though it is covered anywhere it can run)
  • Add a few obvious specs, based on existing adjacent specs
  • Add a silly spec for Bisect::ShellRunner.name which maybe should just be deleted instead? It's not clear that this method is necessary - if anyone can be confident that it's not, I'd be just as happy to remove it. (But probably in another PR - I like keeping these kinds of things comment/test-only)
  • Start requiring 100% coverage again, now that it's true.
  • If the tests fail, store the coverage output as an artifact. This was because tracking down what lines were uncovered on CI turned out to be fairly annoying; this will make it easy next time.

@nevinera nevinera marked this pull request as draft May 13, 2024 03:50
@nevinera
Copy link
Contributor Author

(Moving back to draft while I figure out what else is covered locally but not in CI)

@nevinera nevinera force-pushed the nev--full-test-coverage branch 3 times, most recently from d0cdac0 to 7ef21be Compare May 13, 2024 04:27
@nevinera nevinera marked this pull request as ready for review May 13, 2024 04:28
Copy link
Member

@pirj pirj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fantastic! Thank you!
Now, if I get asked in a poll if I ever tried to adhere to 100% coverage on any projects I worked on, I can finally answer positively.

lib/rspec/core/formatters/exception_presenter.rb Outdated Show resolved Hide resolved
lib/rspec/core/option_parser.rb Outdated Show resolved Hide resolved
spec/rspec/core/formatters/exception_presenter_spec.rb Outdated Show resolved Hide resolved
end

it '`should_not` does not print a deprecation warning when given a value' do
expect_no_deprecations
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated to the changes in this pr.

Wondering why we test against should_not, but not ‘is_expected.not_to’. To my best memory this is because ‘should’/‘should_not’ are also defined in rspec-core, and we have this spec for is_expected in rspec-expectations.

Why do we expect an Exception here, and not some more specific exception? Also probably to untangle from rspec-expectations that defines them?

Thise are minor either way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have far less clue than you do, but those sound like good hypotheses? I assumed we were handling Exception here (and not StandardError) because the expectation errors aren't descendants of the latter, but I hadn't given it any thought past that. I'm also guessing that the reason for preferring is_expected over should is that the former can be implemented as a matcher, instead of in rspec-core?

@pirj pirj requested a review from JonRowe May 13, 2024 13:37
(and doesn't run in current versions of ruby)
And conditionalize the specs that weren't yet to only run if the
'taint' feature is supported (it was removed in 2.7).
It is actually fully covered (I checked manually) by
spec/integration/bisect_spec.rb, but the code in question is running in
a forked process, so the Coverage instance in the main process doesn't
track it.
The gem isn't installed on CI, so we need to make the coverage optional
(though it is fully covered, when the specs get to run)
This is a pretty silly spec, but the name method here isn't actually
used by anything that I can see - I assume it exists only for symmetry
with the ShellRunner, to present a more consistent interface). Happy
to just drop the method if that's preferred, and if someone else is
confident that it's not relevant to anything.
@@ -123,6 +131,7 @@ jobs:
env:
LEGACY_CI: true
JRUBY_OPTS: ${{ matrix.container.jruby_opts || '--dev' }}
NO_COVERAGE=true
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: this isn't actually impactful, since none of these were running it anyway. But I thought it would be clearer to supply it anyway - happy to drop it again if you disagree!

@nevinera nevinera force-pushed the nev--full-test-coverage branch 3 times, most recently from 0290c7d to caceb39 Compare May 14, 2024 04:21
This allows us to check coverage on lines that only run on modern
rubies, rather than needing to :nocov: them so older rubies can pass the
test suite. It also makes it easy to keep track of and change which
ruby's coverage is being _used_ in CI, since it's just being specified
in an environment variable on the matrix.
Copy link
Member

@pirj pirj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank yo! A couple of cosmetic nitpicks, but not blockers to merge.

script/rspec_with_simplecov Outdated Show resolved Hide resolved
script/rspec_with_simplecov Outdated Show resolved Hide resolved
Copy link
Member

@pirj pirj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My apologies for another round of comments. Now when we have a check for >= 3.1, would it work to run coverage on those versions?
That way we would get rid of a necessity having this coverage_only_on. At a (quite low) cost of running coverage on 3.1 and 3.2. What do you think?

@nevinera
Copy link
Contributor Author

nevinera commented May 15, 2024

My apologies for another round of comments. Now when we have a check for >= 3.1, would it work to run coverage on those versions? That way we would get rid of a necessity having this coverage_only_on. At a (quite low) cost of running coverage on 3.1 and 3.2. What do you think?

Ah! Yes, it shouldn't be necessary anymore. But that does call to mind the reason I had it as an environment variable in the first place, which was that controlling which rubies we want to enforce coverage against should ideally be specified near the matrix, instead of in the script - I should have used that variable for this purpose instead! One moment.

There, that simplifies things a bit. The only remaining awkwardness (that I see) is that if someone is locally running say, 2.7 and runs the script, it'll fail their builds because they don't have 100% coverage. But they can export ENFORCE_COVERAGE_AFTER=3.1 and it'll fix that.. I don't know, should I default it to 3.1 if not supplied, or something?

Copy link
Member

@pirj pirj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@pirj
Copy link
Member

pirj commented May 15, 2024

3.1 coverage seems to be 99.9. I’m ok to enforce on 3.2+

@nevinera
Copy link
Contributor Author

3.1 coverage seems to be 99.9. I’m ok to enforce on 3.2+

Oh, it looks like if SyntaxError.instance_methods.include?(:detailed_message) amounts to 3.2+ - I'll update the boundary :-)

It turns out that this condition:

  SyntaxError.instance_methods.include?(:detailed_message)

is false under ruby-3.1, so we don't have 100% coverage there. Ah well!
@pirj pirj merged commit 8d6898f into rspec:main May 15, 2024
29 of 30 checks passed
@pirj
Copy link
Member

pirj commented May 15, 2024

Thank you!

@pirj pirj mentioned this pull request May 15, 2024
@nevinera
Copy link
Contributor Author

Thank you!

@nevinera nevinera deleted the nev--full-test-coverage branch May 16, 2024 15:22
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

Successfully merging this pull request may close these issues.

None yet

2 participants