File tree 9 files changed +148
-10
lines changed
spec/rubocop/cop/capybara
9 files changed +148
-10
lines changed Original file line number Diff line number Diff line change 20
20
- Change to default ` EnforcedStyle: have_no ` for ` Capybara/NegationMatcher ` cop. ([ @ydah ] )
21
21
- Fix a false positive for ` Capybara/SpecificMatcher ` when ` text: ` or ` exact_text: ` with regexp. ([ @ydah ] )
22
22
23
+ - Add a new ` Capybara/NegationMatcherAfterVisit ` cop. ([ @ydah ] )
24
+
23
25
## 2.19.0 (2023-09-20)
24
26
25
27
- Add new ` Capybara/RSpec/PredicateMatcher ` cop. ([ @ydah ] )
Original file line number Diff line number Diff line change @@ -56,6 +56,12 @@ Capybara/NegationMatcher:
56
56
- not_to
57
57
Reference : https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/NegationMatcher
58
58
59
+ Capybara/NegationMatcherAfterVisit :
60
+ Description : Do not allow negative matchers to be used immediately after `visit`.
61
+ Enabled : pending
62
+ VersionAdded : " <<next>>"
63
+ Reference : https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/NegationMatcherAfterVisit
64
+
59
65
Capybara/RedundantWithinFind :
60
66
Description : Checks for redundant `within find(...)` calls.
61
67
Enabled : pending
Original file line number Diff line number Diff line change 8
8
* xref:cops_capybara.adoc#capybarafindallfirst[Capybara/FindAllFirst]
9
9
* xref:cops_capybara.adoc#capybaramatchstyle[Capybara/MatchStyle]
10
10
* xref:cops_capybara.adoc#capybaranegationmatcher[Capybara/NegationMatcher]
11
+ * xref:cops_capybara.adoc#capybaranegationmatcheraftervisit[Capybara/NegationMatcherAfterVisit]
11
12
* xref:cops_capybara.adoc#capybararedundantwithinfind[Capybara/RedundantWithinFind]
12
13
* xref:cops_capybara.adoc#capybaraspecificactions[Capybara/SpecificActions]
13
14
* xref:cops_capybara.adoc#capybaraspecificfinders[Capybara/SpecificFinders]
Original file line number Diff line number Diff line change @@ -324,6 +324,52 @@ expect(page).not_to have_css('a')
324
324
325
325
* https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/NegationMatcher
326
326
327
+ [#capybaranegationmatcheraftervisit]
328
+ == Capybara/NegationMatcherAfterVisit
329
+
330
+ |===
331
+ | Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed
332
+
333
+ | Pending
334
+ | Yes
335
+ | No
336
+ | <<next>>
337
+ | -
338
+ |===
339
+
340
+ Do not allow negative matchers to be used immediately after `visit`.
341
+
342
+ [#examples-capybaranegationmatcheraftervisit]
343
+ === Examples
344
+
345
+ [source,ruby]
346
+ ----
347
+ # bad
348
+ visit foo_path
349
+ expect(page).to have_no_link('bar')
350
+ expect(page).to have_css('a')
351
+
352
+ # good
353
+ visit foo_path
354
+ expect(page).to have_css('a')
355
+ expect(page).to have_no_link('bar')
356
+
357
+ # bad
358
+ visit foo_path
359
+ expect(page).not_to have_link('bar')
360
+ expect(page).to have_css('a')
361
+
362
+ # good
363
+ visit foo_path
364
+ expect(page).to have_css('a')
365
+ expect(page).not_to have_link('bar')
366
+ ----
367
+
368
+ [#references-capybaranegationmatcheraftervisit]
369
+ === References
370
+
371
+ * https://www.rubydoc.info/gems/rubocop-capybara/RuboCop/Cop/Capybara/NegationMatcherAfterVisit
372
+
327
373
[#capybararedundantwithinfind]
328
374
== Capybara/RedundantWithinFind
329
375
Original file line number Diff line number Diff line change @@ -6,6 +6,16 @@ module Capybara
6
6
# Help methods for capybara.
7
7
# @api private
8
8
module CapybaraHelp
9
+ CAPYBARA_MATCHERS = %w[
10
+ selector css xpath text title current_path link button
11
+ field checked_field unchecked_field select table
12
+ sibling ancestor content
13
+ ] . freeze
14
+ POSITIVE_MATCHERS =
15
+ Set . new ( CAPYBARA_MATCHERS ) { |element | :"have_#{ element } " } . freeze
16
+ NEGATIVE_MATCHERS =
17
+ Set . new ( CAPYBARA_MATCHERS ) { |element | :"have_no_#{ element } " }
18
+ . freeze
9
19
COMMON_OPTIONS = %w[
10
20
id class style
11
21
] . freeze
Original file line number Diff line number Diff line change @@ -26,18 +26,9 @@ module Capybara
26
26
class NegationMatcher < ::RuboCop ::Cop ::Base
27
27
extend AutoCorrector
28
28
include ConfigurableEnforcedStyle
29
+ include CapybaraHelp
29
30
30
31
MSG = 'Use `expect(...).%<runner>s %<matcher>s`.'
31
- CAPYBARA_MATCHERS = %w[
32
- selector css xpath text title current_path link button
33
- field checked_field unchecked_field select table
34
- sibling ancestor content
35
- ] . freeze
36
- POSITIVE_MATCHERS =
37
- Set . new ( CAPYBARA_MATCHERS ) { |element | :"have_#{ element } " } . freeze
38
- NEGATIVE_MATCHERS =
39
- Set . new ( CAPYBARA_MATCHERS ) { |element | :"have_no_#{ element } " }
40
- . freeze
41
32
RESTRICT_ON_SEND = ( POSITIVE_MATCHERS + NEGATIVE_MATCHERS ) . freeze
42
33
43
34
# @!method not_to?(node)
Original file line number Diff line number Diff line change
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Capybara
6
+ # Do not allow negative matchers to be used immediately after `visit`.
7
+ #
8
+ # @example
9
+ # # bad
10
+ # visit foo_path
11
+ # expect(page).to have_no_link('bar')
12
+ # expect(page).to have_css('a')
13
+ #
14
+ # # good
15
+ # visit foo_path
16
+ # expect(page).to have_css('a')
17
+ # expect(page).to have_no_link('bar')
18
+ #
19
+ # # bad
20
+ # visit foo_path
21
+ # expect(page).not_to have_link('bar')
22
+ # expect(page).to have_css('a')
23
+ #
24
+ # # good
25
+ # visit foo_path
26
+ # expect(page).to have_css('a')
27
+ # expect(page).not_to have_link('bar')
28
+ #
29
+ class NegationMatcherAfterVisit < ::RuboCop ::Cop ::Base
30
+ include CapybaraHelp
31
+
32
+ MSG = 'Do not use negation matcher immediately after visit.'
33
+ RESTRICT_ON_SEND = %i[ visit ] . freeze
34
+
35
+ # @!method negation_matcher?(node)
36
+ def_node_matcher :negation_matcher? , <<~PATTERN
37
+ {
38
+ (send (send nil? :expect _) :to (send nil? %NEGATIVE_MATCHERS ...))
39
+ (send (send nil? :expect _) :not_to (send nil? %POSITIVE_MATCHERS ...))
40
+ }
41
+ PATTERN
42
+
43
+ def on_send ( node )
44
+ negation_matcher? ( node . right_sibling ) do
45
+ add_offense ( node . right_sibling )
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
Original file line number Diff line number Diff line change 9
9
require_relative 'capybara/find_all_first'
10
10
require_relative 'capybara/match_style'
11
11
require_relative 'capybara/negation_matcher'
12
+ require_relative 'capybara/negation_matcher_after_visit'
12
13
require_relative 'capybara/redundant_within_find'
13
14
require_relative 'capybara/specific_actions'
14
15
require_relative 'capybara/specific_finders'
Original file line number Diff line number Diff line change
1
+ # frozen_string_literal: true
2
+
3
+ RSpec . describe RuboCop ::Cop ::Capybara ::NegationMatcherAfterVisit , :config do
4
+ it 'registers an offense when using `have_no_*` after ' \
5
+ 'immediately `visit` method call' do
6
+ expect_offense ( <<~RUBY )
7
+ visit foo_path
8
+ expect(page).to have_no_link('bar')
9
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not use negation matcher immediately after visit.
10
+ RUBY
11
+ end
12
+
13
+ it 'registers an offense when using `not_to` with `have_*` after ' \
14
+ 'immediately `visit` method call' do
15
+ expect_offense ( <<~RUBY )
16
+ visit foo_path
17
+ expect(page).not_to have_link('bar')
18
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not use negation matcher immediately after visit.
19
+ RUBY
20
+ end
21
+
22
+ it 'does not register an offense when using positive matchers after ' \
23
+ 'immediately `visit` method call' do
24
+ expect_no_offenses ( <<~RUBY )
25
+ visit foo_path
26
+ expect(page).to have_css('a')
27
+ expect(page).to have_no_link('bar')
28
+ RUBY
29
+ end
30
+ end
You can’t perform that action at this time.
0 commit comments