Skip to content

Commit

Permalink
Make it possible to get less verbose output for compare failures.
Browse files Browse the repository at this point in the history
  • Loading branch information
MGPalmer committed Mar 30, 2012
1 parent c2fce5b commit 3c6842e
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 12 deletions.
6 changes: 6 additions & 0 deletions README.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,12 @@ The implicit rules are:

You can add extra rules with the rule method - see Masterplan::DefineRules#rule for details.

You can control the verbosity of the output with the :format option:

>> Masterplan.compare(:scheme => doc, :to => {:example => :data}, :format => :mini)

Valid values are :full (the default), or :mini. :mini produces only a one-line output (leaving out the "Expected...but was" part).

There is also an added assertion for unit tests or specs:

assert_masterplan(doc, [{:example => :data})
Expand Down
26 changes: 16 additions & 10 deletions lib/masterplan.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ class FailedError < Test::Unit::AssertionFailedError

class << self

def compare(options = {:scheme => {}, :to => {}})
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)
compare_hash(scheme, testee)
raise ArgumentError, ":format needs to be one of [:full, :mini] !" unless [:full, :mini].include?(format)
compare_hash(scheme, testee, format)
true
end

Expand All @@ -36,7 +38,7 @@ def compare_value(template, value, path)
end
end

def compare_hash(template, testee, trail = ["root"])
def compare_hash(template, testee, format, trail = ["root"])
template.stringify_keys!
testee.stringify_keys!
raise FailedError, "keys don't match in #{format_path(trail)}:\nexpected:\t#{template.keys.sort.join(',')}\nreceived:\t#{testee.keys.sort.join(',')}" if template.keys.sort != testee.keys.sort
Expand All @@ -51,7 +53,7 @@ def compare_hash(template, testee, trail = ["root"])
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, array_path)
compare_hash(elements_template, elements_value, format, array_path)
end
end
end
Expand All @@ -61,16 +63,16 @@ def compare_hash(template, testee, trail = ["root"])
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, array_path)
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, current_path)
compare_hash(t_value.example_value, value, format, current_path)
else
compare_hash(t_value, value, current_path)
compare_hash(t_value, value, format, current_path)
end
end
end
Expand All @@ -81,10 +83,14 @@ def compare_hash(template, testee, trail = ["root"])
error = Masterplan::FailedError.new
error.printed = true

expected = PP.pp(template, '')
outcome = PP.pp(testee, '')
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
raise error, "#{e.message}\n\nExpected:\n#{expected}\n\nbut was:\n#{outcome}", caller
end
end

def format_path(trail)
Expand Down
2 changes: 1 addition & 1 deletion lib/masterplan/define_rules.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module Masterplan
module DefineRules

# This turns the supplied +example_value+ (any object) into an object that carries rules about itself with it.
# The rules will be applied when a template is compared with assert_masterplan. Rules are:
# The rules will be applied when a template is compared with assert_masterplan or Masterplan.compare. Rules are:
# (default): This always applies - the value must be of the same class as the +example_value+
# 'allow_nil': This allows the value to be nil (breaking the first rule)
# 'included_in': Pass an array of values - the value must be one of these
Expand Down
38 changes: 37 additions & 1 deletion spec/masterplan_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,16 @@ def test_value_and_expect(testee, *error_and_descripton)
end.should raise_error(ArgumentError, /scheme needs to be a Masterplan::Document/)
end

it "complains if not given a proper format key" do
lambda do
Masterplan.compare(
:scheme => Masterplan::Document.new({}),
:to => {},
:format => :medium
)
end.should raise_error(ArgumentError, ":format needs to be one of [:full, :mini] !")
end

it "complains if there are extra keys" do
test_value_and_expect(
{ :ship => {}, :boat => {} },
Expand Down Expand Up @@ -109,11 +119,37 @@ def test_value_and_expect(testee, *error_and_descripton)
)
end

[nil, :full].each do |format|
it "produces full output for format = #{format}" do
lambda do
Masterplan.compare(
:scheme => @scheme,
:to => { :ship => [] },
:format => format
)
end.should raise_error(
/value at 'root'=>'ship' \(Array\) is not a Hash !\n\s*?Expected:.*?but was/m
)
end
end

it "produces one-line output when using :mini format" do
lambda do
Masterplan.compare(
:scheme => @scheme,
:to => { :ship => [] },
:format => :mini
)
end.should raise_error(
"value at 'root'=>'ship' (Array) is not a Hash !"
)
end

it "checks all values of value arrays, but only against the first array value of the scheme"
it "checks all array values one-to-one if the compare_each rule is used"
end

it "convertsinto plain example hashes"
it "converts into plain example hashes"
it "doesn't create a Document out of anything other than a Hash"
it "checks that the examples of rules obey the rules"
it "has a unit test extension method"
Expand Down

0 comments on commit 3c6842e

Please sign in to comment.