Skip to content

Commit 816fa4b

Browse files
authored
Merge pull request #77 from rubocop/feature/75
Add new `Capybara/RedundantWithinFind` cop
2 parents fe063f6 + fa74ea1 commit 816fa4b

File tree

7 files changed

+207
-0
lines changed

7 files changed

+207
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
- Change to default `EnforcedStyle: link_or_button` for `Capybara/ClickLinkOrButtonStyle` cop. ([@ydah])
66
- Fix a false negative for `RSpec/HaveSelector` when first argument is dstr node. ([@ydah])
7+
- Add new `Capybara/RedundantWithinFind` cop. ([@ydah])
78
- Fix an invalid attributes parse when name with multiple `[]` for `Capybara/SpecificFinders` and `Capybara/SpecificActions` and `Capybara/SpecificMatcher`. ([@ydah])
89

910
## 2.19.0 (2023-09-20)

config/default.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ Capybara/NegationMatcher:
4343
- not_to
4444
Reference: https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/NegationMatcher
4545

46+
Capybara/RedundantWithinFind:
47+
Description: Checks for redundant `within find(...)` calls.
48+
Enabled: pending
49+
VersionAdded: "<<next>>"
50+
Reference: https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/RedundantWithinFind
51+
4652
Capybara/SpecificActions:
4753
Description: Checks for there is a more specific actions offered by Capybara.
4854
Enabled: pending

docs/modules/ROOT/pages/cops.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* xref:cops_capybara.adoc#capybaracurrentpathexpectation[Capybara/CurrentPathExpectation]
77
* xref:cops_capybara.adoc#capybaramatchstyle[Capybara/MatchStyle]
88
* xref:cops_capybara.adoc#capybaranegationmatcher[Capybara/NegationMatcher]
9+
* xref:cops_capybara.adoc#capybararedundantwithinfind[Capybara/RedundantWithinFind]
910
* xref:cops_capybara.adoc#capybaraspecificactions[Capybara/SpecificActions]
1011
* xref:cops_capybara.adoc#capybaraspecificfinders[Capybara/SpecificFinders]
1112
* xref:cops_capybara.adoc#capybaraspecificmatcher[Capybara/SpecificMatcher]

docs/modules/ROOT/pages/cops_capybara.adoc

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,49 @@ expect(page).to have_no_css('a')
217217

218218
* https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/NegationMatcher
219219

220+
== Capybara/RedundantWithinFind
221+
222+
|===
223+
| Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed
224+
225+
| Pending
226+
| Yes
227+
| Yes
228+
| <<next>>
229+
| -
230+
|===
231+
232+
Checks for redundant `within find(...)` calls.
233+
234+
=== Examples
235+
236+
[source,ruby]
237+
----
238+
# bad
239+
within find('foo.bar') do
240+
# ...
241+
end
242+
243+
# good
244+
within 'foo.bar' do
245+
# ...
246+
end
247+
248+
# bad
249+
within find_by_id('foo') do
250+
# ...
251+
end
252+
253+
# good
254+
within '#foo' do
255+
# ...
256+
end
257+
----
258+
259+
=== References
260+
261+
* https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/RedundantWithinFind
262+
220263
== Capybara/SpecificActions
221264

