rubocop-rspec_parity 1.2.2 → 1.2.3

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: 7f6cb712ad716f1a6c82659cd5114785bd93f7ed7344fb2ba6317de8bae3d37e
4
- data.tar.gz: 2588d5b16c636142a361c2d0723d049099e7e1da76ed30b72b0c78b211734fb9
3
+ metadata.gz: e3c642272877446cd87c6b7d88339e284fe29fac025f153489d28398e20e73bd
4
+ data.tar.gz: bb91681c2f70a3a35febf88a132344a125e0f5a6735df0a2a0b5c39bcee79c97
5
5
  SHA512:
6
- metadata.gz: a2d8de79c7cf285c21e656b96ac473037aabd21c9d206753d44c863b6844d9393217bdf1850b21646f96996355270467e07d711230702fbbb6ed51b4c3536699
7
- data.tar.gz: 65836a3ae64470aa713d5c3492fb33b993d137f66f1be2d464104a3ce75a22733dd0a055fd2875f6d7ad24c25b407869d42bfebb9d494c3416a4d7003813d8b8
6
+ metadata.gz: 83ee14e1845f77229138051716410f1cc1c9d751430800300d4e204b6a4ab07df7c0380549e200723d8ff861a8ce52a5ed02fe461ef8059a02217ffe2da3467b
7
+ data.tar.gz: d9300dd4aacf6711bbfc2135c9814f03cfef4b42981f6cc5c9f7c8291ee1f525ebd092cb5645e25faf31c9171311e92a2841f9cc67ba0780ee2cce6e56297057
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [1.2.3] - 2026-02-10
4
+
5
+ Fixed: `PublicMethodHasSpec` correctly detects visibility for `private :method_name`, `protected :method_name`, `private def method_name`, `protected def method_name`, and `private`/`protected` inside `class << self`
6
+
3
7
  ## [1.2.2] - 2026-02-10
4
8
 
5
9
  Added: `PublicMethodHasSpec` now skips class methods marked with `private_class_method` (both inline and post-hoc forms)
@@ -83,16 +83,50 @@ module RuboCop
83
83
  def public_method?(node)
84
84
  return false if node.nil?
85
85
 
86
- class_or_module = find_class_or_module(node)
87
- return true unless class_or_module
86
+ # Inline form: private def method_name / protected def method_name
87
+ if node.parent&.send_type? && VISIBILITY_METHODS.key?(node.parent.method_name)
88
+ return node.parent.method_name == :public
89
+ end
90
+
91
+ scope = find_enclosing_scope(node)
92
+ return true unless scope
88
93
 
89
- compute_visibility(class_or_module, node) == :public
94
+ # Post-hoc targeted form overrides section-level visibility
95
+ targeted = targeted_visibility(scope, node.method_name)
96
+ return targeted == :public unless targeted.nil?
97
+
98
+ compute_visibility(scope, node) == :public
99
+ end
100
+
101
+ def find_enclosing_scope(node)
102
+ node.each_ancestor.find { |n| n.class_type? || n.module_type? || n.sclass_type? }
90
103
  end
91
104
 
92
105
  def find_class_or_module(node)
93
106
  node.each_ancestor.find { |n| n.class_type? || n.module_type? }
94
107
  end
95
108
 
109
+ def targeted_visibility(scope, method_name)
110
+ return nil unless scope.body
111
+
112
+ scope_children(scope).each do |child|
113
+ next unless targeted_visibility_call?(child, method_name)
114
+
115
+ return VISIBILITY_METHODS[child.method_name]
116
+ end
117
+ nil
118
+ end
119
+
120
+ def targeted_visibility_call?(node, method_name)
121
+ node&.send_type? &&
122
+ VISIBILITY_METHODS.key?(node.method_name) &&
123
+ node.arguments.any? { |arg| arg.sym_type? && arg.value == method_name }
124
+ end
125
+
126
+ def scope_children(scope)
127
+ scope.body.begin_type? ? scope.body.children : [scope.body]
128
+ end
129
+
96
130
  def compute_visibility(class_or_module, target_node)
97
131
  visibility = :public
98
132
  class_or_module.body&.each_child_node do |child|
@@ -105,6 +139,7 @@ module RuboCop
105
139
 
106
140
  def update_visibility(child, current_visibility)
107
141
  return current_visibility unless child.send_type?
142
+ return current_visibility if child.arguments.any? # targeted/inline, not section-level
108
143
 
109
144
  VISIBILITY_METHODS.fetch(child.method_name, current_visibility)
110
145
  end
@@ -222,23 +257,17 @@ module RuboCop
222
257
  return 0 unless class_node&.body
223
258
 
224
259
  public_methods = []
260
+ targeted_non_public = []
225
261
  visibility = :public
226
-
227
- # Get all child nodes, handling both single method and begin-wrapped bodies
228
- children = if class_node.body.begin_type?
229
- class_node.body.children
230
- else
231
- [class_node.body]
232
- end
262
+ children = scope_children(class_node)
233
263
 
234
264
  children.each do |child|
235
265
  next unless child
236
266
 
237
267
  case child.type
238
268
  when :send
239
- visibility = VISIBILITY_METHODS[child.method_name] if VISIBILITY_METHODS.key?(child.method_name)
269
+ count_public_methods_handle_send(child, visibility, targeted_non_public).tap { |v| visibility = v if v }
240
270
  when :def
241
- # Only count instance methods (def), not class methods (defs)
242
271
  if visibility == :public
243
272
  method_name = child.method_name.to_s
244
273
  public_methods << method_name unless excluded_method?(method_name)
@@ -246,10 +275,29 @@ module RuboCop
246
275
  end
247
276
  end
248
277
 
249
- public_methods.size
278
+ (public_methods - targeted_non_public).size
250
279
  end
251
280
  # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
252
281
 
282
+ def count_public_methods_handle_send(child, visibility, targeted_non_public)
283
+ return visibility unless VISIBILITY_METHODS.key?(child.method_name)
284
+
285
+ if child.arguments.empty?
286
+ VISIBILITY_METHODS[child.method_name]
287
+ else
288
+ collect_targeted_non_public(child, targeted_non_public)
289
+ nil
290
+ end
291
+ end
292
+
293
+ def collect_targeted_non_public(child, targeted_non_public)
294
+ return if VISIBILITY_METHODS[child.method_name] == :public
295
+
296
+ child.arguments.each do |arg|
297
+ targeted_non_public << arg.value.to_s if arg.sym_type?
298
+ end
299
+ end
300
+
253
301
  def spec_has_examples?(spec_path, class_name)
254
302
  spec_content = File.read(spec_path)
255
303
  escaped_class_name = Regexp.escape(class_name)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RuboCop
4
4
  module RSpecParity
5
- VERSION = "1.2.2"
5
+ VERSION = "1.2.3"
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: 1.2.2
4
+ version: 1.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Povilas Jurcys