Библиотека Vest построена вокруг декларативного описания правил валидации, где каждый набор проверок формируется как изолированная сущность, напоминающая unit-тесты. Такой подход делает систему расширяемой: новые возможности добавляются не через модификацию ядра, а через подключение внешних модулей, условно называемых плагинами.
Плагин в контексте Vest — это функция или набор функций, которые внедряются в процесс выполнения тест-сьюта и влияют на один или несколько этапов жизненного цикла валидации:
Ключевая особенность архитектуры заключается в том, что каждый тест внутри Vest имеет доступ к контексту выполнения, а значит, расширения могут работать не только на уровне входных данных, но и на уровне результатов.
Базовая форма плагина сводится к функции, принимающей контекст выполнения и возвращающей расширение поведения.
Контекст обычно содержит:
Типовая структура:
const myPlugin = (context) => {
return {
name: 'my-plugin',
setup() {
// инициализация
},
onRun(rule, value) {
// логика перед выполнением правила
},
onResult(result) {
// модификация результата
}
};
};
Такой подход позволяет внедрять расширения без изменения ядра библиотеки.
Vest не предполагает глобального состояния как обязательного условия работы. Плагины подключаются локально к конкретному тест-сьюту или набору правил.
Пример интеграции:
import { create, test } from 'vest';
const suite = create((data, use) => {
use(myPlugin);
test('username', 'required', () => {
// проверка
});
});
В момент вызова use плагин регистрируется в текущем
контексте выполнения и становится частью цепочки обработки.
Каждый последующий test проходит через слой расширений,
что позволяет влиять на:
Внутренняя модель выполнения Vest представляет собой последовательность шагов, каждый из которых может быть расширен.
Инициализация сьюта
Регистрация теста
Выполнение теста
Формирование результата
Финализация отчёта
Перехват этих этапов реализуется через хуки:
const plugin = () => ({
onStart() {},
onTestStart(test) {},
onTestEnd(testResult) {},
onFinish(report) {}
});
Такая модель делает плагины сопоставимыми с middleware-подходом.
Одной из ключевых возможностей является добавление новых типов валидаторов без изменения ядра.
Плагин может регистрировать собственные правила:
const customRulePlugin = () => ({
rules: {
isUUID: (value) => {
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);
}
}
});
После регистрации такие правила становятся доступны внутри тестов:
test('id', 'invalid uuid', () => {
enforce(data.id).isUUID();
});
Подобный механизм позволяет формировать доменно-специфичные наборы проверок, не перегружая основной API.
Результат работы Vest представляет собой структурированный отчёт, содержащий:
Плагины могут изменять этот отчёт до его возврата:
const reportPlugin = () => ({
onFinish(report) {
return {
...report,
timestamp: Date.now(),
formattedErrors: Object.entries(report.errors)
};
}
});
Это особенно важно при интеграции с внешними системами, где требуется специфический формат данных.
Некоторые расширения требуют асинхронной логики, например обращения к серверу или базе данных.
Vest поддерживает асинхронное выполнение тестов, что позволяет плагинам работать в таком же режиме:
const asyncPlugin = () => ({
async onTestStart(test) {
const result = await fetch(`/api/rules/${test.name}`);
test.metadata.remoteRule = await result.json();
}
});
Асинхронные плагины влияют на порядок выполнения и могут вводить дополнительные ожидания между тестами.
Несколько плагинов могут работать одновременно, формируя цепочку обработки.
Порядок их подключения влияет на результат, поскольку каждый следующий плагин получает уже модифицированный контекст.
use(pluginA);
use(pluginB);
use(pluginC);
Возможные конфликты решаются через:
Плагины часто используются для адаптации Vest под конкретные экосистемы.
Типовые сценарии:
Пример адаптера:
const apiPlugin = () => ({
onFinish(report) {
return {
status: report.valid ? 'ok' : 'error',
errors: report.errors
};
}
});
Главный принцип работы плагинов заключается в доступе к общему контексту выполнения.
Контекст может включать:
Благодаря этому плагины могут не только модифицировать поведение, но и взаимодействовать друг с другом через общую среду.
Несмотря на гибкость, система плагинов имеет ограничения:
Эти ограничения являются следствием высокой степени расширяемости архитектуры.
На практике выделяются несколько устойчивых подходов:
Модификация существующих правил без изменения их логики.
Последовательная обработка тестов через цепочку функций.
Приведение результатов Vest к внешним форматам.
Замена алгоритмов валидации в зависимости от условий.
Поскольку плагины могут выполнять произвольный код, важно учитывать уровень изоляции:
Архитектурно Vest предполагает, что ответственность за безопасное поведение расширений лежит на уровне их реализации.