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

Implement autocorrect for Capybara/CurrentPathExpectation #641

Merged
merged 1 commit into from
Nov 6, 2018

Conversation

ypresto
Copy link
Contributor

@ypresto ypresto commented Jun 13, 2018

Capybara/CurrentPathExpectation did not have autocorrect so I implemented it!

Note that match(variable) is not supported due to ambiguous replacement:

  • If variable returns string, it should be replaced with have_current_path(/#{variable}/).
  • If variable returns regexp, it should be replaced with have_current_path(variable).

ref: #470


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.
  • Added an entry to the changelog 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).

@ypresto ypresto force-pushed the current-path-autocorrect branch 4 times, most recently from 5ceba73 to 82d458d Compare June 13, 2018 14:05
@ypresto
Copy link
Contributor Author

ypresto commented Jun 13, 2018

Possible bug: if current_path is overridden in current context (let, local variable or helper method), it can cause false-positive.

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.

Overall, this looks really good. I am a bit concerned about the two matchers. The first is quite complicated, and the 2nd somewhat repeats part of the 1st one.

What are the downsides of splitting the 1st matcher in two, one being specific to the :match(str $_) pattern? That would reduce duplication in the matchers, but perhaps introduce extra duplication further down in the class…


def autocorrect(node)
lambda do |corrector|
return unless node.chained?
Copy link
Collaborator

Choose a reason for hiding this comment

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

There is no test case covering this line.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added test!

Copy link
Member

Choose a reason for hiding this comment

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

Add empty line after the return

current_path_node = node.first_argument
corrector.replace(current_path_node.loc.expression, 'page')
corrector.replace(node.parent.loc.selector, 'to')
matche_method = if to_symbol == :to
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this is a typo: matche_method -> matcher_method.

@ypresto
Copy link
Contributor Author

ypresto commented Jun 25, 2018

What are the downsides of splitting the 1st matcher in two

Firstly I'm putting all the code into body of def autocorrect so much of duplication with two (large) matchers pattern. But it can be simpler now:

def autocorrect(node)
    ...
    as_is_matcher(node.parent) do |to_symbol, matcher_node|
      rewrite_expectation(corrector, node, to_symbol, matcher_node)
    end
    regexp_str_matcher(node.parent) do |to_symbol, matcher_node|
      rewrite_expectation(corrector, node, to_symbol, matcher_node)
      convert_regexp_str_to_literal(corrector, matcher_node)
    end
    ...
end

@ypresto ypresto force-pushed the current-path-autocorrect branch 3 times, most recently from 11ecfe7 to 06c1a94 Compare August 2, 2018 02:04
@ypresto
Copy link
Contributor Author

ypresto commented Aug 2, 2018

Thank you for reviewing, finally fixed them! :)

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.

You need to rebase on master, but other than that I think this PR is fine.

@Darhazer, any comments?

# Supported matchers: eq(...) / match(/regexp/) / match('regexp')
def_node_matcher :as_is_matcher, <<-PATTERN
(send
(send nil? :expect (send {(send nil? :page) nil?} :current_path)) ${:to :not_to :to_not}
Copy link
Member

Choose a reason for hiding this comment

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

At least reuse the expectation_set_on_current_path - you can write

#expectation_set_on_current_path ${:to :not_to :to_not}


def_node_matcher :regexp_str_matcher, <<-PATTERN
(send
(send nil? :expect (send {(send nil? :page) nil?} :current_path)) ${:to :not_to :to_not}
Copy link
Member

Choose a reason for hiding this comment

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

reuse expectation_set_on_current_path


def autocorrect(node)
lambda do |corrector|
return unless node.chained?
Copy link
Member

Choose a reason for hiding this comment

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

Add empty line after the return

as_is_matcher(node.parent) do |to_sym, matcher_node|
rewrite_expectation(corrector, node, to_sym, matcher_node)
end
regexp_str_matcher(node.parent) do |to_sym, matcher_node, regexp|
Copy link
Member

Choose a reason for hiding this comment

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

maybe you can combine the 2 matchers in one and just check if the method_name of the matcher_node is match and argument is of regexp_type

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Firstly they was combined, but it was split according to below comment:
#641 (review)

Copy link
Collaborator

Choose a reason for hiding this comment

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

I guess my comment “that would reduce duplication in the matchers, but perhaps introduce extra duplication further down in the class…” turned out to be true :-)

@Darhazer
Copy link
Member

Darhazer commented Nov 1, 2018

@ypresto would you have time to push this forward or do you prefer if I apply my own feedback on the code? It's a really nice feature and it would be great to include it in the next release

@ypresto
Copy link
Contributor Author

ypresto commented Nov 2, 2018

updated PR!

@Darhazer
Copy link
Member

Darhazer commented Nov 5, 2018

@bquorning maybe take another look?

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’m fine with this change. As commented there is a tradeoff between having duplicated logic in the autocorrect method or in the node matchers, but I think it’s ok as is now.

as_is_matcher(node.parent) do |to_sym, matcher_node|
rewrite_expectation(corrector, node, to_sym, matcher_node)
end
regexp_str_matcher(node.parent) do |to_sym, matcher_node, regexp|
Copy link
Collaborator

Choose a reason for hiding this comment

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

I guess my comment “that would reduce duplication in the matchers, but perhaps introduce extra duplication further down in the class…” turned out to be true :-)

@Darhazer
Copy link
Member

Darhazer commented Nov 6, 2018

@ypresto please rebase 📦

@ypresto
Copy link
Contributor Author

ypresto commented Nov 6, 2018

Thank you all for reviewing!
@Darhazer just rebased!

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

3 participants