Vous pouvez utiliser Test::Deep qui prévoit cmp_deeply
. Il est beaucoup plus polyvalent que la fonction de Test::More is_deeply
.
use Test::Deep;
my $hash1 = {
k1 => { k11 => 'v1', k12 => 'v2' }, k2 => { k21 => [ 'v1', 'v2', 'v3' ] } };
my $hash2 = {
k1 => { k11 => 'v1', k12 => 'v2' }, k2 => { k21 => bag( 'v3', 'v2', 'v1' ) } };
cmp_deeply( $hash1, $hash2, );
L'astuce est la suivante bag()
fonction qui ignore l'ordre des éléments.
Elle effectue une comparaison de sac, c'est-à-dire qu'elle compare deux tableaux mais ignore l'ordre des éléments [...].
Mise à jour : A partir de votre commentaire :
Comment mettre en sac toutes les références de tableaux dans un hash de façon dynamique ?
Quelques recherches dans le code de Test::Deep ont montré qu'il est possible de l'écraser. J'ai regardé at Test::Deep lui-même d'abord, et a constaté qu'il y a un Test::Deep::Array qui traite des tableaux. Tous les paquets qui manipulent des choses à l'intérieur de T::D ont a descend
méthode . C'est donc là qu'il faut s'accrocher.
Sub::Override est idéal pour remplacer temporairement des éléments, au lieu de s'embêter avec des blocs de type.
En fait, tout ce que nous devons faire est de remplacer l'appel à Test::Deep::arrayelementsonly
en Test::Deep::Array::descend
La dernière ligne de l'article est un appel à bag()
. Le reste est simplement copié (l'indentation est de moi). Pour les petits singe-Parcheando une copie du code existant avec une légère modification est généralement l'approche la plus simple.
use Test::Deep;
use Test::Deep::Array;
use Sub::Override;
my $sub = Sub::Override->new(
'Test::Deep::Array::descend' => sub {
my $self = shift;
my $got = shift;
my $exp = $self->{val};
return 0 unless Test::Deep::descend(
$got, Test::Deep::arraylength( scalar @$exp ) );
return 0 unless $self->test_class($got);
return Test::Deep::descend( $got, Test::Deep::bag(@$exp) );
}
);
my $hash1 = {
k1 => { k11 => 'v1', k12 => 'v2' },
k2 => { k21 => [ 'v1', 'v2', 'v3' ] }
};
my $hash2 = {
k1 => { k11 => 'v1', k12 => 'v2' },
k2 => { k21 => [ 'v3', 'v2', 'v1' ] }
};
cmp_deeply( $hash1, $hash2 );
Cela fera passer le test.
Assurez-vous de réinitialiser l'annulation en indéfinissant $sub
ou le laisser sortir de son champ d'application, ou vous pourriez avoir de drôles de surprises si le reste de votre suite de tests utilise également Test::Deep.