Архитектура валидации в библиотеке Vest строится вокруг декларативных правил, которые выполняются в контексте “сессии” тестов. Каждый набор правил (suite) представляет собой последовательность проверок, а middleware выступает промежуточным слоем, влияющим на выполнение, наблюдение и модификацию процесса тестирования.
Middleware в контексте Vest — это не отдельная сущность в классическом смысле серверных фреймворков, а концепция расширения поведения тестового цикла через перехват выполнения, управление состоянием и внедрение дополнительных правил без изменения основной логики валидации.
Внутренний процесс работы Vest можно представить как последовательность шагов:
Middleware внедряется между этими этапами и может:
Middleware в Vest можно рассматривать как функцию следующего вида:
(context, next) => {
// логика до выполнения тестов
const result = next();
// логика после выполнения тестов
return result;
}
Где:
context — объект текущей тестовой сессииnext — функция продолжения цепочки middlewareresult — результат выполнения текущего этапаКонтекст содержит ключевую информацию о текущем тесте:
Пример структуры:
{
field: "email",
value: "user@example.com",
tests: ["required", "email"],
errors: [],
meta: {
suiteName: "loginForm",
index: 2
}
}
Middleware может как читать, так и изменять эти данные.
Исполняется до запуска тестов.
Основные задачи:
Пример:
const trimMiddleware = (ctx, next) => {
if (typeof ctx.value === "string") {
ctx.value = ctx.value.trim();
}
return next();
};
Такой middleware гарантирует, что все тесты работают с очищенными данными, снижая количество ложных ошибок.
Встраивается непосредственно в процесс выполнения правил.
Используется для:
Пример условного пропуска:
const skipIfEmptyMiddleware = (ctx, next) => {
if (ctx.value === "") {
ctx.skip = true;
return ctx;
}
return next();
};
Выполняется после завершения всех тестов.
Задачи:
Пример:
const errorFormatterMiddleware = (ctx, next) => {
const result = next();
return {
...result,
errors: result.errors.map(e => ({
message: e,
field: ctx.field
}))
};
};
Middleware в Vest формируют цепочку выполнения, аналогичную
middleware-цепочкам в серверных фреймворках. Каждый слой получает
управление и обязан передать его дальше через next().
Порядок выполнения критичен:
Нарушение порядка может привести к неконсистентным результатам, особенно при асинхронных проверках.
Vest поддерживает асинхронные тесты, поэтому middleware также может быть асинхронным.
const asyncLoggerMiddleware = async (ctx, next) => {
await logToServer(ctx.field);
const result = await next();
await logResult(result);
return result;
};
Особенности:
next()Middleware может вмешиваться в поток выполнения тестов:
const stopOnFirstError = (ctx, next) => {
const result = next();
if (result.errors.length > 0) {
ctx.abort = true;
}
return result;
};
const conditionalMiddleware = (ctx, next) => {
if (ctx.meta.suiteName === "strictMode") {
return next();
}
ctx.skip = true;
return ctx;
};
Middleware подключается на уровне набора тестов:
suite("email", () => {
use(trimMiddleware);
use(skipIfEmptyMiddleware);
test("required", () => {
enforce(value => value.length > 0);
});
test("format", () => {
enforce(value => value.includes("@"));
});
});
Каждый вызов use() добавляет middleware в текущий стек
выполнения.
Если подключено несколько middleware, они выполняются последовательно:
use(A);
use(B);
use(C);
Фактический порядок:
Это двунаправленная модель, где каждый middleware оборачивает следующий.
Middleware должен учитывать возможные ошибки в тестах:
Пример безопасного middleware:
const safeMiddleware = async (ctx, next) => {
try {
return await next();
} catch (err) {
ctx.errors.push(err.message);
return ctx;
}
};
Middleware напрямую влияет на скорость выполнения suite.
Ключевые факторы:
Рекомендации архитектурного характера:
В Vest каждая suite должна оставаться изолированной. Middleware может нарушить изоляцию, если:
Корректная модель:
const isolatedMiddleware = (ctx, next) => {
const localState = { ...ctx.meta };
const result = next();
return result;
};
Middleware можно комбинировать для создания сложных цепочек поведения:
const composedMiddleware = compose([
trimMiddleware,
normalizeMiddleware,
loggingMiddleware
]);
Композиция позволяет:
За счёт middleware Vest превращается из простой библиотеки валидации в расширяемую систему правил, где поведение определяется не только тестами, но и окружением выполнения.
Через middleware можно реализовать: