rubocop-rspec 1.41.0 → 1.44.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 (106) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +43 -2
  3. data/config/default.yml +41 -3
  4. data/lib/rubocop-rspec.rb +2 -1
  5. data/lib/rubocop/cop/rspec/align_left_let_brace.rb +12 -19
  6. data/lib/rubocop/cop/rspec/align_right_let_brace.rb +12 -19
  7. data/lib/rubocop/cop/rspec/any_instance.rb +1 -1
  8. data/lib/rubocop/cop/rspec/around_block.rb +2 -2
  9. data/lib/rubocop/cop/rspec/base.rb +76 -0
  10. data/lib/rubocop/cop/rspec/be.rb +2 -2
  11. data/lib/rubocop/cop/rspec/be_eql.rb +6 -6
  12. data/lib/rubocop/cop/rspec/before_after_all.rb +1 -1
  13. data/lib/rubocop/cop/rspec/capybara/current_path_expectation.rb +19 -17
  14. data/lib/rubocop/cop/rspec/capybara/feature_methods.rb +14 -12
  15. data/lib/rubocop/cop/rspec/capybara/visibility_matcher.rb +1 -1
  16. data/lib/rubocop/cop/rspec/context_method.rb +7 -9
  17. data/lib/rubocop/cop/rspec/context_wording.rb +3 -3
  18. data/lib/rubocop/cop/rspec/cop.rb +2 -66
  19. data/lib/rubocop/cop/rspec/describe_class.rb +40 -30
  20. data/lib/rubocop/cop/rspec/describe_method.rb +14 -6
  21. data/lib/rubocop/cop/rspec/describe_symbol.rb +2 -2
  22. data/lib/rubocop/cop/rspec/described_class.rb +12 -9
  23. data/lib/rubocop/cop/rspec/described_class_module_wrapping.rb +1 -1
  24. data/lib/rubocop/cop/rspec/dialect.rb +5 -12
  25. data/lib/rubocop/cop/rspec/empty_example_group.rb +124 -6
  26. data/lib/rubocop/cop/rspec/empty_hook.rb +6 -10
  27. data/lib/rubocop/cop/rspec/empty_line_after_example.rb +5 -7
  28. data/lib/rubocop/cop/rspec/empty_line_after_example_group.rb +5 -9
  29. data/lib/rubocop/cop/rspec/empty_line_after_final_let.rb +8 -8
  30. data/lib/rubocop/cop/rspec/empty_line_after_hook.rb +5 -9
  31. data/lib/rubocop/cop/rspec/empty_line_after_subject.rb +6 -6
  32. data/lib/rubocop/cop/rspec/example_length.rb +1 -1
  33. data/lib/rubocop/cop/rspec/example_without_description.rb +1 -1
  34. data/lib/rubocop/cop/rspec/example_wording.rb +10 -11
  35. data/lib/rubocop/cop/rspec/expect_actual.rb +8 -11
  36. data/lib/rubocop/cop/rspec/expect_change.rb +10 -35
  37. data/lib/rubocop/cop/rspec/expect_in_hook.rb +3 -3
  38. data/lib/rubocop/cop/rspec/expect_output.rb +2 -2
  39. data/lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb +20 -20
  40. data/lib/rubocop/cop/rspec/factory_bot/create_list.rb +20 -22
  41. data/lib/rubocop/cop/rspec/factory_bot/factory_class_name.rb +7 -8
  42. data/lib/rubocop/cop/rspec/file_path.rb +25 -17
  43. data/lib/rubocop/cop/rspec/focus.rb +7 -11
  44. data/lib/rubocop/cop/rspec/hook_argument.rb +16 -23
  45. data/lib/rubocop/cop/rspec/hooks_before_examples.rb +13 -14
  46. data/lib/rubocop/cop/rspec/implicit_block_expectation.rb +2 -3
  47. data/lib/rubocop/cop/rspec/implicit_expect.rb +7 -15
  48. data/lib/rubocop/cop/rspec/implicit_subject.rb +16 -11
  49. data/lib/rubocop/cop/rspec/instance_spy.rb +18 -12
  50. data/lib/rubocop/cop/rspec/instance_variable.rb +1 -1
  51. data/lib/rubocop/cop/rspec/invalid_predicate_matcher.rb +3 -6
  52. data/lib/rubocop/cop/rspec/it_behaves_like.rb +5 -6
  53. data/lib/rubocop/cop/rspec/iterated_expectation.rb +1 -1
  54. data/lib/rubocop/cop/rspec/leading_subject.rb +27 -20
  55. data/lib/rubocop/cop/rspec/leaky_constant_declaration.rb +1 -1
  56. data/lib/rubocop/cop/rspec/let_before_examples.rb +13 -11
  57. data/lib/rubocop/cop/rspec/let_setup.rb +6 -3
  58. data/lib/rubocop/cop/rspec/message_chain.rb +7 -6
  59. data/lib/rubocop/cop/rspec/message_expectation.rb +2 -2
  60. data/lib/rubocop/cop/rspec/message_spies.rb +2 -3
  61. data/lib/rubocop/cop/rspec/missing_example_group_argument.rb +1 -1
  62. data/lib/rubocop/cop/rspec/multiple_describes.rb +11 -8
  63. data/lib/rubocop/cop/rspec/multiple_expectations.rb +7 -11
  64. data/lib/rubocop/cop/rspec/multiple_memoized_helpers.rb +148 -0
  65. data/lib/rubocop/cop/rspec/multiple_subjects.rb +18 -19
  66. data/lib/rubocop/cop/rspec/named_subject.rb +2 -2
  67. data/lib/rubocop/cop/rspec/nested_groups.rb +4 -4
  68. data/lib/rubocop/cop/rspec/not_to_not.rb +5 -6
  69. data/lib/rubocop/cop/rspec/overwriting_setup.rb +1 -1
  70. data/lib/rubocop/cop/rspec/pending.rb +1 -1
  71. data/lib/rubocop/cop/rspec/predicate_matcher.rb +30 -67
  72. data/lib/rubocop/cop/rspec/rails/http_status.rb +5 -9
  73. data/lib/rubocop/cop/rspec/receive_counts.rb +15 -17
  74. data/lib/rubocop/cop/rspec/receive_never.rb +12 -12
  75. data/lib/rubocop/cop/rspec/repeated_description.rb +1 -1
  76. data/lib/rubocop/cop/rspec/repeated_example.rb +2 -2
  77. data/lib/rubocop/cop/rspec/repeated_example_group_body.rb +1 -1
  78. data/lib/rubocop/cop/rspec/repeated_example_group_description.rb +1 -1
  79. data/lib/rubocop/cop/rspec/repeated_include_example.rb +103 -0
  80. data/lib/rubocop/cop/rspec/return_from_stub.rb +9 -20
  81. data/lib/rubocop/cop/rspec/scattered_let.rb +8 -11
  82. data/lib/rubocop/cop/rspec/scattered_setup.rb +1 -1
  83. data/lib/rubocop/cop/rspec/shared_context.rb +8 -21
  84. data/lib/rubocop/cop/rspec/shared_examples.rb +6 -9
  85. data/lib/rubocop/cop/rspec/single_argument_message_chain.rb +15 -18
  86. data/lib/rubocop/cop/rspec/stubbed_mock.rb +172 -0
  87. data/lib/rubocop/cop/rspec/subject_stub.rb +6 -6
  88. data/lib/rubocop/cop/rspec/unspecified_exception.rb +1 -1
  89. data/lib/rubocop/cop/rspec/variable_definition.rb +6 -6
  90. data/lib/rubocop/cop/rspec/variable_name.rb +28 -9
  91. data/lib/rubocop/cop/rspec/verified_doubles.rb +1 -1
  92. data/lib/rubocop/cop/rspec/void_expect.rb +1 -1
  93. data/lib/rubocop/cop/rspec/yield.rb +14 -11
  94. data/lib/rubocop/cop/rspec_cops.rb +3 -0
  95. data/lib/rubocop/rspec/corrector/move_node.rb +7 -5
  96. data/lib/rubocop/rspec/description_extractor.rb +1 -1
  97. data/lib/rubocop/rspec/{blank_line_separation.rb → empty_line_separation.rb} +13 -10
  98. data/lib/rubocop/rspec/example_group.rb +2 -2
  99. data/lib/rubocop/rspec/hook.rb +1 -5
  100. data/lib/rubocop/rspec/language.rb +12 -5
  101. data/lib/rubocop/rspec/language/node_pattern.rb +6 -1
  102. data/lib/rubocop/rspec/top_level_describe.rb +2 -2
  103. data/lib/rubocop/rspec/top_level_group.rb +26 -13
  104. data/lib/rubocop/rspec/variable.rb +1 -1
  105. data/lib/rubocop/rspec/version.rb +1 -1
  106. metadata +40 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4899c717a87d579939d5c1420800d2fe6c150e4421908e75b9d52c57c8362e60
