module Masterplan
Public Class Methods
compare(options = {:scheme => {}, :to => {}, :format => :full})
click to toggle source
# File lib/masterplan.rb, line 20 def compare(options = {:scheme => {}, :to => {}, :format => :full}) scheme = options[:scheme] testee = options[:to] format = options[:format] || :full raise ArgumentError, ":to needs to be a hash !" unless testee.is_a?(Hash) raise ArgumentError, ":scheme needs to be a Masterplan::Document !" unless scheme.is_a?(Document) raise ArgumentError, ":format needs to be one of [:full, :mini] !" unless [:full, :mini].include?(format) compare_hash(scheme, testee, format) true end
Private Class Methods
compare_hash(template, testee, format, trail = ["root"])
click to toggle source
# File lib/masterplan.rb, line 67 def compare_hash(template, testee, format, trail = ["root"]) compare_hash_keys(template, testee, trail) template.each do |t_key_or_rule, t_value| key_is_optional = t_key_or_rule.is_a?(Masterplan::Rule) && t_key_or_rule.options["optional"] t_key = if key_is_optional t_key_or_rule.example_value.to_s else t_key_or_rule.to_s end current_path = trail + [t_key] value = testee[t_key] compare_value(t_value, value, format_path(current_path)) unless key_is_optional and value.nil? if value && t_value.is_a?(Array) # all array elements need to be of the same type as the first value in the template elements_template = t_value.first value.each_with_index do |elements_value, index| array_path = current_path + [index] compare_value(elements_template, elements_value, format_path(array_path)) if elements_value.is_a?(Hash) compare_hash(elements_template, elements_value, format, array_path) end end end if value.is_a?(Array) && t_value.is_a?(Rule) && t_value.options['compare_each'] value.each_with_index do |elements_value, index| elements_template = t_value.example_value[index] array_path = current_path + [index] compare_value(elements_template, elements_value, format_path(array_path)) if elements_value.is_a?(Hash) compare_hash(elements_template, elements_value, format, array_path) end end end if value.is_a?(Hash) if t_value.is_a?(Masterplan::Rule) compare_value(t_value, value, current_path) compare_hash(t_value.example_value, value, format, current_path) else compare_hash(t_value, value, format, current_path) end end end rescue Masterplan::FailedError => e raise e if e.printed error = Masterplan::FailedError.new error.printed = true if format == :mini raise error, e.message, caller else expected = PP.pp(template, '') outcome = PP.pp(testee, '') raise error, "#{e.message}\n\nExpected:\n#{expected}\n\nbut was:\n#{outcome}", caller end end
compare_hash_keys(template, testee, trail)
click to toggle source
# File lib/masterplan.rb, line 41 def compare_hash_keys(template, testee, trail) mandatory_keys = Set.new optional_keys = Set.new template.keys.each do |key| if key.is_a?(Masterplan::Rule) && key.options["optional"] optional_keys << key.example_value.to_s else mandatory_keys << key.to_s end end failed = false testee.stringify_keys! testee_set = Set.new(testee.keys) if((mandatory_keys - testee_set).size > 0) # missing keys failed = true else extra_keys = (testee_set - mandatory_keys) if extra_keys.size > 0 && !extra_keys.subset?(optional_keys) failed = true end end if failed raise FailedError, "keys don't match in #{format_path(trail)}:\nexpected:\t#{mandatory_keys.sort.join(',')}\nreceived:\t#{testee.keys.sort.join(',')}" end end
compare_value(template, value, path)
click to toggle source
# File lib/masterplan.rb, line 33 def compare_value(template, value, path) if template.is_a?(Rule) template.masterplan_compare(value, path) else Rule.check_class_equality!(template, value, path) end end
format_path(trail)
click to toggle source
# File lib/masterplan.rb, line 126 def format_path(trail) "'" + trail.join("'=>'") + "'" end