rubocop-rspec 2.18.0 → 2.19.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +22 -1
  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 +13 -7
@@ -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.0'
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.0
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-16 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
@@ -30,16 +30,16 @@ dependencies:
30
30
  name: rubocop-capybara
31
31
  requirement: !ruby/object:Gem::Requirement
32
32
  requirements:
33
- - - ">="
33
+ - - "~>"
34
34
  - !ruby/object:Gem::Version
35
- version: '0'
35
+ version: '2.17'
36
36
  type: :runtime
37
37
  prerelease: false
38
38
  version_requirements: !ruby/object:Gem::Requirement
39
39
  requirements:
40
- - - ">="
40
+ - - "~>"
41
41
  - !ruby/object:Gem::Version
42
- version: '0'
42
+ version: '2.17'
43
43
  description: |2
44
44
  Code style checking for RSpec files.
45
45
  A plugin for the RuboCop code style enforcing & linting tool.
@@ -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