rubocop-rspec 2.14.2 → 2.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -0
  3. data/config/default.yml +48 -29
  4. data/lib/rubocop/cop/rspec/be.rb +2 -0
  5. data/lib/rubocop/cop/rspec/be_eq.rb +3 -0
  6. data/lib/rubocop/cop/rspec/be_eql.rb +3 -0
  7. data/lib/rubocop/cop/rspec/capybara/current_path_expectation.rb +3 -3
  8. data/lib/rubocop/cop/rspec/capybara/negation_matcher.rb +1 -1
  9. data/lib/rubocop/cop/rspec/capybara/specific_actions.rb +1 -1
  10. data/lib/rubocop/cop/rspec/capybara/specific_finders.rb +1 -1
  11. data/lib/rubocop/cop/rspec/capybara/specific_matcher.rb +3 -5
  12. data/lib/rubocop/cop/rspec/capybara/visibility_matcher.rb +1 -1
  13. data/lib/rubocop/cop/rspec/duplicated_metadata.rb +58 -0
  14. data/lib/rubocop/cop/rspec/empty_line_after_example.rb +2 -0
  15. data/lib/rubocop/cop/rspec/expect_actual.rb +2 -0
  16. data/lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb +1 -1
  17. data/lib/rubocop/cop/rspec/factory_bot/consistent_parentheses_style.rb +16 -9
  18. data/lib/rubocop/cop/rspec/factory_bot/create_list.rb +9 -2
  19. data/lib/rubocop/cop/rspec/factory_bot/factory_class_name.rb +1 -1
  20. data/lib/rubocop/cop/rspec/factory_bot/factory_name_style.rb +74 -0
  21. data/lib/rubocop/cop/rspec/implicit_expect.rb +2 -0
  22. data/lib/rubocop/cop/rspec/leading_subject.rb +2 -2
  23. data/lib/rubocop/cop/rspec/message_spies.rb +2 -0
  24. data/lib/rubocop/cop/rspec/mixin/metadata.rb +49 -0
  25. data/lib/rubocop/cop/rspec/named_subject.rb +81 -6
  26. data/lib/rubocop/cop/rspec/nested_groups.rb +1 -1
  27. data/lib/rubocop/cop/rspec/pending_without_reason.rb +123 -0
  28. data/lib/rubocop/cop/rspec/predicate_matcher.rb +2 -0
  29. data/lib/rubocop/cop/rspec/rails/have_http_status.rb +5 -2
  30. data/lib/rubocop/cop/rspec/rails/inferred_spec_type.rb +1 -1
  31. data/lib/rubocop/cop/rspec/repeated_description.rb +25 -2
  32. data/lib/rubocop/cop/rspec/scattered_setup.rb +2 -0
  33. data/lib/rubocop/cop/rspec/sort_metadata.rb +4 -35
  34. data/lib/rubocop/cop/rspec/stubbed_mock.rb +2 -0
  35. data/lib/rubocop/cop/rspec/unspecified_exception.rb +2 -0
  36. data/lib/rubocop/cop/rspec_cops.rb +3 -0
  37. data/lib/rubocop/rspec/config_formatter.rb +2 -2
  38. data/lib/rubocop/rspec/description_extractor.rb +5 -10
  39. data/lib/rubocop/rspec/language.rb +9 -3
  40. data/lib/rubocop/rspec/shared_contexts/default_rspec_language_config_context.rb +29 -0
  41. data/lib/rubocop/rspec/version.rb +1 -1
  42. data/lib/rubocop-rspec.rb +18 -13
  43. metadata +7 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bbd70ea9708a7d87e0a1307234e3ac5cc37cc6197e6b1cc72487342b772ec6f1
