Строковые правила

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

Строковые правила в основном реализуются через механизм enforce, который предоставляет набор цепочечных методов для описания ограничений.


Базовая модель строковой проверки

Любая строковая проверка в Vest опирается на принцип:

  • входное значение рассматривается как неизменяемая строка;
  • каждое правило проверяется независимо;
  • результат каждого правила влияет только на состояние текущего теста.

Пример базовой проверки:

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

const validate = suite((data = {}) => {
  test('username', 'Имя пользователя обязательно', () => {
    enforce(data.username).isNotEmpty();
  });
});

Здесь строка username проверяется на непустое значение.


Обязательность строки и пустые значения

Одним из ключевых аспектов строковых правил является различие между undefined, null и пустой строкой.

Vest рассматривает их как отдельные случаи:

  • undefined — значение не передано;
  • null — явно отсутствующее значение;
  • "" — строка существует, но не содержит символов.

Проверка обязательности

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

Метод isNotEmpty() учитывает все три состояния и трактует их как нарушение.

Дополнительная проверка пробелов

Часто требуется исключить строки, содержащие только пробелы:

test('name', 'Имя не должно быть пустым', () => {
  enforce(data.name).trim().isNotEmpty();
});

Метод trim() нормализует строку перед проверкой.


Ограничение длины строки

Длина строки — одно из наиболее частых ограничений валидации.

Vest предоставляет явные методы для контроля диапазона длины.

Минимальная длина

test('password', 'Минимальная длина пароля 8 символов', () => {
  enforce(data.password).longerThanOrEquals(8);
});

Максимальная длина

test('title', 'Слишком длинный заголовок', () => {
  enforce(data.title).shorterThanOrEquals(120);
});

Диапазон длины

Комбинация двух правил:

test('nickname', 'Никнейм должен быть от 3 до 20 символов', () => {
  enforce(data.nickname).longerThanOrEquals(3);
  enforce(data.nickname).shorterThanOrEquals(20);
});

Сопоставление с шаблоном (регулярные выражения)

Регулярные выражения являются основным инструментом проверки формата строки.

Базовая проверка

test('phone', 'Некорректный номер телефона', () => {
  enforce(data.phone).matches(/^\+?[0-9]{10,15}$/);
});

Проверка структуры email

test('email', 'Некорректный email', () => {
  enforce(data.email).matches(/^[^\s@]+@[^\s@]+\.[^\s@]+$/);
});

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


Проверка содержания строки

Помимо формата, часто требуется анализ содержимого строки.

Наличие подстроки

test('bio', 'Описание должно содержать ключевое слово', () => {
  enforce(data.bio).contains('javascript');
});

Начало строки

test('code', 'Код должен начинаться с префикса JS-', () => {
  enforce(data.code).startsWith('JS-');
});

Конец строки

test('filename', 'Файл должен быть HTML', () => {
  enforce(data.filename).endsWith('.html');
});

Эти методы особенно полезны при работе с идентификаторами, путями и метаданными.


Нормализация строк перед проверкой

Строковые правила часто требуют предварительной очистки данных.

Удаление пробелов

enforce(data.username).trim().isNotEmpty();

Приведение регистра

Хотя Vest не навязывает конкретную стратегию нормализации, часто используется предварительное преобразование:

const normalized = data.email?.toLowerCase();

test('email', 'Email некорректен', () => {
  enforce(normalized).matches(/^[^\s@]+@[^\s@]+\.[^\s@]+$/);
});

Нормализация важна при сравнении строк, чувствительных к регистру.


Комбинирование строковых правил

Сила Vest заключается в возможности объединять правила без усложнения структуры.

test('username', 'Некорректное имя пользователя', () => {
  enforce(data.username).isNotEmpty();
  enforce(data.username).longerThanOrEquals(3);
  enforce(data.username).shorterThanOrEquals(20);
  enforce(data.username).matches(/^[a-zA-Z0-9_]+$/);
});

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


Кастомные строковые правила

При необходимости можно описывать собственные проверки.

test('slug', 'Slug должен быть уникальным форматом', () => {
  enforce(data.slug).satisfies((value) => {
    return /^[a-z0-9-]+$/.test(value);
  });
});

Метод satisfies позволяет внедрять произвольную логику, сохраняя совместимость с системой тестов Vest.


Условные проверки строк

Строковые правила часто зависят от контекста данных.

test('vat', 'VAT обязателен для компаний', () => {
  if (data.isCompany) {
    enforce(data.vat).isNotEmpty();
  }
});

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


Типичные ошибки при работе со строками

Игнорирование пробелов

enforce(data.name).isNotEmpty();

Строка " " будет считаться валидной, если не использовать trim().


Некорректная проверка длины

Ошибкой является проверка длины без учёта нормализации:

enforce(data.input.length).greaterThan(5);

Корректнее использовать встроенные методы строки через enforce.


Чрезмерная зависимость от регулярных выражений

Регулярные выражения часто усложняют поддержку кода. В Vest предпочтительнее комбинировать простые правила:

enforce(value).isNotEmpty();
enforce(value).longerThanOrEquals(3);

вместо одного сложного regex, если логика допускает разделение.


Структурирование строковых правил в больших формах

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

suite('UserForm', (data = {}) => {

  test('username', () => {
    enforce(data.username).isNotEmpty();
  });

  test('email', () => {
    enforce(data.email).matches(/^[^\s@]+@[^\s@]+\.[^\s@]+$/);
  });

  test('password', () => {
    enforce(data.password).longerThanOrEquals(8);
  });

});

Такой подход сохраняет читаемость и упрощает сопровождение логики валидации.