Class: RuboCop::Cop::Vicenzo::RSpec::LeakyDefinition

Inherits:
RSpec::Base
  • Object
show all
Defined in:
lib/rubocop/cop/vicenzo/rspec/leaky_definition.rb

Overview

Checks for methods, classes, or modules defined directly within RSpec blocks or at the top level of a spec file.

Such definitions pollute the global namespace or the test class scope, leading to state leaking and intermittent test failures.

Examples:

# bad
describe User do
  def setup_user
    # ...
  end
end

# bad
def global_helper
end

# bad
def stub_service
  allow(Service).to receive(:call)
end

# good
describe User do
  let(:user) { create(:user) }
end

# good (inside anonymous class)
let(:model) do
  Class.new do
    def safe_method; end
  end
end

# good
before do
  allow(Service).to receive(:call)
end

Constant Summary collapse

MSG =
'Do not define methods, classes, or modules directly in the global scope or within spec blocks. ' \
'This pollutes the namespace. ' \
'Move this logic to `spec/support`, use `let`, before, ' \
'or encapsulate it within a safe structure (e.g., `Class.new`).'

Instance Method Summary collapse

Instance Method Details

#dynamic_definition?(node) ⇒ Object

Matcher to identify dynamic class/module definitions commonly used in specs Looks for blocks applied to Class.new, Module.new, or Struct.new considers controller {} a valid mock



59
60
61
62
63
64
65
66
67
# File 'lib/rubocop/cop/vicenzo/rspec/leaky_definition.rb', line 59

def_node_matcher :dynamic_definition?, <<~PATTERN
  (block
    {
      (send (const {nil? cbase} {:Class :Module :Struct}) :new ...)
      (send nil? :controller ...)
    }
    ...
  )
PATTERN

#on_class(node) ⇒ Object



73
74
75
# File 'lib/rubocop/cop/vicenzo/rspec/leaky_definition.rb', line 73

def on_class(node)
  check_node(node)
end

#on_def(node) ⇒ Object



69
70
71
# File 'lib/rubocop/cop/vicenzo/rspec/leaky_definition.rb', line 69

def on_def(node)
  check_node(node)
end

#on_module(node) ⇒ Object



77
78
79
# File 'lib/rubocop/cop/vicenzo/rspec/leaky_definition.rb', line 77

def on_module(node)
  check_node(node)
end