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

Finish branch coverage for RSpec/DescribedClass #2030

Conversation

corsonknowles
Copy link
Contributor

@corsonknowles corsonknowles commented Feb 9, 2025

Finish branch coverage for RSpec/DescribedClass

Showing that the tested code evaluates:

zenpayroll(dev)* class MyClass3
zenpayroll(dev)> end
=> nil
zenpayroll(dev)> ("MyClass" + "3").constantize
=> MyClass3

zenpayroll(dev)* class MyClass3; class MyClass; end;
zenpayroll(dev)> end
=> nil
zenpayroll(dev)> (("MyClass" + "3").constantize)::MyClass
=> MyClass3::MyClass

Although at this point the math is superfluous -- (method_that_returns_a_class)::MyClass will cover this branch while method_that_returns_a_class::MyClass will not

Before:
Screenshot 2025-02-08 at 10 25 14 PM
After:
Screenshot 2025-02-08 at 10 25 31 PM


Before submitting the PR make sure the following are checked:

  • Feature branch is up-to-date with master (if not - rebase it).
  • Squashed related commits together.
  • Added tests.
  • Updated documentation.
  • Added an entry to the CHANGELOG.md if the new code introduces user-observable changes.
  • The build (bundle exec rake) passes (be sure to run this locally, since it may produce updated documentation that you will need to commit).

If you have created a new cop:

  • Added the new cop to config/default.yml.
  • The cop is configured as Enabled: pending in config/default.yml.
  • The cop is configured as Enabled: true in .rubocop.yml.
  • The cop documents examples of good and bad code.
  • The tests assert both that bad code is reported and that good code is not reported.
  • Set VersionAdded: "<<next>>" in default/config.yml.

If you have modified an existing cop's configuration options:

  • Set VersionChanged: "<<next>>" in config/default.yml.

@corsonknowles corsonknowles requested a review from a team as a code owner February 9, 2025 02:16
@bquorning
Copy link
Collaborator

bquorning commented Feb 9, 2025

(1 + 2)::MyClass generates invalid Ruby, since a module cannot be named 3. Can we can come up with a valid example that hits the else branch? Otherwise, if the code is unreachable, we can tell SimpleCov to ignore it with

          else
            # :nocov:
            raise "Invalid argument" # or similar
            # :nocov:

@bquorning bquorning added this to the Code coverage milestone Feb 9, 2025
@corsonknowles corsonknowles force-pushed the finish_branch_coverage_for_described_class branch from 29bd635 to a64bebc Compare February 9, 2025 14:55
@corsonknowles
Copy link
Contributor Author

Thanks @bquorning -- it works with a little magic sprinkled in, and it documents the behavior I think.

@corsonknowles
Copy link
Contributor Author

It's possible there's another approach here to handle the s(:begin, block this example creates in the AST, but I don't know how it should handle that.

it 'ignores a class with a dynamic namespace' do
expect_no_offenses(<<~RUBY)
describe MyClass do
subject { (("MyClass" + "3").constantize)::MyClass }
Copy link
Collaborator

Choose a reason for hiding this comment

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

This example still seems a bit far fetched 😅

Copy link
Collaborator

Choose a reason for hiding this comment

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

I’ll see in real-world-rspec if there’s any code that hits the branch you’re looking at.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not just far fetched, a little hard to find! A good puzzle.

I buried this in the updated description above, but the way we're getting past the case statement here is just by having a :begin node from the parentheses.

I replaced the example with a simpler parenthesized method call.

The weird thing is:
subject { method_that_returns_a_class::MyClass }
does get handled.

I'm not certain how method_that_returns_a_class or (method_that_returns_a_class) ought to be corrected, but maybe they should be handled identically.

Copy link
Collaborator

@bquorning bquorning Feb 9, 2025

Choose a reason for hiding this comment

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

subject { method_that_returns_a_class::MyClass } makes namespace a send type, whereas subject { (method_that_returns_a_class)::MyClass } makes namespace a begin type. So maybe the test case we want is just explicitly having parentheses around the namespace?

@corsonknowles corsonknowles force-pushed the finish_branch_coverage_for_described_class branch from a64bebc to 8cfcd26 Compare February 9, 2025 16:38
@bquorning
Copy link
Collaborator

Btw I just found that changing line 85 from let(:baz) { foo::CONST } to let(:baz) { @foo::CONST } will raise an exception. Not sure if that is related at all, or should be a separate issue.

@corsonknowles corsonknowles force-pushed the finish_branch_coverage_for_described_class branch from 8cfcd26 to 67ecc8f Compare February 9, 2025 17:19
@corsonknowles
Copy link
Contributor Author

Btw I just found that changing line 85 from let(:baz) { foo::CONST } to let(:baz) { @foo::CONST } will raise an exception. Not sure if that is related at all, or should be a separate issue.

Great find! Separate issue, but another perk of the exercise.

Copy link
Collaborator

@bquorning bquorning left a comment

Choose a reason for hiding this comment

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

Don’t forget to update .simplecov ✨

@corsonknowles
Copy link
Contributor Author

corsonknowles commented Feb 9, 2025 via email

@bquorning bquorning merged commit 226f332 into rubocop:master Feb 9, 2025
27 checks passed
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.

2 participants