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

RSpec aliases runtime matchers #956

Merged
merged 1 commit into from Nov 3, 2020

Conversation

sl4vr
Copy link
Contributor

@sl4vr sl4vr commented Jul 7, 2020

This is an attempt of implementation of issue #333 and evolution of PR #921. Allowing to configure 3rd partly DSLs as valid RSpec syntax.

Configurable language elements:

  • Hooks
  • Examples
  • Hook scopes
  • Includes
  • Example groups
  • Shared groups
  • Helpers
  • Subject
  • Expectations
  • Runners

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. (Add v2 update docs #1013)
  • 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).

@sl4vr sl4vr marked this pull request as draft July 7, 2020 18:26
@sl4vr sl4vr force-pushed the rspec-aliases_runtime-matchers branch 3 times, most recently from 2d63428 to f310907 Compare July 8, 2020 08:22
@sl4vr
Copy link
Contributor Author

sl4vr commented Jul 8, 2020

Looks like smoke tests fail, need to rewrite RuntimeMacros in a same manner like RuboCop's Macros are made.
Seems that smoke tests fail due to another reason, which should be fixed here: #955

@sl4vr sl4vr force-pushed the rspec-aliases_runtime-matchers branch 3 times, most recently from 62c3a15 to 346b685 Compare July 8, 2020 16:45
@sl4vr sl4vr closed this Jul 8, 2020
@sl4vr sl4vr force-pushed the rspec-aliases_runtime-matchers branch from 346b685 to 44e7d6e Compare July 8, 2020 16:49
@sl4vr sl4vr reopened this Jul 8, 2020
@sl4vr sl4vr force-pushed the rspec-aliases_runtime-matchers branch 3 times, most recently from 853e47b to bfa1475 Compare July 14, 2020 07:02
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.

Frankly, it looks great. All code review notes are minor nitpicks.

I'm concerned about two major things:

  • performance impact: dynamic way to define matchers may cost us
  • consistency: are we going to use this approach for all RSpec's DSL constructs

If there's no significant performance impact (e.g. on Discourse/GitLab specs suite runs), I'll be more than happy to merge this. We'll eventually catch up and rework other DSL elements to use this dynamic configuration.

lib/rubocop/rspec/example_group.rb Outdated Show resolved Hide resolved
lib/rubocop/rspec/language/runtime_macros.rb Outdated Show resolved Hide resolved
lib/rubocop/cop/rspec/described_class.rb Outdated Show resolved Hide resolved
lib/rubocop/cop/rspec/empty_hook.rb Outdated Show resolved Hide resolved
lib/rubocop/rspec/language.rb Outdated Show resolved Hide resolved
@pirj pirj changed the title WIP: Rspec aliases runtime matchers RSpec aliases runtime matchers Jul 15, 2020
@pirj
Copy link
Member

pirj commented Aug 2, 2020

@sl4vr Do you need some help with this?
Highly appreciate if you could at least come up with a PoC, I can take it from there if you like, or we can share the work if you like.

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.

Looks good! 👏
Minor notes, mostly on how to keep the existing cops intact.
Eager to rework the rest in the same way and start hacking on adding the missing DSL pieces.

lib/rubocop/cop/rspec/dialect.rb Show resolved Hide resolved
lib/rubocop/cop/rspec/hook_argument.rb Outdated Show resolved Hide resolved
lib/rubocop/cop/rspec/named_subject.rb Show resolved Hide resolved
lib/rubocop/rspec/language.rb Outdated Show resolved Hide resolved
lib/rubocop/rspec/language.rb Outdated Show resolved Hide resolved
@sl4vr sl4vr force-pushed the rspec-aliases_runtime-matchers branch 4 times, most recently from 9590e21 to 89acc68 Compare August 6, 2020 06:58
@sl4vr
Copy link
Contributor Author

sl4vr commented Aug 7, 2020

NodePattern is bloated a bit with similar methods, I would wait for all RSpec language parts implementation and then do something like:

{
  regular_examples: ['Examples', 'Regular'],
  focused_examples: ['Examples', 'Focused'],
  skipped_examples: ['Examples', 'Skipped'],
  pending_examples: ['Examples', 'Pending'],
  hooks: ['Hooks'],
}.each do |name, config_keys|
  define_method "rspec_#{name}" do |keyword|
    send("#{name}_set").include?(keyword)
  end

  define_method "#{name}_set" do
    instance_variable_get("@#{name}_set") ||
      instance_variable_set(
        "@#{name}_set",
        Set.new(rspec_language_for(*config_keys))
      )
  end
