Class: RuboCop::Cop::Vicenzo::RSpec::InconsistentSiblingStructure

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

Overview

Enforces strict structural consistency in RSpec files.

It forbids mixing:

  1. Examples (it) with Groups (describe or context)
  2. Different types of Groups (describe with context)

Examples:

# bad (Mixing Describe and Context)
RSpec.describe User do
  describe '#admin?' do ... end
  context 'when user is logged' do ... end
end

# bad (Mixing Example and Context)
RSpec.describe User do
  it { is_expected.to be_valid }
  context 'when invalid' do ... end
end

# good
RSpec.describe User do
  describe '#admin?' do ... end
  describe '#client?' do ... end
end

Constant Summary collapse

MSG =
'Do not mix %<type_a>s with %<type_b>s at the same level.'
EXAMPLES =
%i[it specify example scenario focus].freeze
DESCRIBES =
%i[describe feature experiment].freeze
CONTEXTS =
%i[context].freeze

Instance Method Summary collapse

Instance Method Details

#context_definition?(node) ⇒ Object



50
51
52
# File 'lib/rubocop/cop/vicenzo/rspec/inconsistent_sibling_structure.rb', line 50

def_node_matcher :context_definition?, <<~PATTERN
  (block (send nil? {#{CONTEXTS.map(&:inspect).join(' ')}} ...) ...)
PATTERN

#describe_definition?(node) ⇒ Object



45
46
47
# File 'lib/rubocop/cop/vicenzo/rspec/inconsistent_sibling_structure.rb', line 45

def_node_matcher :describe_definition?, <<~PATTERN
  (block (send nil? {#{DESCRIBES.map(&:inspect).join(' ')}} ...) ...)
PATTERN

#example_definition?(node) ⇒ Object



40
41
42
# File 'lib/rubocop/cop/vicenzo/rspec/inconsistent_sibling_structure.rb', line 40

def_node_matcher :example_definition?, <<~PATTERN
  (block (send nil? {#{EXAMPLES.map(&:inspect).join(' ')}} ...) ...)
PATTERN

#on_block(node) ⇒ Object Also known as: on_numblock



54
55
56
57
58
59
60
61
62
63
# File 'lib/rubocop/cop/vicenzo/rspec/inconsistent_sibling_structure.rb', line 54

def on_block(node)
  return unless example_group?(node)
  return unless node.body

  # Normaliza e classifica em passos separados
  children = child_nodes_for(node)
  found_nodes = classify_children(children)

  validate_consistency(found_nodes)
end