class RuboCop::Cop::RSpec::MultipleExpectations
Checks if examples contain too many ‘expect` calls.
@see betterspecs.org/#single Single expectation test
This cop is configurable using the ‘Max` option and works with `–auto-gen-config`.
@example
# 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
@example ‘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
@example ‘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
@example ‘Max: 1` (default)
# bad describe UserCreator do it 'builds a user' do expect(user.name).to eq("John") expect(user.age).to eq(22) end end
@example ‘Max: 2`
# good describe UserCreator do it 'builds a user' do expect(user.name).to eq("John") expect(user.age).to eq(22) end end
Constants
- ANYTHING
- MSG
- TRUE_NODE
Public Instance Methods
on_block(node)
click to toggle source
# File lib/rubocop/cop/rspec/multiple_expectations.rb, line 93 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
Private Instance Methods
example_with_aggregate_failures?(example_node)
click to toggle source
# File lib/rubocop/cop/rspec/multiple_expectations.rb, line 109 def example_with_aggregate_failures?(example_node) node_with_aggregate_failures = find_aggregate_failures(example_node) return false unless node_with_aggregate_failures aggregate_failures?(node_with_aggregate_failures, TRUE_NODE) end
find_aggregate_failures(example_node)
click to toggle source
# File lib/rubocop/cop/rspec/multiple_expectations.rb, line 116 def find_aggregate_failures(example_node) example_node.send_node.each_ancestor(:block) .find { |block_node| aggregate_failures?(block_node, ANYTHING) } end
find_expectation(node) { || ... }
click to toggle source
# File lib/rubocop/cop/rspec/multiple_expectations.rb, line 121 def find_expectation(node, &block) yield if expect?(node) || aggregate_failures_block?(node) # do not search inside of aggregate_failures block return if aggregate_failures_block?(node) node.each_child_node do |child| find_expectation(child, &block) end end
flag_example(node, expectation_count:)
click to toggle source
# File lib/rubocop/cop/rspec/multiple_expectations.rb, line 132 def flag_example(node, expectation_count:) add_offense( node.send_node, message: format( MSG, total: expectation_count, max: max_expectations ) ) end
max_expectations()
click to toggle source
# File lib/rubocop/cop/rspec/multiple_expectations.rb, line 143 def max_expectations Integer(cop_config.fetch('Max', 1)) end