<commit_before>require 'active_model/validator'

module ValidatesTimeliness
  class Validator < ActiveModel::EachValidator
    include Conversion

    CHECKS = {
      :is_at        => :==,
      :before       => :<,
      :after        => :>,
      :on_or_before => :<=,
      :on_or_after  => :>=,
    }.freeze

    def self.kind
      :timeliness
    end

    def initialize(options)
      @allow_nil, @allow_blank = options.delete(:allow_nil), options.delete(:allow_blank)
      @type = options.delete(:type)

      if range = options.delete(:between)
        raise ArgumentError, ":between must be a Range or an Array" unless range.is_a?(Range) || range.is_a?(Array)
        options[:on_or_after], options[:on_or_before] = range.begin, range.end
      end
      super
    end

    def check_validity!
    end

    def validate_each(record, attr_name, value)
      raw_value = attribute_raw_value(record, attr_name) || value
      return if (@allow_nil && raw_value.nil?) || (@allow_blank && raw_value.blank?)

      return record.errors.add(attr_name, :"invalid_#{@type}") if value.blank?

      value = type_cast(value)

      (CHECKS.keys & options.keys).each do |check|
        check_value = type_cast(options[check])
        unless value.send(CHECKS[check], check_value)
          return record.errors.add(attr_name, check, :restriction => check_value)
        end
      end
    end

    def attribute_raw_value(record, attr_name)
      before_type_cast = "#{attr_name}_before_type_cast"
      record.send("#{attr_name}_before_type_cast") if record.respond_to?(before_type_cast)
    end

    def type_cast(value)
      type_cast_value(value, @type)
    end
  end
end

# Compatibility with ActiveModel validates method which tries match option keys to their validator class
TimelinessValidator = ValidatesTimeliness::Validator<commit_msg>use restriction instead of check<commit_after>require 'active_model/validator'

module ValidatesTimeliness
  class Validator < ActiveModel::EachValidator
    include Conversion

    RESTRICTIONS = {
      :is_at        => :==,
      :before       => :<,
      :after        => :>,
      :on_or_before => :<=,
      :on_or_after  => :>=,
    }.freeze

    def self.kind
      :timeliness
    end

    def initialize(options)
      @allow_nil, @allow_blank = options.delete(:allow_nil), options.delete(:allow_blank)
      @type = options.delete(:type)

      if range = options.delete(:between)
        raise ArgumentError, ":between must be a Range or an Array" unless range.is_a?(Range) || range.is_a?(Array)
        options[:on_or_after], options[:on_or_before] = range.begin, range.end
      end
      super
    end

    def check_validity!
    end

    def validate_each(record, attr_name, value)
      raw_value = attribute_raw_value(record, attr_name) || value
      return if (@allow_nil && raw_value.nil?) || (@allow_blank && raw_value.blank?)

      return record.errors.add(attr_name, :"invalid_#{@type}") if value.blank?

      value = type_cast(value)

      (RESTRICTIONS.keys & options.keys).each do |restriction|
        restriction_value = type_cast(evaluate_option_value(options[restriction], record))
        unless value.send(RESTRICTIONS[restriction], restriction_value)
          return record.errors.add(attr_name, restriction, :restriction => restriction_value)
        end
      end
    end

    def attribute_raw_value(record, attr_name)
      before_type_cast = "#{attr_name}_before_type_cast"
      record.send("#{attr_name}_before_type_cast") if record.respond_to?(before_type_cast)
    end

    def type_cast(value)
      type_cast_value(value, @type)
    end
  end
end

# Compatibility with ActiveModel validates method which tries match option keys to their validator class
TimelinessValidator = ValidatesTimeliness::Validator
{'fraction_non_alphanumeric': 0.1070489216201999, 'fraction_numerical': 0.0, 'mean_word_length': 3.244419642857143, 'pattern_counts': {'":': 2, '<': 9, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1066013', 'n_tokens_mistral': 1187, 'n_tokens_neox': 1163, 'n_words': 252}