4
- data.tar.gz: 1155018e6595c843c1ade5cdecb748af349c1c2f94dbcd5b17fb4a4fb5d324be
3
+ metadata.gz: 93297f5bb7dfcb8e201365ec296afe22e5e3bbc7150b7a48e7991a22739debdd
4
+ data.tar.gz: 6343b337cf3d879a50553d09c3f4e30e4ff320285c16b533b8fbd73b8732bcd4
5
5
  SHA512:
6
- metadata.gz: 79d9dc291018b0551b52c85dc6b09a1151356e1c85fe4e6a8a7aca5ade036be690f9b5aae7301cf232a0d067b18c0321be44f9915d5485dcaf993786ed07d328
7
- data.tar.gz: cd9db102d912c42b484c7a514f5954b5f35d29bb7f0f3e186ed946898ba1134de5bf452611812465103aa2effc67016e4536bfc6dd365681aa90b2f4c1957f39
6
+ metadata.gz: 7c3eabc2946eb2b36bdb7a2be61eda35605b32f6ba0a6433cd3bde30982e13f909ea3330111631293c89cbf0237a46d3e3782610448396cdcf6dd77726e5cbda
7
+ data.tar.gz: da8f502adeb29f94294eb5a947ee455168dcfb44e23a5ad83365e4503dcdf39225b46bdb5e8357f40a231a4644fc97e8ddb85933fbc78159c43d40bbf5dddc94
@@ -2,6 +2,41 @@
2
2
 
