Вы можете использовать Test::Deep, который обеспечивает cmp_deeply
. Это намного более универсальный, чем Test :: More's 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,);
Трюк bag()
function, который игнорирует порядок элементов.
Это делает сравнение мешок, который он сравнивает два массива, но игнорирует порядок элементов [...]
Update: От your comment:
Как суммировать все массивные ссылки внутри хэш динамически
Некоторые копания в коде Test :: Deep показали, что его можно перезаписать. Сначала я посмотрел at Test::Deep и обнаружил, что есть Test::Deep::Array, в котором рассматриваются массивы. Все пакеты, которые обрабатывают вещи внутри T :: D, имеют a descend
method. Так вот где нам нужно зацепить.
Sub::Override отлично подходит для временного переопределения вещей, вместо того, чтобы возиться с typeglobs.
В основном все, что нам нужно сделать, это заменить вызов на Test::Deep::arrayelementsonly
в окончательной строке Test::Deep::Array::descend
с вызовом bag()
. Остальное просто скопировано (отступы мои). Для небольших monkey-patching копия существующего кода с небольшой модификацией, как правило, является самым легким подходом.
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.
Спасибо simbabque за ответ, Как суммировать все массивные ссылки внутри хэша динамически. $ hash2 выводится и содержит вложенный хеш, как я могу динамически сказать cmp_deeply, что любое сравнение массива должно выполняться через сумку, или я должен пересекать хэш и делать сравнения отдельных сумм. – Girish
Спасибо @simbabque, Как я могу суммировать все массивные ссылки внутри хеша динамически. 'my $ arr_of_h1 = {'a' => [1, 2, 3], b => [{2 => 1}, {1 => 1}, {3 => 1}]};' ' my $ arr_of_h2 = {'a' => [1, 2, 3], b => [{2 => 1}, {3 => 1}, {1 => 1}]}; ' ' cmp_deeply ($ arr_of_h1 -> {b}, bag (@ {$ arr_of_h2 -> {b}}), "Array равны"); ' Выше stmt работает, но ниже нужно работать, выполняя сравнения пакетов. 'cmp_deeply ($ arr_of_h1, $ arr_of_h2," Hash равны ");' – Girish
@user Я думаю, вам нужно будет это построить. Или, может быть, есть механизм зацепления. Вы читали полные документы Test :: Deep? В противном случае вы можете использовать https://metacpan.org/pod/Data::Visitor или что-то подобное для построения обхода. Я предлагаю вам задать новый вопрос для этого, так как он отличается от начального вопроса здесь. – simbabque