end

Because it highly depends on config and may change yet.

@pirj
Copy link
Member

pirj commented Nov 2, 2020

@bquorning True. Fixed this by tagging those specs :config, adding a cop to be investigated and calling on_new_investigation on this cop. It's kind of a trick to set Language for those specs that typically happens automatically when expect_offense conducts an investigation.
Specs in question were Concept specs (Example, ExampleGroup, Hook) that don't call expect_offense.

@pirj
Copy link
Member

pirj commented Nov 2, 2020

@bquorning Both this PR's build and #1007 that I've just rebased onto this are green.

@bquorning
Copy link
Collaborator

But how come the specs passed when run with the entire suite? Usually it means there is some global state being changed somewhere.

@pirj
Copy link
Member

pirj commented Nov 2, 2020

There is indeed global state, in Language.config that is assigned when the first cop is initialized and starts the investigation.

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.

This PR looks so much better now. I think we are getting very close to merging.

lib/rubocop/rspec/language.rb Outdated Show resolved Hide resolved
lib/rubocop/rspec/language.rb Outdated Show resolved Hide resolved
lib/rubocop/rspec/language.rb Outdated Show resolved Hide resolved
lib/rubocop/rspec/language.rb Outdated Show resolved Hide resolved
lib/rubocop/rspec/language.rb Outdated Show resolved Hide resolved

module ExampleGroups
GROUPS = SelectorSet.new(%i[describe context feature example_group])
Copy link
Collaborator

Choose a reason for hiding this comment

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

By the way, how come that we changed from ExampleGroups::GROUPS to ExampleGroups#regular and from Examples::EXAMPLES to Examples#regular?

Copy link
Member

Choose a reason for hiding this comment

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

Hm. I lost track of this.
To me, "regular" sounds better. But we at least have to mention this in the update_to_v2 document.

lib/rubocop/cop/rspec/let_setup.rb Outdated Show resolved Hide resolved
@@ -32,7 +32,7 @@ def on_block(node)

def in_spec_block?(node)
node.each_ancestor(:block).any? do |ancestor|
Examples::ALL.include?(ancestor.method_name)
Examples.all(ancestor.method_name)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This code reads a bit weird. It looks like there’s a question mark missing, i.e. Examples.all?(ancestor.method_name), but that’s also not good.

Probably not something we need to fix now, but just an observation.

Copy link
Member

Choose a reason for hiding this comment

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

Indeed. Those new helpers fit patterns more.
I can think of adding an include? alias for all to all of them, however, this will not provide a similar interface to Examples.regular.

Another way is to check if an argument has been passed (used in a pattern), or not. If not - just return a list, and this will make both Examples.all.include?(ancestor.method_name) and Examples.regular.include?(ancestor.method_name) possible.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Returning different types (boolean vs array) from the same method also isn’t great. Maybe we should call #all? from within out patterns? Also not really a great option :-/

I think we should just leave it for now.

lib/rubocop/cop/rspec/hooks_before_examples.rb Outdated Show resolved Hide resolved
spec/rubocop/rspec/hook_spec.rb Show resolved Hide resolved
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.

I… have run out of comments 😅

Thank you for the great work @pirj and @sl4vr. 🎉

Squash and merge at will.

@pirj pirj force-pushed the rspec-aliases_runtime-matchers branch from d2d1355 to e515d21 Compare November 3, 2020 10:11
@pirj pirj merged commit 13cb62f into rubocop:release-2.0 Nov 3, 2020
@pirj
Copy link
Member

pirj commented Nov 3, 2020

@sl4vr Thanks a lot for implementing this. It is a huge amount of work, really, I now understand this after making subtle changes. It's time to claim your CoM trophy, but it's not all, you also get this symbolic golden RuboCop statuette:
output-onlinepngtools

@marcandre Thanks a lot for early-stage reviews, incredible suggestions and making changes to rubocop-ast that allowed this change to be made. You get a golden RuboCop statuette as well, and I guess it's not your first one!
output-onlinepngtools

@marcandre
Copy link
Contributor

Thanks @pirj, you're too kind 😅
Congrats to @sl4vr, @bquorning and yourself for landing this 🎉

@sl4vr
Copy link
Contributor Author

sl4vr commented Nov 4, 2020

@pirj thank you for leading and finishing this PR 😅

