summaryrefslogtreecommitdiff
path: root/Master/tlpkg/tlperl.straw/lib/Test/Deep.pod
diff options
context:
space:
mode:
Diffstat (limited to 'Master/tlpkg/tlperl.straw/lib/Test/Deep.pod')
-rwxr-xr-xMaster/tlpkg/tlperl.straw/lib/Test/Deep.pod932
1 files changed, 932 insertions, 0 deletions
diff --git a/Master/tlpkg/tlperl.straw/lib/Test/Deep.pod b/Master/tlpkg/tlperl.straw/lib/Test/Deep.pod
new file mode 100755
index 00000000000..ffaab48b400
--- /dev/null
+++ b/Master/tlpkg/tlperl.straw/lib/Test/Deep.pod
@@ -0,0 +1,932 @@
+=head1 NAME
+
+Test::Deep - Extremely flexible deep comparison
+
+=head1 SYNOPSIS
+
+ use Test::More tests => $Num_Tests;
+ use Test::Deep;
+
+ cmp_deeply(
+ $actual_horrible_nested_data_structure,
+ $expected_horrible_nested_data_structure,
+ "got the right horrible nested data structure"
+ );
+
+ cmp_deeply(
+ $object,
+ methods(name => "John", phone => "55378008"),
+ "object methods ok"
+ );
+
+ cmp_deeply(
+ \@array,
+ [$hash1, $hash2, ignore(
+ "first 2 elements are as expected, ignoring 3"
+ );
+
+ cmp_deeply(
+ $object,
+ noclass({value => 5}),
+ "object looks ok, not checking it's class"
+ );
+
+ cmp_deeply(
+ \@result,
+ bag('a', 'b', {key => [1, 2]}),
+ "array has the 3 things we wanted in some order"
+ );
+
+=head1 DESCRIPTION
+
+If you don't know anything about automated testing in Perl then you should
+probably read about Test::Simple and Test::More before preceding.
+Test::Deep uses the Test::Builder framework.
+
+Test::Deep gives you very flexible ways to check that the result you got is
+the result you were expecting. At it's simplest it compares two structures
+by going through each level, ensuring that the values match, that arrays and
+hashes have the same elements and that references are blessed into the
+correct class. It also handles circular data structures without getting
+caught in an infinite loop.
+
+Where it becomes more interesting is in allowing you to do something besides
+simple exact comparisons. With strings, the C<eq> operator checks that 2
+strings are exactly equal but sometimes that's not what you want. When you
+don't know exactly what the string should be but you do know some things
+about how it should look, C<eq> is no good and you must use pattern matching
+instead. Test::Deep provides pattern matching for complex data structures
+
+=head1 EXAMPLES
+
+How Test::Deep works is much easier to understand by seeing some examples.
+
+=head2 Without Test::Deep
+
+Say you want to test a function which returns a string. You know that your
+string should be a 7 digit number beginning with 0, C<eq> is no good in this
+situation, you need a regular expression. So you could use Test::More's
+C<like()> function:
+
+ like($string, '/^0d{6}$/', "number looks good");
+
+Similarly, to check that a string looks like a name, you could do:
+
+ like($string, '/^(Mr|Mrs|Miss) \w+ \w+$/',
+ "got title, first and last name");
+
+Now imagine your function produces a hash with some personal details in it.
+You want to make sure that there are 2 keys, Name and Phone and that the
+name looks like a name and the phone number looks like a phone number. You
+could do:
+
+ $hash = make_person();
+ like($hash->{Name}, '/^(Mr|Mrs|Miss) \w+ \w+$/', "name ok");
+ like($hash->{Phone}, '/^0d{6}$/', "phone ok");
+ is(scalar keys %$hash, 2, "correct number of keys");
+
+But that's not quite right, what if make_person has a serious problem and
+didn't even return a hash? We really need to write
+
+ if (ref($hash) eq "HASH")
+ {
+ like($hash->{Name}, '/^(Mr|Mrs|Miss) \w+ \w+$/', "name ok");
+ like($hash->{Phone}, '/^0d{6}$/', "phone ok");
+ is(scalar keys %$hash, 2, "correct number of keys");
+ }
+ else
+ {
+ fail("person not a hash");
+ fail("person not a hash");
+ fail("person not a hash"); # need 3 to keep the plan correct
+ }
+
+Already this is getting messy, now imagine another entry in the hash, an
+array of children's names. This would require
+
+
+ if (ref($hash) eq "HASH")
+ {
+ like($hash->{Name}, $name_pat, "name ok");
+ like($hash->{Phone}, '/^0d{6}$/', "phone ok");
+ my $cn = $hash->{ChildNames};
+ if (ref($cn) eq "ARRAY")
+ {
+ foreach my $child (@$cn)
+ {
+ like($child, $name_pat);
+ }
+ }
+ else
+ {
+ fail("child names not an array")
+ }
+ }
+ else
+ {
+ fail("person not a hash");
+ }
+
+This is a horrible mess and because we don't know in advance how many
+children's names there will be, we can't make a plan for our test anymore
+(actually, we could but it would make things even more complicated).
+
+Test::Deep to the rescue.
+
+=head2 With Test::Deep
+
+ my $name_re = re('^(Mr|Mrs|Miss) \w+ \w+$');
+ cmp_deeply(
+ $person,
+ {
+ Name => $name_re,
+ Phone => re('^0d{6}$'),
+ ChildNames => array_each($name_re)
+ },
+ "person ok"
+ );
+
+This will do everything that the messy code above does and it will give a
+sensible message telling you exactly what went wrong if it finds a part of
+$person that doesn't match the pattern. C<re()> and C<array_each()> are
+special function imported from Test::Deep. They create a marker that tells
+Test::Deep that something different is happening here. Instead of just doing
+a simple comparison and checking are two things exactly equal, it should do
+something else.
+
+If a person was asked to check that 2 structures are equal, they could print
+them both out and compare them line by line. The markers above are similar
+to writing a note in red pen on one of the printouts telling the person that
+for this piece of the structure, they should stop doing simple line by line
+comparison and do something else.
+
+C<re($regex)> means that Test::Deep should check that the current piece of
+data matches the regex in C<$regex>. C<array_each($struct)> means that
+Test::Deep should expect the current piece of data to be an array and it
+should check that every element of that array matches C<$struct>.
+In this case, every element of C<$person->{ChildNames}> should look like a
+name. If say the 3rd one didn't you would get an error message something
+like
+
+ Using Regexp on $data->{ChildNames}[3]
+ got : 'Queen John Paul Sartre'
+ expect : /^(Mr|Mrs|Miss) \w+ \w+$/
+
+There are lots of other special comparisons available, see
+L<SPECIAL COMPARISONS PROVIDED> below for the full list.
+
+=head2 Reusing structures
+
+Test::Deep is good for reusing test structures so you can do this
+
+ my $name_re = re('^(Mr|Mrs|Miss) \w+ \w+$');
+ my $person_cmp = {
+ Name => $name_re,
+ Phone => re('^0d{6}$'),
+ ChildNames => array_each($name_re)
+ };
+
+ cmp_deeply($person1, $person_cmp, "person ok");
+ cmp_deeply($person2, $person_cmp, "person ok");
+ cmp_deeply($person3, $person_cmp, "person ok");
+
+You can even put $person_cmp in a module and let other people use it when
+they are writing test scripts for modules that use your modules.
+
+To make things a little more difficult, lets change the person data
+structure so that instead of a list of ChildNames, it contains a list of
+hashes, one for each child. So in fact our person structure will contain
+other person structures which may contain other person structures and so on.
+This is easy to handle with Test::Deep because Test::Deep structures can
+include themselves. Simply do
+
+ my $name_re = re('^(Mr|Mrs|Miss) \w+ \w+$');
+ my $person_cmp = {
+ Name => $name_re,
+ Phone => re('^0d{6}$'),
+ # note no mention of Children here
+ };
+
+ $person_cmp->{Children} = each_array($person_cmp);
+
+ cmp_deeply($person, $person_cmp, "person ok");
+
+This will now check that $person->{Children} is an array and that every
+element of that array also matches C<$person_cmp>, this includes checking
+that it's children also match the same pattern and so on.
+
+=head2 Circular data structures
+
+A circular data structure is one which loops back on itself, you can make
+one easily by doing
+
+ my @b;
+ my @a = (1, 2, 3, \@b);
+ push(@b, \@a);
+
+now @a contains a reference to be @b and @b contains a reference to @a. This
+causes problems if you have a program that wants to look inside @a and keep
+looking deeper and deeper at every level, it could get caught in an infinite
+loop looking into @a then @b then @a then @b and so on.
+
+Test::Deep avoids this problem so we can extend our example further by
+saying that a person should also list their parents.
+
+ my $name_re = re('^(Mr|Mrs|Miss) \w+ \w+$');
+ my $person_cmp = {
+ Name => $name_re,
+ Phone => re('^0d{6}$'),
+ # note no mention of Children here
+ };
+
+ $person_cmp->{Children} = each_array($person_cmp);
+ $person_cmp->{Parents} = each_array($person_cmp);
+
+ cmp_deeply($person, $person_cmp, "person ok");
+
+So this will check that for each child C<$child> in C<$person->{Children}>
+that the C<$child->{Parents} matches C<$person_cmp> however it is smart
+enough not to get caught in an infinite loop where it keeps bouncing between
+the same Parent and Child.
+
+=head1 TERMINOLOGY
+
+C<cmp_deeply($got, $expected, $name)> takes 3 arguments. C<$got> is the
+structure that you are checking, you must not include any special
+comparisons in this structure or you will get a fatal error. C<$expected>
+describes what Test::Deep will be looking for in $got. You can put special
+comparisons in $expected if you want to.
+
+As Test::Deep descends through the 2 structures, it compares them one piece
+at a time, so at any point in the process, Test::Deep is thinking about 2
+things - the current value from C<$got> and the current value from
+C<$expected>. In the documentation, I call them C<$got_v> and C<exp_v>
+respectively.
+
+=head1 COMPARISON FUNCTIONS
+
+=head3 $ok = cmp_deeply($got, $expected, $name)
+
+$got is the result to be checked. $expected is the structure against which
+$got will be check. $name is the test name.
+
+This is the main comparison function, the others are just wrappers around
+this. Without any special comparisons, it will descend into $expected,
+following every reference and comparing C<$expected_v> to C<$got_v> (using
+C<eq>) at the same position. If at any stage C<$expected_v> is a special
+comparison then Test::Deep may do something else besides a simple string
+comparison, exactly what it does depends on which special comparison it is.
+
+=head3 $ok = cmp_bag(\@got, \@bag, $name)
+
+Is shorthand for cmp_deeply(\@got, bag(@bag), $name)
+
+N.B. Both arguments must be array refs. If they aren't an error will
+be raised via die.
+
+=head3 $ok = cmp_set(\@got, \@set, $name)
+
+Is shorthand for cmp_deeply(\@got, set(@set), $name)
+
+=head3 $ok = cmp_methods(\@got, \@methods, $name)
+
+Is shorthand for cmp_deeply(\@got, methods(@methods), $name)
+
+=head3 $ok = eq_deeply($got, $expected)
+
+This is the same as cmp_deeply() except it just returns true or
+false. It does not create diagnostics or talk to L<Test::Builder>, but
+if you want to use it in a non-testing environment then you should
+import it through L<Test::Deep::NoTest>. For example
+
+ use Test::Deep::NoTest;
+ print "a equals b" unless eq_deeply($a, $b);
+
+otherwise the L<Test::Builder> framework will be loaded and testing messages
+will be output when your program ends.
+
+=head3 ($ok, $stack) = cmp_details($got, $expected)
+
+This behaves much like eq_deeply, but it additionally allows you to
+produce diagnostics in case of failure by passing the value in C<$stack>
+to C<deep_diag>.
+
+Do not make assumptions about the structure or content of C<$stack> and
+do not use it if C<$ok> contains a true value.
+
+See L</USING TEST::DEEP WITH TEST::BUILDER> for example uses.
+
+=head1 SPECIAL COMPARISONS PROVIDED
+
+=head3 ignore()
+
+This makes Test::Deep skip tests on $got_v. No matter what value C<$got_v>
+has, Test::Deep will think it's correct. This is useful if some part of the
+structure you are testing is very complicated and already tested elsewhere,
+or is unpredictable.
+
+ cmp_deeply($got, { name => 'John', random => ignore(), address => ['5 A
+ street', 'a town', 'a country'],
+ })
+
+is the equivalent of checking
+
+ $got->{name} eq 'John';
+ exists $got->{random};
+ cmp_deeply($got->{address};
+ ['5 A street', 'a town', 'a country']);
+
+=head3 methods(%hash)
+
+%hash is a hash of method call => expected value pairs.
+
+This lets you call methods on an object and check the result of each call.
+The methods will be called in the order supplied. If you want to pass
+arguments to the method you should wrap the method name and arguments in an
+array reference.
+
+ cmp_deeply(
+ $obj,
+ methods(name => "John", ["favourite", "food"] => "taco")
+ );
+
+is roughly the equivalent of checking that
+
+ $obj->name eq "John"
+ $obj->favourite("food") eq "taco"
+
+The methods will be called in the order you supply them and will be called
+in scalar context. If you need to test methods called in list context then
+you should use listmethods().
+
+B<NOTE> Just as in a normal test script, you need to be careful if the
+methods you call have side effects like changing the object or other objects
+in the structure. Although the order of the methods is fixed, the order of
+some other tests is not so if $expected is
+
+ {
+ manager => methods(@manager_methods),
+ coder => methods(@coder_methods)
+ }
+
+there is no way to know which if manager and coder will be tested first. If
+the methods you are testing depend on and alter global variables or if
+manager and coder are the same object then you may run into problems.
+
+=head3 listmethods(%hash)
+
+%hash is a hash of method call => expected value pairs.
+
+This is almost identical to methods() except the methods are called in list
+context instead of scalar context. This means that the expected values
+supplied must be an array reference.
+
+ cmp_deeply(
+ $obj,
+ listmethods(
+ name => "John",
+ ["favourites", "food"] => ["Mapo tofu", "Gongbao chicken"]
+ )
+ );
+
+is the equivalent of checking that
+
+ $obj->name eq "John"
+ cmp_deeply([$obj->favourites("food")], ["Mapo tofu", "Gongbao chicken"]);
+
+The methods will be called in the order you supply them.
+
+B<NOTE> The same caveats apply as for methods().
+
+=head3 shallow($thing)
+
+$thing is a ref.
+
+This prevents Test::Deep from looking inside $thing. It allows you to
+check that $got_v and $thing are references to the same variable. So
+
+ my @a = @b = (1, 2, 3);
+ cmp_deeply(\@a, \@b);
+
+will pass because @a and @b have the same elements however
+
+ cmp_deeply(\@a, shallow(\@b))
+
+will fail because although \@a and \@b both contain C<1, 2, 3> they are
+references to different arrays.
+
+=head3 noclass($thing)
+
+$thing is a structure to be compared against.
+
+This makes Test::Deep ignore the class of objects, so it just looks at the
+data they contain. Class checking will be turned off until Test::Deep is
+finished comparing C<$got_v> against C<$thing>. Once Test::Deep comes out of
+C<$thing> it will go back to it's previous setting for checking class.
+
+This can be useful when you want to check that objects have been
+constructed correctly but you don't want to write lots of
+C<bless>es. If \@people is an array of Person objects then
+
+ cmp_deeply(\@people, noclass([
+ bless {name => 'John', phone => '555-5555'}, "Person",
+ bless {name => 'Anne', phone => '444-4444'}, "Person",
+ ]));
+
+can be replaced with
+
+ cmp_deeply(\@people, noclass([
+ {name => 'John', phone => '555-5555'},
+ {name => 'Anne', phone => '444-4444'}
+ ]));
+
+However, this is testing so you should also check that the objects are
+blessed correctly. You could use a map to bless all those hashes or you
+could do a second test like
+
+ cmp_deeply($people, array_each(isa("Person"));
+
+=head3 useclass($thing)
+
+This turns back on the class comparison while inside a noclass().
+
+ cmp_deeply(
+ $got,
+ noclass(
+ [
+ useclass( $object )
+ ]
+ )
+ )
+
+In this example the class of the array reference in C<$got> is ignored but
+the class of C<$object> is checked, as is the class of everything inside
+C<$object>.
+
+=head3 re($regexp, $capture_data, $flags)
+
+$regexp is either a regular expression reference produced with C<qr/.../> or
+a string which will be used to construct a regular expression.
+
+$capture_data is optional and is used to check the strings captured by
+an regex. This should can be an array ref or a Test::Deep comparator
+that works on array refs.
+
+$flags is an optional string which controls whether the regex runs as a
+global match. If $flags is "g" then the regex will run as m/$regexp/g.
+
+Without $capture_data, this simply compares $got_v with the regular expression
+provided. So
+
+ cmp_deeply($got, [ re("ferg") ])
+
+is the equivalent of
+
+ $got->[0] =~ /ferg/
+
+With $capture_data
+
+ cmp_deeply($got, [re($regex, $capture_data])
+
+is the equivalent of
+
+ my @data = $got->[0] =~ /$regex/;
+ cmp_deeply(\@data, $capture_data);
+
+So you can do something simple like
+
+ cmp_deeply($got, re(qr/(\d\d)(\w\w)/, [25, "ab" ])
+
+to check that (\d\d) was 25 and (\w\w) was "ab" but you can also use
+Test::Deep objects to do more complex testing of the captured values
+
+ cmp_deeply("cat=2,dog=67,sheep=3,goat=2,dog=5",
+ re(qr/(\D+)=\d+,?/, set(qw( cat sheep dog )), "g"))
+
+here, the regex will match the string and will capture the animal names and
+check that they match the specified set, in this case it will fail,
+complaining that "goat" is not in the set.
+
+=head3 superhashof(\%hash)
+
+This will check that the hash C<%$got> is a "super-hash" of C<%hash>. That
+is that all the key and value pairs in C<%hash> appear in C<%$got> but
+C<%$got> can have extra ones also.
+
+For example
+
+ cmp_deeply({a => 1, b => 2}, superhashof({a => 1}))
+
+will pass but
+
+ cmp_deeply({a => 1, b => 2}, superhashof({a => 1, c => 3}))
+
+will fail.
+
+=head3 subhashof(\%hash)
+
+This will check that the hash C<%$got> is a "sub-hash" of C<%hash>. That is
+that all the key and value pairs in C<%$got> also appear in C<%hash>.
+
+For example
+
+ cmp_deeply({a => 1}, subhashof({a => 1, b => 2}))
+
+will pass but
+
+ cmp_deeply({a => 1, c => 3}, subhashof({a => 1, b => 2}))
+
+will fail.
+
+=head3 bag(@elements)
+
+@elements is an array of elements.
+
+This does a bag comparison, that is, it compares two arrays but ignores the
+order of the elements so
+
+ cmp_deeply([1, 2, 2], bag(2, 2, 1))
+
+will be a pass.
+
+The object returned by bag() has an add() method.
+
+ my $bag = bag(1, 2, 3);
+ $bag->add(2, 3, 4);
+
+will result in a bag containing 1, 2, 2, 3, 3, 4.
+
+C<NOTE> If you use certain special comparisons within a bag or set
+comparison there is a danger that a test will fail when it should have
+passed. It can only happen if two or more special comparisons in the bag are
+competing to match elements. Consider this comparison
+
+ cmp_deeply(['furry', 'furball'], bag(re("^fur"), re("furb")))
+
+There are two things that could happen, hopefully C<re("^fur")> is paired with
+"furry" and C<re("^furb")> is paired with "furb" and everything is fine but it
+could happen that C<re("^fur")> is paired with "furball" and then C<re("^furb")>
+cannot find a match and so the test fails. Examples of other competing
+comparisons are C<bag(1, 2, 2)> vs C<set(1, 2)> and
+C<methods(m1 => "v1", m2 => "v2")> vs C<methods(m1 => "v1")>
+
+This problem is could be solved by using a slower and more complicated
+algorithm for set and bag matching. Something for the future...
+
+=head3 set(@elements)
+
+@elements is an array of elements.
+
+This does a set comparison, that is, it compares two arrays but ignores the
+order of the elements and it ignores duplicate elements, so
+
+ cmp_deeply([1, 2, 2, 3], set(3, 2, 1, 1))
+
+will be a pass.
+
+The object returned by set() has an add() method.
+
+ my $set = set(1, 2, 3);
+ $set->add(4, 5, 6);
+
+will result in a set containing 1, 2, 3, 4, 5, 5.
+
+C<NOTE> See the NOTE on the bag() comparison for some dangers in using
+special comparisons inside set()
+
+=head3 superbagof(@elements), subbagof(@elements), supersetof(@elements) and subsetof(@elements)
+
+@elements is an array of elements.
+
+These do exactly what you'd expect them to do, so for example
+
+ cmp_deeply($data, subbagof(1, 1, 3, 4));
+
+checks that @$data contains at most 2 "1"s, 1 "3" and 1 "4" and
+
+ cmp_deeply($data, supsersetof(1, 4));
+
+check that @$data contains at least 1 "1" and 1 "4".
+
+These are just special cases of the Set and Bag comparisons so they also
+give you an add() method and they also have the same limitations when using
+special comparisons inside them (see the NOTE in the bag() section).
+
+=head3 all(@expecteds)
+
+@expecteds is an array of expected structures.
+
+This allows you to compare data against multiple expected results and make
+sure each of them matches.
+
+ cmp_deeply($got, all(isa("Person"), methods(name => 'John')))
+
+is equivalent to
+
+ $got->isa("Person")
+ $got->name eq 'John'
+
+If either test fails then the whole thing is considered a fail. This is a
+short-circuit test, the testing is stopped after the first failure, although
+in the future it may complete all tests so that diagnostics can be output
+for all failures. When reporting failure, the parts are counted from 1.
+
+Thanks to the magic of overloading, you can write
+
+ all(isa("Person"), methods(name => 'John'), re("^wi"))
+
+as
+
+ isa("Person") & methods(name => 'John') | re("^wi")
+
+Note B<single> | not double as || cannot be overloaded. This will only work
+when there is a special comparison involved. If you write
+
+ "john" | "anne" | "robert"
+
+Perl will turn this into
+
+ "{onort"
+
+which is presumably not what you wanted. This is because Perl |s them
+together as strings before Test::Deep gets a chance to do any overload
+tricks.
+
+=head3 any(@expecteds)
+
+@expecteds is an array of expected structures.
+
+This can be used to compare data against multiple expected results and make
+sure that at least one of them matches. This is a short-circuit test so if
+a test passes then none of the tests after that will be attempted.
+
+You can also use overloading with | similarly to all().
+
+=head3 isa($class), Isa($class)
+
+$class is a class name.
+
+This uses UNIVERSAL::isa() to check that $got_v is blessed into the class
+$class.
+
+B<NOTE:> Isa() does exactly as documented here, isa() is slightly
+different. If isa() is called with 1 argument it falls through to
+Isa(). If isa() called with 2 arguments, it falls through to
+UNIVERAL::isa. This is to prevent breakage when you import isa() into
+a package that is used as a class. Without this, anyone calling
+C<Class-E<gt>isa($other_class)> would get the wrong answer. This is a
+hack to patch over the fact that isa is exported by default.
+
+=head3 array_each($thing)
+
+$thing is a structure to be compared against.
+
+<$got_v> must be an array reference. Each element of it will be compared to
+$thing. This is useful when you have an array of similar things, for example
+objects of a known type and you don't want to have to repeat the same test
+for each one.
+
+ my $common_tests = all(
+ isa("MyFile"),
+ methods(
+ handle => isa("IO::Handle")
+ filename => re("^/home/ted/tmp"),
+ )
+ );
+
+ cmp_deeply($got, array_each($common_tests));
+
+is similar to
+
+ foreach my $got_v (@$got) {
+ cmp_deeply($got_v, $common_tests)
+ }
+
+Except it will not explode is $got is not an array reference. It will check
+that each of the objects in @$got is a MyFile and that each one gives the
+correct results for it's methods.
+
+You could go further, if for example there were 3 files and you knew the
+size of each one you could do this
+
+ cmp_deeply(
+ $got,
+ all(
+ array_each($common_tests),
+ [
+ methods(size => 1000),
+ methods(size => 200),
+ methods(size => 20)
+ ]
+ )
+ )
+ cmp_deeply($got, array_each($structure));
+
+=head3 str($string)
+
+$string is a string.
+
+This will stringify C<$got_v> and compare it to C<$string> using C<eq>, even
+if $got_v is a ref. It is useful for checking the stringified value of an
+overloaded reference.
+
+=head3 num($number, $tolerance)
+
+$number is a number.
+$tolerance is an optional number.
+
+This will add 0 to C<$got_v> and check if it's numerically equal to
+C<$number>, even if $got_v is a ref. It is useful for checking the numerical
+value of an overloaded reference. If $tolerance is supplied then this will
+check that $got_v and $exp_v are less than $tolerance apart. This is useful
+when comparing floating point numbers as rounding errors can make it hard or
+impossible for $got_v to be exactly equal to $exp_v. When $tolerance is
+supplied, the test passes if C<abs($got_v - $exp_v) <= $tolerance>.
+
+B<Note> in Perl, C<"12blah" == 12> because Perl will be smart and convert
+"12blah" into 12. You may not want this. There was a strict mode but that is
+now gone. A "lookslike s number" test will replace it soon. Until then you
+can usually just use the string() comparison to be more strict. This will
+work fine for almost all situations, however it will not work when <$got_v>
+is an overloaded value who's string and numerical values differ.
+
+=head3 bool($value)
+
+$value is anything you like but it's probably best to use 0 or 1
+
+This will check that C<$got_v> and C<$value> have the same truth value, that
+is they will give the same result when used in boolean context, like in an
+if() statement.
+
+=head3 code(\&subref)
+
+\&subref is a reference to a subroutine which will be passed a single
+argument, it then should return a true or false and possibly a string
+
+This will pass C<$got_v> to the subroutine which returns true or false to
+indicate a pass or fail. Fails can be accompanied by a diagnostic string
+which gives an explanation of why it's a fail.
+
+ sub check_name
+ {
+ my $name = shift;
+ if ($boss->likes($name))
+ {
+ return 1;
+ }
+ else
+ {
+ return (0, "the boss doesn't like your name");
+ }
+ }
+
+ cmp_deeply("Brian", \&check_name);
+
+=head1 DIAGNOSTIC FUNCTIONS
+
+=head3 my $reason = deep_diag($stack)
+
+C<$stack> is a value returned by cmp_details. Do not call this function
+if cmp_details returned a true value for C<$ok>.
+
+deep_diag() returns a human readable string describing how the
+comparison failed.
+
+=head1 ANOTHER EXAMPLE
+
+You've written a module to handle people and their film interests. Say you
+have a function that returns an array of people from a query, each person is
+a hash with 2 keys: Name and Age and the array is sorted by Name. You can do
+
+ cmp_deeply(
+ $result,
+ [
+ {Name => 'Anne', Age => 26},
+ {Name => "Bill", Age => 47}
+ {Name => 'John', Age => 25},
+ ]
+ );
+
+Soon after, your query function changes and all the results now have an ID
+field. Now your test is failing again because you left out ID from each of
+the hashes. The problem is that the IDs are generated by the database and
+you have no way of knowing what each person's ID is. With Test::Deep you can
+change your query to
+
+ cmp_deeply(
+ $result,
+ [
+ {Name => 'John', Age => 25, ID => ignore()},
+ {Name => 'Anne', Age => 26, ID => ignore()},
+ {Name => "Bill", Age => 47, ID => ignore()}
+ ]
+ );
+
+But your test still fails. Now, because you're using a database, you no
+longer know what order the people will appear in. You could add a sort into
+the database query but that could slow down your application. Instead you
+can get Test::Deep to ignore the order of the array by doing a bag
+comparison instead.
+
+ cmp_deeply(
+ $result,
+ bag(
+ {Name => 'John', Age => 25, ID => ignore()},
+ {Name => 'Anne', Age => 26, ID => ignore()},
+ {Name => "Bill", Age => 47, ID => ignore()}
+ )
+ );
+
+Finally person gets even more complicated and includes a new field called
+Movies, this is a list of movies that the person has seen recently, again
+these movies could also come back in any order so we need a bag inside our
+other bag comparison, giving us something like
+
+ cmp_deeply(
+ $result,
+ bag(
+ {Name => 'John', Age => 25, ID => ignore(), Movies => bag(...)},
+ {Name => 'Anne', Age => 26, ID => ignore(), Movies => bag(...)},
+ {Name => "Bill", Age => 47, ID => ignore(), Movies => bag(...)}
+ )
+ );
+
+=head1 USING TEST::DEEP WITH TEST::BUILDER
+
+Combining C<cmp_details> and C<test_diag> makes it possible to use
+Test::Deep in your own test classes.
+
+In a L<Test::Builder> subclass, create a test method in the following
+form:
+
+ sub behaves_ok {
+ my $self = shift;
+ my $expected = shift;
+ my $test_name = shift;
+
+ my $got = do_the_important_work_here();
+
+ my ($ok, $stack) = cmp_details($got, $expected);
+ unless ($Test->ok($ok, $test_name)) {
+ my $diag = deep_diag($stack);
+ $Test->diag($diag);
+ }
+ }
+
+As the subclass defines a test class, not tests themselves, make sure it
+uses L<Test::Deep::NoTest>, not C<Test::Deep> itself.
+
+=head1 LIMITATIONS
+
+Currently any CODE, GLOB or IO refs will be compared using shallow(), which
+means only their memory addresses are compared.
+
+=head1 BUGS
+
+There is a bug in set and bag compare to do with competing SCs. It only
+occurs when you put certain special comparisons inside bag or set
+comparisons you don't need to worry about it. The full details are in the
+bag() docs. It will be fixed in an upcoming version.
+
+=head1 WHAT ARE SPECIAL COMPARISONS?
+
+A special comparison (SC) is simply an object that inherits from
+Test::Deep::Cmp. Whenever C<$expected_v> is an SC then instead of checking
+C<$got_v eq $expected_v>, we pass control over to the SC and let it do it's
+thing.
+
+Test::Deep exports lots of SC constructors, to make it easy for you to use
+them in your test scripts. For example is C<re("hello")> is just a handy way
+of creating a Test::Deep::Regexp object that will match any string containing
+"hello". So
+
+ cmp_deeply([ 'a', 'b', 'hello world'], ['a', 'b', re("^hello")]);
+
+will check C<'a' eq 'a'>, C<'b' eq 'b'> but when it comes to comparing
+C<'hello world'> and C<re("^hello")> it will see that
+$expected_v is an SC and so will pass control to the Test::Deep::Regexp class
+by do something like C<$expected_v->descend($got_v)>. The C<descend()>
+method should just return true or false.
+
+This gives you enough to write your own SCs but I haven't documented how
+diagnostics works because it's about to get an overhaul.
+
+=head1 SEE ALSO
+
+L<Test::More>
+
+=head1 AUTHOR
+
+Fergal Daly E<lt>fergal@esatclear.ieE<gt>, with thanks to Michael G Schwern
+for Test::More's is_deeply function which inspired this.
+
+=head1 COPYRIGHT
+
+Copyright 2003, 2004 by Fergal Daly E<lt>fergal@esatclear.ieE<gt>.
+
+This program is free software; you can redistribute it and/or
+modify it under the same terms as Perl itself.
+
+See F<http://www.perl.com/perl/misc/Artistic.html>
+
+=cut