http://www.perlmonks.org?node_id=839655

mje has asked for the wisdom of the Perl Monks concerning the following question:

I use Test::Deep quite a bit and like it but the following structure has defeated me as to coming up with a matching structure:

[ 11, 22, # optional [ [ 1 ], [ # -1 # only here if 2 above is there ] # ] ]

so I get:

[11,22,[[1],[-1]]]

or

[11,[[1]]

The closest I've got is:

use Test::More tests => 2; use Test::Deep; my $id_re = re('^\d+$'); my $vpt_re = re('^-?1$'); my $x = [ '11', '22', [ [ '-1', ], [ # '1', # only present if '22' above present ] # ] ]; my $y = [ '11', [ [ '-1', ], ] ]; my $comp = [ $id_re, $id_re, subbagof([$vpt_re], [$vpt_re]) ]; cmp_deeply($x, $comp, 'test1'); cmp_deeply($y, $comp, 'test2');

but it does not handle a) the optional $id_re at the top level and the subbagof allows none. I tried to put it all in a subbagof but the problem with subbags is it depends on what matches first.

Obviously I could test to see if it is an arrayref then use one of 2 patterns depending on whether the array contains 2 or 3 items but that seems like a cop out.

Replies are listed 'Best First'.
Re: Problem defining a Test::Deep structure to match this arrayref
by JavaFan (Canon) on May 12, 2010 at 15:04 UTC
    Wouldn't
    cmp_deeply($x, any([11,22,[[1],[-1]]], [11,[[1]]), 'test1'); cmp_deeply($y, any([11,22,[[1],[-1]]], [11,[[1]]), 'test2');
    do the trick?

      JavaFan yes it does. I guess I just got lost trying to do it with one structure. Would still be interested if anyone spots a way of doing it without specifying two patterns.

      Working version using JavaFan's suggestion:

      use Test::More tests => 2; use Test::Deep; my $id_re = re('^\d+$'); my $vpt_re = re('^-?1$'); my $x = [ '11', '22', [ [ '-1', ], [ # '1', # only present if '22' above present ] # ] ]; my $y = [ '11', [ [ '-1', ], ] ]; my $comp1 = [ $id_re, [[$vpt_re]] ]; my $comp2 = [ $id_re, $id_re, [[$vpt_re], [$vpt_re]] ]; cmp_deeply($x, any($comp1, $comp2), 'test1'); cmp_deeply($y, any($comp1, $comp2), 'test2');
Re: Problem defining a Test::Deep structure to match this arrayref
by pemungkah (Priest) on May 12, 2010 at 20:50 UTC
    Well, I'm kind of in the "tests are documentation" camp here; if breaking the test up makes it clear that it might be one thing, or it might be the other, then it's better to break them up for the extra clarity you achieve.