3
3
  ## Master (Unreleased)
4
4
 
5
+ ## 1.44.0 (2020-10-20)
6
+
7
+ * Move our documentation from rubocop-rspec.readthedocs.io to docs.rubocop.org/rubocop-rspec. ([@bquorning][])
8
+ * Add `RSpec/RepeatedIncludeExample` cop. ([@biinari][])
9
+ * Add `RSpec/StubbedMock` cop. ([@bquorning][], [@pirj][])
10
+ * Add `IgnoredMetadata` configuration option to `RSpec/DescribeClass`. ([@Rafix02][])
11
+ * Fix false positives in `RSpec/EmptyExampleGroup`. ([@pirj][])
12
+ * Fix a false positive for `RSpec/EmptyExampleGroup` when example is defined in an `if` branch. ([@koic][])
13
+
14
+ ## 1.43.2 (2020-08-25)
15
+
16
+ * Fix `RSpec/FilePath` when checking a file with a shared example. ([@pirj][])
17
+ * Fix subject nesting detection in `RSpec/LeadingSubject`. ([@pirj][])
18
+
19
+ ## 1.43.1 (2020-08-17)
20
+
21
+ * Fix `RSpec/FilePath` when checking a file defining e.g. an empty class. ([@bquorning][])
22
+
23
+ ## 1.43.0 (2020-08-17)
24
+
25
+ * Add a new base cop class `::RuboCop::Cop::RSpec::Base`. The old base class `::RuboCop::Cop::RSpec::Cop` is deprecated, and will be removed in the next major release. ([@bquorning][])
26
+ * Add support for subject detection after includes and example groups in `RSpec/LeadingSubject`. ([@pirj][])
27
+ * Ignore trailing punctuation in context description prefix. ([@elliterate][])
28
+ * Relax `RSpec/VariableDefinition` cop so interpolated and multiline strings are accepted even when configured to enforce the `symbol` style. ([@bquorning][])
29
+ * Fix `RSpec/EmptyExampleGroup` to flag example groups with examples in invalid scopes. ([@mlarraz][])
30
+ * Fix `RSpec/EmptyExampleGroup` to ignore examples groups with examples defined inside iterators. ([@pirj][])
31
+ * Improve `RSpec/NestedGroups`, `RSpec/FilePath`, `RSpec/DescribeMethod`, `RSpec/MultipleDescribes`, `RSpec/DescribeClass`'s top-level example group detection. ([@pirj][])
32
+ * Add detection of `let!` with a block-pass or a string literal to `RSpec/LetSetup`. ([@pirj][])
33
+ * Add `IgnoredPatterns` configuration option to `RSpec/VariableName`. ([@jtannas][])
34
+ * Add `RSpec/MultipleMemoizedHelpers` cop. ([@mockdeep][])
35
+
36
+ ## 1.42.0 (2020-07-09)
37
+
38
+ * Update RuboCop dependency to 0.87.0 because of changes to internal APIs. ([@bquorning][], [@Darhazer][])
39
+
5
40
  ## 1.41.0 (2020-07-03)