4
- data.tar.gz: 0c50303e8a0d4218508c51e778d5cb6633b54fe6f823951ea5f8df68d162dfda
3
+ metadata.gz: c31ad963289938a78bf4a8439ad44c6f1a2eaf852a25d715be483ebe71e622fc
4
+ data.tar.gz: 70b4e942004dd6654fa12c3ecaf7367c1f6bcf4bcd122573129984f5f0a66ff5
5
5
  SHA512:
6
- metadata.gz: 2e1a6e55fb7aeef036448fe57f03b2d80b796e6971fbd22cd63db496e61b1e211a64e89e987cccc74f5124746713581fb621c805d458f7ff273d436432599483
7
- data.tar.gz: 76655025092f103fbd6ca3eda6d466236a8a9857f207e11bc3f8e51c38238367346971c4a0f3feeca6b9069a53fa48bf8281d5dff61f68c6562edce4405a10f0
6
+ metadata.gz: 250a68082a8e6406df3934035e5ccba4e1a7f9a13e021e196911c15981a2f4557e7b7a98efa93f995ad164d2a52e41bf948f4c1fa7c9637829c3c219c8116f74
7
+ data.tar.gz: 7ce965fc56bf214eb65b63d2138cc710766ac16b476a63399271cc5562fb259cefc81cddcf3878f6324faf104d6552e48efcba2eff1fa0865bf463963e5a1a8e
data/CHANGELOG.md CHANGED
@@ -2,6 +2,27 @@
2
2
 
3
3
  ## Master (Unreleased)
4
4
 
5
+ ## 2.16.0 (2022-12-13)
6
+
7
+ - Add new `RSpec/FactoryBot/FactoryNameStyle` cop. ([@ydah])
8
+ - Improved processing speed for `RSpec/Be`, `RSpec/ExpectActual`, `RSpec/ImplicitExpect`, `RSpec/MessageSpies`, `RSpec/PredicateMatcher` and `RSpec/Rails/HaveHttpStatus`. ([@ydah])
9
+ - Fix wrong autocorrection in `n_times` style on `RSpec/FactoryBot/CreateList`. ([@r7kamura])
10
+ - Fix a false positive for `RSpec/FactoryBot/ConsistentParenthesesStyle` when using `generate` with multiple arguments. ([@ydah])
11
+ - Mark `RSpec/BeEq` as `Safe: false` ([@r7kamura])
12
+ - Add `RSpec/DuplicatedMetadata` cop. ([@r7kamura])
13
+ - Mark `RSpec/BeEql` as `Safe: false`. ([@r7kamura])
14
+ - Add `RSpec/PendingWithoutReason` cop. ([@r7kamura])
15
+
16
+ ## 2.15.0 (2022-11-03)
17
+
18
+ - Fix a false positive for `RSpec/RepeatedDescription` when different its block expectations are used. ([@ydah])
19
+ - Add `named_only` style to `RSpec/NamedSubject`. ([@kuahyeow])
20
+ - Fix `RSpec/FactoryBot/ConsistentParenthesesStyle` to ignore calls without the first positional argument. ([@pirj])
21
+ - Fix `RSpec/FactoryBot/ConsistentParenthesesStyle` to ignore calls inside a Hash or an Array. ([@pirj])
22
+ - Fix `RSpec/NestedGroups` to correctly use `AllowedGroups` config. ([@samrjenkins])
23
+ - Remove `Runners` and `HookScopes` RSpec DSL elements from configuration. ([@pirj])
24
+ - Add `with default RSpec/Language config` helper to `lib` (under `rubocop/rspec/shared_contexts/default_rspec_language_config_context`), to allow use for downstream cops based on `RuboCop::Cop::RSpec::Base`. ([@smcgivern])
25
+
5
26
  ## 2.14.2 (2022-10-25)
6
27
 
7
28
  - Fix an incorrect autocorrect for `FactoryBot/ConsistentParenthesesStyle` with `omit_parentheses` option when method name and first argument are not on same line. ([@ydah])
@@ -724,6 +745,7 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
724
745
  [@jtannas]: https://github.com/jtannas
