Вы можете использовать Test::Deep, который предоставляет cmp_deeply
. Он намного более универсален, чем is_deeply
Test::More.
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, );
Хитрость заключается в bag()
функции, которая игнорирует порядок элементов.
Это делает сравнение пакетов, то есть сравнивает два массива, но игнорирует порядок элементов [...]
Обновление: из вашего комментария а>:
Как мне динамически упаковать все ссылки на массив внутри хэша
Некоторое копание в коде Test::Deep показало, что его можно перезаписать. Я посмотрел на Test::Deep сам и обнаружил, что существует Test::Deep::Array, который работает с массивами. Все пакеты, которые обрабатывают вещи внутри T::D, имеют метод descend
< /а>. Так вот где нам нужно зацепиться.
Sub::Override отлично подходит для временного переопределения вещей, вместо того, чтобы возиться с typeglobs.
По сути, все, что нам нужно сделать, это заменить вызов Test::Deep::arrayelementsonly
в последней строке Test::Deep::Array::descend
вызовом bag()
. Остальное просто копируется (отступ мой). Для небольших monkey-patch копия существующего кода с небольшой модификацией обычно является самым простым подходом. .
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 );
Это сделает тест пройденным.
Обязательно сбросьте переопределение, отменив определение $sub
или выпустив его из области действия, иначе вас могут ожидать странные сюрпризы, если остальная часть вашего набора тестов также использует Test::Deep.
person
simbabque
schedule
10.05.2016