class Shoulda::Matchers::ActiveModel::ValidateComparisonOfMatcher

@private

def add_submatcher(submatcher)

def add_submatcher(submatcher)
  @submatchers << submatcher
end

def allow_nil

def allow_nil
  @expects_to_allow_nil = true
  prepare_submatcher(allow_value_matcher(nil))
  self
end

def allowed_type_name

def allowed_type_name
  'value'
end

def attribute_is_active_record_column?

def attribute_is_active_record_column?
  columns_hash.key?(attribute.to_s)
end

def build_submatcher_failure_message_for(

def build_submatcher_failure_message_for(
  submatcher,
  failure_message_method
)
  failure_message = submatcher.public_send(failure_message_method)
  submatcher_description = submatcher.simple_description.
    sub(/\bvalidate that\b/, 'validates').
    sub(/\bdisallow\b/, 'disallows').
    sub(/\ballow\b/, 'allows')
  submatcher_message =
    if number_of_submatchers_for_failure_message > 1
      "In checking that #{model.name} #{submatcher_description}, " +
        failure_message[0].downcase +
        failure_message[1..]
    else
      failure_message
    end
  Shoulda::Matchers.word_wrap(submatcher_message, indent: 2)
end

def column_type

def column_type
  columns_hash[attribute.to_s].type
end

def columns_hash

def columns_hash
  if subject.class.respond_to?(:columns_hash)
    subject.class.columns_hash
  else
    {}
  end
end

def comparison_descriptions

def comparison_descriptions
  description_array = submatcher_comparison_descriptions
  if description_array.empty?
    ''
  else
    submatcher_comparison_descriptions.join(' and ')
  end
end

def comparison_matcher_for(value, operator)

def comparison_matcher_for(value, operator)
  @comparison_matcher = true
  ComparisonMatcher.
    new(self, value, operator).
    for(attribute)
end

def does_not_match?(subject)

def does_not_match?(subject)
  @subject = subject
  @number_of_submatchers = @submatchers.size
  qualify_submatchers
  first_submatcher_that_fails_to_not_match.nil?
end

def expects_to_allow_nil?

def expects_to_allow_nil?
  @expects_to_allow_nil
end

def failure_message

def failure_message
  overall_failure_message.dup.tap do |message|
    message << "\n"
    message << failure_message_for_first_submatcher_that_fails_to_match
  end
end

def failure_message_for_first_submatcher_that_fails_to_match

def failure_message_for_first_submatcher_that_fails_to_match
  build_submatcher_failure_message_for(
    first_submatcher_that_fails_to_match,
    :failure_message,
  )
end

def failure_message_for_first_submatcher_that_fails_to_not_match

def failure_message_for_first_submatcher_that_fails_to_not_match
  build_submatcher_failure_message_for(
    first_submatcher_that_fails_to_not_match,
    :failure_message_when_negated,
  )
end

def failure_message_when_negated

def failure_message_when_negated
  overall_failure_message_when_negated.dup.tap do |message|
    message << "\n"
    message <<
      failure_message_for_first_submatcher_that_fails_to_not_match
  end
end

def first_submatcher_that_fails_to_match

def first_submatcher_that_fails_to_match
  @_first_submatcher_that_fails_to_match ||=
    @submatchers.detect do |submatcher|
      !submatcher.matches?(subject)
    end
end

def first_submatcher_that_fails_to_not_match

def first_submatcher_that_fails_to_not_match
  @_first_submatcher_that_fails_to_not_match ||=
    @submatchers.detect do |submatcher|
      submatcher.matches?(subject)
    end
end

def given_numeric_column?

def given_numeric_column?
  attribute_is_active_record_column? &&
    [:integer, :float, :decimal].include?(column_type)
end

def has_been_qualified?

def has_been_qualified?
  @submatchers.any? { |submatcher| submatcher_qualified?(submatcher) }
end

def initialize(attribute)

def initialize(attribute)
  super
  @submatchers = []
  @diff_to_compare = DEFAULT_DIFF_TO_COMPARE
  @expects_to_allow_nil = false
  @comparison_submatcher = false
end

def is_equal_to(value)

def is_equal_to(value)
  prepare_submatcher(comparison_matcher_for(value, :==).for(attribute))
  self
end

def is_greater_than(value)

def is_greater_than(value)
  prepare_submatcher(comparison_matcher_for(value, :>).for(attribute))
  self
end

def is_greater_than_or_equal_to(value)

def is_greater_than_or_equal_to(value)
  prepare_submatcher(comparison_matcher_for(value, :>=).for(attribute))
  self
end

def is_less_than(value)

def is_less_than(value)
  prepare_submatcher(comparison_matcher_for(value, :<).for(attribute))
  self
end

def is_less_than_or_equal_to(value)

def is_less_than_or_equal_to(value)
  prepare_submatcher(comparison_matcher_for(value, :<=).for(attribute))
  self
end

def is_other_than(value)

def is_other_than(value)
  prepare_submatcher(comparison_matcher_for(value, :!=).for(attribute))
  self
end

def matches?(subject)

def matches?(subject)
  @subject = subject
  @number_of_submatchers = @submatchers.size
  unless @comparison_matcher
    raise(ArgumentError, "matcher isn't qualified with any comparison matcher")
  end
  qualify_submatchers
  first_submatcher_that_fails_to_match.nil?
end

def non_numeric_value

def non_numeric_value
  'abcd'
end

def number_of_submatchers_for_failure_message

def number_of_submatchers_for_failure_message
  if has_been_qualified?
    number_of_submatchers - 1
  else
    number_of_submatchers
  end
end

def prepare_submatcher(submatcher)

def prepare_submatcher(submatcher)
  add_submatcher(submatcher)
  submatcher
end

def qualify_submatchers

def qualify_submatchers
  @submatchers.each do |submatcher|
    if @expects_strict
      submatcher.strict
    end
    if @expected_message.present?
      submatcher.with_message(@expected_message)
    end
    if @context
      submatcher.on(@context)
    end
    submatcher.ignoring_interference_by_writer(
      ignore_interference_by_writer,
    )
  end
end

def simple_description

def simple_description
  String.new.tap do |description|
    description << "validate that :#{attribute} looks like "
    description << Shoulda::Matchers::Util.a_or_an(allowed_type_name)
    if comparison_descriptions.present?
      description << " #{comparison_descriptions}"
    end
  end
end

def submatcher_comparison_descriptions

def submatcher_comparison_descriptions
  @submatchers.inject([]) do |arr, submatcher|
    arr << if submatcher.respond_to? :comparison_description
             submatcher.comparison_description
           end
  end
end

def submatcher_qualified?(submatcher)

def submatcher_qualified?(submatcher)
  submatcher.instance_of?(ComparisonMatcher)
end