725
746
  [@kellysutton]: https://github.com/kellysutton
726
747
  [@koic]: https://github.com/koic
748
+ [@kuahyeow]: https://github.com/kuahyeow
727
749
  [@lazycoder9]: https://github.com/lazycoder9
728
750
  [@leoarnold]: https://github.com/leoarnold
729
751
  [@liberatys]: https://github.com/Liberatys
@@ -760,9 +782,11 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
760
782
  [@rrosenblum]: https://github.com/rrosenblum
761
783
  [@rspeicher]: https://github.com/rspeicher
762
784
  [@rst-j]: https://github.com/RST-J
785
+ [@samrjenkins]: https://github.com/samrjenkins
763
786
  [@schmijos]: https://github.com/schmijos
764
787
  [@seanpdoyle]: https://github.com/seanpdoyle
765
788
  [@sl4vr]: https://github.com/sl4vr
789
+ [@smcgivern]: https://github.com/smcgivern
766
790
  [@stephannv]: https://github.com/stephannv
767
791
  [@t3h2mas]: https://github.com/t3h2mas
768
792
  [@tdeo]: https://github.com/tdeo
data/config/default.yml CHANGED
@@ -12,8 +12,6 @@ RSpec:
12
12
  - Expectations
13
13
  - Helpers
14
14
  - Hooks
15
- - HookScopes
16
- - Runners
17
15
  - Subjects
18
16
  ExampleGroups:
19
17
  inherit_mode:
@@ -81,12 +79,6 @@ RSpec:
81
79
  - prepend_after
82
80
  - after
83
81
  - append_after
84
- HookScopes:
85
- - each
86
- - example
87
- - context
88
- - all
89
- - suite
90
82
  Includes:
91
83
  inherit_mode:
92
84
  merge:
@@ -98,10 +90,6 @@ RSpec:
98
90
  - include_examples
99
91
  Context:
100
92
  - include_context
101
- Runners:
102
- - to
103
- - to_not
104
- - not_to
105
93
  SharedGroups:
106
94
  inherit_mode:
107
95
  merge:
@@ -159,13 +147,17 @@ RSpec/Be:
159
147
  RSpec/BeEq:
160
148
  Description: Check for expectations where `be(...)` can replace `eq(...)`.
161
149
  Enabled: pending
150
+ Safe: false
162
151
  VersionAdded: 2.9.0
152
+ VersionChanged: '2.16'
163
153
  Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/BeEq
164
154
 
165
155
  RSpec/BeEql:
166
156
  Description: Check for expectations where `be(...)` can replace `eql(...)`.
167
157
  Enabled: true
158
+ Safe: false
168
159
  VersionAdded: '1.7'
160
+ VersionChanged: '2.16'
169
161
  Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/BeEql
170
162
 
171
163
  RSpec/BeNil:
@@ -296,6 +288,12 @@ RSpec/Dialect:
296
288
  VersionAdded: '1.33'
297
289
  Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Dialect
298
290
 
291
+ RSpec/DuplicatedMetadata:
292
+ Description: Avoid duplicated metadata.
293
+ Enabled: pending
294
+ VersionAdded: '2.16'
295
+ Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/DuplicatedMetadata
296
+
299
297
  RSpec/EmptyExampleGroup:
300
298
  Description: Checks if an example group does not include any tests.
301
299
  Enabled: true
@@ -368,12 +366,6 @@ RSpec/ExampleWithoutDescription:
368
366
  VersionAdded: '1.22'
369
367
  Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ExampleWithoutDescription
370
368
 
371
- RSpec/ExcessiveDocstringSpacing:
372
- Description: Checks for excessive whitespace in example descriptions.
373
- Enabled: pending
374
- VersionAdded: '2.5'
375
- Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ExcessiveDocstringSpacing
376
-
377
369
  RSpec/ExampleWording:
378
370
  Description: Checks for common mistakes in example descriptions.
