rubocop-rspec 2.10.0 → 2.11.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8d0bedaa464141123a49b02ad1a31ed8a63b9960304014c0ef5e52f96fb78176
4
- data.tar.gz: e310236f596a19629629c70d9f94fcb46a39183c43908b5864860efb2abd7602
3
+ metadata.gz: 8b1c8f65ec3429d357c99302f307f318750117e2329719e4cffc60123546a356
4
+ data.tar.gz: 178b52063271fe727162e196b6a364254e86a7343233ee8d15ad2d27f812367d
5
5
  SHA512:
6
- metadata.gz: 7cd82a374f1cd9362070fe6561f9c04927a2ac33f5e1b5ee97a80bc443b0a4c3c90a75d93778e7bf6f439ff759b60857cdeccc2a7b51bfdc8feebccc519e36c8
7
- data.tar.gz: 19bbbdd2d38ef4802be62f44a18e95e83caaf6899c654dff281fe7058fc9bdf6f776cf0491b825b274f67450388a7aef292c2ee51033f6ae96a9d8671829c5e4
6
+ metadata.gz: fdc010e5813ab0d100c50da5686ce10dfff440fb279c01a0f7c0a99f5066202cea53789cbee6d3792b75cc22ce1574e6f06f216822a7ebb960e39f8ad8994139
7
+ data.tar.gz: 055a453f761b8d6ebda211002f2d0265deb4cdc2f8b5567d71cf28d25bcba7d34a1be7f88bd3e7768e29671bb278aa9af4bb6bc910e42008ee083c4c33525cc4
data/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  ## Master (Unreleased)
4
4
 
5
+ ## 2.11.0 (2022-05-18)
6
+
7
+ * Drop Ruby 2.5 support. ([@ydah][])
8
+ * Add new `RSpec/ChangeByZero` cop. ([@ydah][])
9
+ * Improve `RSpec/ExpectChange` to detect namespaced and top-level constants. ([@M-Yamashita01][])
10
+ * Introduce an amendment to `Metrics/BlockLength` to exclude spec files. ([@luke-hill][])
11
+
5
12
  ## 2.10.0 (2022-04-19)
6
13
 
7
14
  * Fix a false positive for `RSpec/EmptyExampleGroup` when expectations in case statement. ([@ydah][])
@@ -681,3 +688,5 @@ Compatibility release so users can upgrade RuboCop to 0.51.0. No new features.
681
688
  [@oshiro3]: https://github.com/oshiro3
682
689
  [@ydah]: https://github.com/ydah
683
690
  [@t3h2mas]: https://github.com/t3h2mas
691
+ [@M-Yamashita01]: https://github.com/M-Yamashita01
692
+ [@luke-hill]: https://github.com/luke-hill
data/config/default.yml CHANGED
@@ -110,6 +110,14 @@ RSpec:
110
110
  - subject
111
111
  - subject!
112
112
 
113
+ Metrics/BlockLength:
114
+ inherit_mode:
115
+ merge:
116
+ - Exclude
117
+ Exclude:
118
+ - "**/*_spec.rb"
119
+ - "**/spec/**/*"
120
+
113
121
  RSpec/AlignLeftLetBrace:
114
122
  Description: Checks that left braces for adjacent single line lets are aligned.
115
123
  Enabled: false
@@ -176,6 +184,12 @@ RSpec/BeforeAfterAll:
176
184
  StyleGuide: https://rspec.rubystyle.guide/#avoid-hooks-with-context-scope
177
185
  Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/BeforeAfterAll
178
186
 
187
+ RSpec/ChangeByZero:
188
+ Description: Prefer negated matchers over `to change.by(0)`.
189
+ Enabled: pending
190
+ VersionAdded: 2.11.0
191
+ Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ChangeByZero
192
+
179
193
  RSpec/ContextMethod:
180
194
  Description: "`context` should not be used for specifying methods."
181
195
  Enabled: true
@@ -256,7 +270,7 @@ RSpec/DescribedClassModuleWrapping:
256
270
  Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/DescribedClassModuleWrapping
257
271
 
258
272
  RSpec/Dialect:
259
- Description: This cop enforces custom RSpec dialects.
273
+ Description: Enforces custom RSpec dialects.
260
274
  Enabled: false
261
275
  PreferredMethods: {}
262
276
  VersionAdded: '1.33'
@@ -787,13 +801,13 @@ RSpec/VerifiedDoubles:
787
801
  Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/VerifiedDoubles
788
802
 
