Odd Devel::Покрытие "условия" с операторами Or (||) и Defined-Or (//)

  • Перл: 5,40
  • Разработка::Обложка: 1.44

Я писал несколько модульных тестов и решил попробовать Devel::Cover. Я вижу кое-что, что не могу объяснить, просматривая отчет об условном покрытии, включающий использование операторов «ИЛИ» (||) и «Определенное-ИЛИ» (//).

Это базовый код, который работает как положено:

use strict;
use warnings;

use 5.026;

my($DEF_MIN) = 1;
our($DEF_MAX) = 10;

sub test
{
    my($hashref) = @_;
    $hashref ||= {};

    my($min) = $hashref->{'min'} || 1;
    my($max) = $hashref->{'max'} // 10;

    say qq(MIN: $min / MAX: $max);

    return;
}

test();
test({});
test({ min => 14 });
test({ max => 14 });
test({ min => 10, max => 14 });

Когда я запускаю это, я получаю следующий отчет о состоянии:

Примерно то, что я ожидал.

Если я внесу эти изменения:

my($min) = $hashref->{'min'} || $DEF_MIN;
my($max) = $hashref->{'max'} // $DEF_MAX;

то вместо этого я получаю этот отчет:

Почему вместо просто столбца A заменены столбцы A и B? Как я могу завершить покрытие или пометить его как не покрываемое?

Как можно видеть, не имеет значения, использую ли я || или //, и не имеет значения, является ли правая часть лексической или пакетной переменной.

Если кто-нибудь знает, что означает заголовок столбца dec?

Joe Casadonte 17.08.2024 19:59

Вероятное решение, т.е. результат логической операции

ikegami 17.08.2024 20:09
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
2
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Следующее определяет работу ||:

А Б Результат А неверно Любое значение Б А верно Не оценено А

Ваш тест охватывает оба этих пути. В рамках этой модели у вас будет полное покрытие. Однако Devel::Cover использует другую модель.

А Б Результат А неверно Б неверно Б А неверно Б верно Б А верно Не оценено А

Выражение «полностью покрыто» учитывается только в том случае, если во время теста были посещены все три пути. Это имеет смысл в логическом контексте, но здесь || используется вне логического контекста.

Поскольку вы не запустили свой код с ложным значением $DEF_MIN, первый путь не был посещен, и покрытие считается неполным.

Когда операнд является литералом, он исключает путь, по которому он ожидал бы, что истинный литерал окажется ложным, поскольку его невозможно охватить, и удаляет его. (То же самое происходит, когда он ожидает, что ложный литерал будет истинным.) Вот почему при использовании литерала на один столбец меньше.

Это имеет большой смысл - спасибо. Есть ли способ пометить его как необнаружимый?

Joe Casadonte 17.08.2024 22:52

Я подозреваю, что использование константы (use constant DEF_MIN => ...;) решит проблему.

ikegami 18.08.2024 00:38

Другие вопросы по теме