6
41
 
7
42
  * Extend the list of Rails spec types for `RSpec/DescribeClass`. ([@pirj][])
@@ -480,8 +515,8 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
480
515
  [@rspeicher]: https://github.com/rspeicher
481
516
  [@jonatas]: https://github.com/jonatas
482
517
  [@pocke]: https://github.com/pocke
483
- [@bmorrall]: https:/github.com/bmorrall
484
- [@zverok]: https:/github.com/zverok
518
+ [@bmorrall]: https://github.com/bmorrall
519
+ [@zverok]: https://github.com/zverok
485
520
  [@timrogers]: https://github.com/timrogers
486
521
  [@yevhene]: https://github.com/yevhene
487
522
  [@walf443]: https://github.com/walf443
@@ -525,3 +560,9 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
525
560
  [@rolfschmidt]: https://github.com/rolfschmidt
526
561
  [@andrykonchin]: https://github.com/andrykonchin
527
562
  [@harrylewis]: https://github.com/harrylewis
563
+ [@elliterate]: https://github.com/elliterate
564
+ [@jtannas]: https://github.com/jtannas
565
+ [@mockdeep]: https://github.com/mockdeep
566
+ [@biinari]: https://github.com/biinari
567
+ [@koic]: https://github.com/koic
568
+ [@Rafix02]: https://github.com/Rafix02
@@ -74,9 +74,25 @@ RSpec/ContextWording:
74
74
  StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ContextWording
75
75
 
76
76
  RSpec/DescribeClass:
77
- Description: Check that the first argument to the top level describe is a constant.
78
- Enabled: true
77
+ Description: Check that the first argument to the top-level describe is a constant.
78
+ Enabled: true
79
+ IgnoredMetadata:
80
+ type:
81
+ - channel
82
+ - controller
83
+ - helper
84
+ - job
85
+ - mailer
86
+ - model
87
+ - request
88
+ - routing
89
+ - view
90
+ - feature
91
+ - system
92
+ - mailbox
93
+ - aruba
79
94
  VersionAdded: '1.0'
95
+ VersionChanged: '1.44'
80
96
  StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/DescribeClass
81
97
 
82
98
  RSpec/DescribeMethod:
@@ -381,7 +397,7 @@ RSpec/MissingExampleGroupArgument:
381
397
  StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/MissingExampleGroupArgument
