Skip to content

Commit

Permalink
Merge pull request #39 from rubocop/fix/37
Browse files Browse the repository at this point in the history
Fix an incorrect autocorrect for `Capybara/CurrentPathExpectation` when matcher's argument is a method with a argument and no parentheses
  • Loading branch information
ydah committed Apr 17, 2023
2 parents 4fadd1d + a899466 commit 0eed12c
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- Fix an offense message for `Capybara/SpecificFinders`. ([@ydah])
- Expand `Capybara/NegationMatcher` to support `have_content` ([@OskarsEzerins])
- Fix an incorrect autocorrect for `Capybara/CurrentPathExpectation` when matcher's argument is a method with a argument and no parentheses. ([@ydah])

## 2.17.1 (2023-02-13)

Expand Down
19 changes: 17 additions & 2 deletions lib/rubocop/cop/capybara/current_path_expectation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ module Capybara
#
class CurrentPathExpectation < ::RuboCop::Cop::Base
extend AutoCorrector
include RangeHelp

MSG = 'Do not set an RSpec expectation on `current_path` in ' \
'Capybara feature specs - instead, use the ' \
Expand Down Expand Up @@ -85,15 +86,15 @@ def autocorrect(corrector, node)
end

def rewrite_expectation(corrector, node, to_symbol, matcher_node)
current_path_node = node.first_argument
corrector.replace(current_path_node, 'page')
corrector.replace(node.first_argument, 'page')
corrector.replace(node.parent.loc.selector, 'to')
matcher_method = if to_symbol == :to
'have_current_path'
else
'have_no_current_path'
end
corrector.replace(matcher_node.loc.selector, matcher_method)
add_argument_parentheses(corrector, matcher_node.first_argument)
add_ignore_query_options(corrector, node)
end

Expand All @@ -111,6 +112,20 @@ def regexp_node_to_regexp_expr(regexp_node)
end
end

def add_argument_parentheses(corrector, arg_node)
return unless method_call_with_no_parentheses?(arg_node)

first_argument_range = range_with_surrounding_space(
arg_node.first_argument.source_range, side: :left
)
corrector.insert_before(first_argument_range, '(')
corrector.insert_after(arg_node.last_argument, ')')
end

def method_call_with_no_parentheses?(arg_node)
arg_node.send_type? && arg_node.arguments? && !arg_node.parenthesized?
end

# `have_current_path` with no options will include the querystring
# while `page.current_path` does not.
# This ensures the option `ignore_query: true` is added
Expand Down
48 changes: 48 additions & 0 deletions spec/rubocop/cop/capybara/current_path_expectation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,54 @@
RUBY
end

it "registers an offense when matcher's argument is a method " \
'with a argument and no parentheses' do
expect_offense(<<~RUBY)
expect(current_path).to eq(foo bar)
^^^^^^ Do not set an RSpec expectation on `current_path` in Capybara feature specs - instead, use the `have_current_path` matcher on `page`
RUBY

expect_correction(<<~RUBY)
expect(page).to have_current_path(foo( bar), ignore_query: true)
RUBY
end

it "registers an offense when matcher's argument is a method " \
'with arguments and no parentheses' do
expect_offense(<<~RUBY)
expect(current_path).to eq(foo bar, baz)
^^^^^^ Do not set an RSpec expectation on `current_path` in Capybara feature specs - instead, use the `have_current_path` matcher on `page`
RUBY

expect_correction(<<~RUBY)
expect(page).to have_current_path(foo( bar, baz), ignore_query: true)
RUBY
end

it "registers an offense when matcher's argument is a method " \
'with a argument and parentheses' do
expect_offense(<<~RUBY)
expect(current_path).to eq(foo(bar))
^^^^^^ Do not set an RSpec expectation on `current_path` in Capybara feature specs - instead, use the `have_current_path` matcher on `page`
RUBY

expect_correction(<<~RUBY)
expect(page).to have_current_path(foo(bar), ignore_query: true)
RUBY
end

it "registers an offense when matcher's argument is a method " \
'with arguments and parentheses' do
expect_offense(<<~RUBY)
expect(current_path).to eq(foo bar(baz))
^^^^^^ Do not set an RSpec expectation on `current_path` in Capybara feature specs - instead, use the `have_current_path` matcher on `page`
RUBY

expect_correction(<<~RUBY)
expect(page).to have_current_path(foo( bar(baz)), ignore_query: true)
RUBY
end

it 'preserves parentheses' do
expect_offense(<<~RUBY)
expect(current_path).to eq(expected_path)
Expand Down

0 comments on commit 0eed12c

Please sign in to comment.