Class: RuboCop::Cop::RSpec::MultipleExpectations

Inherits:
Base
  • Object
show all
Includes:
ConfigurableMax
Defined in:
lib/rubocop/cop/rspec/multiple_expectations.rb

Overview

Checks if examples contain too many ‘expect` calls.

This cop is configurable using the ‘Max` option and works with `–auto-gen-config`.

Examples:

# bad
describe UserCreator do
  it 'builds a user' do
    expect(user.name).to eq("John")
    expect(user.age).to eq(22)
  end
end

# good
describe UserCreator do
  it 'sets the users name' do
    expect(user.name).to eq("John")
  end

  it 'sets the users age' do
    expect(user.age).to eq(22)
  end
end

‘aggregate_failures: true` (default)

# good - the cop ignores when RSpec aggregates failures
 describe UserCreator do
   it 'builds a user', :aggregate_failures do
     expect(user.name).to eq("John")
     expect(user.age).to eq(22)
   end
 end

‘aggregate_failures: false`

# Detected as an offense
 describe UserCreator do
   it 'builds a user', aggregate_failures: false do
     expect(user.name).to eq("John")
     expect(user.age).to eq(22)
   end
 end

configuration

# .rubocop.yml
# RSpec/MultipleExpectations:
#   Max: 2

# not flagged by rubocop
describe UserCreator do
  it 'builds a user' do
    expect(user.name).to eq("John")
    expect(user.age).to eq(22)
  end
end

See Also:

Constant Summary collapse

MSG =
'Example has too many expectations [%<total>d/%<max>d].'
ANYTHING =
->(_node) { true }
TRUE =
->(node) { node.true_type? }

Instance Method Summary collapse

Methods inherited from Base

inherited, #on_new_investigation

Methods included from RSpec::Language::NodePattern

#block_or_numblock_pattern, #block_pattern, #numblock_pattern, #send_pattern

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

#aggregate_failures?(node) ⇒ Object



73
74
75
76
77
78
# File 'lib/rubocop/cop/rspec/multiple_expectations.rb', line 73

def_node_matcher :aggregate_failures?, <<-PATTERN
  (block {
      (send _ _ <(sym :aggregate_failures) ...>)
      (send _ _ ... (hash <(pair (sym :aggregate_failures) %1) ...>))
    } ...)
PATTERN

#aggregate_failures_block?(node) ⇒ Object



84
85
86
# File 'lib/rubocop/cop/rspec/multiple_expectations.rb', line 84

def_node_matcher :aggregate_failures_block?, <<-PATTERN
  (block (send nil? :aggregate_failures ...) ...)
PATTERN

#expect?(node) ⇒ Object



81
# File 'lib/rubocop/cop/rspec/multiple_expectations.rb', line 81

def_node_matcher :expect?, '(send nil? #Expectations.all ...)'

#on_block(node) ⇒ Object

rubocop:disable InternalAffairs/NumblockHandler



88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/rubocop/cop/rspec/multiple_expectations.rb', line 88

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

  return if example_with_aggregate_failures?(node)

  expectations_count = to_enum(:find_expectation, node).count

  return if expectations_count <= max_expectations

  self.max = expectations_count

  flag_example(node, expectation_count: expectations_count)
end