<commit_before>module Surveyor
  module Models
    module DependencyConditionMethods
      def self.included(base)
        # Associations
        base.send :belongs_to, :answer
        base.send :belongs_to, :dependency
        base.send :belongs_to, :dependent_question, :foreign_key => :question_id, :class_name => :question
        base.send :belongs_to, :question

        # Validations
        base.send :validates_presence_of, :operator, :rule_key
        base.send :validates_inclusion_of, :operator, :in => Surveyor::Common::OPERATORS
        base.send :validates_uniqueness_of, :rule_key, :scope => :dependency_id
        # this causes issues with building and saving
        # base.send :validates_numericality_of, :question_id, :dependency_id
        
        base.send :include, Surveyor::ActsAsResponse # includes "as" instance method

        # Class methods
        base.instance_eval do
          def operators
            Surveyor::Common::OPERATORS
          end
        end
      end

      # Instance methods
      def to_hash(response_set)
        # all responses to associated question
        responses = response_set.responses.select do |r| 
          question && question.answers.include?(r.answer)
        end
        {rule_key.to_sym => (!responses.empty? and self.is_met?(responses))}
      end

      # Checks to see if the responses passed in meet the dependency condition
      def is_met?(responses)
        # response to associated answer if available, or first response
        response = if self.answer_id
                     responses.detect do |r| 
                       r.answer == self.answer
                     end 
                   end || responses.first
        klass = response.answer.response_class
        return case self.operator
        when "==", "<", ">", "<=", ">="
          response.as(klass).send(self.operator, self.as(klass))
        when "!="
          !(response.as(klass) == self.as(klass))
        when /count\>\d+/
          responses.count > self.operator.scan(/\d+/).first.to_i
        else
          false
        end
      end
    end
  end
end<commit_msg>Add custom validation to handle count operator<commit_after>module Surveyor
  module Models
    module DependencyConditionMethods
      def self.included(base)
        # Associations
        base.send :belongs_to, :answer
        base.send :belongs_to, :dependency
        base.send :belongs_to, :dependent_question, :foreign_key => :question_id, :class_name => :question
        base.send :belongs_to, :question

        # Validations
        base.send :validates_presence_of, :operator, :rule_key
        base.send :validate, :validates_operator
        base.send :validates_uniqueness_of, :rule_key, :scope => :dependency_id
        # this causes issues with building and saving
        # base.send :validates_numericality_of, :question_id, :dependency_id
        
        base.send :include, Surveyor::ActsAsResponse # includes "as" instance method

        # Class methods
        base.instance_eval do
          def operators
            Surveyor::Common::OPERATORS
          end
        end
      end

      # Instance methods
      def to_hash(response_set)
        # all responses to associated question
        responses = response_set.responses.select do |r| 
          question && question.answers.include?(r.answer)
        end
        {rule_key.to_sym => (!responses.empty? and self.is_met?(responses))}
      end

      # Checks to see if the responses passed in meet the dependency condition
      def is_met?(responses)
        # response to associated answer if available, or first response
        response = if self.answer_id
                     responses.detect do |r| 
                       r.answer == self.answer
                     end 
                   end || responses.first
        klass = response.answer.response_class
        return case self.operator
        when "==", "<", ">", "<=", ">="
          response.as(klass).send(self.operator, self.as(klass))
        when "!="
          !(response.as(klass) == self.as(klass))
        when /count\>\d+/
          responses.count > self.operator.scan(/\d+/).first.to_i
        else
          false
        end
      end

    protected

      def validates_operator
        errors.add(:operator, "Invalid operator") unless
          Surveyor::Common::OPERATORS.include?(self.operator) ||
            self.operator && self.operator.match(/^count(<|>|==|>=|<=|!=)(\d+)/)
      end
    end
  end
end
{'fraction_non_alphanumeric': 0.09877913429522753, 'fraction_numerical': 0.0, 'mean_word_length': 2.1248266296809986, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 22, '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': '5006583', 'n_tokens_mistral': 1264, 'n_tokens_neox': 1242, 'n_words': 304}