hasErrors, hasWarnings

Vest реализует декларативный подход к валидации данных, в котором правила группируются в тестовые сьюты, а результат вычисления представляет собой структурированное дерево состояний. Одной из ключевых особенностей является разделение результатов валидации на ошибки и предупреждения, что позволяет строить более гибкую бизнес-логику: не только блокировать некорректные данные, но и сигнализировать о потенциальных проблемах.

Система результатов валидации в Vest построена вокруг двух независимых потоков:

  • ошибки (errors) — нарушения, которые делают данные недопустимыми
  • предупреждения (warnings) — отклонения от рекомендаций, не блокирующие выполнение

Такой подход позволяет разделять критические и некритические состояния формы или данных.

Внутренне результат выполнения теста формируется как объект, содержащий структурированную информацию по каждому полю, включая агрегированные флаги состояния:

  • hasErrors
  • hasWarnings

Эти флаги являются производными от результатов выполнения всех правил валидации и используются для быстрого определения общего состояния набора данных.

hasErrors

hasErrors — это булевый индикатор, который показывает наличие хотя бы одной критической ошибки в наборе валидационных результатов.

Если хотя бы один тест вернул ошибку, значение hasErrors становится true.

Логика вычисления

Обобщённо поведение можно представить следующим образом:

  • если существует хотя бы один field с error → hasErrors = true
  • если ошибок нет ни в одном поле → hasErrors = false

Практическое значение

hasErrors используется в сценариях, где необходимо строго запретить дальнейшее выполнение операций:

  • отправка формы на сервер
  • сохранение данных
  • переход к следующему шагу мастера
  • выполнение бизнес-операций

Пример поведения

Если задан набор правил:

  • email должен быть валидным
  • пароль должен содержать минимум 8 символов

И email не проходит проверку, результат будет:

  • hasErrors: true
  • поле email содержит сообщение ошибки
  • поле password остаётся валидным

Особенности

hasErrors не учитывает предупреждения. Даже если присутствует множество warning-сообщений, но отсутствуют ошибки, значение останется false.

Это делает флаг строго бинарным индикатором критичности состояния.

hasWarnings

hasWarnings отражает наличие некритических отклонений от рекомендуемых правил.

В отличие от ошибок, warnings не блокируют выполнение логики, но сигнализируют о потенциальных проблемах или нежелательных паттернах.

Логика вычисления

  • если хотя бы один warning присутствует → hasWarnings = true
  • если warning отсутствуют → hasWarnings = false

Назначение предупреждений

Warnings применяются для:

  • подсказок пользователю (например, слабый пароль)
  • рекомендаций по улучшению данных
  • уведомлений о нежелательных форматах
  • бизнес-правил, которые не являются обязательными

Пример сценария

Пароль соответствует минимальным требованиям, но:

  • отсутствуют спецсимволы
  • пароль слишком распространён

В этом случае:

  • hasErrors = false
  • hasWarnings = true

Система может разрешить отправку формы, но показать рекомендации по улучшению безопасности.

Отличие от ошибок

Ключевое различие:

  • errors блокируют процесс
  • warnings не блокируют процесс

Это разделение позволяет строить UX с постепенным улучшением данных без жёстких ограничений.

Взаимодействие hasErrors и hasWarnings

Оба флага могут существовать одновременно, но описывают разные уровни состояния:

  • hasErrors = true, hasWarnings = true Данные некорректны и одновременно содержат рекомендации

  • hasErrors = true, hasWarnings = false Данные строго некорректны без дополнительных предупреждений

  • hasErrors = false, hasWarnings = true Данные допустимы, но требуют улучшения

  • hasErrors = false, hasWarnings = false Полностью корректные данные

Такое разделение позволяет формировать многослойную систему обратной связи.

Пример использования в Vest

import { suite, test, enforce } from 'vest';

const validateUser = (data) => {
  return suite('user_validation', () => {

    test('email', 'Email обязателен', () => {
      enforce(data.email).isNotEmpty();
    });

    test('email', 'Email должен быть корректным', () => {
      enforce(data.email).matches(/.+@.+\..+/);
    });

    test('password', () => {
      if (data.password && data.password.length < 8) {
        warn('Пароль слишком короткий');
      }

      enforce(data.password).isNotEmpty();
    });

  });
};

В результате выполнения такого сьюта:

  • если email пустой → hasErrors = true
  • если пароль короткий → hasWarnings = true
  • итоговый объект содержит оба флага независимо

Роль в архитектуре формы

В приложениях с использованием Vest флаги hasErrors и hasWarnings часто применяются на разных уровнях:

UI уровень

  • блокировка кнопки отправки при hasErrors
  • отображение желтых подсказок при hasWarnings

Логический уровень

  • предотвращение API-запросов при ошибках
  • логирование предупреждений для аналитики

Серверная синхронизация

  • ошибки могут быть дублированы серверной валидацией
  • warnings могут использоваться для телеметрии качества данных

Состояние выполнения сьютов

При каждом запуске сьюта Vest пересчитывает:

  • индивидуальные результаты тестов
  • агрегированные поля по каждому ключу
  • глобальные индикаторы состояния

hasErrors и hasWarnings являются производными от всей структуры, а не от отдельных тестов, что делает их устойчивыми к изменению внутренней реализации правил.

Важные особенности поведения

  • значения обновляются при каждом rerun сьюта
  • warnings не влияют на errors
  • порядок тестов не влияет на итоговые флаги
  • флаги агрегируются по всей структуре данных, а не по одному полю

Такая модель позволяет использовать Vest как систему декларативной валидации с многоуровневой семантикой состояния данных.