ManageIQ/manageiq-automation_engine

View on GitHub
app/models/miq_ae_method_compare.rb

Summary

Maintainability
A
55 mins
Test Coverage
A
100%
class MiqAeMethodCompare
  attr_reader :compatibilities
  attr_reader :incompatibilities
  attr_reader :fields_in_use
  attr_reader :adds
  IGNORE_PROPERTY_NAMES  = %w[name owner created_on updated_on updated_by
                              updated_by_user_id id class_id instance_id field_id].freeze
  WARNING_PROPERTY_NAMES = %w[priority message display_name default_value substitute
                              visibility collect scope description condition on_entry
                              on_exit on_error max_retries max_time].freeze
  ERROR_PROPERTY_NAMES   = %w[aetype datatype].freeze
  MAIN_METHOD_ATTRIBUTES = %w[scope language location data].freeze

  CONGRUENT_METHOD = 1
  COMPATIBLE_METHOD = 2
  INCOMPATIBLE_METHOD = 4

  def initialize(new_method, old_method)
    @new_method = new_method
    @old_method = old_method
  end

  def compare
    load_field_names
    initialize_results
    venn_list
    validate_similar
    compare_main_attributes
    status
  end

  def status
    return CONGRUENT_METHOD  if congruent?
    return COMPATIBLE_METHOD if compatible?

    INCOMPATIBLE_METHOD
  end

  def congruent?
    @adds.empty? && @incompatibilities.empty? &&
      @compatibilities.empty? && @fields_in_use.empty? &&
      @deletes.empty?
  end

  def compatible?
    @incompatibilities.empty? && @deletes.empty?
  end

  private

  def initialize_results
    @incompatibilities = []
    @compatibilities   = []
    @fields_in_use     = []
    @adds              = []
    @deletes           = []
  end

  def compare_main_attributes
    MAIN_METHOD_ATTRIBUTES.each { |f| add_to_incompatibilities_if_different(f) }
  end

  def add_to_incompatibilities_if_different(method)
    old_value = @old_method.send(method) if @old_method.respond_to?(method)
    new_value = @new_method.send(method) if @new_method.respond_to?(method)
    return if old_value == new_value

    @incompatibilities << {'attribute' => method, 'old_data' => old_value, 'new_data' => new_value}
  end

  def load_field_names
    @old_names = @old_method.field_names
    @new_names = @new_method.field_names
  end

  def venn_list
    @similar = @new_names & @old_names
    @adds    = @new_names - @old_names
    @deletes = @old_names - @new_names
  end

  def validate_similar
    @similar.each do |name|
      old_value = @old_method.field_value_hash(name)
      new_value = @new_method.field_value_hash(name)
      compare_value_properties(name, old_value, new_value)
    end
  end

  def compare_value_properties(field_name, old_value, new_value)
    old_value.each do |property, data|
      next if IGNORE_PROPERTY_NAMES.include?(property)
      next if data == new_value[property]

      hash = {'property'   => property,
              'old_data'   => data,
              'new_data'   => new_value[property],
              'field_name' => field_name}
      @compatibilities << hash if WARNING_PROPERTY_NAMES.include?(property)
      @incompatibilities << hash if ERROR_PROPERTY_NAMES.include?(property)
    end
  end
end