789
803
  RSpec/VoidExpect:
790
- Description: This cop checks void `expect()`.
804
+ Description: Checks void `expect()`.
791
805
  Enabled: true
792
806
  VersionAdded: '1.16'
793
807
  Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/VoidExpect
794
808
 
795
809
  RSpec/Yield:
796
- Description: This cop checks for calling a block within a stub.
810
+ Description: Checks for calling a block within a stub.
797
811
  Enabled: true
798
812
  VersionAdded: '1.32'
799
813
  Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Yield
@@ -46,7 +46,7 @@ module RuboCop
46
46
 
47
47
  MSG = 'Use `%<replacement>s` instead of `%<method>s`.'
48
48
 
49
- # https://git.io/v7Kwr
49
+ # https://github.com/teamcapybara/capybara/blob/e283c1aeaa72441f5403963577e16333bf111a81/lib/capybara/rspec/features.rb#L31-L36
50
50
  MAP = {
51
51
  background: :before,
52
52
  scenario: :it,
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpec
6
+ # Prefer negated matchers over `to change.by(0)`.
7
+ #
8
+ # @example
9
+ # # bad
10
+ # expect { run }.to change(Foo, :bar).by(0)
11
+ # expect { run }.to change { Foo.bar }.by(0)
12
+ # expect { run }
13
+ # .to change(Foo, :bar).by(0)
14
+ # .and change(Foo, :baz).by(0)
15
+ # expect { run }
16
+ # .to change { Foo.bar }.by(0)
17
+ # .and change { Foo.baz }.by(0)
18
+ #
19
+ # # good
20
+ # expect { run }.not_to change(Foo, :bar)
21
+ # expect { run }.not_to change { Foo.bar }
22
+ # expect { run }
23
+ # .to not_change(Foo, :bar)
24
+ # .and not_change(Foo, :baz)
25
+ # expect { run }
26
+ # .to not_change { Foo.bar }
27
+ # .and not_change { Foo.baz }
28
+ #
29
+ class ChangeByZero < Base
30
+ extend AutoCorrector
31
+ MSG = 'Prefer `not_to change` over `to change.by(0)`.'
32
+ MSG_COMPOUND = 'Prefer negated matchers with compound expectations ' \
33
+ 'over `change.by(0)`.'
34
+ RESTRICT_ON_SEND = %i[change].freeze
35
+
36
+ # @!method expect_change_with_arguments(node)
37
+ def_node_matcher :expect_change_with_arguments, <<-PATTERN
38
+ (send
39
+ (send nil? :change ...) :by
40
+ (int 0))
41
+ PATTERN
42
+
43
+ # @!method expect_change_with_block(node)
44
+ def_node_matcher :expect_change_with_block, <<-PATTERN
45
+ (send
46
+ (block
47
+ (send nil? :change)
48
+ (args)
49
+ (send (...) $_)) :by
50
+ (int 0))
51
+ PATTERN
52
+
53
+ def on_send(node)
54
+ expect_change_with_arguments(node.parent) do
55
+ check_offence(node.parent)
56
+ end
57
+
58
+ expect_change_with_block(node.parent.parent) do
59
+ check_offence(node.parent.parent)
60
+ end
61
+ end
62
+
63
+ private
64
+
65
+ def check_offence(node)
66
+ expression = node.loc.expression
67
+ if compound_expectations?(node)
68
+ add_offense(expression, message: MSG_COMPOUND)
69
+ else
70
+ add_offense(expression) do |corrector|
71
+ autocorrect(corrector, node)
72
+ end
73
+ end
74
+ end
75
+
76
+ def compound_expectations?(node)
77
+ %i[and or].include?(node.parent.method_name)
78
+ end
79
+
80
+ def autocorrect(corrector, node)
81
+ corrector.replace(node.parent.loc.selector, 'not_to')
82
+ range = node.loc.dot.with(end_pos: node.loc.expression.end_pos)
83
+ corrector.remove(range)
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -78,9 +78,8 @@ module RuboCop
78
78
  PATTERN
79
79
 
80
80
  # @!method contains_described_class?(node)
81
- def_node_search :contains_described_class?, <<-PATTERN
82
- (send nil? :described_class)
83
- PATTERN
81
+ def_node_search :contains_described_class?,
82
+ '(send nil? :described_class)'
84
83
 
85
84
  def on_block(node)
86
85
  # In case the explicit style is used, we need to remember what's
@@ -129,17 +128,13 @@ module RuboCop
129
128
  end
130
129
 
131
130
  def scope_change?(node)
132
- scope_changing_syntax?(node) ||
131
+ scope_changing_syntax?(node) ||
133
132
  common_instance_exec_closure?(node) ||
134
133
  skippable_block?(node)
135
134
  end
136
135
 
137
136
  def skippable_block?(node)
138
- node.block_type? && !rspec_block?(node) && skip_blocks?
139
- end
140
-
141
- def skip_blocks?
142
- cop_config['SkipBlocks']
137
+ node.block_type? && !rspec_block?(node) && cop_config['SkipBlocks']
143
138
  end
144
139
 
145
140
  def offensive?(node)
@@ -152,6 +147,7 @@ module RuboCop
152
147
 
153
148
  def offensive_described_class?(node)
154
149
  return unless node.const_type?
150
+
155
151
  # E.g. `described_class::CONSTANT`
156
152
  return if contains_described_class?(node)
157
153
 
@@ -172,14 +168,13 @@ module RuboCop
172
168
  # @return [Array<Symbol>]
173
169
  # @example
174
170
  # # nil represents base constant
175
- # collapse_namespace([], :C) # => [:C]
176
- # collapse_namespace([:A, :B], [:C) # => [:A, :B, :C]
177
- # collapse_namespace([:A, :B], [:B, :C) # => [:A, :B, :C]
178
- # collapse_namespace([:A, :B], [nil, :C) # => [nil, :C]
179
- # collapse_namespace([:A, :B], [nil, :B, :C) # => [nil, :B, :C]
171
+ # collapse_namespace([], [:C]) # => [:C]
172
+ # collapse_namespace([:A, :B], [:C]) # => [:A, :B, :C]
173
+ # collapse_namespace([:A, :B], [:B, :C]) # => [:A, :B, :C]
174
+ # collapse_namespace([:A, :B], [nil, :C]) # => [nil, :C]
175
+ # collapse_namespace([:A, :B], [nil, :B, :C]) # => [nil, :B, :C]
180
176
  def collapse_namespace(namespace, const)
181
- return const if namespace.empty?
182
- return const if const.first.nil?
177
+ return const if namespace.empty? || const.first.nil?
183
178
 
184
179
  start = [0, (namespace.length - const.length)].max
185
180
  max = namespace.length
@@ -196,9 +191,7 @@ module RuboCop
196
191
  # const_name(s(:const, s(:const, nil, :M), :C)) # => [:M, :C]
197
192
  # const_name(s(:const, s(:cbase), :C)) # => [nil, :C]
198
193
  def const_name(node)
199
- # rubocop:disable InternalAffairs/NodeDestructuring
200
- namespace, name = *node
201
- # rubocop:enable InternalAffairs/NodeDestructuring
194
+ namespace, name = *node # rubocop:disable InternalAffairs/NodeDestructuring
202
195
  if !namespace
203
196
  [name]
204
197
  elsif namespace.const_type?
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module RSpec
6
- # This cop enforces custom RSpec dialects.
6
+ # Enforces custom RSpec dialects.
7
7
  #
8
8
  # A dialect can be based on the following RSpec methods:
9
9
  #
@@ -39,7 +39,7 @@ module RuboCop
39
39
 
40
40
  # @!method expect_change_with_arguments(node)
41
41
  def_node_matcher :expect_change_with_arguments, <<-PATTERN
42
- (send nil? :change $_ (sym $_))
42
+ (send nil? :change $_ ({sym str} $_))
43
43
  PATTERN
44
44
 
45
45
  # @!method expect_change_with_block(node)
@@ -47,7 +47,7 @@ module RuboCop
47
47
  (block
48
48
  (send nil? :change)
49
49
  (args)
50
- (send ({const send} nil? $_) $_)
50
+ (send $_ $_)
51
51
  )
52
52
  PATTERN
53
53
 
@@ -67,9 +67,9 @@ module RuboCop
67
67
  return unless style == :method_call
68
68
 
69
69
  expect_change_with_block(node) do |receiver, message|
70
- msg = format(MSG_BLOCK, obj: receiver, attr: message)
70
+ msg = format(MSG_BLOCK, obj: receiver.source, attr: message)
71
71
  add_offense(node, message: msg) do |corrector|
72
- replacement = "change(#{receiver}, :#{message})"
72
+ replacement = "change(#{receiver.source}, :#{message})"
73
73
  corrector.replace(node, replacement)
74
74
  end
75
75
  end
@@ -24,7 +24,7 @@ module RuboCop
24
24
  # rubocop:disable InternalAffairs/NodeDestructuring
25
25
  variable_name, _rhs = *node
26
26
  # rubocop:enable InternalAffairs/NodeDestructuring
27
- name = variable_name[1..-1]
27
+ name = variable_name[1..]
28
28
  return unless name.eql?('stdout') || name.eql?('stderr')
29
29
 
30
30
  add_offense(node.loc.name, message: format(MSG, name: name))
@@ -47,7 +47,7 @@ module RuboCop
47
47
  def correct_variable(variable)
48
48
  case variable.type
49
49
  when :dsym
50
- variable.source[1..-1]
50
+ variable.source[1..]
51
51
  when :sym
52
52
  variable.value.to_s.inspect
53
53
  else
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module RSpec
6
- # This cop checks void `expect()`.
6
+ # Checks void `expect()`.
7
7
  #
8
8
  # @example
9
9
  # # bad
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module RSpec
6
- # This cop checks for calling a block within a stub.
6
+ # Checks for calling a block within a stub.
7
7
  #
8
8
  # @example
9
9
  # # bad
@@ -25,6 +25,7 @@ require_relative 'rspec/be_eq'
25
25
  require_relative 'rspec/be_eql'
26
26
  require_relative 'rspec/be_nil'
27
27
  require_relative 'rspec/before_after_all'
28
+ require_relative 'rspec/change_by_zero'
28
29
  require_relative 'rspec/context_method'
29
30
  require_relative 'rspec/context_wording'
30
31
  require_relative 'rspec/describe_class'
@@ -8,6 +8,7 @@ module RuboCop
8
8
  class ConfigFormatter
9
9
  EXTENSION_ROOT_DEPARTMENT = %r{^(RSpec/)}.freeze
10
10
  SUBDEPARTMENTS = %(RSpec/Capybara RSpec/FactoryBot RSpec/Rails)
11
+ AMENDMENTS = %(Metrics/BlockLength)
11
12
  COP_DOC_BASE_URL = 'https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/'
12
13
 
13
14
  def initialize(config, descriptions)
@@ -18,6 +19,7 @@ module RuboCop
18
19
  def dump
19
20
  YAML.dump(unified_config)
20
21
  .gsub(EXTENSION_ROOT_DEPARTMENT, "\n\\1")
22
+ .gsub(*AMENDMENTS, "\n\\0")
21
23
  .gsub(/^(\s+)- /, '\1 - ')
22
24
  end
23
25
 
@@ -26,6 +28,7 @@ module RuboCop
26
28
  def unified_config
27
29
  cops.each_with_object(config.dup) do |cop, unified|
28
30
  next if SUBDEPARTMENTS.include?(cop)
31
+ next if AMENDMENTS.include?(cop)
29
32
 
30
33
  unified[cop].merge!(descriptions.fetch(cop))
31
34
  unified[cop]['Reference'] = COP_DOC_BASE_URL + cop.sub('RSpec/', '')
@@ -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.10.0'
7
+ STRING = '2.11.0'
8
8
  end
9
9
  end
10
10
  end
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.10.0
4
+ version: 2.11.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: 2022-04-19 00:00:00.000000000 Z
13
+ date: 2022-05-18 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rubocop
@@ -142,6 +142,7 @@ files:
142
142
  - lib/rubocop/cop/rspec/capybara/current_path_expectation.rb
143
143
  - lib/rubocop/cop/rspec/capybara/feature_methods.rb
144
144
  - lib/rubocop/cop/rspec/capybara/visibility_matcher.rb
145
+ - lib/rubocop/cop/rspec/change_by_zero.rb
145
146
  - lib/rubocop/cop/rspec/context_method.rb
146
147
  - lib/rubocop/cop/rspec/context_wording.rb
147
148
  - lib/rubocop/cop/rspec/describe_class.rb
@@ -262,14 +263,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
262
263
  requirements:
263
264
  - - ">="
264
265
  - !ruby/object:Gem::Version
265
- version: 2.5.0
266
+ version: 2.6.0
266
267
  required_rubygems_version: !ruby/object:Gem::Requirement
267
268
  requirements:
268
269
  - - ">="
269
270
  - !ruby/object:Gem::Version
270
271
  version: '0'
271
272
  requirements: []
272
- rubygems_version: 3.3.1
273
+ rubygems_version: 3.1.6
273
274
  signing_key:
274
275
  specification_version: 4
275
276
  summary: Code style checking for RSpec files