382
398
 
383
399
  RSpec/MultipleDescribes:
384
- Description: Checks for multiple top level describes.
400
+ Description: Checks for multiple top-level example groups.
385
401
  Enabled: true
386
402
  VersionAdded: '1.0'
387
403
  StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/MultipleDescribes
@@ -394,6 +410,14 @@ RSpec/MultipleExpectations:
394
410
  VersionChanged: '1.21'
395
411
  StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/MultipleExpectations
396
412
 
413
+ RSpec/MultipleMemoizedHelpers:
414
+ Description: Checks if example groups contain too many `let` and `subject` calls.
415
+ Enabled: true
416
+ AllowSubject: true
417
+ Max: 5
418
+ VersionAdded: '1.43'
419
+ StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/MultipleMemoizedHelpers
420
+
397
421
  RSpec/MultipleSubjects:
398
422
  Description: Checks if an example group defines `subject` multiple times.
399
423
  Enabled: true
@@ -486,6 +510,12 @@ RSpec/RepeatedExampleGroupDescription:
486
510
  VersionAdded: '1.38'
487
511
  StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/RepeatedExampleGroupDescription
488
512
 
513
+ RSpec/RepeatedIncludeExample:
514
+ Description: Check for repeated include of shared examples.
515
+ Enabled: true
516
+ VersionAdded: '1.44'
517
+ StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/RepeatedIncludeExample
518
+
489
519
  RSpec/ReturnFromStub:
490
520
  Description: Checks for consistent style of stub's return setting.
491
521
  Enabled: true
@@ -529,6 +559,12 @@ RSpec/SingleArgumentMessageChain:
529
559
  VersionChanged: '1.10'
530
560
  StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/SingleArgumentMessageChain
531
561
 
562
+ RSpec/StubbedMock:
563
+ Description: Checks that message expectations do not have a configured response.
564
+ Enabled: pending
565
+ VersionAdded: '1.44'
566
+ StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/StubbedMock
567
+
532
568
  RSpec/SubjectStub:
533
569
  Description: Checks for stubbed test subjects.
534
570
  Enabled: true
@@ -558,7 +594,9 @@ RSpec/VariableName:
558
594
  SupportedStyles:
559
595
  - snake_case
560
596
  - camelCase
597
+ IgnoredPatterns: []
561
598
  VersionAdded: '1.40'
599
+ VersionChanged: '1.43'
562
600
  StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/VariableName
563
601
 
564
602
  RSpec/VerifiedDoubles:
@@ -19,11 +19,12 @@ require_relative 'rubocop/rspec/example_group'
19
19
  require_relative 'rubocop/rspec/example'
20
20
  require_relative 'rubocop/rspec/hook'
21
21
  require_relative 'rubocop/rspec/variable'
22
+ require_relative 'rubocop/cop/rspec/base'
22
23
  require_relative 'rubocop/cop/rspec/cop'
23
24
  require_relative 'rubocop/rspec/align_let_brace'
24
25
  require_relative 'rubocop/rspec/factory_bot'
25
26
  require_relative 'rubocop/rspec/final_end_location'
26
- require_relative 'rubocop/rspec/blank_line_separation'
27
+ require_relative 'rubocop/rspec/empty_line_separation'
27
28
  require_relative 'rubocop/rspec/corrector/move_node'
28
29
 
29
30
  RuboCop::RSpec::Inject.defaults!
@@ -17,36 +17,29 @@ module RuboCop
17
17
  # let(:baz) { bar }
18
18
  # let(:a) { b }
19
19
  #
20
- class AlignLeftLetBrace < Cop
20
+ class AlignLeftLetBrace < Base
21
+ extend AutoCorrector
22
+
21
23
  MSG = 'Align left let brace'
22
24
 
23
25
  def self.autocorrect_incompatible_with
24
26
  [Layout::ExtraSpacing]
25
27
  end
26
28
 
