From cb85ed5d13da15269e4be5f6d32ababe858fb373 Mon Sep 17 00:00:00 2001 From: Thomas Walpole Date: Wed, 31 Aug 2016 14:55:03 -0700 Subject: [PATCH] optimize Result#matches_count? --- lib/capybara/result.rb | 33 ++++++++++++++++++++++++--------- spec/result_spec.rb | 3 +++ 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/lib/capybara/result.rb b/lib/capybara/result.rb index 208723c4..8c5314e3 100644 --- a/lib/capybara/result.rb +++ b/lib/capybara/result.rb @@ -45,7 +45,7 @@ module Capybara end def [](*args) - if (args.size == 1) && ((idx = args[0]).is_a? Integer) && (idx > 0) + if (args.size == 1) && ((idx = args[0]).is_a? Integer) && (idx >= 0) @result_cache << @results_enum.next while @result_cache.size <= idx @result_cache[idx] else @@ -61,26 +61,43 @@ module Capybara end def matches_count? - return Integer(@query.options[:count]) == count if @query.options[:count] - - return false if @query.options[:between] && !(@query.options[:between] === count) + # Only check filters for as many elements as necessary to determine result + if @query.options[:count] + count_opt = Integer(@query.options[:count]) + loop do + break if @result_cache.size > count_opt + @result_cache << @results_enum.next + end + return @result_cache.size == count_opt + end if @query.options[:minimum] + min_opt = Integer(@query.options[:minimum]) begin - @result_cache << @results_enum.next while @result_cache.size < Integer(@query.options[:minimum]) + @result_cache << @results_enum.next while @result_cache.size < min_opt rescue StopIteration return false end end if @query.options[:maximum] + max_opt = Integer(@query.options[:maximum]) begin - @result_cache << @results_enum.next while @result_cache.size <= Integer(@query.options[:maximum]) + @result_cache << @results_enum.next while @result_cache.size <= max_opt return false rescue StopIteration end end + if @query.options[:between] + max = Integer(@query.options[:between].max) + loop do + break if @result_cache.size > max + @result_cache << @results_enum.next + end + return false unless (@query.options[:between] === @result_cache.size) + end + return true end @@ -105,9 +122,7 @@ module Capybara private def full_results - loop do - @result_cache << @results_enum.next - end + loop { @result_cache << @results_enum.next } @result_cache end diff --git a/spec/result_spec.rb b/spec/result_spec.rb index 5f1683d6..eb32a431 100644 --- a/spec/result_spec.rb +++ b/spec/result_spec.rb @@ -81,6 +81,9 @@ RSpec.describe Capybara::Result do expect(result.instance_variable_get('@result_cache').size).to be 1 #works for indexed access + result[0] + expect(result.instance_variable_get('@result_cache').size).to be 1 + result[2] expect(result.instance_variable_get('@result_cache').size).to be 3