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 +4 -4
- data/CHANGELOG.md +5 -0
- data/lib/rubocop/cop/rspec_parity/public_method_has_spec.rb +39 -3
- data/lib/rubocop/rspec_parity/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 888fb83446806d8a28fecfc45aaeef7c72183e95214cc9e12b63d3f98e0c746a
|
|
4
|
+
data.tar.gz: 56d460393929a8ca3e990cef75441f49fa0be2cf0c814e151ab911b0392e2162
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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)
|