379
371
  Enabled: true
@@ -390,6 +382,12 @@ RSpec/ExampleWording:
390
382
  StyleGuide: https://rspec.rubystyle.guide/#should-in-example-docstrings
391
383
  Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ExampleWording
392
384
 
385
+ RSpec/ExcessiveDocstringSpacing:
386
+ Description: Checks for excessive whitespace in example descriptions.
387
+ Enabled: pending
388
+ VersionAdded: '2.5'
389
+ Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ExcessiveDocstringSpacing
390
+
393
391
  RSpec/ExpectActual:
394
392
  Description: Checks for `expect(...)` calls containing literal values.
395
393
  Enabled: true
@@ -624,8 +622,13 @@ RSpec/MultipleSubjects:
624
622
  RSpec/NamedSubject:
625
623
  Description: Checks for explicitly referenced test subjects.
626
624
  Enabled: true
625
+ EnforcedStyle: always
626
+ SupportedStyles:
627
+ - always
628
+ - named_only
627
629
  IgnoreSharedExamples: true
628
630
  VersionAdded: 1.5.3
631
+ VersionChanged: '2.15'
629
632
  StyleGuide: https://rspec.rubystyle.guide/#use-subject
630
633
  Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/NamedSubject
631
634
 
@@ -671,6 +674,12 @@ RSpec/Pending:
671
674
  VersionAdded: '1.25'
672
675
  Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Pending
673
676
 
677
+ RSpec/PendingWithoutReason:
678
+ Description: Checks for pending or skipped examples without reason.
679
+ Enabled: pending
680
+ VersionAdded: '2.16'
681
+ Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/PendingWithoutReason
682
+
674
683
  RSpec/PredicateMatcher:
675
684
  Description: Prefer using predicate matcher over using predicate method directly.
676
685
  Enabled: true
@@ -967,6 +976,16 @@ RSpec/FactoryBot/FactoryClassName:
967
976
  VersionChanged: '2.0'
968
977
  Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/FactoryBot/FactoryClassName
969
978
 
979
+ RSpec/FactoryBot/FactoryNameStyle:
980
+ Description: Checks for name style for argument of FactoryBot::Syntax::Methods.
981
+ Enabled: pending
982
+ VersionAdded: '2.16'
983
+ EnforcedStyle: symbol
984
+ SupportedStyles:
985
+ - symbol
986
+ - string
987
+ Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/FactoryBot/FactoryNameStyle
988
+
970
989
  RSpec/FactoryBot/SyntaxMethods:
971
990
  Description: Use shorthands from `FactoryBot::Syntax::Methods` in your specs.
972
991
  Enabled: pending
@@ -992,6 +1011,17 @@ RSpec/Rails/HaveHttpStatus:
992
1011
  VersionAdded: '2.12'
993
1012
  Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Rails/HaveHttpStatus
994
1013
 
1014
+ RSpec/Rails/HttpStatus:
1015
+ Description: Enforces use of symbolic or numeric value to describe HTTP status.
1016
+ Enabled: true
1017
+ EnforcedStyle: symbolic
1018
+ SupportedStyles:
1019
+ - numeric
1020
+ - symbolic
1021
+ VersionAdded: '1.23'
1022
+ VersionChanged: '2.0'
1023
+ Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Rails/HttpStatus
1024
+
995
1025
  RSpec/Rails/InferredSpecType:
996
1026
  Description: Identifies redundant spec type.
997
1027
  Enabled: pending
@@ -1014,14 +1044,3 @@ RSpec/Rails/InferredSpecType:
1014
1044
  routing: routing
1015
1045
  system: system
1016
1046
  views: view
1017
-
1018
- RSpec/Rails/HttpStatus:
1019
- Description: Enforces use of symbolic or numeric value to describe HTTP status.
1020
- Enabled: true
1021
- EnforcedStyle: symbolic
1022
- SupportedStyles:
1023
- - numeric
1024
- - symbolic
1025
- VersionAdded: '1.23'
1026
- VersionChanged: '2.0'
1027
- Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Rails/HttpStatus
@@ -21,6 +21,8 @@ module RuboCop
21
21
  class Be < Base