222265
|===
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# frozen_string_literal: true
2+
3+
module RuboCop
4+
module Cop
5+
module Capybara
6+
# Checks for redundant `within find(...)` calls.
7+
#
8+
# @example
9+
# # bad
10+
# within find('foo.bar') do
11+
# # ...
12+
# end
13+
#
14+
# # good
15+
# within 'foo.bar' do
16+
# # ...
17+
# end
18+
#
19+
# # bad
20+
# within find_by_id('foo') do
21+
# # ...
22+
# end
23+
#
24+
# # good
25+
# within '#foo' do
26+
# # ...
27+
# end
28+
#
29+
class RedundantWithinFind < ::RuboCop::Cop::Base
30+
extend AutoCorrector
31+
MSG = 'Redundant `within %<method>s(...)` call detected.'
32+
RESTRICT_ON_SEND = %i[within].freeze
33+
FIND_METHODS = Set.new(%i[find find_by_id]).freeze
34+
35+
# @!method within_find(node)
36+
def_node_matcher :within_find, <<~PATTERN
37+
(send nil? :within
38+
$(send nil? %FIND_METHODS ...))
39+
PATTERN
40+
41+
def on_send(node)
42+
within_find(node) do |find_node|
43+
add_offense(find_node, message: msg(find_node)) do |corrector|
44+
corrector.replace(find_node, replaced(find_node))
45+
end
46+
end
47+
end
48+
49+
private
50+
51+
def msg(node)
52+
format(MSG, method: node.method_name)
53+
end
54+
55+
def replaced(node)
56+
replaced = node.arguments.map(&:source).join(', ')
57+
if node.method?(:find_by_id)
58+
replaced.sub(/\A(["'])/, '\1#')
59+
else
60+
replaced
61+
end
62+
end
63+
end
64+
end
65+
end
66+
end

lib/rubocop/cop/capybara_cops.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
require_relative 'capybara/current_path_expectation'
88
require_relative 'capybara/match_style'
99
require_relative 'capybara/negation_matcher'
10+
require_relative 'capybara/redundant_within_find'
1011
require_relative 'capybara/specific_actions'
1112
require_relative 'capybara/specific_finders'
1213
require_relative 'capybara/specific_matcher'
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.describe RuboCop::Cop::Capybara::RedundantWithinFind, :config do
4+
it 'registers an offense when using `within find(...)`' do
5+
expect_offense(<<~RUBY)
6+
within find('foo.bar') do
7+
^^^^^^^^^^^^^^^ Redundant `within find(...)` call detected.
8+
end
9+
RUBY
10+
11+
expect_correction(<<~RUBY)
12+
within 'foo.bar' do
13+
end
14+
RUBY
15+
end
16+
17+
it 'registers an offense when using `within(find ...)`' do
18+
expect_offense(<<~RUBY)
19+
within(find 'foo.bar') do
20+
^^^^^^^^^^^^^^ Redundant `within find(...)` call detected.
21+
end
22+
RUBY
23+
24+
expect_correction(<<~RUBY)
25+
within('foo.bar') do
26+
end
27+
RUBY
28+
end
29+
30+
it 'registers an offense when using `within find(...)` with other argument' do
31+
expect_offense(<<~RUBY)
32+
within find('foo.bar', visible: false) do
33+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Redundant `within find(...)` call detected.
34+
end
35+
RUBY
36+
37+
expect_correction(<<~RUBY)
38+
within 'foo.bar', visible: false do
39+
end
40+
RUBY
41+
end
42+
43+
it 'registers an offense when using `within find_by_id(...)`' do
44+
expect_offense(<<~RUBY)
45+
within find_by_id('foo') do
46+
^^^^^^^^^^^^^^^^^ Redundant `within find_by_id(...)` call detected.
47+
end
48+
RUBY
49+
50+
expect_correction(<<~RUBY)
51+
within '#foo' do
52+
end
53+
RUBY
54+
end
55+
56+
it 'registers an offense when using `within(find_by_id ...)`' do
57+
expect_offense(<<~RUBY)
58+
within(find_by_id 'foo') do
59+
^^^^^^^^^^^^^^^^ Redundant `within find_by_id(...)` call detected.
60+
end
61+
RUBY
62+
63+
expect_correction(<<~RUBY)
64+
within('#foo') do
65+
end
66+
RUBY
67+
end
68+
69+
it 'registers an offense when using `within find_by_id(...)` with ' \
70+
'other argument' do
71+
expect_offense(<<~RUBY)
72+
within find_by_id('foo', visible: false) do
73+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Redundant `within find_by_id(...)` call detected.
74+
end
75+
RUBY
76+
77+
expect_correction(<<~RUBY)
78+
within '#foo', visible: false do
79+
end
80+
RUBY
81+
end
82+
83+
it 'does not register an offense when using `within` without `find`' do
84+
expect_no_offenses(<<~RUBY)
85+
within 'foo.bar' do
86+
end
87+
RUBY
88+
end
89+
end

0 commit comments

Comments
 (0)