[Moscow.pm] Test::Deep: проверка необязательных ключей хеша

Maxim Vuets maxim.vuets на gmail.com
Чт Июл 19 03:43:24 PDT 2012


Привет!

Test::Deep строг в проверке хешей. Во-первых, все заявленные ключи должны
существовать, а их значения проходить проверку. Во-вторых, не должно быть
лишних ключей. Мне нужен компромисс: проверять значения ключей, но только если
они существуют (либо если их значения defined).

Есть ли уже готовый код для этого?

Я не нашёл, потому вижу следующее решение.

Написать свой SC (special comparison) (например,
Test::Deep::RequiredOptional), и использовать его для явного описания
обязательных и опциональных ключей примерно так:

    use Test::Deep::NoTest ':all';
    my ($ok, $stack) = cmp_details(
        {
            login       => 'jsmith',
            #password    => 'Hello1',
            age         => 24,
            #some       => 'rubbish',
        },
        req_opt(
            # Required keys
            {
                login       => re(qr/^[a-z0-9]+$/i),
                #password    => re(qr/^[\x21-\x7e]+$/),
            },
            # Optional keys
            {
                age         => code(sub {(shift || 0) >= 18}),
                color       => any(qw/red green blue/),
            }
        )
    );
    say $ok ? 'ok' : ('fail: ', deep_diag($stack));

Самая простая реализация такого SC будет транслировать $expected (просто
используя уже существующие тесты) в следующий код:

    all(
        superhashof({
            login       => re(qr/^[a-z0-9]+$/i),
            #password    => re(qr/^[\x21-\x7e]+$/),
        }),
        subhashof({
            login       => ignore(),
            #password    => ignore(),
            age         => code(sub {(shift || 0) >= 18}),
            color       => any(qw/red green blue/),
        }),
    )

Немного контекста. Я решаю проблему проверки сложной структуры, а не
написание тестов. Потому готов рассмотреть альтернативные модули. Пока
наиболее близкая альтернатива --- Params::Validate. Минус: делает только
одноуровневою проверку (можно проверить, что значение ключа HASHREF, но
не его содержимое). Контрплюс Test::Deep-а --- богатый декларативный
синтаксис.

Мысли, идеи, соображения?

-- 
maxim.vuets.name


Подробная информация о списке рассылки Moscow-pm