27
- def investigate(_processed_source)
29
+ def on_new_investigation
28
30
  return if processed_source.blank?
29
31
 
30
- token_aligner.offending_tokens.each do |let|
31
- add_offense(let, location: :begin)
32
- end
33
- end
32
+ token_aligner =
33
+ RuboCop::RSpec::AlignLetBrace.new(processed_source.ast, :begin)
34
34
 
35
- def autocorrect(let)
36
- lambda do |corrector|
37
- corrector.insert_before(
38
- let.loc.begin,
39
- token_aligner.indent_for(let)
40
- )
35
+ token_aligner.offending_tokens.each do |let|
36
+ add_offense(let.loc.begin) do |corrector|
37
+ corrector.insert_before(
38
+ let.loc.begin, token_aligner.indent_for(let)
39
+ )
40
+ end
41
41
  end
42
42
  end
43
-
44
- private
45
-
46
- def token_aligner
47
- @token_aligner ||=
48
- RuboCop::RSpec::AlignLetBrace.new(processed_source.ast, :begin)
49
- end
50
43
  end
51
44
  end
52
45
  end
@@ -17,36 +17,29 @@ module RuboCop
17
17
  # let(:baz) { bar }
18
18
  # let(:a) { b }
19
19
  #
20
- class AlignRightLetBrace < Cop
20
+ class AlignRightLetBrace < Base
21
+ extend AutoCorrector
22
+
21
23
  MSG = 'Align right let brace'
22
24
 
23
25
  def self.autocorrect_incompatible_with
24
26
  [Layout::ExtraSpacing]
25
27
  end
26
28
 
27
- def investigate(_processed_source)
29
+ def on_new_investigation
28
30
  return if processed_source.blank?
29
31
 
30
- token_aligner.offending_tokens.each do |let|
31
- add_offense(let, location: :end)
32
- end
33
- end
32
+ token_aligner =
33
+ RuboCop::RSpec::AlignLetBrace.new(processed_source.ast, :end)
34
34
 
35
- def autocorrect(let)
36
- lambda do |corrector|
37
- corrector.insert_before(
38
- let.loc.end,
39
- token_aligner.indent_for(let)
40
- )
35
+ token_aligner.offending_tokens.each do |let|
36
+ add_offense(let.loc.end) do |corrector|
37
+ corrector.insert_before(
38
+ let.loc.end, token_aligner.indent_for(let)
39
+ )
40
+ end
41
41
  end
42
42
  end
43
-
44
- private
45
-
46
- def token_aligner
47
- @token_aligner ||=
48
- RuboCop::RSpec::AlignLetBrace.new(processed_source.ast, :end)
49
- end
50
43
  end
51
44
  end
52
45
  end
@@ -22,7 +22,7 @@ module RuboCop
22
22
  # allow(my_instance).to receive(:foo)
23
23
  # end
24
24
  # end
25
- class AnyInstance < Cop
25
+ class AnyInstance < Base
26
26
  MSG = 'Avoid stubbing using `%<method>s`.'
27
27
 
28
28
  def_node_matcher :disallowed_stub, <<-PATTERN
@@ -25,13 +25,13 @@ module RuboCop
25
25
  # some_method
26
26
  # test.run
27
27
  # end
28
- class AroundBlock < Cop
28
+ class AroundBlock < Base
29
29
  MSG_NO_ARG = 'Test object should be passed to around block.'
30
30
  MSG_UNUSED_ARG = 'You should call `%<arg>s.call` '\
31
31
  'or `%<arg>s.run`.'
32
32
 
33
33
  def_node_matcher :hook, <<-PATTERN
34
- (block {(send nil? :around) (send nil? :around sym)} (args $...) ...)
34
+ (block (send nil? :around sym ?) (args $...) ...)
35
35
  PATTERN
36
36
 