pirj added a commit to pirj/action_policy that referenced this pull request Nov 8, 2020
Previously, RuboCop RSpec failed to detect RSpec aliases. A number of
cops were failing false offences, and some cops were unable to lint, as
they were skipping locally defined RSpec aliases taking them for
arbitrary blocks and method calls.

See:
 - rubocop/rubocop-rspec#1077
 - rubocop/rubocop-rspec#956
 - palkan#103
pirj added a commit to pirj/action_policy that referenced this pull request Nov 8, 2020
Previously, RuboCop RSpec failed to detect RSpec aliases. A number of
cops were failing false offences, and some cops were unable to lint, as
they were skipping locally defined RSpec aliases taking them for
arbitrary blocks and method calls.

See:
 - rubocop/rubocop-rspec#1077
 - rubocop/rubocop-rspec#956
 - palkan#103
pirj added a commit to pirj/test-prof that referenced this pull request Nov 9, 2020
Previously, RuboCop RSpec failed to detect RSpec aliases. A number of
cops were failing false offences, and some cops were unable to lint, as
they were skipping locally defined RSpec aliases taking them for
arbitrary blocks and method calls.

See:
 - rubocop/rubocop-rspec#1077
 - rubocop/rubocop-rspec#956

Sibling pull requests:
 - palkan/action_policy#138
pirj added a commit to pirj/test-prof that referenced this pull request Nov 9, 2020
Previously, RuboCop RSpec failed to detect RSpec aliases. A number of
cops were failing false offences, and some cops were unable to lint, as
they were skipping locally defined RSpec aliases taking them for
arbitrary blocks and method calls.

See:
 - rubocop/rubocop-rspec#1077
 - rubocop/rubocop-rspec#956

Sibling pull requests:
 - palkan/action_policy#138
pirj added a commit to pirj/test-prof that referenced this pull request Nov 9, 2020
Previously, RuboCop RSpec failed to detect RSpec aliases. A number of
cops were failing false offences, and some cops were unable to lint, as
they were skipping locally defined RSpec aliases taking them for
arbitrary blocks and method calls.

See:
 - rubocop/rubocop-rspec#1077
 - rubocop/rubocop-rspec#956

Sibling pull requests:
 - palkan/action_policy#138
pirj added a commit to pirj/action_policy that referenced this pull request Nov 17, 2020
Previously, RuboCop RSpec failed to detect RSpec aliases. A number of
cops were failing false offences, and some cops were unable to lint, as
they were skipping locally defined RSpec aliases taking them for
arbitrary blocks and method calls.

See:
 - rubocop/rubocop-rspec#1077
 - rubocop/rubocop-rspec#956
 - palkan#103
pirj added a commit to pirj/test-prof that referenced this pull request Nov 17, 2020
Previously, RuboCop RSpec failed to detect RSpec aliases. A number of
cops were failing false offences, and some cops were unable to lint, as
they were skipping locally defined RSpec aliases taking them for
arbitrary blocks and method calls.

See:
 - rubocop/rubocop-rspec#1077
 - rubocop/rubocop-rspec#956

Sibling pull requests:
 - palkan/action_policy#138
palkan pushed a commit to palkan/action_policy that referenced this pull request Nov 18, 2020
Previously, RuboCop RSpec failed to detect RSpec aliases. A number of
cops were failing false offences, and some cops were unable to lint, as
they were skipping locally defined RSpec aliases taking them for
arbitrary blocks and method calls.

See:
 - rubocop/rubocop-rspec#1077
 - rubocop/rubocop-rspec#956
 - #103
pirj added a commit to pirj/test-prof that referenced this pull request Nov 18, 2020
Previously, RuboCop RSpec failed to detect RSpec aliases. A number of
cops were failing false offences, and some cops were unable to lint, as
they were skipping locally defined RSpec aliases taking them for
arbitrary blocks and method calls.

See:
 - rubocop/rubocop-rspec#1077
 - rubocop/rubocop-rspec#956

Sibling pull requests:
 - palkan/action_policy#138
palkan pushed a commit to test-prof/test-prof that referenced this pull request Nov 18, 2020
Previously, RuboCop RSpec failed to detect RSpec aliases. A number of
cops were failing false offences, and some cops were unable to lint, as
they were skipping locally defined RSpec aliases taking them for
arbitrary blocks and method calls.

See:
 - rubocop/rubocop-rspec#1077
 - rubocop/rubocop-rspec#956

Sibling pull requests:
 - palkan/action_policy#138
@pirj pirj mentioned this pull request Oct 3, 2021
5 tasks
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

5 participants