From 8b38f8f78d543d11bd918e9162dafea16dff2ebb Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sat, 28 Mar 2026 13:44:37 +0300 Subject: [PATCH] feat: add mxl-* tests (batch 3), support cwd in skill config and preRun - mxl-compile, mxl-validate, mxl-info, mxl-decompile: 4 cases - runner: cwd option in _skill.json and preRun steps for skills that resolve OutputPath relative to current directory - Finding: mxl-compile only accepts relative OutputPath 21 tests across 9 skills, all passing. Co-Authored-By: Claude Opus 4.6 (1M context) --- tests/skills/cases/mxl-compile/_skill.json | 13 +++++++ .../cases/mxl-compile/simple-template.json | 18 +++++++++ .../snapshots/simple-template/Template.xml | 39 +++++++++++++++++++ tests/skills/cases/mxl-decompile/_skill.json | 11 ++++++ .../skills/cases/mxl-decompile/roundtrip.json | 13 +++++++ .../snapshots/roundtrip/Template.xml | 39 +++++++++++++++++++ tests/skills/cases/mxl-info/_skill.json | 11 ++++++ .../snapshots/template-overview/Template.xml | 39 +++++++++++++++++++ .../cases/mxl-info/template-overview.json | 13 +++++++ tests/skills/cases/mxl-validate/_skill.json | 11 ++++++ .../snapshots/valid-template/Template.xml | 39 +++++++++++++++++++ .../cases/mxl-validate/valid-template.json | 12 ++++++ tests/skills/runner.mjs | 13 ++++--- 13 files changed, 266 insertions(+), 5 deletions(-) create mode 100644 tests/skills/cases/mxl-compile/_skill.json create mode 100644 tests/skills/cases/mxl-compile/simple-template.json create mode 100644 tests/skills/cases/mxl-compile/snapshots/simple-template/Template.xml create mode 100644 tests/skills/cases/mxl-decompile/_skill.json create mode 100644 tests/skills/cases/mxl-decompile/roundtrip.json create mode 100644 tests/skills/cases/mxl-decompile/snapshots/roundtrip/Template.xml create mode 100644 tests/skills/cases/mxl-info/_skill.json create mode 100644 tests/skills/cases/mxl-info/snapshots/template-overview/Template.xml create mode 100644 tests/skills/cases/mxl-info/template-overview.json create mode 100644 tests/skills/cases/mxl-validate/_skill.json create mode 100644 tests/skills/cases/mxl-validate/snapshots/valid-template/Template.xml create mode 100644 tests/skills/cases/mxl-validate/valid-template.json diff --git a/tests/skills/cases/mxl-compile/_skill.json b/tests/skills/cases/mxl-compile/_skill.json new file mode 100644 index 00000000..1f25e9ac --- /dev/null +++ b/tests/skills/cases/mxl-compile/_skill.json @@ -0,0 +1,13 @@ +{ + "script": "mxl-compile/scripts/mxl-compile", + "setup": "none", + "cwd": "workDir", + "args": [ + { "flag": "-JsonPath", "from": "inputFile" }, + { "flag": "-OutputPath", "from": "case.outputPath" } + ], + "snapshot": { + "root": "workDir", + "normalizeUuids": false + } +} diff --git a/tests/skills/cases/mxl-compile/simple-template.json b/tests/skills/cases/mxl-compile/simple-template.json new file mode 100644 index 00000000..b61bf805 --- /dev/null +++ b/tests/skills/cases/mxl-compile/simple-template.json @@ -0,0 +1,18 @@ +{ + "name": "Простой макет с одной областью", + "input": { + "columns": 3, + "areas": [ + { + "name": "Заголовок", + "rows": [ + ["Наименование", "Количество", "Сумма"] + ] + } + ] + }, + "params": { "outputPath": "Template.xml" }, + "expect": { + "files": ["Template.xml"] + } +} diff --git a/tests/skills/cases/mxl-compile/snapshots/simple-template/Template.xml b/tests/skills/cases/mxl-compile/snapshots/simple-template/Template.xml new file mode 100644 index 00000000..c72484ff --- /dev/null +++ b/tests/skills/cases/mxl-compile/snapshots/simple-template/Template.xml @@ -0,0 +1,39 @@ + + + + ru + ru + + ru + Русский + Русский + + + + 3 + + + 0 + + true + + + true + 1 + 1 + 1 + + Заголовок + + Rows + 0 + 0 + -1 + -1 + + + + + 10 + + diff --git a/tests/skills/cases/mxl-decompile/_skill.json b/tests/skills/cases/mxl-decompile/_skill.json new file mode 100644 index 00000000..5781eec0 --- /dev/null +++ b/tests/skills/cases/mxl-decompile/_skill.json @@ -0,0 +1,11 @@ +{ + "script": "mxl-decompile/scripts/mxl-decompile", + "setup": "none", + "args": [ + { "flag": "-TemplatePath", "from": "workPath", "field": "templatePath" } + ], + "snapshot": { + "root": "workDir", + "normalizeUuids": false + } +} diff --git a/tests/skills/cases/mxl-decompile/roundtrip.json b/tests/skills/cases/mxl-decompile/roundtrip.json new file mode 100644 index 00000000..71f7344f --- /dev/null +++ b/tests/skills/cases/mxl-decompile/roundtrip.json @@ -0,0 +1,13 @@ +{ + "name": "Декомпиляция макета в JSON", + "preRun": [ + { + "script": "mxl-compile/scripts/mxl-compile", + "input": { "columns": 3, "areas": [{ "name": "Test", "rows": [["A", "B", "C"]] }] }, + "args": { "-JsonPath": "{inputFile}", "-OutputPath": "Template.xml" }, + "cwd": "{workDir}" + } + ], + "params": { "templatePath": "Template.xml" }, + "expect": { "stdoutContains": "columns" } +} diff --git a/tests/skills/cases/mxl-decompile/snapshots/roundtrip/Template.xml b/tests/skills/cases/mxl-decompile/snapshots/roundtrip/Template.xml new file mode 100644 index 00000000..38ea918a --- /dev/null +++ b/tests/skills/cases/mxl-decompile/snapshots/roundtrip/Template.xml @@ -0,0 +1,39 @@ + + + + ru + ru + + ru + Русский + Русский + + + + 3 + + + 0 + + true + + + true + 1 + 1 + 1 + + Test + + Rows + 0 + 0 + -1 + -1 + + + + + 10 + + diff --git a/tests/skills/cases/mxl-info/_skill.json b/tests/skills/cases/mxl-info/_skill.json new file mode 100644 index 00000000..f304d001 --- /dev/null +++ b/tests/skills/cases/mxl-info/_skill.json @@ -0,0 +1,11 @@ +{ + "script": "mxl-info/scripts/mxl-info", + "setup": "none", + "args": [ + { "flag": "-TemplatePath", "from": "workPath", "field": "templatePath" } + ], + "snapshot": { + "root": "workDir", + "normalizeUuids": false + } +} diff --git a/tests/skills/cases/mxl-info/snapshots/template-overview/Template.xml b/tests/skills/cases/mxl-info/snapshots/template-overview/Template.xml new file mode 100644 index 00000000..c72484ff --- /dev/null +++ b/tests/skills/cases/mxl-info/snapshots/template-overview/Template.xml @@ -0,0 +1,39 @@ + + + + ru + ru + + ru + Русский + Русский + + + + 3 + + + 0 + + true + + + true + 1 + 1 + 1 + + Заголовок + + Rows + 0 + 0 + -1 + -1 + + + + + 10 + + diff --git a/tests/skills/cases/mxl-info/template-overview.json b/tests/skills/cases/mxl-info/template-overview.json new file mode 100644 index 00000000..fd154e61 --- /dev/null +++ b/tests/skills/cases/mxl-info/template-overview.json @@ -0,0 +1,13 @@ +{ + "name": "Обзор макета", + "preRun": [ + { + "script": "mxl-compile/scripts/mxl-compile", + "input": { "columns": 3, "areas": [{ "name": "Заголовок", "rows": [["A", "B", "C"]] }] }, + "args": { "-JsonPath": "{inputFile}", "-OutputPath": "Template.xml" }, + "cwd": "{workDir}" + } + ], + "params": { "templatePath": "Template.xml" }, + "expect": { "stdoutContains": "Заголовок" } +} diff --git a/tests/skills/cases/mxl-validate/_skill.json b/tests/skills/cases/mxl-validate/_skill.json new file mode 100644 index 00000000..4233005e --- /dev/null +++ b/tests/skills/cases/mxl-validate/_skill.json @@ -0,0 +1,11 @@ +{ + "script": "mxl-validate/scripts/mxl-validate", + "setup": "none", + "args": [ + { "flag": "-TemplatePath", "from": "workPath", "field": "templatePath" } + ], + "snapshot": { + "root": "workDir", + "normalizeUuids": false + } +} diff --git a/tests/skills/cases/mxl-validate/snapshots/valid-template/Template.xml b/tests/skills/cases/mxl-validate/snapshots/valid-template/Template.xml new file mode 100644 index 00000000..38ea918a --- /dev/null +++ b/tests/skills/cases/mxl-validate/snapshots/valid-template/Template.xml @@ -0,0 +1,39 @@ + + + + ru + ru + + ru + Русский + Русский + + + + 3 + + + 0 + + true + + + true + 1 + 1 + 1 + + Test + + Rows + 0 + 0 + -1 + -1 + + + + + 10 + + diff --git a/tests/skills/cases/mxl-validate/valid-template.json b/tests/skills/cases/mxl-validate/valid-template.json new file mode 100644 index 00000000..acdda893 --- /dev/null +++ b/tests/skills/cases/mxl-validate/valid-template.json @@ -0,0 +1,12 @@ +{ + "name": "Корректный макет проходит валидацию", + "preRun": [ + { + "script": "mxl-compile/scripts/mxl-compile", + "input": { "columns": 3, "areas": [{ "name": "Test", "rows": [["A", "B", "C"]] }] }, + "args": { "-JsonPath": "{inputFile}", "-OutputPath": "Template.xml" }, + "cwd": "{workDir}" + } + ], + "params": { "templatePath": "Template.xml" } +} diff --git a/tests/skills/runner.mjs b/tests/skills/runner.mjs index b5a5bde4..80ab35ea 100644 --- a/tests/skills/runner.mjs +++ b/tests/skills/runner.mjs @@ -122,13 +122,14 @@ function resolveScript(scriptRelPath, runtime) { return full; } -function execSkillRaw(runtime, scriptPath, args) { +function execSkillRaw(runtime, scriptPath, args, cwd) { + const execCwd = cwd || REPO_ROOT; if (runtime === 'python') { return execFileSync(process.env.PYTHON || 'python', [scriptPath, ...args], { encoding: 'utf8', timeout: 60_000, stdio: ['pipe', 'pipe', 'pipe'], - cwd: REPO_ROOT, + cwd: execCwd, }); } // PowerShell @@ -139,7 +140,7 @@ function execSkillRaw(runtime, scriptPath, args) { encoding: 'utf8', timeout: 60_000, stdio: ['pipe', 'pipe', 'pipe'], - cwd: REPO_ROOT, + cwd: execCwd, }); } @@ -358,7 +359,8 @@ function runCase(testCase, opts) { } } try { - execSkillRaw(opts.runtime, preScript, preArgs); + const preCwd = step.cwd === '{workDir}' ? workDir : undefined; + execSkillRaw(opts.runtime, preScript, preArgs, preCwd); } catch (e) { throw new Error(`preRun step "${step.script}" failed: ${e.stderr || e.message}`); } @@ -377,7 +379,8 @@ function runCase(testCase, opts) { let stdout = '', stderr = '', exitCode = 0; try { - stdout = execSkillRaw(opts.runtime, scriptPath, args); + const execCwd = skillConfig.cwd === 'workDir' ? workDir : undefined; + stdout = execSkillRaw(opts.runtime, scriptPath, args, execCwd); } catch (e) { exitCode = e.status ?? 1; stdout = e.stdout || '';