37
37
  def_node_search :find_arg_usage, <<-PATTERN
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpec
6
+ # @abstract parent class to RSpec cops
7
+ #
8
+ # The criteria for whether rubocop-rspec analyzes a certain ruby file
9
+ # is configured via `AllCops/RSpec`. For example, if you want to
10
+ # customize your project to scan all files within a `test/` directory
11
+ # then you could add this to your configuration:
12
+ #
13
+ # @example configuring analyzed paths
14
+ # # .rubocop.yml
15
+ # # AllCops:
16
+ # # RSpec:
17
+ # # Patterns:
18
+ # # - '_test.rb$'
19
+ # # - '(?:^|/)test/'
20
+ class Base < ::RuboCop::Cop::Base
21
+ include RuboCop::RSpec::Language
22
+ include RuboCop::RSpec::Language::NodePattern
23
+
24
+ DEFAULT_CONFIGURATION =
25
+ RuboCop::RSpec::CONFIG.fetch('AllCops').fetch('RSpec')
26
+
27
+ DEFAULT_PATTERN_RE = Regexp.union(
28
+ DEFAULT_CONFIGURATION.fetch('Patterns')
29
+ .map(&Regexp.public_method(:new))
30
+ )
31
+
32
+ exclude_from_registry
33
+
34
+ # Invoke the original inherited hook so our cops are recognized
35
+ def self.inherited(subclass) # rubocop:disable Lint/MissingSuper
36
+ RuboCop::Cop::Base.inherited(subclass)
37
+ end
38
+
39
+ def relevant_file?(file)
40
+ relevant_rubocop_rspec_file?(file) && super
41
+ end
42
+
43
+ private
44
+
45
+ def relevant_rubocop_rspec_file?(file)
46
+ rspec_pattern.match?(file)
47
+ end
48
+
49
+ def rspec_pattern
50
+ if rspec_pattern_config?
51
+ Regexp.union(rspec_pattern_config.map(&Regexp.public_method(:new)))
52
+ else
53
+ DEFAULT_PATTERN_RE
54
+ end
55
+ end
56
+
57
+ def all_cops_config
58
+ config
59
+ .for_all_cops
60
+ end
61
+
62
+ def rspec_pattern_config?
63
+ return unless all_cops_config.key?('RSpec')
64
+
65
+ all_cops_config.fetch('RSpec').key?('Patterns')
66
+ end
67
+
68
+ def rspec_pattern_config
69
+ all_cops_config
70
+ .fetch('RSpec', DEFAULT_CONFIGURATION)
71
+ .fetch('Patterns')
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -19,7 +19,7 @@ module RuboCop
19
19
  # expect(foo).to be 1.0
20
20
  # expect(foo).to be(true)
21
21
  #
22
- class Be < Cop
22
+ class Be < Base
23
23
  MSG = 'Don\'t use `be` without an argument.'
24
24
 
25
25
  def_node_matcher :be_without_args, <<-PATTERN
@@ -28,7 +28,7 @@ module RuboCop
28
28
 
29
29
  def on_send(node)
30
30
  be_without_args(node) do |matcher|
31
- add_offense(matcher, location: :selector)
31
+ add_offense(matcher.loc.selector)
32
32
  end
33
33
  end
34
34
  end
@@ -35,7 +35,9 @@ module RuboCop
35
35
  # necessarily the same type as `b` since the `#==` operator can
36
36
  # coerce objects for comparison.
37
37
  #
38
- class BeEql < Cop
38
+ class BeEql < Base
39
+ extend AutoCorrector
40
+
39
41
  MSG = 'Prefer `be` over `eql`.'
40
42
 
41
43
  def_node_matcher :eql_type_with_identity, <<-PATTERN
@@ -44,13 +46,11 @@ module RuboCop
44
46
 
45
47
  def on_send(node)
46
48
  eql_type_with_identity(node) do |eql|
47
- add_offense(eql, location: :selector)
49
+ add_offense(eql.loc.selector) do |corrector|
50
+ corrector.replace(eql.loc.selector, 'be')
51
+ end
48
52
  end
49
53
  end
