Class: RuboCop::Cop::Vicenzo::RSpec::IterationInsideExample

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

Overview

Do not use expect inside an iteration within an example.

Placing expect calls inside an iteration block (e.g. each) makes tests implicit and hard to debug: when the assertion fails it is unclear which element caused the failure, and not all elements may represent the same condition. Using iteration to build or transform data before calling expect is fine; the problem is calling expect inside the iteration. Write explicit assertions for each relevant case instead.

Examples:

# bad — expect is called inside the iteration

it 'returns vehicle costs general values' do
  response_body[:vehicle_costs].first.each do |attribute, value|
    expect(value).to eq(vehicle_cost.send(attribute).to_s)
  end
end

# good — iteration builds data, expect is called once outside

it 'returns the expected column names' do
  columns = VehicleCost.column_names.map { |column| column.gsub('_centavos', '') }
  expect(response_body[:vehicle_costs].first.keys).to match_array(columns.map(&:to_sym))
end

# good — each attribute has an explicit example

it 'returns the correct name' do
  expect(response_body[:vehicle_costs].first[:name]).to eq(vehicle_cost.name)
end

it 'returns the correct value' do
  expect(response_body[:vehicle_costs].first[:value]).to eq(vehicle_cost.value.to_s)
end

Constant Summary collapse

MSG =
'Do not call `expect` inside an iteration. ' \
'Write explicit assertions instead.'
ENUMERATION_METHODS =
%i[each each_with_index each_with_object].freeze

Instance Method Summary collapse

Instance Method Details

#enumeration_block?(node) ⇒ Object



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

def_node_matcher :enumeration_block?, <<~PATTERN
  (block
    (send _ {#{ENUMERATION_METHODS.map(&:inspect).join(' ')}} ...)
    ...)
PATTERN

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



54
55
56
57
58
# File 'lib/rubocop/cop/vicenzo/rspec/iteration_inside_example.rb', line 54

def on_block(node)
  return unless example?(node)

  find_iterations_with_assertions(node.body)
end