rubocop-rspec_parity 2.0.1 → 2.0.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c258389ca56666df76d2865c8fee4ecca3dec132d02b7295d6e245747dbc4896
4
- data.tar.gz: 02612dbd491de04d9819742f61bcdb47933837a6b3211d9888765e9eea94ef36
3
+ metadata.gz: 888fb83446806d8a28fecfc45aaeef7c72183e95214cc9e12b63d3f98e0c746a
4
+ data.tar.gz: 56d460393929a8ca3e990cef75441f49fa0be2cf0c814e151ab911b0392e2162
5
5
  SHA512:
6
- metadata.gz: 6fb8521af37136c1449fc5292fcc7658966f42f538197081d5a9ff53985dc4901c70e5e17c7a93c3204c8be0dc179c10c909ec2499ced966251d7ffc124e14e9
7
- data.tar.gz: d18fc9c48f6063187c20472ada669bbf374192687dce5ae7e91d5bfceb2dc7b282340e623e72165363ad398d4e8cb43251dc8ef7820306cab73279ef71c92c41
6
+ metadata.gz: 4dbc71657523c23118ff2bd823991ceea9aa635b02f35e3da8324e3e0dafc851c263af485991e9897ebf4efbaffc15518099a1c6a2ed69c84b290968229e3d4a
7
+ data.tar.gz: ce9de4bb85bf234ea735755b65b28ba6021eb5fd99a054a483c18e4c82d67d37ab51454b77e7750a5aa15ba163eb62e243ac3478f7766ea0676ba7744e1b365d
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [2.0.2] - 2026-06-18
4
+
5
+ Fixed: `PublicMethodHasSpec` now treats a public class method and a public instance method that share a name (the service-object `def self.call` delegating to `def call`) as one logical method — a single `describe '.call'` or `describe '#call'` satisfies both instead of each requiring its own.
6
+ Fixed: `PublicMethodHasSpec` offense message no longer repeats a describe alias (e.g. `describe '#call' or describe '.call' or describe '.call'`) when a configured alias collides with the flexible-prefix expansion.
7
+
3
8
  ## [2.0.1] - 2026-06-18
4
9
 
5
10
  Fixed: `PublicMethodHasSpec` relaxed validation for single-public-method classes (e.g. service objects) no longer passes when the spec's only method-style `describe`/`context` covers a different method — if a method describe is present it must describe the actual public method.
@@ -29,7 +29,7 @@ module RuboCop
29
29
  return if inside_inner_class?(node)
30
30
 
31
31
  instance_method = !inside_eigenclass?(node) && !inside_class_methods_block?(node)
32
- flexible_prefix = instance_method && module_with_dual_access?(node)
32
+ flexible_prefix = (instance_method && module_with_dual_access?(node)) || dual_scope_method?(node)
33
33
  check_method_has_spec(node, instance_method: instance_method, flexible_prefix: flexible_prefix)
34
34
  end
35
35
 
@@ -38,7 +38,7 @@ module RuboCop
38
38
  return if EXCLUDED_HOOK_METHODS.include?(node.method_name.to_s)
39
39
  return if inside_inner_class?(node)
40
40
 
41
- check_method_has_spec(node, instance_method: false)
41
+ check_method_has_spec(node, instance_method: false, flexible_prefix: dual_scope_method?(node))
42
42
  end
43
43
 
44
44
  private
@@ -151,6 +151,42 @@ module RuboCop
151
151
  node.each_ancestor.find { |n| n.class_type? || n.module_type? }
152
152
  end
153
153
 
154
+ # A class method and an instance method that share a name (the common
155
+ # service-object `def self.call` -> `new(...).call` plus the `def call`
156
+ # it delegates to) describe one logical operation. A single
157
+ # `describe '.call'` or `describe '#call'` should satisfy both, so we
158
+ # check the method with a flexible `#`/`.` prefix.
159
+ def dual_scope_method?(node)
160
+ class_node = find_class_or_module(node)
161
+ return false unless class_node&.body
162
+
163
+ instance_names, class_names = scope_method_names(class_node)
164
+ name = node.method_name
165
+ instance_names.include?(name) && class_names.include?(name)
166
+ end
167
+
168
+ def scope_method_names(class_node)
169
+ instance = []
170
+ klass = []
171
+ scope_children(class_node).each { |child| classify_scope_method(child, instance, klass) }
172
+ [instance, klass]
173
+ end
174
+
175
+ def classify_scope_method(child, instance, klass)
176
+ case child&.type
177
+ when :def then instance << child.method_name
178
+ when :defs then klass << child.method_name if child.children.first&.self_type?
179
+ when :sclass then collect_eigenclass_method_names(child, klass)
180
+ end
181
+ end
182
+
183
+ def collect_eigenclass_method_names(node, klass)
184
+ return unless node.children.first&.self_type? && node.body
185
+
186
+ body_children = node.body.begin_type? ? node.body.children : [node.body]
187
+ body_children.each { |child| klass << child.method_name if child.def_type? }
188
+ end
189
+
154
190
  def targeted_visibility(scope, method_name)
155
191
  return nil unless scope.body
156
192
 
@@ -285,7 +321,7 @@ module RuboCop
285
321
  describes << "describe '#{alias_desc}'"
286
322
  end
287
323
  end
288
- describes.join(" or ")
324
+ describes.uniq.join(" or ")
289
325
  end
290
326
 
291
327
  def prefixes_for(instance_method, flexible_prefix)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RuboCop
4
4
  module RSpecParity
5
- VERSION = "2.0.1"
5
+ VERSION = "2.0.2"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-rspec_parity
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Povilas Jurcys