Class: RuboCop::Cop::RSpec::IndexedLet

Inherits:
Base
  • Object
show all
Includes:
AllowedIdentifiers, AllowedPattern
Defined in:
lib/rubocop/cop/rspec/indexed_let.rb

Overview

Do not set up test data using indexes (e.g., ‘item_1`, `item_2`).

It makes reading the test harder because it’s not clear what exactly is tested by this particular example.

The configurable options ‘AllowedIdentifiers` and `AllowedPatterns` will also read those set in `Naming/VariableNumber`.

Examples:

‘Max: 1 (default)`

# bad
let(:item_1) { create(:item) }
let(:item_2) { create(:item) }

let(:item1) { create(:item) }
let(:item2) { create(:item) }

# good

let(:visible_item) { create(:item, visible: true) }
let(:invisible_item) { create(:item, visible: false) }

‘Max: 2`

# bad
let(:item_1) { create(:item) }
let(:item_2) { create(:item) }
let(:item_3) { create(:item) }

# good
let(:item_1) { create(:item) }
let(:item_2) { create(:item) }

‘AllowedIdentifiers: [’item_1’, ‘item_2’]‘

# good
let(:item_1) { create(:item) }
let(:item_2) { create(:item) }

‘AllowedPatterns: [’item’]‘

# good
let(:item_1) { create(:item) }
let(:item_2) { create(:item) }

Constant Summary collapse

MSG =
'This `let` statement uses `%<index>s` in its name. ' \
'Please give it a meaningful name.'

Instance Method Summary collapse

Methods inherited from Base

inherited, #on_new_investigation

Methods included from RSpec::Language

#example?, #example_group?, #example_group_with_body?, #explicit_rspec?, #hook?, #include?, #let?, #rspec?, #shared_group?, #spec_group?, #subject?

Instance Method Details

#let_name(node) ⇒ Object



55
56
57
58
59
60
# File 'lib/rubocop/cop/rspec/indexed_let.rb', line 55

def_node_matcher :let_name, <<~PATTERN
  {
    (block (send nil? #Helpers.all ({str sym} $_) ...) ...)
    (send nil? #Helpers.all ({str sym} $_) block_pass)
  }
PATTERN

#on_block(node) ⇒ Object

rubocop:disable InternalAffairs/NumblockHandler



62
63
64
65
66
67
68
69
70
71
72
# File 'lib/rubocop/cop/rspec/indexed_let.rb', line 62

def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
  return unless spec_group?(node)

  children = node.body&.child_nodes
  return unless children

  filter_indexed_lets(children).each do |let_node|
    index = let_name(let_node)[INDEX_REGEX]
    add_offense(let_node, message: format(MSG, index: index))
  end
end