Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
5.4 KiB
Фикс наследия сплита: хардкод app/ в инструментах прогона тестов
Цель
После разделения управляющего слоя из проекта Лидерра часть инструментов прогона тестов
осталась с жёстко прописанным путём app/ — это подпапка layout'а Лидерры. В этом
репозитории папки app/ нет: конфиг сюиты лежит в корне (vitest.config.tools.mjs).
Из-за хардкода прогон одного тест-файла через tools/run-test-json.mjs не находит конфиг,
возвращает loadError, и по-критерийный зелёный (produce-criterion-greens) выходит
никогда не зелёным. Цель — выбирать корень и конфиг сюиты ОТ КОРНЯ репозитория (как уже
делает tools/produce-verify-receipt.mjs), единым источником истины, и эмпирически
проверить, подписывает ли производитель verify-расписки расписку при дочернем прогоне сюиты
в этом окружении.
Контракт buildVitestJsonArgs
Новая чистая экспортируемая функция в tools/run-test-json.mjs:
buildVitestJsonArgs(testFile, gitCwd, exists) → массив аргументов для npx:
['vitest', 'run', testFile, '--root', <root>, '--config', <config>, '--reporter', 'json'],
где <root> и <config> берутся из resolveVitestConfig(gitCwd, exists). Параметр exists
инъектируется (для теста), по умолчанию — existsSync. Функция чистая: никакого исполнения,
никакого fs кроме инъектируемого предиката.
Алгоритм
resolveVitestConfigимпортируется изtools/produce-verify-receipt.mjs— единый источник выбора: естьapp/vitest.config.tools.mjs→ app-режим (root=<repo>/app); иначе корень репозитория (root=<repo>,config=<repo>/vitest.config.tools.mjs).buildVitestJsonArgsстроит массив аргументов на основе результата (1).- I/O-функция
runVitestJsonвызываетbuildVitestJsonArgs(testFile, gitCwd)и передаёт результат вexecFileSync('npx', args, …)вместо захардкоженногоapp/. Разбор stdout (parseVitestJson) — без изменений.
Крайние случаи
- Есть
app/vitest.config.tools.mjs(layout Лидерры) →root=<repo>/app, config изapp— обратная совместимость сохранена. - Нет
app/-конфига (этот репозиторий) →root=<repo>, config из корня. existsинъектируем — выбор детерминирован и тестируем без файловой системы.
Конвенция заголовка
Шапка-комментарий модуля run-test-json сохраняет существующий стиль (назначение, анти-вакуум
SE-LB-1/11). Новая функция документируется одной строкой назначения над сигнатурой.
Диагностика производителя расписки
Эмпирически проверить под текущим окружением: запуск node tools/produce-verify-receipt.mjs
печатает signed GREEN (дочерний прогон сюиты отработал — выбор пути достаточен) либо
NOT signed: suite-not-passed (дочерний прогон не отработал — выбор пути верен, но нужна
отдельная стратегия прогона). Наблюдаемый исход фиксирует, достаточно ли одного выбора пути.
Граница задачи
В границах: миграция выбора конфига в run-test-json на resolveVitestConfig (через TDD) и
наблюдение исхода производителя расписки. ВНЕ границ: если дочерний прогон не отрабатывает —
сама стратегия прогона (чтение готового результата вместо своего прогона / неколлапсирующая
конфигурация пула воркеров) — отдельная задача; здесь не реализуется.
Критерий приёмки
- В построении аргументов прогона в
tools/run-test-json.mjsнет литерала'app'. buildVitestJsonArgsпокрыт тестами: app-режим и корневой режим (через инъекциюexists).- Полная сюита (
vitest.config.tools.mjs) зелёная.
[
{"id":"ax1","kind":"EXTRACTED","ref":"tools/run-test-json.mjs","anchor":"export function runVitestJson"},
{"id":"ax2","kind":"EXTRACTED","ref":"tools/produce-verify-receipt.mjs","anchor":"export function resolveVitestConfig"}
]