Class: Shirobai::Cop::RSpec::DescribedClass

Inherits:
RuboCop::Cop::Base
  • Object
show all
Extended by:
RuboCop::Cop::AutoCorrector
Includes:
RuboCop::Cop::ConfigurableEnforcedStyle, RuboCop::Cop::RSpec::Namespace, RuboCop::RSpec::Language, BundleEligible
Defined in:
lib/shirobai/cop/rspec/described_class.rb

Overview

Drop-in Rust reimplementation of RSpec/DescribedClass (rubocop-rspec 3.10.2).

Rust identifies candidate describe(Const) blocks on the shared walk. This wrapper locates the parser block node and runs stock's full detection + autocorrect VERBATIM: find_usage recursion with scope-change guards, collapse_namespace, described_constant, and all config axes (EnforcedStyle, SkipBlocks, OnlyStaticConstants).

Probed quirks live as differential specs in described_class_edge_cases_spec.rb.

Constant Summary collapse

DESCRIBED_CLASS =
'described_class'
MSG =
'Use `%<replacement>s` instead of `%<src>s`.'

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.badgeObject



28
# File 'lib/shirobai/cop/rspec/described_class.rb', line 28

def self.badge = RuboCop::Cop::Badge.parse(cop_name)

.bundle_args(_config) ⇒ Object

No bundle_args needed -- the Rust side does not pack config for this cop (all config axes are handled in the Ruby wrapper).



32
33
34
# File 'lib/shirobai/cop/rspec/described_class.rb', line 32

def self.bundle_args(_config)
  []
end

.cop_nameObject



27
# File 'lib/shirobai/cop/rspec/described_class.rb', line 27

def self.cop_name = "RSpec/DescribedClass"

Instance Method Details

#common_instance_exec_closure?(node) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
# File 'lib/shirobai/cop/rspec/described_class.rb', line 37

def_node_matcher :common_instance_exec_closure?, <<~PATTERN
  (block
    {
      (send (const nil? {:Class :Module :Struct}) :new ...)
      (send (const nil? :Data) :define ...)
      (send _ {:class_eval :module_eval :instance_eval} ...)
      (send _ {:class_exec :module_exec :instance_exec} ...)
    }
    ...
  )
PATTERN

#contains_described_class?(node) ⇒ Object



62
63
# File 'lib/shirobai/cop/rspec/described_class.rb', line 62

def_node_search :contains_described_class?,
'(send nil? :described_class)'

#described_constant(node) ⇒ Object



57
58
59
# File 'lib/shirobai/cop/rspec/described_class.rb', line 57

def_node_matcher :described_constant, <<~PATTERN
  (block (send _ :describe $(const ...) ...) (args) $_)
PATTERN

#on_new_investigationObject



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/shirobai/cop/rspec/described_class.rb', line 65

def on_new_investigation
  RuboCop::RSpec::Language.config = config["RSpec"]["Language"]
  ranges = resolved_candidates
  return if ranges.nil? || ranges.empty?

  source = bundle_eligible? ? processed_source.raw_source : processed_source.buffer.source
  off = SourceOffsets.for(source)
  keys = ranges.map { |(start, fin)| [off[start], off[fin]] }
  located = Shirobai::RSpec::NodeLocator.locate(processed_source, keys)

  keys.each do |key|
    node = located[key]
    process_candidate(node) if node&.block_type?
  end
end

#rspec_block?(node) ⇒ Object



50
51
# File 'lib/shirobai/cop/rspec/described_class.rb', line 50

def_node_matcher :rspec_block?,
'(any_block (send #rspec? #ALL.all ...) ...)'

#scope_changing_syntax?(node) ⇒ Object



54
# File 'lib/shirobai/cop/rspec/described_class.rb', line 54

def_node_matcher :scope_changing_syntax?, '{def class module}'