50
-
51
- def autocorrect(node)
52
- ->(corrector) { corrector.replace(node.loc.selector, 'be') }
53
- end
54
54
  end
55
55
  end
56
56
  end
@@ -23,7 +23,7 @@ module RuboCop
23
23
  # before(:each) { Widget.create }
24
24
  # after(:each) { Widget.delete_all }
25
25
  # end
26
- class BeforeAfterAll < Cop
26
+ class BeforeAfterAll < Base
27
27
  MSG = 'Beware of using `%<hook>s` as it may cause state to leak '\
28
28
  'between tests. If you are using `rspec-rails`, and '\
29
29
  '`use_transactional_fixtures` is enabled, then records created '\
@@ -23,7 +23,9 @@ module RuboCop
23
23
  # expect(page).to have_current_path("/callback")
24
24
  # expect(page).to have_current_path(/widgets/)
25
25
  #
26
- class CurrentPathExpectation < Cop
26
+ class CurrentPathExpectation < Base
27
+ extend AutoCorrector
28
+
27
29
  MSG = 'Do not set an RSpec expectation on `current_path` in ' \
28
30
  'Capybara feature specs - instead, use the ' \
29
31
  '`have_current_path` matcher on `page`'
@@ -47,30 +49,30 @@ module RuboCop
47
49
 
48
50
  def on_send(node)
49
51
  expectation_set_on_current_path(node) do
50
- add_offense(node, location: :selector)
52
+ add_offense(node.loc.selector) do |corrector|
53
+ next unless node.chained?
54
+
55
+ autocorrect(corrector, node)
56
+ end
51
57
  end
52
58
  end
53
59
 
54
- def autocorrect(node)
55
- lambda do |corrector|
56
- return unless node.chained?
60
+ private
57
61
 
58
- as_is_matcher(node.parent) do |to_sym, matcher_node|
59
- rewrite_expectation(corrector, node, to_sym, matcher_node)
60
- end
62
+ def autocorrect(corrector, node)
63
+ as_is_matcher(node.parent) do |to_sym, matcher_node|
64
+ rewrite_expectation(corrector, node, to_sym, matcher_node)
65
+ end
61
66
 
62
- regexp_str_matcher(node.parent) do |to_sym, matcher_node, regexp|
63
- rewrite_expectation(corrector, node, to_sym, matcher_node)
64
- convert_regexp_str_to_literal(corrector, matcher_node, regexp)
65
- end
67
+ regexp_str_matcher(node.parent) do |to_sym, matcher_node, regexp|
68
+ rewrite_expectation(corrector, node, to_sym, matcher_node)
69
+ convert_regexp_str_to_literal(corrector, matcher_node, regexp)
66
70
  end
67
71
  end
68
72
 
69
- private
70
-
71
73
  def rewrite_expectation(corrector, node, to_symbol, matcher_node)
72
74
  current_path_node = node.first_argument
73
- corrector.replace(current_path_node.loc.expression, 'page')
75
+ corrector.replace(current_path_node, 'page')
74
76
  corrector.replace(node.parent.loc.selector, 'to')
75
77
  matcher_method = if to_symbol == :to
76
78
  'have_current_path'
@@ -84,7 +86,7 @@ module RuboCop
84
86
  def convert_regexp_str_to_literal(corrector, matcher_node, regexp_str)
85
87
  str_node = matcher_node.first_argument
86
88
  regexp_expr = Regexp.new(regexp_str).inspect
87
- corrector.replace(str_node.loc.expression, regexp_expr)
89
+ corrector.replace(str_node, regexp_expr)
88
90
  end
89
91
 
90
92
  # `have_current_path` with no options will include the querystring
@@ -97,7 +99,7 @@ module RuboCop
97
99
  return if %i[regexp str].include?(expectation_last_child.type)
98
100
 
99
101
  corrector.insert_after(
100
- expectation_last_child.loc.expression,
102
+ expectation_last_child,
101
103
  ', ignore_query: true'
102
104
  )
103
105
  end