Is_deeply test ignores array order?

I am looking for a test procedure, for example is_deeply in Test::More . There cmp_bag from Test::Deep , but this only works on the array itself, and not on the terribly large hashes of data hashes, the structure I am passing. Is there something like:

 is_deeply $got, $expected, { array => cmp_bag, # and other configuration... }, "Ugly data structure should be the same, barring array order."; 

Explanation

I could recursively dig into my $expected and $got objects and convert arrays to bag objects:

 sub bagIt { my $obj = shift; switch (ref($obj)) { case "ARRAY" { return bag([ map { $_ = bagIt($_) } @$obj ]); } case "HASH" { return { map { $_ => bagIt( $obj->{$_} ) } keys %$obj }; } else { return $obj; } } } 

I am wondering if there is a way to tell some is_deeply option to do this for me.

+4
source share
3 answers

It seems that in Test::Deep or other Test::* packages there is no way to treat each array as a set of packages. The following function works, but is not effective for testing on large data structures:

 sub bagIt { my $obj = shift; my $ref = ref($obj); if ($ref eq 'ARRAY') { return Test::Deep::bag( map { $_ = bagIt($_) } @$obj ); } elsif ($ref eq 'HASH') { return { map { $_ => bagIt( $obj->{$_} ) } keys %$obj }; } else { return $obj; } } 

In the end, I finished refactoring my code so as not to depend on such a gradient test.

+1
source

Well, from Test :: Deep docs , cmp_bag(\@got, \@bag, $name) is just short for cmp_deeply(\@got, bag(@bag), $name) .

 is_deeply( $got, { array => bag(qw/the values you expect/), # and other expected values }, "Ugly data structure should be the same, barring array order." ); 
+2
source

Using the bagIt function you wrote, you can always make a wrapper for is_deeply , which applies bagIt for you:

 sub is_deep_bag { splice @_, 1, 1, bagIt($_[1]); goto &is_deeply # magic goto so that errors are reported on the right line } 
+2
source

Source: https://habr.com/ru/post/1399250/


All Articles