lib/rubocop/cop/rspec/multiple_expectations.rb in rubocop-rspec-1.12.0 vs lib/rubocop/cop/rspec/multiple_expectations.rb in rubocop-rspec-1.13.0
- old
+ new
@@ -46,24 +46,56 @@
# end
#
class MultipleExpectations < Cop
include ConfigurableMax
- MSG = 'Example has too many expectations [%{total}/%{max}]'.freeze
+ MSG = 'Example has too many expectations [%{total}/%{max}].'.freeze
- def_node_search :expect, '(send _ :expect ...)'
+ def_node_search :with_aggregated_failures?, '(sym :aggregate_failures)'
+ def_node_search :disabled_aggregated_failures?, <<-PATTERN
+ (pair (sym :aggregate_failures) (false))
+ PATTERN
+ def_node_matcher :expect?, '(send _ :expect ...)'
+ def_node_matcher :aggregate_failures?, <<-PATTERN
+ (block (send _ :aggregate_failures ...) ...)
+ PATTERN
+
def on_block(node)
- return unless example?(node) && (expectations = expect(node))
+ return unless example?(node)
- return if expectations.count <= max_expectations
+ return if example_with_aggregated_failures?(node)
- self.max = expectations.count
+ expectations_count = to_enum(:find_expectation, node).count
- flag_example(node, expectation_count: expectations.count)
+ return if expectations_count <= max_expectations
+
+ self.max = expectations_count
+
+ flag_example(node, expectation_count: expectations_count)
end
private
+
+ def example_with_aggregated_failures?(node)
+ example = node.children.first
+
+ with_aggregated_failures?(example) &&
+ !disabled_aggregated_failures?(example)
+ end
+
+ def find_expectation(node, &block)
+ return unless node.is_a?(Parser::AST::Node)
+
+ yield if expect?(node) || aggregate_failures?(node)
+
+ # do not search inside of aggregate_failures block
+ return if aggregate_failures?(node)
+
+ node.children.each do |child|
+ find_expectation(child, &block)
+ end
+ end
def flag_example(node, expectation_count:)
method, = *node
add_offense(