22
22
  MSG = "Don't use `be` without an argument."
23
23
 
24
+ RESTRICT_ON_SEND = Runners.all
25
+
24
26
  # @!method be_without_args(node)
25
27
  def_node_matcher :be_without_args, <<-PATTERN
26
28
  (send _ #Runners.all $(send nil? :be))
@@ -9,6 +9,9 @@ module RuboCop
9
9
  # using `==`. Booleans and nil can be compared by identity and therefore
10
10
  # the `be` matcher is preferable as it is a more strict test.
11
11
  #
12
+ # @safety
13
+ # This cop is unsafe because it changes how values are compared.
14
+ #
12
15
  # @example
13
16
  # # bad
14
17
  # expect(foo).to eq(true)
@@ -10,6 +10,9 @@ module RuboCop
10
10
  # can be compared by identity and therefore the `be` matcher is
11
11
  # preferable as it is a more strict test.
12
12
  #
13
+ # @safety
14
+ # This cop is unsafe because it changes how values are compared.
15
+ #
13
16
  # @example
14
17
  # # bad
15
18
  # expect(foo).to eql(1)
@@ -29,7 +29,7 @@ module RuboCop
29
29
  # # good
30
30
  # expect(page).to have_current_path('/callback')
31
31
  #
32
- class CurrentPathExpectation < Base
32
+ class CurrentPathExpectation < ::RuboCop::Cop::Base
33
33
  extend AutoCorrector
34
34
 
35
35
  MSG = 'Do not set an RSpec expectation on `current_path` in ' \
@@ -47,14 +47,14 @@ module RuboCop
47
47
  # @!method as_is_matcher(node)
48
48
  def_node_matcher :as_is_matcher, <<-PATTERN
49
49
  (send
50
- #expectation_set_on_current_path $#Runners.all
50
+ #expectation_set_on_current_path ${:to :to_not :not_to}
51
51
  ${(send nil? :eq ...) (send nil? :match (regexp ...))})
52
52
  PATTERN
53
53
 
54
54
  # @!method regexp_str_matcher(node)
55
55
  def_node_matcher :regexp_str_matcher, <<-PATTERN
56
56
  (send
57
- #expectation_set_on_current_path $#Runners.all
57
+ #expectation_set_on_current_path ${:to :to_not :not_to}
58
58
  $(send nil? :match (str $_)))
59
59
  PATTERN
60
60
 
@@ -24,7 +24,7 @@ module RuboCop
24
24
  # expect(page).to have_no_selector
25
25
  # expect(page).to have_no_css('a')
26
26
  #
27
- class NegationMatcher < Base
27
+ class NegationMatcher < ::RuboCop::Cop::Base
28
28
  extend AutoCorrector
29
29
  include ConfigurableEnforcedStyle
30
30
 
@@ -20,7 +20,7 @@ module RuboCop
20
20
  # click_link(exact_text: 'foo')
21
21
  # find('div').click_button
22
22
  #
23
- class SpecificActions < Base
23
+ class SpecificActions < ::RuboCop::Cop::Base
24
24
  MSG = "Prefer `%<good_action>s` over `find('%<selector>s').click`."
25
25
  RESTRICT_ON_SEND = %i[click].freeze
26
26
  SPECIFIC_ACTION = {
@@ -15,7 +15,7 @@ module RuboCop
15
15
  # find_by_id('some-id')
16
16
  # find_by_id('some-id', visible: true)
17
17
  #
18
- class SpecificFinders < Base
18
+ class SpecificFinders < ::RuboCop::Cop::Base
19
19
  extend AutoCorrector
20
20
 
21
21
  include RangeHelp
@@ -26,9 +26,7 @@ module RuboCop
26
26
  # expect(page).to have_select
27
27
  # expect(page).to have_field('foo')
28
28
  #
29
- class SpecificMatcher < Base
30
- include CapybaraHelp
31
-
29
+ class SpecificMatcher < ::RuboCop::Cop::Base
32
30
  MSG = 'Prefer `%<good_matcher>s` over `%<bad_matcher>s`.'
33
31
  RESTRICT_ON_SEND = %i[have_selector have_no_selector have_css
34
32
  have_no_css].freeze
@@ -49,8 +47,8 @@ module RuboCop
49
47
  first_argument(node) do |arg|
50
48
  next unless (matcher = specific_matcher(arg))
51
49
  next if CssSelector.multiple_selectors?(arg)
52
- next unless specific_option?(node, arg, matcher)
53
- next unless specific_pseudo_classes?(arg)
50
+ next unless CapybaraHelp.specific_option?(node, arg, matcher)
51
+ next unless CapybaraHelp.specific_pseudo_classes?(arg)
54
52
 
55
53
  add_offense(node, message: message(node, matcher))
56
54
  end
@@ -26,7 +26,7 @@ module RuboCop
26
26
  # expect(page).to have_css('.foo', visible: :all)
27
27
  # expect(page).to have_link('my link', visible: :hidden)
28
28
  #
29
- class VisibilityMatcher < Base
29
+ class VisibilityMatcher < ::RuboCop::Cop::Base
30
30
  MSG_FALSE = 'Use `:all` or `:hidden` instead of `false`.'
31
31
  MSG_TRUE = 'Use `:visible` instead of `true`.'
32
32
  CAPYBARA_MATCHER_METHODS = %w[
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpec
6
+ # Avoid duplicated metadata.
7
+ #
8
+ # @example
9
+ # # bad
10
+ # describe 'Something', :a, :a
11
+ #
12
+ # # good
13
+ # describe 'Something', :a
14
+ class DuplicatedMetadata < Base
15
+ extend AutoCorrector
16
+
17
+ include Metadata
18
+ include RangeHelp
19
+
20
+ MSG = 'Avoid duplicated metadata.'
21
+
22
+ def on_metadata(symbols, _pairs)
23
+ symbols.each do |symbol|
24
+ on_metadata_symbol(symbol)
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def on_metadata_symbol(node)
31
+ return unless duplicated?(node)
32
+
33
+ add_offense(node) do |corrector|
34
+ autocorrect(corrector, node)
35
+ end
36
+ end
37
+
38
+ def autocorrect(corrector, node)
39
+ corrector.remove(
40
+ range_with_surrounding_comma(
41
+ range_with_surrounding_space(
42
+ node.location.expression,
43
+ side: :left
44
+ ),
45
+ :left
46
+ )
47
+ )
48
+ end
49
+
50
+ def duplicated?(node)
51
+ node.left_siblings.any? do |sibling|
52
+ sibling.eql?(node)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -55,6 +55,8 @@ module RuboCop
55
55
  end
56
56
  end
57
57
 
58
+ private
59
+
58
60
  def allowed_one_liner?(node)
59
61
  consecutive_one_liner?(node) && allow_consecutive_one_liners?
60
62
  end
@@ -26,6 +26,8 @@ module RuboCop
26
26
 
27
27
  MSG = 'Provide the actual you are testing to `expect(...)`.'
28
28
 
29
+ RESTRICT_ON_SEND = Runners.all
30
+
29
31
  SIMPLE_LITERALS = %i[
30
32
  true
31
33
  false
@@ -25,7 +25,7 @@ module RuboCop
25
25
  # # good
26
26
  # count { 1 }
27
27
  #
28
- class AttributeDefinedStatically < Base
28
+ class AttributeDefinedStatically < ::RuboCop::Cop::Base
29
29
  extend AutoCorrector
30
30
 
31
31
  MSG = 'Use a block to declare attribute values.'
@@ -40,7 +40,7 @@ module RuboCop
40
40
  # name: 'foo'
41
41
  # )
42
42
  #
43
- class ConsistentParenthesesStyle < Base
43
+ class ConsistentParenthesesStyle < ::RuboCop::Cop::Base
44
44
  extend AutoCorrector
45
45
  include ConfigurableEnforcedStyle
46
46
  include RuboCop::RSpec::FactoryBot::Language
@@ -55,17 +55,22 @@ module RuboCop
55
55
 
56
56
  FACTORY_CALLS = RuboCop::RSpec::FactoryBot::Language::METHODS
57
57
 
58
+ RESTRICT_ON_SEND = FACTORY_CALLS
59
+
58
60
  # @!method factory_call(node)
59
61
  def_node_matcher :factory_call, <<-PATTERN
60
- (send
61
- ${#factory_bot? nil?} %FACTORY_CALLS
62
- $...)
62
+ (send
63
+ {#factory_bot? nil?} %FACTORY_CALLS
64
+ {sym str send lvar} _*
65
+ )
63
66
  PATTERN
64
67
 
65
68
  def on_send(node)
66
- return if nested_call?(node) # prevent from nested matching
69
+ return if ambiguous_without_parentheses?(node)
67
70
 
68
71
  factory_call(node) do
72
+ return if node.method?(:generate) && node.arguments.count > 1
73
+
69
74
  if node.parenthesized?
70
75
  process_with_parentheses(node)
71
76
  else
@@ -74,6 +79,8 @@ module RuboCop
74
79
  end
75
80
  end
76
81
 
82
+ private
83
+
77
84
  def process_with_parentheses(node)
78
85
  return unless style == :omit_parentheses
79
86
  return unless same_line?(node, node.first_argument)
@@ -93,12 +100,12 @@ module RuboCop
93
100
  end
94
101
  end
95
102
 
96
- def nested_call?(node)
97
- node.parent&.send_type?
103
+ def ambiguous_without_parentheses?(node)
104
+ node.parent&.send_type? ||
105
+ node.parent&.pair_type? ||
106
+ node.parent&.array_type?
98
107
  end
99
108
 
100
- private
101
-
102
109
  def remove_parentheses(corrector, node)
103
110
  corrector.replace(node.location.begin, ' ')
104
111
  corrector.remove(node.location.end)
@@ -31,7 +31,7 @@ module RuboCop
31
31
  # # good
32
32
  # 3.times { create :user }
33
33
  #
34
- class CreateList < Base
34
+ class CreateList < ::RuboCop::Cop::Base
35
35
  extend AutoCorrector
36
36
  include ConfigurableEnforcedStyle
37
37
  include RuboCop::RSpec::FactoryBot::Language
@@ -143,7 +143,7 @@ module RuboCop
143
143
 
144
144
  def call(corrector)
145
145
  replacement = generate_n_times_block(node)
146
- corrector.replace(node, replacement)
146
+ corrector.replace(node.block_node || node, replacement)
147
147
  end
148
148
 
149
149
  private
@@ -159,8 +159,15 @@ module RuboCop
159
159
 
160
160
  replacement = format_receiver(node.receiver)
161
161
  replacement += format_method_call(node, 'create', arguments)
162
+ replacement += " #{factory_call_block_source}" if node.block_node
162
163
  "#{count.source}.times { #{replacement} }"
163
164
  end
165
+
166
+ def factory_call_block_source
167
+ node.block_node.location.begin.with(
168
+ end_pos: node.block_node.location.end.end_pos
169
+ ).source
170
+ end
164
171
  end
165
172
 
166
173
  # :nodoc:
@@ -20,7 +20,7 @@ module RuboCop
20
20
  # factory :foo, class: 'Foo' do
21
21
  # end
22
22
  #
23
- class FactoryClassName < Base
23
+ class FactoryClassName < ::RuboCop::Cop::Base
24
24
  extend AutoCorrector
25
25
 
26
26
  MSG = "Pass '%<class_name>s' string instead of `%<class_name>s` " \
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpec
6
+ module FactoryBot
7
+ # Checks for name style for argument of FactoryBot::Syntax::Methods.
8
+ #
9
+ # @example EnforcedStyle: symbol (default)
10
+ # # bad
11
+ # create('user')
12
+ # build "user", username: "NAME"
13
+ #
14
+ # # good
15
+ # create(:user)
16
+ # build :user, username: "NAME"
17
+ #
18
+ # @example EnforcedStyle: string
19
+ # # bad
20
+ # create(:user)
21
+ # build :user, username: "NAME"
22
+ #
23
+ # # good
24
+ # create('user')
25
+ # build "user", username: "NAME"
26
+ #
27
+ class FactoryNameStyle < ::RuboCop::Cop::Base
28
+ extend AutoCorrector
29
+ include ConfigurableEnforcedStyle
30
+ include RuboCop::RSpec::FactoryBot::Language
31
+
32
+ MSG = 'Use %<prefer>s to refer to a factory.'
33
+ FACTORY_CALLS = RuboCop::RSpec::FactoryBot::Language::METHODS
34
+ RESTRICT_ON_SEND = FACTORY_CALLS
35
+
36
+ # @!method factory_call(node)
37
+ def_node_matcher :factory_call, <<-PATTERN
38
+ (send
39
+ {#factory_bot? nil?} %FACTORY_CALLS
40
+ ${str sym} ...
41
+ )
42
+ PATTERN
43
+
44
+ def on_send(node)
45
+ factory_call(node) do |name|
46
+ if offense_for_symbol_style?(name)
47
+ register_offense(name, name.value.to_sym.inspect)
48
+ elsif offense_for_string_style?(name)
49
+ register_offense(name, name.value.to_s.inspect)
50
+ end
51
+ end
52
+ end
53
+
54
+ private
55
+
56
+ def offense_for_symbol_style?(name)
57
+ name.str_type? && style == :symbol
58
+ end
59
+
60
+ def offense_for_string_style?(name)
61
+ name.sym_type? && style == :string
62
+ end
63
+
64
+ def register_offense(name, prefer)
65
+ add_offense(name,
66
+ message: format(MSG, prefer: style.to_s)) do |corrector|
67
+ corrector.replace(name, prefer)
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -28,6 +28,8 @@ module RuboCop
28
28
 
29
29
  MSG = 'Prefer `%<good>s` over `%<bad>s`.'
30
30
 
31
+ RESTRICT_ON_SEND = Runners.all + %i[should should_not]
32
+
31
33
  # @!method implicit_expect(node)
32
34
  def_node_matcher :implicit_expect, <<-PATTERN
33
35
  {
@@ -44,6 +44,8 @@ module RuboCop
44
44
  check_previous_nodes(node)
45
45
  end
46
46
 
47
+ private
48
+
47
49
  def check_previous_nodes(node)
48
50
  offending_node(node) do |offender|
49
51
  msg = format(MSG, offending: offender.method_name)
@@ -53,8 +55,6 @@ module RuboCop
53
55
  end
54
56
  end
55
57
 
56
- private
57
-
58
58
  def offending_node(node)
59
59
  parent(node).each_child_node.find do |sibling|
60
60
  break if sibling.equal?(node)
@@ -41,6 +41,8 @@ module RuboCop
41
41
 
42
42
  SUPPORTED_STYLES = %w[have_received receive].freeze
43
43
 
44
+ RESTRICT_ON_SEND = Runners.all
45
+
44
46
  # @!method message_expectation(node)
45
47
  def_node_matcher :message_expectation, %(
46
48
  (send (send nil? :expect $_) #Runners.all ...)