class Shoulda::Matchers::ActiveModel::ValidateExclusionOfMatcher

@private

def allows_any_values_in_array?

def allows_any_values_in_array?
  @array.any? do |value|
    allows_value_of(value, @expected_message)
  end
end

def allows_higher_value

def allows_higher_value
  allows_value_of(@maximum + 1, @expected_message)
end

def allows_lower_value

def allows_lower_value
  @minimum == 0 || allows_value_of(@minimum - 1, @expected_message)
end

def allows_maximum_value

def allows_maximum_value
  allows_value_of(@maximum, @expected_message)
end

def allows_minimum_value

def allows_minimum_value
  allows_value_of(@minimum, @expected_message)
end

def disallows_all_values_in_array?

def disallows_all_values_in_array?
  @array.all? do |value|
    disallows_value_of(value, @expected_message)
  end
end

def disallows_higher_value

def disallows_higher_value
  disallows_value_of(@maximum + 1, @expected_message)
end

def disallows_lower_value

def disallows_lower_value
  @minimum != 0 && disallows_value_of(@minimum - 1, @expected_message)
end

def disallows_maximum_value

def disallows_maximum_value
  disallows_value_of(@maximum, @expected_message)
end

def disallows_minimum_value

def disallows_minimum_value
  disallows_value_of(@minimum, @expected_message)
end

def does_not_match?(subject)

def does_not_match?(subject)
  super(subject)
  if @range
    disallows_lower_value ||
      allows_minimum_value ||
      allows_maximum_value ||
      disallows_higher_value
  elsif @array
    allows_any_values_in_array?
  end
end

def in_array(array)

def in_array(array)
  @array = array
  self
end

def in_range(range)

def in_range(range)
  @range = range
  @minimum = range.first
  @maximum = range.max
  self
end

def initialize(attribute)

def initialize(attribute)
  super(attribute)
  @expected_message = :exclusion
  @array = nil
  @range = nil
end

def inspect_message

def inspect_message
  if @range
    @range.inspect
  else
    @array.inspect
  end
end

def inspected_array

def inspected_array
  Shoulda::Matchers::Util.inspect_values(@array).to_sentence(
    two_words_connector: ' nor ',
    last_word_connector: ', nor ',
  )
end

def matches?(subject)

def matches?(subject)
  super(subject)
  if @range
    allows_lower_value &&
      disallows_minimum_value &&
      disallows_maximum_value &&
      allows_higher_value
  elsif @array
    disallows_all_values_in_array?
  end
end

def simple_description

def simple_description
  if @range
    "validate that :#{@attribute} lies outside the range " +
      Shoulda::Matchers::Util.inspect_range(@range)
  else
    description = "validate that :#{@attribute}"
    description <<
      if @array.many?
        " is neither #{inspected_array}"
      else
        " is not #{inspected_array}"
      end
    description
  end
end