From ce7238792ef12fabdef4a564ff0520ce34db4496 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Thu, 24 Sep 2026 18:08:20 +0300 Subject: [PATCH] =?UTF-8?q?test(runner):=20=D1=88=D0=B0=D0=B3=20preRun=20g?= =?UTF-8?q?it=20=D0=B4=D0=BB=D1=8F=20=D0=BA=D0=B5=D0=B9=D1=81=D0=BE=D0=B2?= =?UTF-8?q?=20=D1=81=20=D1=80=D0=B5=D0=BF=D0=BE=D0=B7=D0=B8=D1=82=D0=BE?= =?UTF-8?q?=D1=80=D0=B8=D0=B5=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Кейсы навыков, читающих изменения из git, строят репозиторий шагом { "git": [...] }. Общая реализация для runner.mjs и verify-snapshots.mjs в tests/common/git-step.mjs — настройки машины на фикстуру не влияют. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01ANXwbMUhuRFSCsq2RgmTTm --- tests/common/git-step.mjs | 14 ++++++++++++++ tests/skills/README.md | 2 ++ tests/skills/runner.mjs | 7 +++++++ tests/skills/verify-snapshots.mjs | 9 ++++++++- 4 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 tests/common/git-step.mjs diff --git a/tests/common/git-step.mjs b/tests/common/git-step.mjs new file mode 100644 index 000000000..0d16e2625 --- /dev/null +++ b/tests/common/git-step.mjs @@ -0,0 +1,14 @@ +// Шаг preRun `git` — общий для runner.mjs и verify-snapshots.mjs, чтобы оба раннера строили +// одинаковый репозиторий. Настройки машины не влияют: автор коммита задан, перевод строк и +// подпись коммитов выключены. +import { execFileSync } from 'child_process'; + +const GIT_STEP_CONFIG = [ + '-c', 'user.name=test', '-c', 'user.email=test@example.com', + '-c', 'core.autocrlf=false', '-c', 'core.safecrlf=false', + '-c', 'commit.gpgsign=false', '-c', 'init.defaultBranch=main', +]; + +export function runGitStep(workDir, args) { + execFileSync('git', [...GIT_STEP_CONFIG, ...args], { cwd: workDir, stdio: 'pipe' }); +} diff --git a/tests/skills/README.md b/tests/skills/README.md index c558949d4..4738eaf09 100644 --- a/tests/skills/README.md +++ b/tests/skills/README.md @@ -478,6 +478,8 @@ ibcmd-проход автоматически `○ skipped`, если рядом |---|---| | `{ "script": "<навык>/scripts/<файл>", "input": {...}, "args": { "-Flag": "{inputFile}" } }` | Прогон другого навыка для подготовки фикстуры. Плейсхолдеры: `{inputFile}`, `{workDir}` | | `{ "writeFile": { "path": "<путь>", "content": "<строка или объект>" } }` | Записать произвольный файл в `workDir` (объект сериализуется в JSON). Ключ `"executable": true` ставит бит исполнения — нужен фейку платформы на *nix, где навык запускает её через `exec`; на Windows no-op | +| `{ "deletePath": "<путь>" }` | Удалить файл или каталог в `workDir` — состояние «файла нет», которое навыки сами не создают | +| `{ "git": ["<аргумент>", ...] }` | Выполнить `git` с аргументами в `workDir` — репозиторий для навыков, читающих изменения из git. Автор коммита задан, `core.autocrlf` выключен | Дополнительно у шага-скрипта: `"cwd": "{workDir}"` — запустить шаг из рабочего каталога. Нужно, когда относительный путь в `args` (напр. `-OutputPath: "Template.xml"`) должен лечь в фикстуру, а diff --git a/tests/skills/runner.mjs b/tests/skills/runner.mjs index 7f4be4eab..1a92b99d4 100644 --- a/tests/skills/runner.mjs +++ b/tests/skills/runner.mjs @@ -12,6 +12,7 @@ import { tmpdir, cpus } from 'os'; // есть не-ASCII символы — кириллическое имя пользователя в %TEMP%, кириллическое имя объекта 1С // в deletePath. Подробности и таблица сборок — в самом модуле. import { removePathSync, copyTreeSync } from '../common/fsutil.mjs'; +import { runGitStep } from '../common/git-step.mjs'; // ─── Paths ────────────────────────────────────────────────────────────────── @@ -869,6 +870,12 @@ async function runCaseAsync(testCase, opts) { removePathSync(join(workDir, step.deletePath)); continue; } + // git step — git-команда в workDir: так строится репозиторий для навыков, читающих + // изменения из git (общая реализация с verify-snapshots — tests/common/git-step.mjs). + if (step.git) { + runGitStep(workDir, step.git); + continue; + } const preScript = resolveScript(step.script, opts.runtime); const preArgs = []; for (const [flag, value] of Object.entries(step.args || {})) { diff --git a/tests/skills/verify-snapshots.mjs b/tests/skills/verify-snapshots.mjs index 768e0ad6e..ce021829d 100644 --- a/tests/skills/verify-snapshots.mjs +++ b/tests/skills/verify-snapshots.mjs @@ -20,6 +20,7 @@ import { tmpdir } from 'os'; // fs.rmSync/fs.cpSync напрямую не зовём: на Windows они молча ничего не делают, когда в пути // есть не-ASCII символы. Подробности и таблица сборок — в самом модуле. import { removePathSync, copyTreeSync } from '../common/fsutil.mjs'; +import { runGitStep } from '../common/git-step.mjs'; // ─── Paths ────────────────────────────────────────────────────────────────── @@ -646,8 +647,14 @@ function runPreSteps(preRun, workDir, runtime, log) { log(`preRun: deletePath ${step.deletePath}`, true); continue; } + // git step — как в runner.mjs: репозиторий для навыков, читающих изменения из git. + if (step.git) { + runGitStep(workDir, step.git); + log(`preRun: git ${step.git.join(' ')}`, true); + continue; + } if (!step.script) { - throw new Error(`preRun: шаг без script/writeFile/deletePath — ${JSON.stringify(step).slice(0, 120)}`); + throw new Error(`preRun: шаг без script/writeFile/deletePath/git — ${JSON.stringify(step).slice(0, 120)}`); } const preArgs = []; for (const [flag, value] of Object.entries(step.args || {})) {