module RSpec::Matchers::BuiltIn::CountExpectation

@api private Asbtract class to implement `once`, `at_least` and other count constraints.

Attributes

count_expectation_type[R]

@api private

expected_count[R]

@api private

Public Instance Methods

at_least(number) click to toggle source

@api public Specifies the minimum number of times the method is expected to match

# File lib/rspec/matchers/built_in/count_expectation.rb, line 42
def at_least(number)
  set_expected_count(:>=, number)
  self
end
at_most(number) click to toggle source

@api public Specifies the maximum number of times the method is expected to match

# File lib/rspec/matchers/built_in/count_expectation.rb, line 35
def at_most(number)
  set_expected_count(:<=, number)
  self
end
exactly(number) click to toggle source

@api public Specifies that the method is expected to match the given number of times.

# File lib/rspec/matchers/built_in/count_expectation.rb, line 28
def exactly(number)
  set_expected_count(:==, number)
  self
end
once() click to toggle source

@api public Specifies that the method is expected to match once.

# File lib/rspec/matchers/built_in/count_expectation.rb, line 10
def once
  exactly(1)
end
thrice() click to toggle source

@api public Specifies that the method is expected to match thrice.

# File lib/rspec/matchers/built_in/count_expectation.rb, line 22
def thrice
  exactly(3)
end
times() click to toggle source

@api public No-op. Provides syntactic sugar.

# File lib/rspec/matchers/built_in/count_expectation.rb, line 49
def times
  self
end
twice() click to toggle source

@api public Specifies that the method is expected to match twice.

# File lib/rspec/matchers/built_in/count_expectation.rb, line 16
def twice
  exactly(2)
end

Private Instance Methods

count_constraint_to_number(n) click to toggle source
# File lib/rspec/matchers/built_in/count_expectation.rb, line 120
def count_constraint_to_number(n)
  case n
  when Numeric then n
  when :once then 1
  when :twice then 2
  when :thrice then 3
  else
    raise ArgumentError, "Expected a number, :once, :twice or :thrice," \
      " but got #{n}"
  end
end
count_expectation_description() click to toggle source
# File lib/rspec/matchers/built_in/count_expectation.rb, line 139
def count_expectation_description
  "#{human_readable_expectation_type}#{human_readable_count(expected_count)}"
end
count_failure_reason(action) click to toggle source
# File lib/rspec/matchers/built_in/count_expectation.rb, line 143
def count_failure_reason(action)
  "#{count_expectation_description}" \
  " but #{action}#{human_readable_count(@actual_count)}"
end
cover?(count, number) click to toggle source
# File lib/rspec/matchers/built_in/count_expectation.rb, line 60
def cover?(count, number)
  count.cover?(number)
end
expected_count_matches?(actual_count) click to toggle source
# File lib/rspec/matchers/built_in/count_expectation.rb, line 69
def expected_count_matches?(actual_count)
  @actual_count = actual_count
  return @actual_count > 0 unless count_expectation_type
  return cover?(expected_count, actual_count) if count_expectation_type == :<=>

  @actual_count.__send__(count_expectation_type, expected_count)
end
has_expected_count?() click to toggle source
# File lib/rspec/matchers/built_in/count_expectation.rb, line 77
def has_expected_count?
  !!count_expectation_type
end
human_readable_count(count) click to toggle source
# File lib/rspec/matchers/built_in/count_expectation.rb, line 157
def human_readable_count(count)
  case count
  when Range then " #{count.first} and #{count.last} times"
  when nil then ''
  when 1 then ' once'
  when 2 then ' twice'
  else " #{count} times"
  end
end
human_readable_expectation_type() click to toggle source
# File lib/rspec/matchers/built_in/count_expectation.rb, line 148
def human_readable_expectation_type
  case count_expectation_type
  when :<= then ' at most'
  when :>= then ' at least'
  when :<=> then ' between'
  else ''
  end
end
raise_impossible_count_expectation(count) click to toggle source
# File lib/rspec/matchers/built_in/count_expectation.rb, line 100
def raise_impossible_count_expectation(count)
  text =
    case count_expectation_type
    when :<= then "at_least(#{count}).at_most(#{expected_count})"
    when :>= then "at_least(#{expected_count}).at_most(#{count})"
    end
  raise ArgumentError, "The constraint #{text} is not possible"
end
raise_unsupported_count_expectation() click to toggle source
# File lib/rspec/matchers/built_in/count_expectation.rb, line 109
def raise_unsupported_count_expectation
  text =
    case count_expectation_type
    when :<= then "at_least"
    when :>= then "at_most"
    when :<=> then "at_least/at_most combination"
    else "count"
    end
  raise ArgumentError, "Multiple #{text} constraints are not supported"
end
set_expected_count(relativity, n) click to toggle source
# File lib/rspec/matchers/built_in/count_expectation.rb, line 81
def set_expected_count(relativity, n)
  raise_unsupported_count_expectation if unsupported_count_expectation?(relativity)

  count = count_constraint_to_number(n)

  if count_expectation_type == :<= && relativity == :>=
    raise_impossible_count_expectation(count) if count > expected_count
    @count_expectation_type = :<=>
    @expected_count = count..expected_count
  elsif count_expectation_type == :>= && relativity == :<=
    raise_impossible_count_expectation(count) if count < expected_count
    @count_expectation_type = :<=>
    @expected_count = expected_count..count
  else
    @count_expectation_type = relativity
    @expected_count = count
  end
end
unsupported_count_expectation?(relativity) click to toggle source
# File lib/rspec/matchers/built_in/count_expectation.rb, line 132
def unsupported_count_expectation?(relativity)
  return true if count_expectation_type == :==
  return true if count_expectation_type == :<=>
  (count_expectation_type == :<= && relativity == :<=) ||
    (count_expectation_type == :>= && relativity == :>=)
end