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) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-03-28 13:44:37 +03:00
parent 74b3f76a32
commit 8b38f8f78d
13 changed files with 266 additions and 5 deletions
@@ -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
}
}
@@ -0,0 +1,18 @@
{
"name": "Простой макет с одной областью",
"input": {
"columns": 3,
"areas": [
{
"name": "Заголовок",
"rows": [
["Наименование", "Количество", "Сумма"]
]
}
]
},
"params": { "outputPath": "Template.xml" },
"expect": {
"files": ["Template.xml"]
}
}
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<document xmlns="http://v8.1c.ru/8.2/data/spreadsheet" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<languageSettings>
<currentLanguage>ru</currentLanguage>
<defaultLanguage>ru</defaultLanguage>
<languageInfo>
<id>ru</id>
<code>Русский</code>
<description>Русский</description>
</languageInfo>
</languageSettings>
<columns>
<size>3</size>
</columns>
<rowsItem>
<index>0</index>
<row>
<empty>true</empty>
</row>
</rowsItem>
<templateMode>true</templateMode>
<defaultFormatIndex>1</defaultFormatIndex>
<height>1</height>
<vgRows>1</vgRows>
<namedItem xsi:type="NamedItemCells">
<name>Заголовок</name>
<area>
<type>Rows</type>
<beginRow>0</beginRow>
<endRow>0</endRow>
<beginColumn>-1</beginColumn>
<endColumn>-1</endColumn>
</area>
</namedItem>
<font faceName="Arial" height="10" bold="false" italic="false" underline="false" strikeout="false" kind="Absolute" scale="100"/>
<format>
<width>10</width>
</format>
</document>
@@ -0,0 +1,11 @@
{
"script": "mxl-decompile/scripts/mxl-decompile",
"setup": "none",
"args": [
{ "flag": "-TemplatePath", "from": "workPath", "field": "templatePath" }
],
"snapshot": {
"root": "workDir",
"normalizeUuids": false
}
}
@@ -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" }
}
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<document xmlns="http://v8.1c.ru/8.2/data/spreadsheet" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<languageSettings>
<currentLanguage>ru</currentLanguage>
<defaultLanguage>ru</defaultLanguage>
<languageInfo>
<id>ru</id>
<code>Русский</code>
<description>Русский</description>
</languageInfo>
</languageSettings>
<columns>
<size>3</size>
</columns>
<rowsItem>
<index>0</index>
<row>
<empty>true</empty>
</row>
</rowsItem>
<templateMode>true</templateMode>
<defaultFormatIndex>1</defaultFormatIndex>
<height>1</height>
<vgRows>1</vgRows>
<namedItem xsi:type="NamedItemCells">
<name>Test</name>
<area>
<type>Rows</type>
<beginRow>0</beginRow>
<endRow>0</endRow>
<beginColumn>-1</beginColumn>
<endColumn>-1</endColumn>
</area>
</namedItem>
<font faceName="Arial" height="10" bold="false" italic="false" underline="false" strikeout="false" kind="Absolute" scale="100"/>
<format>
<width>10</width>
</format>
</document>
+11
View File
@@ -0,0 +1,11 @@
{
"script": "mxl-info/scripts/mxl-info",
"setup": "none",
"args": [
{ "flag": "-TemplatePath", "from": "workPath", "field": "templatePath" }
],
"snapshot": {
"root": "workDir",
"normalizeUuids": false
}
}
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<document xmlns="http://v8.1c.ru/8.2/data/spreadsheet" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<languageSettings>
<currentLanguage>ru</currentLanguage>
<defaultLanguage>ru</defaultLanguage>
<languageInfo>
<id>ru</id>
<code>Русский</code>
<description>Русский</description>
</languageInfo>
</languageSettings>
<columns>
<size>3</size>
</columns>
<rowsItem>
<index>0</index>
<row>
<empty>true</empty>
</row>
</rowsItem>
<templateMode>true</templateMode>
<defaultFormatIndex>1</defaultFormatIndex>
<height>1</height>
<vgRows>1</vgRows>
<namedItem xsi:type="NamedItemCells">
<name>Заголовок</name>
<area>
<type>Rows</type>
<beginRow>0</beginRow>
<endRow>0</endRow>
<beginColumn>-1</beginColumn>
<endColumn>-1</endColumn>
</area>
</namedItem>
<font faceName="Arial" height="10" bold="false" italic="false" underline="false" strikeout="false" kind="Absolute" scale="100"/>
<format>
<width>10</width>
</format>
</document>
@@ -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": "Заголовок" }
}
@@ -0,0 +1,11 @@
{
"script": "mxl-validate/scripts/mxl-validate",
"setup": "none",
"args": [
{ "flag": "-TemplatePath", "from": "workPath", "field": "templatePath" }
],
"snapshot": {
"root": "workDir",
"normalizeUuids": false
}
}
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<document xmlns="http://v8.1c.ru/8.2/data/spreadsheet" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<languageSettings>
<currentLanguage>ru</currentLanguage>
<defaultLanguage>ru</defaultLanguage>
<languageInfo>
<id>ru</id>
<code>Русский</code>
<description>Русский</description>
</languageInfo>
</languageSettings>
<columns>
<size>3</size>
</columns>
<rowsItem>
<index>0</index>
<row>
<empty>true</empty>
</row>
</rowsItem>
<templateMode>true</templateMode>
<defaultFormatIndex>1</defaultFormatIndex>
<height>1</height>
<vgRows>1</vgRows>
<namedItem xsi:type="NamedItemCells">
<name>Test</name>
<area>
<type>Rows</type>
<beginRow>0</beginRow>
<endRow>0</endRow>
<beginColumn>-1</beginColumn>
<endColumn>-1</endColumn>
</area>
</namedItem>
<font faceName="Arial" height="10" bold="false" italic="false" underline="false" strikeout="false" kind="Absolute" scale="100"/>
<format>
<width>10</width>
</format>
</document>
@@ -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" }
}
+8 -5
View File
@@ -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 || '';