teamcapybara--capybara/lib/capybara/queries/base_query.rb

107 lines
3.2 KiB
Ruby
Raw Normal View History

2016-03-08 00:52:19 +00:00
# frozen_string_literal: true
2018-01-08 20:23:54 +00:00
module Capybara
# @api private
module Queries
class BaseQuery
2018-01-08 20:23:54 +00:00
COUNT_KEYS = %i[count minimum maximum between].freeze
attr_reader :options
attr_writer :session_options
2017-05-28 15:54:55 +00:00
def initialize(options)
@session_options = options.delete(:session_options)
end
def session_options
@session_options || Capybara.session_options
end
def wait
self.class.wait(options, session_options.default_max_wait_time)
end
2018-01-09 22:05:50 +00:00
def self.wait(options, default = Capybara.default_max_wait_time)
# if no value or nil for the :wait option is passed it should default to the default
wait = options.fetch(:wait, nil)
wait = default if wait.nil?
wait || 0
end
2016-08-30 18:37:54 +00:00
##
#
# Checks if a count of 0 is valid for the query
# Returns false if query does not have any count options specified.
#
def expects_none?
2018-01-13 21:06:03 +00:00
count_specified? ? matches_count?(0) : false
2016-08-30 18:37:54 +00:00
end
##
#
# Checks if the given count matches the query count options.
# Defaults to true if no count options are specified. If multiple
# count options exist, it tests that all conditions are met;
# however, if :count is specified, all other options are ignored.
#
# @param [Integer] count The actual number. Should be coercible via Integer()
#
def matches_count?(count)
2018-01-09 22:05:50 +00:00
return (Integer(options[:count]) == count) if options[:count]
2016-08-30 18:37:54 +00:00
return false if options[:maximum] && (Integer(options[:maximum]) < count)
return false if options[:minimum] && (Integer(options[:minimum]) > count)
2018-01-09 22:05:50 +00:00
return false if options[:between] && !options[:between].include?(count)
2018-09-24 16:43:46 +00:00
2018-01-13 21:06:03 +00:00
true
2016-08-30 18:37:54 +00:00
end
##
#
# Generates a failure message from the query description and count options.
#
def failure_message
2018-05-10 20:20:23 +00:00
+"expected to find #{description}" << count_message
2016-08-30 18:37:54 +00:00
end
def negative_failure_message
2018-05-10 20:20:23 +00:00
+"expected not to find #{description}" << count_message
2016-08-30 18:37:54 +00:00
end
2018-01-09 22:05:50 +00:00
private
2018-01-13 21:06:03 +00:00
def count_specified?
COUNT_KEYS.any? { |key| options.key? key }
2018-01-13 21:06:03 +00:00
end
2016-08-30 18:37:54 +00:00
def count_message
2018-07-10 21:18:39 +00:00
message = +''
count, between, maximum, minimum = options.values_at(:count, :between, :maximum, :minimum)
if count
message << " #{occurrences count}"
2018-07-10 21:18:39 +00:00
elsif between
2022-07-09 18:20:40 +00:00
message << " between #{between.begin ? between.first : 1} and " \
"#{between.end ? between.last : 'infinite'} times"
2018-07-10 21:18:39 +00:00
elsif maximum
message << " at most #{occurrences maximum}"
2018-07-10 21:18:39 +00:00
elsif minimum
message << " at least #{occurrences minimum}"
2016-08-30 18:37:54 +00:00
end
message
end
def occurrences(count)
"#{count} #{Capybara::Helpers.declension('time', 'times', count)}"
end
def assert_valid_keys
invalid_keys = @options.keys - valid_keys
2018-01-09 22:05:50 +00:00
return if invalid_keys.empty?
2018-07-10 21:18:39 +00:00
invalid_names = invalid_keys.map(&:inspect).join(', ')
valid_names = valid_keys.map(&:inspect).join(', ')
2019-03-26 16:28:48 +00:00
raise ArgumentError, "Invalid option(s) #{invalid_names}, should be one of #{valid_names}"
end
end
end
end