class Reflekt::RuleSetAggregator

Public Class Methods

new(meta_map) click to toggle source

@param meta_map [Hash] The rules that apply to each meta type.

# File lib/rule_set_aggregator.rb, line 21
def initialize(meta_map)
  @meta_map = meta_map
  # Key rule sets by class and method.
  @rule_sets = {}
end
testable?(args, input_rule_sets) click to toggle source
# File lib/rule_set_aggregator.rb, line 193
def self.testable?(args, input_rule_sets)

  args.each_with_index do |arg, arg_num|

    rule_type = value_to_rule_type(arg)
    if input_rule_sets[arg_num].rules[rule_type].nil?
      return false
    end

  end

  return true

end
value_to_rule_type(value) click to toggle source

Get the base rule type for a data type.

# File lib/rule_set_aggregator.rb, line 175
def self.value_to_rule_type(value)

  data_type = value.class

  rule_types = {
    Array      => ArrayRule,
    TrueClass  => BooleanRule,
    FalseClass => BooleanRule,
    Float      => FloatRule,
    Integer    => IntegerRule,
    NilClass   => NullRule,
    String     => StringRule
  }

  return rule_types[data_type]

end

Public Instance Methods

get_input_rule_sets(klass, method) click to toggle source

Get aggregated RuleSets for all inputs.

@stage Called when building a reflection. @param klass [Symbol] @param method [Symbol] @return [Array]

# File lib/rule_set_aggregator.rb, line 156
def get_input_rule_sets(klass, method)
  @rule_sets.dig(klass, method, :inputs)
end
get_output_rule_set(klass, method) click to toggle source

Get an aggregated RuleSet for an output.

@stage Called when building a reflection. @param klass [Symbol] @param method [Symbol] @return [RuleSet]

# File lib/rule_set_aggregator.rb, line 168
def get_output_rule_set(klass, method)
  @rule_sets.dig(klass, method, :output)
end
test_inputs(inputs, input_rule_sets) click to toggle source

Validate inputs.

@stage Called when validating a control reflection. @param inputs [Array] The method's arguments. @param input_rule_sets [Array] The RuleSets to validate each input with.

# File lib/rule_set_aggregator.rb, line 100
def test_inputs(inputs, input_rule_sets)

  # Default result to PASS.
  result = true

  # Validate each argument against each rule set for that argument.
  inputs.each_with_index do |input, arg_num|

    unless input_rule_sets[arg_num].nil?

      rule_set = input_rule_sets[arg_num]

      unless rule_set.test(input)
        result = false
      end

    end
  end

  return result

end
test_output(output, output_rule_set) click to toggle source

Validate output.

@stage Called when validating a reflection. @param output [Dynamic] The method's return value. @param output_rule_set [RuleSet] The rule set to validate the output with.

# File lib/rule_set_aggregator.rb, line 130
def test_output(output, output_rule_set)

  # Default to a PASS result.
  result = true

  unless output_rule_set.nil?

    # Validate output rule set for that argument.
    unless output_rule_set.test(output)
      result = false
    end

  end

  return result

end
train(controls) click to toggle source

Create aggregated rule sets from control metadata.

@stage Called on setup. @param controls [Array] Controls with metadata. @TODO Revert string keys to symbols once “Fix Rowdb.get(path)” bug fixed.

# File lib/rule_set_aggregator.rb, line 34
def train(controls)

  # On first use there are no previous controls.
  return if controls.nil?

  controls.each do |control|

    klass = control["class"].to_sym
    method = control["method"].to_sym

    ##
    # INPUT
    ##

    # Singular null input.
    if control["inputs"].nil?
      train_input(klass, method, nil, 0)
    # Multiple inputs.
    else
      control["inputs"].each_with_index do |meta, arg_num|
        train_input(klass, method, meta, arg_num)
      end
    end

    ##
    # OUTPUT
    ##

    # Get rule set.
    output_rule_set = get_output_rule_set(klass, method)
    if output_rule_set.nil?
      output_rule_set = RuleSet.new(@meta_map)
      set_output_rule_set(klass, method, output_rule_set)
    end

    # Train on metadata.
    output_rule_set.train(Meta.deserialize(control["output"]))

  end

end
train_input(klass, method, meta, arg_num) click to toggle source
# File lib/rule_set_aggregator.rb, line 76
def train_input(klass, method, meta, arg_num)

  # Get deserialized meta.
  meta = Meta.deserialize(meta)

  # Get rule set.
  rule_set = get_input_rule_set(klass, method, arg_num)
  if rule_set.nil?
    rule_set = RuleSet.new(@meta_map)
    set_input_rule_set(klass, method, arg_num, rule_set)
  end

  # Train on metadata.
  rule_set.train(meta)

end

Private Instance Methods

get_input_rule_set(klass, method, arg_num) click to toggle source

Get an aggregated RuleSet for an input.

@param klass [Symbol] @param method [Symbol] @return [RuleSet]

# File lib/rule_set_aggregator.rb, line 221
def get_input_rule_set(klass, method, arg_num)
  @rule_sets.dig(klass, method, :inputs, arg_num)
end
set_input_rule_set(klass, method, arg_num, rule_set) click to toggle source

Set an aggregated RuleSet for an input.

@param klass [Symbol] @param method [Symbol]

# File lib/rule_set_aggregator.rb, line 231
def set_input_rule_set(klass, method, arg_num, rule_set)

  # Set defaults.
  @rule_sets[klass] = {} unless @rule_sets.key? klass
  @rule_sets[klass][method] = {} unless @rule_sets[klass].key? method
  @rule_sets[klass][method][:inputs] = [] unless @rule_sets[klass][method].key? :inputs
  # Set value.
  @rule_sets[klass][method][:inputs][arg_num] = rule_set

end
set_output_rule_set(klass, method, rule_set) click to toggle source

Set an aggregated RuleSet for an output.

@param klass [Symbol] @param method [Symbol] @param rule_set [RuleSet]

# File lib/rule_set_aggregator.rb, line 249
def set_output_rule_set(klass, method, rule_set)

  # Set defaults.
  @rule_sets[klass] = {} unless @rule_sets.key? klass
  @rule_sets[klass][method] = {} unless @rule_sets[klass].key? method
  # Set value.
  @rule_sets[klass][method][:output] = rule_set

end