class Optimizely::CustomAttributeConditionEvaluator
Constants
- CUSTOM_ATTRIBUTE_CONDITION_TYPE
- EVALUATORS_BY_MATCH_TYPE
- EXACT_MATCH_TYPE
Conditional match types
- EXISTS_MATCH_TYPE
- GREATER_EQUAL_MATCH_TYPE
- GREATER_THAN_MATCH_TYPE
- LESS_EQUAL_MATCH_TYPE
- LESS_THAN_MATCH_TYPE
- SEMVER_EQ
- SEMVER_GE
- SEMVER_GT
- SEMVER_LE
- SEMVER_LT
- SUBSTRING_MATCH_TYPE
Attributes
user_attributes[R]
Public Class Methods
new(user_attributes, logger)
click to toggle source
# File lib/optimizely/custom_attribute_condition_evaluator.rb, line 58 def initialize(user_attributes, logger) @user_attributes = user_attributes @logger = logger end
Public Instance Methods
evaluate(leaf_condition)
click to toggle source
# File lib/optimizely/custom_attribute_condition_evaluator.rb, line 63 def evaluate(leaf_condition) # Top level method to evaluate audience conditions. # # conditions - Nested array of and/or conditions. # Example: ['and', operand_1, ['or', operand_2, operand_3]] # # Returns boolean if the given user attributes match/don't match the given conditions, # nil if the given conditions can't be evaluated. unless leaf_condition['type'] == CUSTOM_ATTRIBUTE_CONDITION_TYPE @logger.log( Logger::WARN, format(Helpers::Constants::AUDIENCE_EVALUATION_LOGS['UNKNOWN_CONDITION_TYPE'], leaf_condition) ) return nil end condition_match = leaf_condition['match'] || EXACT_MATCH_TYPE if !@user_attributes.key?(leaf_condition['name']) && condition_match != EXISTS_MATCH_TYPE @logger.log( Logger::DEBUG, format( Helpers::Constants::AUDIENCE_EVALUATION_LOGS['MISSING_ATTRIBUTE_VALUE'], leaf_condition, leaf_condition['name'] ) ) return nil end if @user_attributes[leaf_condition['name']].nil? && condition_match != EXISTS_MATCH_TYPE @logger.log( Logger::DEBUG, format( Helpers::Constants::AUDIENCE_EVALUATION_LOGS['NULL_ATTRIBUTE_VALUE'], leaf_condition, leaf_condition['name'] ) ) return nil end unless EVALUATORS_BY_MATCH_TYPE.include?(condition_match) @logger.log( Logger::WARN, format(Helpers::Constants::AUDIENCE_EVALUATION_LOGS['UNKNOWN_MATCH_TYPE'], leaf_condition) ) return nil end begin send(EVALUATORS_BY_MATCH_TYPE[condition_match], leaf_condition) rescue InvalidAttributeType condition_name = leaf_condition['name'] user_value = @user_attributes[condition_name] @logger.log( Logger::WARN, format( Helpers::Constants::AUDIENCE_EVALUATION_LOGS['UNEXPECTED_TYPE'], leaf_condition, user_value.class, condition_name ) ) return nil rescue InvalidSemanticVersion condition_name = leaf_condition['name'] @logger.log( Logger::WARN, format( Helpers::Constants::AUDIENCE_EVALUATION_LOGS['INVALID_SEMANTIC_VERSION'], leaf_condition, condition_name ) ) return nil end end
exact_evaluator(condition)
click to toggle source
# File lib/optimizely/custom_attribute_condition_evaluator.rb, line 145 def exact_evaluator(condition) # Evaluate the given exact match condition for the given user attributes. # # Returns boolean true if numbers values matched, i.e 2 is equal to 2.0 # true if the user attribute value is equal (===) to the condition value, # false if the user attribute value is not equal (!==) to the condition value, # nil if the condition value or user attribute value has an invalid type, # or if there is a mismatch between the user attribute type and the condition value type. condition_value = condition['value'] user_provided_value = @user_attributes[condition['name']] if !value_type_valid_for_exact_conditions?(condition_value) || (condition_value.is_a?(Numeric) && !Helpers::Validator.finite_number?(condition_value)) @logger.log( Logger::WARN, format(Helpers::Constants::AUDIENCE_EVALUATION_LOGS['UNKNOWN_CONDITION_VALUE'], condition) ) return nil end if !value_type_valid_for_exact_conditions?(user_provided_value) || !Helpers::Validator.same_types?(condition_value, user_provided_value) raise InvalidAttributeType end if user_provided_value.is_a?(Numeric) && !Helpers::Validator.finite_number?(user_provided_value) @logger.log( Logger::WARN, format( Helpers::Constants::AUDIENCE_EVALUATION_LOGS['INFINITE_ATTRIBUTE_VALUE'], condition, condition['name'] ) ) return nil end condition_value == user_provided_value end
exists_evaluator(condition)
click to toggle source
# File lib/optimizely/custom_attribute_condition_evaluator.rb, line 187 def exists_evaluator(condition) # Evaluate the given exists match condition for the given user attributes. # Returns boolean true if both: # 1) the user attributes have a value for the given condition, and # 2) the user attribute value is neither nil nor undefined # Returns false otherwise !@user_attributes[condition['name']].nil? end
greater_than_evaluator(condition)
click to toggle source
# File lib/optimizely/custom_attribute_condition_evaluator.rb, line 197 def greater_than_evaluator(condition) # Evaluate the given greater than match condition for the given user attributes. # Returns boolean true if the user attribute value is greater than the condition value, # false if the user attribute value is less than or equal to the condition value, # nil if the condition value isn't a number or the user attribute value isn't a number. condition_value = condition['value'] user_provided_value = @user_attributes[condition['name']] return nil unless valid_numeric_values?(user_provided_value, condition_value, condition) user_provided_value > condition_value end
greater_than_or_equal_evaluator(condition)
click to toggle source
# File lib/optimizely/custom_attribute_condition_evaluator.rb, line 211 def greater_than_or_equal_evaluator(condition) # Evaluate the given greater than or equal match condition for the given user attributes. # Returns boolean true if the user attribute value is greater than or equal to the condition value, # false if the user attribute value is less than the condition value, # nil if the condition value isn't a number or the user attribute value isn't a number. condition_value = condition['value'] user_provided_value = @user_attributes[condition['name']] return nil unless valid_numeric_values?(user_provided_value, condition_value, condition) user_provided_value >= condition_value end
less_than_evaluator(condition)
click to toggle source
# File lib/optimizely/custom_attribute_condition_evaluator.rb, line 225 def less_than_evaluator(condition) # Evaluate the given less than match condition for the given user attributes. # Returns boolean true if the user attribute value is less than the condition value, # false if the user attribute value is greater than or equal to the condition value, # nil if the condition value isn't a number or the user attribute value isn't a number. condition_value = condition['value'] user_provided_value = @user_attributes[condition['name']] return nil unless valid_numeric_values?(user_provided_value, condition_value, condition) user_provided_value < condition_value end
less_than_or_equal_evaluator(condition)
click to toggle source
# File lib/optimizely/custom_attribute_condition_evaluator.rb, line 239 def less_than_or_equal_evaluator(condition) # Evaluate the given less than or equal match condition for the given user attributes. # Returns boolean true if the user attribute value is less than or equal to the condition value, # false if the user attribute value is greater than the condition value, # nil if the condition value isn't a number or the user attribute value isn't a number. condition_value = condition['value'] user_provided_value = @user_attributes[condition['name']] return nil unless valid_numeric_values?(user_provided_value, condition_value, condition) user_provided_value <= condition_value end
semver_equal_evaluator(condition)
click to toggle source
# File lib/optimizely/custom_attribute_condition_evaluator.rb, line 275 def semver_equal_evaluator(condition) # Evaluate the given semantic version equal match target version for the user version. # Returns boolean true if the user version is equal to the target version, # false if the user version is not equal to the target version target_version = condition['value'] user_version = @user_attributes[condition['name']] SemanticVersion.compare_user_version_with_target_version(target_version, user_version).zero? end
semver_greater_than_evaluator(condition)
click to toggle source
# File lib/optimizely/custom_attribute_condition_evaluator.rb, line 286 def semver_greater_than_evaluator(condition) # Evaluate the given semantic version greater than match target version for the user version. # Returns boolean true if the user version is greater than the target version, # false if the user version is less than or equal to the target version target_version = condition['value'] user_version = @user_attributes[condition['name']] SemanticVersion.compare_user_version_with_target_version(target_version, user_version).positive? end
semver_greater_than_or_equal_evaluator(condition)
click to toggle source
# File lib/optimizely/custom_attribute_condition_evaluator.rb, line 297 def semver_greater_than_or_equal_evaluator(condition) # Evaluate the given semantic version greater than or equal to match target version for the user version. # Returns boolean true if the user version is greater than or equal to the target version, # false if the user version is less than the target version target_version = condition['value'] user_version = @user_attributes[condition['name']] SemanticVersion.compare_user_version_with_target_version(target_version, user_version) >= 0 end
semver_less_than_evaluator(condition)
click to toggle source
# File lib/optimizely/custom_attribute_condition_evaluator.rb, line 308 def semver_less_than_evaluator(condition) # Evaluate the given semantic version less than match target version for the user version. # Returns boolean true if the user version is less than the target version, # false if the user version is greater than or equal to the target version target_version = condition['value'] user_version = @user_attributes[condition['name']] SemanticVersion.compare_user_version_with_target_version(target_version, user_version).negative? end
semver_less_than_or_equal_evaluator(condition)
click to toggle source
# File lib/optimizely/custom_attribute_condition_evaluator.rb, line 319 def semver_less_than_or_equal_evaluator(condition) # Evaluate the given semantic version less than or equal to match target version for the user version. # Returns boolean true if the user version is less than or equal to the target version, # false if the user version is greater than the target version target_version = condition['value'] user_version = @user_attributes[condition['name']] SemanticVersion.compare_user_version_with_target_version(target_version, user_version) <= 0 end
substring_evaluator(condition)
click to toggle source
# File lib/optimizely/custom_attribute_condition_evaluator.rb, line 253 def substring_evaluator(condition) # Evaluate the given substring match condition for the given user attributes. # Returns boolean true if the condition value is a substring of the user attribute value, # false if the condition value is not a substring of the user attribute value, # nil if the condition value isn't a string or the user attribute value isn't a string. condition_value = condition['value'] user_provided_value = @user_attributes[condition['name']] unless condition_value.is_a?(String) @logger.log( Logger::WARN, format(Helpers::Constants::AUDIENCE_EVALUATION_LOGS['UNKNOWN_CONDITION_VALUE'], condition) ) return nil end raise InvalidAttributeType unless user_provided_value.is_a?(String) user_provided_value.include? condition_value end
Private Instance Methods
valid_numeric_values?(user_value, condition_value, condition)
click to toggle source
# File lib/optimizely/custom_attribute_condition_evaluator.rb, line 332 def valid_numeric_values?(user_value, condition_value, condition) # Returns true if user and condition values are valid numeric. # false otherwise. unless Helpers::Validator.finite_number?(condition_value) @logger.log( Logger::WARN, format(Helpers::Constants::AUDIENCE_EVALUATION_LOGS['UNKNOWN_CONDITION_VALUE'], condition) ) return false end raise InvalidAttributeType unless user_value.is_a?(Numeric) unless Helpers::Validator.finite_number?(user_value) @logger.log( Logger::WARN, format( Helpers::Constants::AUDIENCE_EVALUATION_LOGS['INFINITE_ATTRIBUTE_VALUE'], condition, condition['name'] ) ) return false end true end
value_type_valid_for_exact_conditions?(value)
click to toggle source
# File lib/optimizely/custom_attribute_condition_evaluator.rb, line 361 def value_type_valid_for_exact_conditions?(value) # Returns true if the value is valid for exact conditions. Valid values include # strings or booleans or is a number. # false otherwise. (Helpers::Validator.boolean? value) || (value.is_a? String) || value.is_a?(Numeric) end