rubocop-rspec 2.18.1 → 2.19.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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +17 -0
  3. data/README.md +1 -1
  4. data/config/default.yml +31 -0
  5. data/lib/rubocop/cop/rspec/be_nil.rb +2 -2
  6. data/lib/rubocop/cop/rspec/change_by_zero.rb +3 -3
  7. data/lib/rubocop/cop/rspec/contain_exactly.rb +45 -0
  8. data/lib/rubocop/cop/rspec/context_wording.rb +13 -5
  9. data/lib/rubocop/cop/rspec/describe_method.rb +16 -8
  10. data/lib/rubocop/cop/rspec/described_class.rb +2 -1
  11. data/lib/rubocop/cop/rspec/described_class_module_wrapping.rb +3 -1
  12. data/lib/rubocop/cop/rspec/dialect.rb +1 -1
  13. data/lib/rubocop/cop/rspec/duplicated_metadata.rb +1 -1
  14. data/lib/rubocop/cop/rspec/empty_example_group.rb +7 -7
  15. data/lib/rubocop/cop/rspec/empty_hook.rb +2 -2
  16. data/lib/rubocop/cop/rspec/example_wording.rb +1 -1
  17. data/lib/rubocop/cop/rspec/excessive_docstring_spacing.rb +1 -1
  18. data/lib/rubocop/cop/rspec/expect_in_hook.rb +1 -1
  19. data/lib/rubocop/cop/rspec/factory_bot/attribute_defined_statically.rb +1 -1
  20. data/lib/rubocop/cop/rspec/factory_bot/syntax_methods.rb +2 -2
  21. data/lib/rubocop/cop/rspec/file_path.rb +1 -1
  22. data/lib/rubocop/cop/rspec/focus.rb +4 -5
  23. data/lib/rubocop/cop/rspec/hook_argument.rb +12 -9
  24. data/lib/rubocop/cop/rspec/hooks_before_examples.rb +5 -3
  25. data/lib/rubocop/cop/rspec/let_before_examples.rb +4 -4
  26. data/lib/rubocop/cop/rspec/let_setup.rb +6 -8
  27. data/lib/rubocop/cop/rspec/match_array.rb +41 -0
  28. data/lib/rubocop/cop/rspec/mixin/empty_line_separation.rb +1 -2
  29. data/lib/rubocop/cop/rspec/mixin/location_help.rb +37 -0
  30. data/lib/rubocop/cop/rspec/mixin/skip_or_pending.rb +20 -4
  31. data/lib/rubocop/cop/rspec/multiple_expectations.rb +2 -1
  32. data/lib/rubocop/cop/rspec/named_subject.rb +6 -4
  33. data/lib/rubocop/cop/rspec/no_expectation_example.rb +2 -5
  34. data/lib/rubocop/cop/rspec/overwriting_setup.rb +3 -1
  35. data/lib/rubocop/cop/rspec/pending.rb +12 -12
  36. data/lib/rubocop/cop/rspec/pending_without_reason.rb +65 -36
  37. data/lib/rubocop/cop/rspec/predicate_matcher.rb +9 -34
  38. data/lib/rubocop/cop/rspec/rails/inferred_spec_type.rb +4 -4
  39. data/lib/rubocop/cop/rspec/rails/travel_around.rb +92 -0
  40. data/lib/rubocop/cop/rspec/receive_counts.rb +1 -1
  41. data/lib/rubocop/cop/rspec/redundant_around.rb +69 -0
  42. data/lib/rubocop/cop/rspec/repeated_example_group_body.rb +3 -6
  43. data/lib/rubocop/cop/rspec/repeated_example_group_description.rb +3 -6
  44. data/lib/rubocop/cop/rspec/repeated_include_example.rb +3 -4
  45. data/lib/rubocop/cop/rspec/shared_context.rb +12 -13
  46. data/lib/rubocop/cop/rspec/shared_examples.rb +6 -4
  47. data/lib/rubocop/cop/rspec/skip_block_inside_example.rb +46 -0
  48. data/lib/rubocop/cop/rspec/sort_metadata.rb +2 -2
  49. data/lib/rubocop/cop/rspec/variable_definition.rb +3 -0
  50. data/lib/rubocop/cop/rspec/variable_name.rb +4 -1
  51. data/lib/rubocop/cop/rspec/verified_double_reference.rb +3 -3
  52. data/lib/rubocop/cop/rspec_cops.rb +5 -0
  53. data/lib/rubocop/rspec/example_group.rb +6 -8
  54. data/lib/rubocop/rspec/language/node_pattern.rb +26 -0
  55. data/lib/rubocop/rspec/language.rb +25 -16
  56. data/lib/rubocop/rspec/version.rb +1 -1
  57. data/lib/rubocop-rspec.rb +1 -0
  58. metadata +9 -3
