Class: Legion::Extensions::Conditioner::Condition

Inherits:
Object
  • Object
show all
Includes:
JSON::Helper
Defined in:
lib/legion/extensions/conditioner/helpers/condition.rb

Constant Summary collapse

BINARY_OPS =
%w[equal not_equal greater_than less_than greater_or_equal less_or_equal between contains starts_with ends_with matches in_set not_in_set
size_equal].freeze
UNARY_OPS =
%w[nil not_nil is_false is_true is_string is_array is_integer empty not_empty].freeze
UNARY_METHOD_MAP =
{
  'is_false' => :false?, 'is_true' => :true?,
  'is_string' => :string?, 'is_array' => :array?, 'is_integer' => :integer?,
  'empty' => :empty?, 'not_empty' => :not_empty?
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(args) ⇒ Condition

Returns a new instance of Condition.



11
12
13
14
# File 'lib/legion/extensions/conditioner/helpers/condition.rb', line 11

def initialize(args)
  @conditions = json_load(args[:conditions])
  @values = to_dotted_hash(args[:values])
end

Instance Method Details

#evaluate_rule(rule) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/legion/extensions/conditioner/helpers/condition.rb', line 61

def evaluate_rule(rule)
  return validate_test(all: rule[:all]) if rule.include?(:all)
  return validate_test(any: rule[:any]) if rule.include?(:any)

  comp = Legion::Extensions::Conditioner::Comparator
  op = rule[:operator]

  if BINARY_OPS.include?(op)
    comp.send(:"#{op}?", rule[:fact], rule[:value], @values)
  elsif UNARY_OPS.include?(op)
    method_name = UNARY_METHOD_MAP[op] || :"#{op}?"
    comp.send(method_name, rule[:fact], @values)
  end
end

#explainObject



108
109
110
# File 'lib/legion/extensions/conditioner/helpers/condition.rb', line 108

def explain
  @explain ||= explain_test
end

#explain_rule(rule) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/legion/extensions/conditioner/helpers/condition.rb', line 91

def explain_rule(rule)
  if rule.include?(:all)
    result = explain_test(all: rule[:all])
    return { group: :all, rules: result[:rules], result: result[:valid] }
  end
  if rule.include?(:any)
    result = explain_test(any: rule[:any])
    return { group: :any, rules: result[:rules], result: result[:valid] }
  end

  result = evaluate_rule(rule)
  explanation = { fact: rule[:fact], operator: rule[:operator], result: result }
  explanation[:value] = rule[:value] if rule.key?(:value)
  explanation[:actual] = @values[rule[:fact]]
  explanation
end

#explain_test(conditions = @conditions) ⇒ Object



81
82
83
84
85
86
87
88
89
# File 'lib/legion/extensions/conditioner/helpers/condition.rb', line 81

def explain_test(conditions = @conditions)
  group = conditions.keys.first
  rules = conditions[group].map do |rule|
    explain_rule(rule)
  end

  valid = group == :all ? rules.all? { |r| r[:result] } : rules.any? { |r| r[:result] }
  { valid: valid, group: group, rules: rules }
end

#to_dotted_hash(source, target = {}, namespace = nil) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/legion/extensions/conditioner/helpers/condition.rb', line 16

def to_dotted_hash(source, target = {}, namespace = nil)
  prefix = "#{namespace}." if namespace
  case source
  when Hash
    source.each do |key, value|
      to_dotted_hash(value, target, "#{prefix}#{key}")
    end
  when Array
    source.each_with_index do |value, index|
      to_dotted_hash(value, target, "#{prefix}#{index}")
    end
  else
    target[namespace] = source
  end
  target
end

#valid?Boolean

Returns:

  • (Boolean)


76
77
78
79
# File 'lib/legion/extensions/conditioner/helpers/condition.rb', line 76

def valid?
  @valid = validate_test if @valid.nil?
  @valid
end

#validate_test(conditions = @conditions) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
# File 'lib/legion/extensions/conditioner/helpers/condition.rb', line 49

def validate_test(conditions = @conditions)
  conditions.each do |condition|
    condition[1].each do |rule|
      result = evaluate_rule(rule)
      return true if condition[0] == :any && result == true
      return false if condition[0] == :all && result == false
    end
    return false if condition[0] == :any
    return true if condition[0] == :all
  end
end

#validate_varsObject

Raises:

  • (Legion::Exception::MissingArgument)


33
34
35
36
37
38
# File 'lib/legion/extensions/conditioner/helpers/condition.rb', line 33

def validate_vars
  raise Legion::Exception::MissingArgument, '@conditions is nil' if @conditions.nil?
  raise Legion::Exception::MissingArgument, '@values is nil' if @values.nil?
  raise Legion::Exception::WrongType::Hash, @values.class unless @values.is_a? Hash
  raise Legion::Exception::WrongType::Hash, @conditions.class unless @conditions.is_a? Hash
end