Module: Optimizely::ConditionTreeEvaluator

Included in:
OptimizelyConfig
Defined in:
lib/optimizely/condition_tree_evaluator.rb

Constant Summary collapse

AND_CONDITION =

Operator types

'and'
OR_CONDITION =
'or'
NOT_CONDITION =
'not'
EVALUATORS_BY_OPERATOR_TYPE =
{
  AND_CONDITION => :and_evaluator,
  OR_CONDITION => :or_evaluator,
  NOT_CONDITION => :not_evaluator
}.freeze
OPERATORS =
[AND_CONDITION, OR_CONDITION, NOT_CONDITION].freeze

Class Method Summary collapse

Class Method Details

.and_evaluator(conditions, leaf_evaluator) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/optimizely/condition_tree_evaluator.rb', line 62

def and_evaluator(conditions, leaf_evaluator)
  # Evaluates an array of conditions as if the evaluator had been applied
  # to each entry and the results AND-ed together.
  #
  # conditions - Array of conditions ex: [operand_1, operand_2]
  #
  # leaf_evaluator - Function which will be called to evaluate leaf condition values.
  #
  # Returns boolean if the user attributes match/don't match the given conditions,
  #         nil if the user attributes and conditions can't be evaluated.

  found_nil = false
  conditions.each do |condition|
    result = evaluate(condition, leaf_evaluator)
    return result if result == false

    found_nil = true if result.nil?
  end

  found_nil ? nil : true
end

.evaluate(conditions, leaf_evaluator) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/optimizely/condition_tree_evaluator.rb', line 35

def evaluate(conditions, leaf_evaluator)
  # Top level method to evaluate audience conditions.
  #
  # conditions - Nested array of and/or conditions.
  #              Example: ['and', operand_1, ['or', operand_2, operand_3]]
  #
  # leaf_evaluator - Function which will be called to evaluate leaf condition values.
  #
  # Returns boolean if the given user attributes match/don't match the given conditions,
  #         nil if the given conditions are invalid or can't be evaluated.

  if conditions.is_a? Array
    first_operator =  conditions[0]
    rest_of_conditions = conditions[1..-1]

    # Operator to apply is not explicit - assume 'or'
    unless EVALUATORS_BY_OPERATOR_TYPE.include?(conditions[0])
      first_operator = OR_CONDITION
      rest_of_conditions = conditions
    end

    return send(EVALUATORS_BY_OPERATOR_TYPE[first_operator], rest_of_conditions, leaf_evaluator)
  end

  leaf_evaluator.call(conditions)
end

.not_evaluator(single_condition, leaf_evaluator) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/optimizely/condition_tree_evaluator.rb', line 84

def not_evaluator(single_condition, leaf_evaluator)
  # Evaluates an array of conditions as if the evaluator had been applied
  # to a single entry and NOT was applied to the result.
  #
  # single_condition - Array of a single condition ex: [operand_1]
  #
  # leaf_evaluator - Function which will be called to evaluate leaf condition values.
  #
  # Returns boolean if the user attributes match/don't match the given conditions,
  #         nil if the user attributes and conditions can't be evaluated.

  return nil if single_condition.empty?

  result = evaluate(single_condition[0], leaf_evaluator)
  result.nil? ? nil : !result
end

.or_evaluator(conditions, leaf_evaluator) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/optimizely/condition_tree_evaluator.rb', line 101

def or_evaluator(conditions, leaf_evaluator)
  # Evaluates an array of conditions as if the evaluator had been applied
  # to each entry and the results OR-ed together.
  #
  # conditions - Array of conditions ex: [operand_1, operand_2]
  #
  # leaf_evaluator - Function which will be called to evaluate leaf condition values.
  #
  # Returns boolean if the user attributes match/don't match the given conditions,
  #         nil if the user attributes and conditions can't be evaluated.

  found_nil = false
  conditions.each do |condition|
    result = evaluate(condition, leaf_evaluator)
    return result if result == true

    found_nil = true if result.nil?
  end

  found_nil ? nil : false
end