@@ -57,27 +57,26 @@ module RuboCop
57
57
  MSG_CONTEXT = "Use `shared_context` when you don't define examples."
58
58
 
59
59
  # @!method examples?(node)
60
- def_node_search :examples?,
61
- send_pattern('{#Includes.examples #Examples.all}')
60
+ def_node_search :examples?, <<~PATTERN
61
+ (send nil? {#Includes.examples #Examples.all} ...)
62
+ PATTERN
62
63
 
63
64
  # @!method context?(node)
64
65
  def_node_search :context?, <<-PATTERN
65
- (
66
- send #rspec? {
67
- #Subjects.all
68
- #Helpers.all
69
- #Includes.context
70
- #Hooks.all
71
- } ...
66
+ (send nil?
67
+ {#Subjects.all #Helpers.all #Includes.context #Hooks.all} ...
72
68
  )
73
69
  PATTERN
74
70
 
75
71
  # @!method shared_context(node)
76
- def_node_matcher :shared_context,
77
- block_pattern('#SharedGroups.context')
72
+ def_node_matcher :shared_context, <<~PATTERN
73
+ (block (send #rspec? #SharedGroups.context ...) ...)
74
+ PATTERN
75
+
78
76
  # @!method shared_example(node)
79
- def_node_matcher :shared_example,
80
- block_pattern('#SharedGroups.examples')
77
+ def_node_matcher :shared_example, <<~PATTERN
78
+ (block (send #rspec? #SharedGroups.examples ...) ...)
79
+ PATTERN
81
80
 
82
81
  def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
83
82
  context_with_only_examples(node) do
@@ -24,10 +24,12 @@ module RuboCop
24
24
  extend AutoCorrector
25
25
 
26
26
  # @!method shared_examples(node)
27
- def_node_matcher :shared_examples,
28
- send_pattern(
29
- '{#SharedGroups.all #Includes.all}'
30
- )
27
+ def_node_matcher :shared_examples, <<~PATTERN
28
+ {
29
+ (send #rspec? #SharedGroups.all ...)
30
+ (send nil? #Includes.all ...)
31
+ }
32
+ PATTERN
31
33
 
32
34
  def on_send(node)
33
35
  shared_examples(node) do
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpec
6
+ # Checks for passing a block to `skip` within examples.
7
+ #
8
+ # @example
9
+ # # bad
10
+ # it 'does something' do
11
+ # skip 'not yet implemented' do
12
+ # do_something
13
+ # end
14
+ # end
15
+ #
16
+ # # good
17
+ # it 'does something' do
18
+ # skip 'not yet implemented'
19
+ # do_something
20
+ # end
21
+ #
22
+ # # good - when outside example
23
+ # skip 'not yet implemented' do
24
+ # end
25
+ #
26
+ class SkipBlockInsideExample < Base
27
+ MSG = "Don't pass a block to `skip` inside examples."
28
+
29
+ def on_block(node)
30
+ return unless node.method?(:skip)
31
+ return unless inside_example?(node)
32
+
33
+ add_offense(node)
34
+ end
35
+
36
+ alias on_numblock on_block
37
+
38
+ private
39
+
40
+ def inside_example?(node)
41
+ node.each_ancestor(:block).any? { |ancestor| example?(ancestor) }
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -38,8 +38,8 @@ module RuboCop
38
38
  metadata = symbols + pairs
39
39
 
40
40
  range_between(
41
- metadata.first.loc.expression.begin_pos,
42
- metadata.last.loc.expression.end_pos
41
+ metadata.first.source_range.begin_pos,
42
+ metadata.last.source_range.end_pos
43
43
  )
44
44
  end
45
45
 
@@ -27,10 +27,13 @@ module RuboCop
27
27
  extend AutoCorrector
28
28
  include ConfigurableEnforcedStyle
29
29
  include Variable
30
+ include InsideExampleGroup
30
31
 
31
32
  MSG = 'Use %<style>s for variable names.'
32
33
 
33
34
  def on_send(node)
35
+ return unless inside_example_group?(node)
36
+
34
37
  variable_definition?(node) do |variable|
35
38
  next unless style_violation?(variable)
36
39
 
@@ -42,15 +42,18 @@ module RuboCop
42
42
  include ConfigurableNaming
43
43
  include AllowedPattern
44
44
  include Variable
45
+ include InsideExampleGroup
45
46
 
46
47
  MSG = 'Use %<style>s for variable names.'
47
48
 
48
49
  def on_send(node)
50
+ return unless inside_example_group?(node)
51
+
49
52
  variable_definition?(node) do |variable|
50
53
  return if variable.dstr_type? || variable.dsym_type?
51
54
  return if matches_allowed_pattern?(variable.value)
52
55
 
53
- check_name(node, variable.value, variable.loc.expression)
56
+ check_name(node, variable.value, variable.source_range)
54
57
  end
55
58
  end
56
59
 
@@ -76,10 +76,10 @@ module RuboCop
76
76
  break correct_style_detected unless opposing_style?(class_reference)
77
77
 
78
78
  message = format(MSG, style: style)
79
- expression = class_reference.loc.expression
79
+ expression = class_reference.source_range
80
80
 
81
81
  add_offense(expression, message: message) do |corrector|
82
- violation = class_reference.children.last.to_s
82
+ violation = class_reference.source
83
83
  corrector.replace(expression, correct_style(violation))
84
84
 
85
85
  opposite_style_detected
@@ -102,7 +102,7 @@ module RuboCop
102
102
  if style == :string
103
103
  "'#{violation}'"
104
104
  else
105
- violation
105
+ violation.gsub(/^['"]|['"]$/, '')
106
106
  end
107
107
  end
108
108
  end
@@ -25,6 +25,7 @@ rescue LoadError
25
25
  end
26
26
  require_relative 'rspec/rails/inferred_spec_type'
27
27
  require_relative 'rspec/rails/minitest_assertions'
28
+ require_relative 'rspec/rails/travel_around'
28
29
 
29
30
  require_relative 'rspec/align_left_let_brace'
30
31
  require_relative 'rspec/align_right_let_brace'
@@ -37,6 +38,7 @@ require_relative 'rspec/be_nil'
37
38
  require_relative 'rspec/before_after_all'
38
39
  require_relative 'rspec/change_by_zero'
39
40
  require_relative 'rspec/class_check'
41
+ require_relative 'rspec/contain_exactly'
40
42
  require_relative 'rspec/context_method'
41
43
  require_relative 'rspec/context_wording'
42
44
  require_relative 'rspec/describe_class'
@@ -77,6 +79,7 @@ require_relative 'rspec/leading_subject'
77
79
  require_relative 'rspec/leaky_constant_declaration'
78
80
  require_relative 'rspec/let_before_examples'
79
81
  require_relative 'rspec/let_setup'
82
+ require_relative 'rspec/match_array'
80
83
  require_relative 'rspec/message_chain'
81
84
  require_relative 'rspec/message_expectation'
82
85
  require_relative 'rspec/message_spies'
@@ -95,6 +98,7 @@ require_relative 'rspec/pending_without_reason'
95
98
  require_relative 'rspec/predicate_matcher'
96
99
  require_relative 'rspec/receive_counts'
97
100
  require_relative 'rspec/receive_never'
101
+ require_relative 'rspec/redundant_around'
98
102
  require_relative 'rspec/repeated_description'
99
103
  require_relative 'rspec/repeated_example'
100
104
  require_relative 'rspec/repeated_example_group_body'
@@ -106,6 +110,7 @@ require_relative 'rspec/scattered_setup'
106
110
  require_relative 'rspec/shared_context'
107
111
  require_relative 'rspec/shared_examples'
108
112
  require_relative 'rspec/single_argument_message_chain'
113
+ require_relative 'rspec/skip_block_inside_example'
109
114
  require_relative 'rspec/sort_metadata'
110
115
  require_relative 'rspec/stubbed_mock'
111
116
  require_relative 'rspec/subject_declaration'
@@ -10,14 +10,12 @@ module RuboCop
10
10
  #
11
11
  # Selectors which indicate that we should stop searching
12
12
  #
13
- def_node_matcher :scope_change?,
14
- block_pattern(<<~PATTERN)
15
- {
16
- #SharedGroups.all
17
- #ExampleGroups.all
18
- #Includes.all
19
- }
20
- PATTERN
13
+ def_node_matcher :scope_change?, <<~PATTERN
14
+ (block {
15
+ (send #rspec? {#SharedGroups.all #ExampleGroups.all} ...)
16
+ (send nil? #Includes.all ...)
17
+ } ...)
18
+ PATTERN
21
19
 
22
20
  def lets
23
21
  find_all_in_scope(node, :let?)
@@ -4,18 +4,44 @@ module RuboCop
4
4
  module RSpec
5
5
  module Language
6
6
  # Helper methods to detect RSpec DSL used with send and block
7
+ # @deprecated Prefer using Node Pattern directly
8
+ # Use `'(block (send nil? #Example.all ...) ...)'` instead of
9
+ # `block_pattern('#Example.all')`
7
10
  module NodePattern
11
+ # @deprecated Prefer using Node Pattern directly
8
12
  def send_pattern(string)
13
+ deprecation_warning __method__
9
14
  "(send #rspec? #{string} ...)"
10
15
  end
11
16
 
17
+ # @deprecated Prefer using Node Pattern directly
12
18
  def block_pattern(string)
19
+ deprecation_warning __method__
13
20
  "(block #{send_pattern(string)} ...)"
14
21
  end
15
22
 
23
+ # @deprecated Prefer using Node Pattern directly
16
24
  def numblock_pattern(string)
25
+ deprecation_warning __method__
17
26
  "(numblock #{send_pattern(string)} ...)"
18
27
  end
28
+
29
+ # @deprecated Prefer using Node Pattern directly
30
+ def block_or_numblock_pattern(string)
31
+ deprecation_warning __method__
32
+ "{#{block_pattern(string)} #{numblock_pattern(string)}}"
33
+ end
34
+
35
+ private
36
+
37
+ def deprecation_warning(method)
38
+ # Only warn in derived extensions' specs
39
+ return unless defined?(::RSpec)
40
+
41
+ Kernel.warn <<~MESSAGE, uplevel: 2
42
+ Usage of #{method} is deprecated. Use node pattern explicitly.
43
+ MESSAGE
44
+ end
19
45
  end
20
46
  end
21
47
  end
@@ -20,52 +20,61 @@ module RuboCop
20
20
  end
21
21
 
22
22
  # @!method rspec?(node)
23
- def_node_matcher :rspec?, '{(const {nil? cbase} :RSpec) nil?}'
23
+ def_node_matcher :rspec?, '{#explicit_rspec? nil?}'
24
+
25
+ # @!method explicit_rspec?(node)
26
+ def_node_matcher :explicit_rspec?, '(const {nil? cbase} :RSpec)'
24
27
 
25
28
  # @!method example_group?(node)
26
- def_node_matcher :example_group?, block_pattern('#ExampleGroups.all')
29
+ def_node_matcher :example_group?, <<~PATTERN
30
+ ({block numblock} (send #rspec? #ExampleGroups.all ...) ...)
31
+ PATTERN
27
32
 
28
33
  # @!method shared_group?(node)
29
- def_node_matcher :shared_group?, block_pattern('#SharedGroups.all')
34
+ def_node_matcher :shared_group?,
35
+ '(block (send #rspec? #SharedGroups.all ...) ...)'
30
36
 
31
37
  # @!method spec_group?(node)
32
- def_node_matcher :spec_group?,
33
- block_pattern('{#SharedGroups.all #ExampleGroups.all}')
38
+ def_node_matcher :spec_group?, <<~PATTERN
39
+ ({block numblock} (send #rspec?
40
+ {#SharedGroups.all #ExampleGroups.all}
41
+ ...) ...)
42
+ PATTERN
34
43
 
35
44
  # @!method example_group_with_body?(node)
36
45
  def_node_matcher :example_group_with_body?, <<-PATTERN
37
- (block #{send_pattern('#ExampleGroups.all')} args !nil?)
46
+ (block (send #rspec? #ExampleGroups.all ...) args !nil?)
38
47
  PATTERN
39
48
 
40
49
  # @!method example?(node)
41
- def_node_matcher :example?, block_pattern('#Examples.all')
50
+ def_node_matcher :example?, '(block (send nil? #Examples.all ...) ...)'
42
51
 
43
52
  # @!method hook?(node)
44
53
  def_node_matcher :hook?, <<-PATTERN
45
- {
46
- #{block_pattern('#Hooks.all')}
47
- #{numblock_pattern('#Hooks.all')}
48
- }
54
+ {
55
+ (numblock (send nil? #Hooks.all ...) ...)
56
+ (block (send nil? #Hooks.all ...) ...)
57
+ }
49
58
  PATTERN
50
59
 
51
60
  # @!method let?(node)
52
61
  def_node_matcher :let?, <<-PATTERN
53
62
  {
54
- #{block_pattern('#Helpers.all')}
55
- (send #rspec? #Helpers.all _ block_pass)
63
+ (block (send nil? #Helpers.all ...) ...)
64
+ (send nil? #Helpers.all _ block_pass)
56
65
  }
57
66
  PATTERN
58
67
 
59
68
  # @!method include?(node)
60
69
  def_node_matcher :include?, <<-PATTERN
61
70
  {
62
- #{send_pattern('#Includes.all')}
63
- #{block_pattern('#Includes.all')}
71
+ (block (send nil? #Includes.all ...) ...)
72
+ (send nil? #Includes.all ...)
64
73
  }
65
74
  PATTERN
66
75
 
67
76
  # @!method subject?(node)
68
- def_node_matcher :subject?, block_pattern('#Subjects.all')
77
+ def_node_matcher :subject?, '(block (send nil? #Subjects.all ...) ...)'
69
78
 
70
79
  module ExampleGroups # :nodoc:
71
80
  class << self
@@ -4,7 +4,7 @@ module RuboCop
4
4
  module RSpec
5
5
  # Version information for the RSpec RuboCop plugin.
6
6
  module Version
7
- STRING = '2.18.1'
7
+ STRING = '2.19.0'
8
8
  end
9
9
  end
10
10
  end
data/lib/rubocop-rspec.rb CHANGED
@@ -20,6 +20,7 @@ require_relative 'rubocop/rspec/factory_bot/language'
20
20
 
21
21
  require_relative 'rubocop/cop/rspec/mixin/final_end_location'
22
22
  require_relative 'rubocop/cop/rspec/mixin/inside_example_group'
23
+ require_relative 'rubocop/cop/rspec/mixin/location_help'
23
24
  require_relative 'rubocop/cop/rspec/mixin/metadata'
24
25
  require_relative 'rubocop/cop/rspec/mixin/namespace'
25
26
  require_relative 'rubocop/cop/rspec/mixin/skip_or_pending'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-rspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.18.1
4
+ version: 2.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Backus
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-01-19 00:00:00.000000000 Z
13
+ date: 2023-03-06 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rubocop
@@ -80,6 +80,7 @@ files:
80
80
  - lib/rubocop/cop/rspec/capybara/visibility_matcher.rb
81
81
  - lib/rubocop/cop/rspec/change_by_zero.rb
82
82
  - lib/rubocop/cop/rspec/class_check.rb
83
+ - lib/rubocop/cop/rspec/contain_exactly.rb
83
84
  - lib/rubocop/cop/rspec/context_method.rb
84
85
  - lib/rubocop/cop/rspec/context_wording.rb
85
86
  - lib/rubocop/cop/rspec/describe_class.rb
@@ -126,6 +127,7 @@ files:
126
127
  - lib/rubocop/cop/rspec/leaky_constant_declaration.rb
127
128
  - lib/rubocop/cop/rspec/let_before_examples.rb
128
129
  - lib/rubocop/cop/rspec/let_setup.rb
130
+ - lib/rubocop/cop/rspec/match_array.rb
129
131
  - lib/rubocop/cop/rspec/message_chain.rb
130
132
  - lib/rubocop/cop/rspec/message_expectation.rb
131
133
  - lib/rubocop/cop/rspec/message_spies.rb
@@ -134,6 +136,7 @@ files:
134
136
  - lib/rubocop/cop/rspec/mixin/empty_line_separation.rb
135
137
  - lib/rubocop/cop/rspec/mixin/final_end_location.rb
136
138
  - lib/rubocop/cop/rspec/mixin/inside_example_group.rb
139
+ - lib/rubocop/cop/rspec/mixin/location_help.rb
137
140
  - lib/rubocop/cop/rspec/mixin/metadata.rb
138
141
  - lib/rubocop/cop/rspec/mixin/namespace.rb
139
142
  - lib/rubocop/cop/rspec/mixin/skip_or_pending.rb
@@ -156,8 +159,10 @@ files:
156
159
  - lib/rubocop/cop/rspec/rails/http_status.rb
157
160
  - lib/rubocop/cop/rspec/rails/inferred_spec_type.rb
158
161
  - lib/rubocop/cop/rspec/rails/minitest_assertions.rb
162
+ - lib/rubocop/cop/rspec/rails/travel_around.rb
159
163
  - lib/rubocop/cop/rspec/receive_counts.rb
160
164
  - lib/rubocop/cop/rspec/receive_never.rb
165
+ - lib/rubocop/cop/rspec/redundant_around.rb
161
166
  - lib/rubocop/cop/rspec/repeated_description.rb
162
167
  - lib/rubocop/cop/rspec/repeated_example.rb
163
168
  - lib/rubocop/cop/rspec/repeated_example_group_body.rb
@@ -169,6 +174,7 @@ files:
169
174
  - lib/rubocop/cop/rspec/shared_context.rb
170
175
  - lib/rubocop/cop/rspec/shared_examples.rb
171
176
  - lib/rubocop/cop/rspec/single_argument_message_chain.rb
177
+ - lib/rubocop/cop/rspec/skip_block_inside_example.rb
172
178
  - lib/rubocop/cop/rspec/sort_metadata.rb
173
179
  - lib/rubocop/cop/rspec/stubbed_mock.rb
174
180
  - lib/rubocop/cop/rspec/subject_declaration.rb
@@ -221,7 +227,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
221
227
  - !ruby/object:Gem::Version
222
228
  version: '0'
223
229
  requirements: []
224
- rubygems_version: 3.3.7
230
+ rubygems_version: 3.3.26
225
231
  signing_key:
226
232
  specification_version: 4
227
233
  summary: Code style checking for RSpec files