refactor: move broken fixtures into skill directory, remove global fixtures/

fixture: paths now resolve relative to skill's cases/ dir, not global.
Each validate skill keeps its broken fixtures locally.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-03-28 13:31:34 +03:00
co-authored by Claude Opus 4.6
parent 671be7c6b5
commit 74b3f76a32
4 changed files with 9 additions and 9 deletions
+3 -4
View File
@@ -52,7 +52,7 @@ Exit code: 0 = все прошли, 1 = есть падения.
| Поле | Описание | | Поле | Описание |
|---|---| |---|---|
| `script` | Путь от `.claude/skills/`, без расширения. Раннер добавит `.ps1` (по умолчанию) или `.py` | | `script` | Путь от `.claude/skills/`, без расширения. Раннер добавит `.ps1` (по умолчанию) или `.py` |
| `setup` | Фикстура: `"empty-config"`, `"base-config"`, `"none"`, `"fixture:<name>"` | | `setup` | Фикстура: `"empty-config"`, `"base-config"`, `"none"`, `"fixture:<name>"` (из `fixtures/` папки навыка) |
| `args` | Маппинг параметров навыка (см. ниже) | | `args` | Маппинг параметров навыка (см. ниже) |
| `snapshot` | Настройки сравнения: `root` (`"workDir"` или `"outputPath"`) и `normalizeUuids` | | `snapshot` | Настройки сравнения: `root` (`"workDir"` или `"outputPath"`) и `normalizeUuids` |
@@ -184,13 +184,12 @@ tests/skills/
runner.mjs # тест-раннер runner.mjs # тест-раннер
README.md # этот файл README.md # этот файл
.cache/ # кэш фикстур (в .gitignore) .cache/ # кэш фикстур (в .gitignore)
fixtures/ # broken-фикстуры для тестов валидаторов
broken/
<имя>/ # сломанный XML для негативных тестов validate-навыков
cases/ cases/
<навык>/ <навык>/
_skill.json # конфиг навыка _skill.json # конфиг навыка
<кейс>.json # тестовый случай <кейс>.json # тестовый случай
snapshots/ snapshots/
<кейс>/ # эталон <кейс>/ # эталон
fixtures/ # broken-фикстуры (для validate-навыков)
<имя>/ # сломанный XML, ссылка: "setup": "fixture:<имя>"
``` ```
@@ -1,6 +1,6 @@
{ {
"name": "Валидатор находит ошибку: неверный корневой элемент", "name": "Валидатор находит ошибку: неверный корневой элемент",
"setup": "fixture:broken/catalog-bad-root", "setup": "fixture:catalog-bad-root",
"params": { "objectPath": "Catalogs/Bad.xml" }, "params": { "objectPath": "Catalogs/Bad.xml" },
"expectError": true "expectError": true
} }
+5 -4
View File
@@ -15,7 +15,6 @@ const REPO_ROOT = resolve(ROOT, '../..');
const SKILLS = resolve(REPO_ROOT, '.claude/skills'); const SKILLS = resolve(REPO_ROOT, '.claude/skills');
const CASES = resolve(ROOT, 'cases'); const CASES = resolve(ROOT, 'cases');
const CACHE = resolve(ROOT, '.cache'); const CACHE = resolve(ROOT, '.cache');
const FIXTURES = resolve(ROOT, 'fixtures');
// ─── CLI args ─────────────────────────────────────────────────────────────── // ─── CLI args ───────────────────────────────────────────────────────────────
@@ -80,11 +79,12 @@ function discoverCases(filter) {
// ─── Setup / Fixtures ─────────────────────────────────────────────────────── // ─── Setup / Fixtures ───────────────────────────────────────────────────────
function ensureSetup(setupName, runtime) { function ensureSetup(setupName, runtime, skillCasesDir) {
if (setupName === 'none' || !setupName) return null; if (setupName === 'none' || !setupName) return null;
if (setupName.startsWith('fixture:')) { if (setupName.startsWith('fixture:')) {
const fixturePath = join(FIXTURES, setupName.slice('fixture:'.length)); // Resolve relative to skill's cases directory (e.g. cases/meta-validate/fixtures/...)
const fixturePath = join(skillCasesDir, 'fixtures', setupName.slice('fixture:'.length));
if (!existsSync(fixturePath)) throw new Error(`Fixture not found: ${fixturePath}`); if (!existsSync(fixturePath)) throw new Error(`Fixture not found: ${fixturePath}`);
return fixturePath; return fixturePath;
} }
@@ -331,7 +331,8 @@ function runCase(testCase, opts) {
try { try {
// 1. Setup workspace // 1. Setup workspace
const fixturePath = ensureSetup(setupName, opts.runtime); const skillCasesDir = join(CASES, testCase.skillDir);
const fixturePath = ensureSetup(setupName, opts.runtime, skillCasesDir);
workDir = createWorkspace(fixturePath); workDir = createWorkspace(fixturePath);
// 2. Pre-run steps (setup prerequisites like creating objects) // 2. Pre-run steps (setup prerequisites like creating objects)