From 0778cc89ee25aa9096bb732624b4319c0bd2aa6f Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sun, 29 Mar 2026 17:09:33 +0300 Subject: [PATCH] feat: post-run validation + integration tests for skill pipeline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - runner.mjs v0.4: --with-validation flag runs validators on real output - postValidate config in 20 _skill.json files (maps skill → validator) - validatePath in ~100 positive test cases - skipValidation for 5 cross-reference cases (isolated workspace limitation) - Integration tests: build-config (19 steps), build-epf (6), build-cfe (4) - base-config cache from build-config for downstream tests - Fix chart-of-calculation-types test data (DependenceOnCalculationTypes) - 285/285 unit + 3/3 integration, all green with validation Co-Authored-By: Claude Opus 4.6 (1M context) --- tests/skills/cases/cf-edit/_skill.json | 3 +- tests/skills/cases/cf-init/_skill.json | 3 +- tests/skills/cases/cfe-borrow/_skill.json | 3 +- tests/skills/cases/cfe-init/_skill.json | 3 +- .../skills/cases/cfe-init/addon-purpose.json | 1 + tests/skills/cases/cfe-init/basic.json | 1 + tests/skills/cases/cfe-init/no-role.json | 1 + .../skills/cases/cfe-init/patch-purpose.json | 1 + tests/skills/cases/cfe-init/with-prefix.json | 1 + .../cases/cfe-init/with-version-vendor.json | 1 + .../skills/cases/cfe-patch-method/_skill.json | 3 +- tests/skills/cases/epf-add-form/_skill.json | 3 +- tests/skills/cases/epf-add-form/basic.json | 3 +- .../skills/cases/epf-add-form/main-form.json | 3 +- .../skills/cases/epf-add-form/named-form.json | 3 +- .../cases/epf-add-form/second-form.json | 3 +- tests/skills/cases/epf-init/_skill.json | 3 +- tests/skills/cases/epf-init/basic.json | 1 + tests/skills/cases/epf-init/latin-name.json | 1 + tests/skills/cases/epf-init/minimal.json | 1 + tests/skills/cases/epf-init/with-synonym.json | 1 + tests/skills/cases/erf-init/_skill.json | 3 +- tests/skills/cases/erf-init/basic.json | 1 + tests/skills/cases/erf-init/minimal.json | 1 + tests/skills/cases/erf-init/with-skd.json | 1 + tests/skills/cases/erf-init/with-synonym.json | 1 + tests/skills/cases/form-add/_skill.json | 3 +- tests/skills/cases/form-add/basic.json | 3 +- .../cases/form-add/dataprocessor-form.json | 3 +- .../skills/cases/form-add/document-form.json | 3 +- tests/skills/cases/form-add/list-form.json | 3 +- tests/skills/cases/form-add/set-default.json | 3 +- tests/skills/cases/form-compile/_skill.json | 3 +- .../cases/form-compile/attributes-types.json | 1 + .../cases/form-compile/catalog-form.json | 1 + tests/skills/cases/form-compile/commands.json | 1 + tests/skills/cases/form-compile/events.json | 1 + .../cases/form-compile/file-dialog.json | 1 + tests/skills/cases/form-compile/groups.json | 1 + .../cases/form-compile/input-fields.json | 1 + tests/skills/cases/form-compile/minimal.json | 1 + tests/skills/cases/form-compile/pages.json | 1 + tests/skills/cases/form-compile/table.json | 1 + tests/skills/cases/form-edit/_skill.json | 3 +- tests/skills/cases/form-edit/add-element.json | 1 + .../form-edit/add-group-with-fields.json | 1 + tests/skills/cases/interface-edit/_skill.json | 3 +- tests/skills/cases/meta-compile/_skill.json | 5 + .../meta-compile/accounting-register.json | 1 + .../meta-compile/accumulation-register.json | 1 + .../cases/meta-compile/business-process.json | 1 + .../meta-compile/calculation-register.json | 1 + .../cases/meta-compile/catalog-basic.json | 1 + .../meta-compile/catalog-hierarchical.json | 1 + .../cases/meta-compile/catalog-minimal.json | 3 +- .../meta-compile/catalog-mixed-types.json | 1 + .../cases/meta-compile/catalog-tabparts.json | 1 + .../cases/meta-compile/chart-of-accounts.json | 1 + .../chart-of-calculation-types.json | 3 +- .../chart-of-characteristic-types.json | 1 + .../meta-compile/common-module-client.json | 1 + .../cases/meta-compile/common-module.json | 1 + tests/skills/cases/meta-compile/constant.json | 1 + .../cases/meta-compile/data-processor.json | 1 + .../cases/meta-compile/defined-type.json | 1 + .../cases/meta-compile/document-basic.json | 1 + .../cases/meta-compile/document-journal.json | 2 + .../document-multiple-tabparts.json | 1 + tests/skills/cases/meta-compile/enum.json | 1 + .../meta-compile/event-subscription.json | 2 + .../cases/meta-compile/exchange-plan.json | 1 + .../cases/meta-compile/http-service.json | 1 + .../meta-compile/information-register.json | 1 + tests/skills/cases/meta-compile/report.json | 1 + .../cases/meta-compile/scheduled-job.json | 2 + .../ВидыНачислений.xml | 2 +- tests/skills/cases/meta-compile/task.json | 1 + .../cases/meta-compile/web-service.json | 1 + tests/skills/cases/meta-edit/_skill.json | 5 + tests/skills/cases/mxl-compile/_skill.json | 5 + .../cases/mxl-compile/column-widths.json | 1 + .../skills/cases/mxl-compile/empty-rows.json | 1 + .../cases/mxl-compile/format-strings.json | 1 + .../cases/mxl-compile/merged-cells.json | 1 + tests/skills/cases/mxl-compile/minimal.json | 1 + .../cases/mxl-compile/multiple-areas.json | 1 + .../cases/mxl-compile/page-a4-landscape.json | 1 + .../mxl-compile/parameters-and-templates.json | 1 + .../skills/cases/mxl-compile/print-form.json | 1 + .../cases/mxl-compile/simple-template.json | 1 + .../mxl-compile/styles-fonts-borders.json | 1 + tests/skills/cases/role-compile/_skill.json | 3 +- .../skills/cases/role-compile/basic-role.json | 1 + .../cases/role-compile/edit-preset.json | 1 + .../cases/role-compile/explicit-rights.json | 1 + tests/skills/cases/role-compile/minimal.json | 1 + .../cases/role-compile/russian-types.json | 1 + .../cases/role-compile/synonym-rights.json | 1 + .../cases/role-compile/view-preset.json | 1 + tests/skills/cases/role-compile/with-rls.json | 1 + tests/skills/cases/skd-compile/_skill.json | 5 + .../cases/skd-compile/calculated-fields.json | 1 + .../cases/skd-compile/field-restrictions.json | 1 + .../cases/skd-compile/full-example.json | 1 + .../skd-compile/grouping-and-totals.json | 1 + tests/skills/cases/skd-compile/minimal.json | 1 + .../cases/skd-compile/multiple-datasets.json | 1 + .../cases/skd-compile/simple-query.json | 1 + .../cases/skd-compile/with-filters.json | 1 + .../cases/skd-compile/with-parameters.json | 1 + tests/skills/cases/skd-edit/_skill.json | 5 + .../cases/subsystem-compile/_skill.json | 3 +- .../skills/cases/subsystem-compile/basic.json | 1 + .../skills/cases/subsystem-compile/full.json | 1 + .../cases/subsystem-compile/minimal.json | 1 + .../subsystem-compile/synonym-objects.json | 1 + .../subsystem-compile/with-children.json | 1 + .../cases/subsystem-compile/with-ci-flag.json | 1 + .../cases/subsystem-compile/with-content.json | 1 + tests/skills/cases/subsystem-edit/_skill.json | 3 +- tests/skills/integration/build-cfe.test.mjs | 43 +++ .../skills/integration/build-config.test.mjs | 278 ++++++++++++++++++ tests/skills/integration/build-epf.test.mjs | 108 +++++++ tests/skills/runner.mjs | 274 ++++++++++++++--- 124 files changed, 837 insertions(+), 62 deletions(-) create mode 100644 tests/skills/integration/build-cfe.test.mjs create mode 100644 tests/skills/integration/build-config.test.mjs create mode 100644 tests/skills/integration/build-epf.test.mjs diff --git a/tests/skills/cases/cf-edit/_skill.json b/tests/skills/cases/cf-edit/_skill.json index 421bbc0a..0e48b71d 100644 --- a/tests/skills/cases/cf-edit/_skill.json +++ b/tests/skills/cases/cf-edit/_skill.json @@ -8,5 +8,6 @@ "snapshot": { "root": "workDir", "normalizeUuids": true - } + }, + "postValidate": { "script": "cf-validate/scripts/cf-validate", "flag": "-ConfigPath", "pathFrom": "workDir" } } diff --git a/tests/skills/cases/cf-init/_skill.json b/tests/skills/cases/cf-init/_skill.json index 83c5b86e..9e738f1d 100644 --- a/tests/skills/cases/cf-init/_skill.json +++ b/tests/skills/cases/cf-init/_skill.json @@ -8,5 +8,6 @@ "snapshot": { "root": "workDir", "normalizeUuids": true - } + }, + "postValidate": { "script": "cf-validate/scripts/cf-validate", "flag": "-ConfigPath", "pathFrom": "workDir" } } diff --git a/tests/skills/cases/cfe-borrow/_skill.json b/tests/skills/cases/cfe-borrow/_skill.json index ee40bdd6..6a50148b 100644 --- a/tests/skills/cases/cfe-borrow/_skill.json +++ b/tests/skills/cases/cfe-borrow/_skill.json @@ -9,5 +9,6 @@ "snapshot": { "root": "workDir", "normalizeUuids": true - } + }, + "postValidate": { "script": "cfe-validate/scripts/cfe-validate", "flag": "-ExtensionPath", "pathFrom": "extensionPath" } } diff --git a/tests/skills/cases/cfe-init/_skill.json b/tests/skills/cases/cfe-init/_skill.json index 419cf051..d153308e 100644 --- a/tests/skills/cases/cfe-init/_skill.json +++ b/tests/skills/cases/cfe-init/_skill.json @@ -9,5 +9,6 @@ "snapshot": { "root": "workDir", "normalizeUuids": true - } + }, + "postValidate": { "script": "cfe-validate/scripts/cfe-validate", "flag": "-ExtensionPath", "pathFrom": "validatePath" } } diff --git a/tests/skills/cases/cfe-init/addon-purpose.json b/tests/skills/cases/cfe-init/addon-purpose.json index 6f737bb9..3889ef34 100644 --- a/tests/skills/cases/cfe-init/addon-purpose.json +++ b/tests/skills/cases/cfe-init/addon-purpose.json @@ -2,6 +2,7 @@ "name": "Расширение-дополнение (AddOn)", "params": { "name": "Дополнение", "outputDir": "ext" }, "args_extra": ["-Purpose", "AddOn"], + "validatePath": "ext", "expect": { "files": ["ext/Configuration.xml"] } diff --git a/tests/skills/cases/cfe-init/basic.json b/tests/skills/cases/cfe-init/basic.json index 10ce8908..db6f680c 100644 --- a/tests/skills/cases/cfe-init/basic.json +++ b/tests/skills/cases/cfe-init/basic.json @@ -1,6 +1,7 @@ { "name": "Пустое расширение", "params": { "name": "МоёРасширение", "outputDir": "ext" }, + "validatePath": "ext", "expect": { "files": ["ext/Configuration.xml"] } diff --git a/tests/skills/cases/cfe-init/no-role.json b/tests/skills/cases/cfe-init/no-role.json index d4d5487b..737f0ec3 100644 --- a/tests/skills/cases/cfe-init/no-role.json +++ b/tests/skills/cases/cfe-init/no-role.json @@ -2,6 +2,7 @@ "name": "Расширение без роли", "params": { "name": "БезРоли", "outputDir": "ext" }, "args_extra": ["-NoRole"], + "validatePath": "ext", "expect": { "files": ["ext/Configuration.xml"] } diff --git a/tests/skills/cases/cfe-init/patch-purpose.json b/tests/skills/cases/cfe-init/patch-purpose.json index 1151b05b..990c1031 100644 --- a/tests/skills/cases/cfe-init/patch-purpose.json +++ b/tests/skills/cases/cfe-init/patch-purpose.json @@ -2,6 +2,7 @@ "name": "Расширение-исправление (Patch)", "params": { "name": "Исправление", "outputDir": "ext" }, "args_extra": ["-Purpose", "Patch"], + "validatePath": "ext", "expect": { "files": ["ext/Configuration.xml"] } diff --git a/tests/skills/cases/cfe-init/with-prefix.json b/tests/skills/cases/cfe-init/with-prefix.json index b537457d..b976b6dd 100644 --- a/tests/skills/cases/cfe-init/with-prefix.json +++ b/tests/skills/cases/cfe-init/with-prefix.json @@ -2,6 +2,7 @@ "name": "Расширение с явным префиксом", "params": { "name": "РасшПрефикс", "outputDir": "ext" }, "args_extra": ["-NamePrefix", "РП_"], + "validatePath": "ext", "expect": { "files": ["ext/Configuration.xml"] } diff --git a/tests/skills/cases/cfe-init/with-version-vendor.json b/tests/skills/cases/cfe-init/with-version-vendor.json index b778eb78..49287737 100644 --- a/tests/skills/cases/cfe-init/with-version-vendor.json +++ b/tests/skills/cases/cfe-init/with-version-vendor.json @@ -2,6 +2,7 @@ "name": "Расширение с версией и поставщиком", "params": { "name": "РасшВерсия", "outputDir": "ext" }, "args_extra": ["-Version", "1.0.0.1", "-Vendor", "ТестКомпания"], + "validatePath": "ext", "expect": { "files": ["ext/Configuration.xml"] } diff --git a/tests/skills/cases/cfe-patch-method/_skill.json b/tests/skills/cases/cfe-patch-method/_skill.json index c604d03b..98011d54 100644 --- a/tests/skills/cases/cfe-patch-method/_skill.json +++ b/tests/skills/cases/cfe-patch-method/_skill.json @@ -10,5 +10,6 @@ "snapshot": { "root": "workDir", "normalizeUuids": true - } + }, + "postValidate": { "script": "cfe-validate/scripts/cfe-validate", "flag": "-ExtensionPath", "pathFrom": "extensionPath" } } diff --git a/tests/skills/cases/epf-add-form/_skill.json b/tests/skills/cases/epf-add-form/_skill.json index 2edd4381..e818f3a5 100644 --- a/tests/skills/cases/epf-add-form/_skill.json +++ b/tests/skills/cases/epf-add-form/_skill.json @@ -9,5 +9,6 @@ "snapshot": { "root": "workDir", "normalizeUuids": true - } + }, + "postValidate": { "script": "epf-validate/scripts/epf-validate", "flag": "-ObjectPath", "pathFrom": "validatePath" } } diff --git a/tests/skills/cases/epf-add-form/basic.json b/tests/skills/cases/epf-add-form/basic.json index a3f348dd..efb99928 100644 --- a/tests/skills/cases/epf-add-form/basic.json +++ b/tests/skills/cases/epf-add-form/basic.json @@ -6,5 +6,6 @@ "args": { "-Name": "МояОбработка", "-SrcDir": "{workDir}" } } ], - "params": { "processorName": "МояОбработка", "formName": "Форма" } + "params": { "processorName": "МояОбработка", "formName": "Форма" }, + "validatePath": "МояОбработка" } diff --git a/tests/skills/cases/epf-add-form/main-form.json b/tests/skills/cases/epf-add-form/main-form.json index cd0fa134..ab491578 100644 --- a/tests/skills/cases/epf-add-form/main-form.json +++ b/tests/skills/cases/epf-add-form/main-form.json @@ -11,5 +11,6 @@ } ], "params": { "processorName": "МояОбработка", "formName": "ФормаОсновная" }, - "args_extra": ["-Main"] + "args_extra": ["-Main"], + "validatePath": "МояОбработка" } diff --git a/tests/skills/cases/epf-add-form/named-form.json b/tests/skills/cases/epf-add-form/named-form.json index d4342c24..c390dcf3 100644 --- a/tests/skills/cases/epf-add-form/named-form.json +++ b/tests/skills/cases/epf-add-form/named-form.json @@ -6,5 +6,6 @@ "args": { "-Name": "ЗагрузкаДанных", "-SrcDir": "{workDir}" } } ], - "params": { "processorName": "ЗагрузкаДанных", "formName": "ФормаНастроек" } + "params": { "processorName": "ЗагрузкаДанных", "formName": "ФормаНастроек" }, + "validatePath": "ЗагрузкаДанных" } diff --git a/tests/skills/cases/epf-add-form/second-form.json b/tests/skills/cases/epf-add-form/second-form.json index 72d7ebc8..6ea42873 100644 --- a/tests/skills/cases/epf-add-form/second-form.json +++ b/tests/skills/cases/epf-add-form/second-form.json @@ -10,5 +10,6 @@ "args": { "-ProcessorName": "МояОбработка", "-FormName": "Форма", "-SrcDir": "{workDir}" } } ], - "params": { "processorName": "МояОбработка", "formName": "ФормаНастроек" } + "params": { "processorName": "МояОбработка", "formName": "ФормаНастроек" }, + "validatePath": "МояОбработка" } diff --git a/tests/skills/cases/epf-init/_skill.json b/tests/skills/cases/epf-init/_skill.json index d30c6c62..8b2add80 100644 --- a/tests/skills/cases/epf-init/_skill.json +++ b/tests/skills/cases/epf-init/_skill.json @@ -8,5 +8,6 @@ "snapshot": { "root": "workDir", "normalizeUuids": true - } + }, + "postValidate": { "script": "epf-validate/scripts/epf-validate", "flag": "-ObjectPath", "pathFrom": "validatePath" } } diff --git a/tests/skills/cases/epf-init/basic.json b/tests/skills/cases/epf-init/basic.json index 42aded3f..5682aa79 100644 --- a/tests/skills/cases/epf-init/basic.json +++ b/tests/skills/cases/epf-init/basic.json @@ -1,6 +1,7 @@ { "name": "Пустая внешняя обработка", "params": { "name": "ТестоваяОбработка" }, + "validatePath": "ТестоваяОбработка", "expect": { "files": ["ТестоваяОбработка.xml"] } diff --git a/tests/skills/cases/epf-init/latin-name.json b/tests/skills/cases/epf-init/latin-name.json index 322e9e53..8f403be7 100644 --- a/tests/skills/cases/epf-init/latin-name.json +++ b/tests/skills/cases/epf-init/latin-name.json @@ -1,6 +1,7 @@ { "name": "Обработка с латинским именем", "params": { "name": "DataLoader" }, + "validatePath": "DataLoader", "expect": { "files": ["DataLoader.xml"] } diff --git a/tests/skills/cases/epf-init/minimal.json b/tests/skills/cases/epf-init/minimal.json index 1ebf38f2..b6bba743 100644 --- a/tests/skills/cases/epf-init/minimal.json +++ b/tests/skills/cases/epf-init/minimal.json @@ -1,6 +1,7 @@ { "name": "Минимальная обработка (короткое имя)", "params": { "name": "Тест" }, + "validatePath": "Тест", "expect": { "files": ["Тест.xml"] } diff --git a/tests/skills/cases/epf-init/with-synonym.json b/tests/skills/cases/epf-init/with-synonym.json index 054bc6a1..f4ffb125 100644 --- a/tests/skills/cases/epf-init/with-synonym.json +++ b/tests/skills/cases/epf-init/with-synonym.json @@ -2,6 +2,7 @@ "name": "Обработка с синонимом", "params": { "name": "ЗагрузкаДанных" }, "args_extra": ["-Synonym", "Загрузка данных из Excel"], + "validatePath": "ЗагрузкаДанных", "expect": { "files": ["ЗагрузкаДанных.xml"] } diff --git a/tests/skills/cases/erf-init/_skill.json b/tests/skills/cases/erf-init/_skill.json index e05c1bdd..dd641f76 100644 --- a/tests/skills/cases/erf-init/_skill.json +++ b/tests/skills/cases/erf-init/_skill.json @@ -8,5 +8,6 @@ "snapshot": { "root": "workDir", "normalizeUuids": true - } + }, + "postValidate": { "script": "epf-validate/scripts/epf-validate", "flag": "-ObjectPath", "pathFrom": "validatePath" } } diff --git a/tests/skills/cases/erf-init/basic.json b/tests/skills/cases/erf-init/basic.json index d8a2e411..5ddcd366 100644 --- a/tests/skills/cases/erf-init/basic.json +++ b/tests/skills/cases/erf-init/basic.json @@ -1,6 +1,7 @@ { "name": "Пустой внешний отчёт", "params": { "name": "ТестовыйОтчёт" }, + "validatePath": "ТестовыйОтчёт", "expect": { "files": ["ТестовыйОтчёт.xml"] } diff --git a/tests/skills/cases/erf-init/minimal.json b/tests/skills/cases/erf-init/minimal.json index f0b35cac..a0d7ae24 100644 --- a/tests/skills/cases/erf-init/minimal.json +++ b/tests/skills/cases/erf-init/minimal.json @@ -1,6 +1,7 @@ { "name": "Минимальный отчёт", "params": { "name": "Отчёт1" }, + "validatePath": "Отчёт1", "expect": { "files": ["Отчёт1.xml"] } diff --git a/tests/skills/cases/erf-init/with-skd.json b/tests/skills/cases/erf-init/with-skd.json index 6d094acf..4d7ae181 100644 --- a/tests/skills/cases/erf-init/with-skd.json +++ b/tests/skills/cases/erf-init/with-skd.json @@ -2,6 +2,7 @@ "name": "Отчёт с СКД", "params": { "name": "ОтчётСКД" }, "args_extra": ["-WithSKD"], + "validatePath": "ОтчётСКД", "expect": { "files": ["ОтчётСКД.xml"] } diff --git a/tests/skills/cases/erf-init/with-synonym.json b/tests/skills/cases/erf-init/with-synonym.json index b4aad915..cc0b1c58 100644 --- a/tests/skills/cases/erf-init/with-synonym.json +++ b/tests/skills/cases/erf-init/with-synonym.json @@ -2,6 +2,7 @@ "name": "Отчёт с синонимом", "params": { "name": "АнализПродаж" }, "args_extra": ["-Synonym", "Анализ продаж"], + "validatePath": "АнализПродаж", "expect": { "files": ["АнализПродаж.xml"] } diff --git a/tests/skills/cases/form-add/_skill.json b/tests/skills/cases/form-add/_skill.json index b0a54e60..91da3aa9 100644 --- a/tests/skills/cases/form-add/_skill.json +++ b/tests/skills/cases/form-add/_skill.json @@ -8,5 +8,6 @@ "snapshot": { "root": "workDir", "normalizeUuids": true - } + }, + "postValidate": { "script": "form-validate/scripts/form-validate", "flag": "-FormPath", "pathFrom": "validatePath" } } diff --git a/tests/skills/cases/form-add/basic.json b/tests/skills/cases/form-add/basic.json index c2eb052c..f4fa1ad5 100644 --- a/tests/skills/cases/form-add/basic.json +++ b/tests/skills/cases/form-add/basic.json @@ -7,5 +7,6 @@ "args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" } } ], - "params": { "objectPath": "Catalogs/Товары.xml", "formName": "ФормаЭлемента" } + "params": { "objectPath": "Catalogs/Товары.xml", "formName": "ФормаЭлемента" }, + "validatePath": "Catalogs/Товары/Forms/ФормаЭлемента" } diff --git a/tests/skills/cases/form-add/dataprocessor-form.json b/tests/skills/cases/form-add/dataprocessor-form.json index 31b615e4..b560083b 100644 --- a/tests/skills/cases/form-add/dataprocessor-form.json +++ b/tests/skills/cases/form-add/dataprocessor-form.json @@ -7,5 +7,6 @@ "args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" } } ], - "params": { "objectPath": "DataProcessors/МояОбработка.xml", "formName": "Форма" } + "params": { "objectPath": "DataProcessors/МояОбработка.xml", "formName": "Форма" }, + "validatePath": "DataProcessors/МояОбработка/Forms/Форма" } diff --git a/tests/skills/cases/form-add/document-form.json b/tests/skills/cases/form-add/document-form.json index d84d3bbb..8f9021ea 100644 --- a/tests/skills/cases/form-add/document-form.json +++ b/tests/skills/cases/form-add/document-form.json @@ -7,5 +7,6 @@ "args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" } } ], - "params": { "objectPath": "Documents/Заказ.xml", "formName": "ФормаДокумента" } + "params": { "objectPath": "Documents/Заказ.xml", "formName": "ФормаДокумента" }, + "validatePath": "Documents/Заказ/Forms/ФормаДокумента" } diff --git a/tests/skills/cases/form-add/list-form.json b/tests/skills/cases/form-add/list-form.json index 36bfea2f..0a62ffad 100644 --- a/tests/skills/cases/form-add/list-form.json +++ b/tests/skills/cases/form-add/list-form.json @@ -8,5 +8,6 @@ } ], "params": { "objectPath": "Catalogs/Контрагенты.xml", "formName": "ФормаСписка" }, - "args_extra": ["-Purpose", "List"] + "args_extra": ["-Purpose", "List"], + "validatePath": "Catalogs/Контрагенты/Forms/ФормаСписка" } diff --git a/tests/skills/cases/form-add/set-default.json b/tests/skills/cases/form-add/set-default.json index 9fe62250..6d3d7e8d 100644 --- a/tests/skills/cases/form-add/set-default.json +++ b/tests/skills/cases/form-add/set-default.json @@ -8,5 +8,6 @@ } ], "params": { "objectPath": "Documents/Счет.xml", "formName": "ФормаДокумента" }, - "args_extra": ["-SetDefault"] + "args_extra": ["-SetDefault"], + "validatePath": "Documents/Счет/Forms/ФормаДокумента" } diff --git a/tests/skills/cases/form-compile/_skill.json b/tests/skills/cases/form-compile/_skill.json index fc08e1c3..4acfab1d 100644 --- a/tests/skills/cases/form-compile/_skill.json +++ b/tests/skills/cases/form-compile/_skill.json @@ -8,5 +8,6 @@ "snapshot": { "root": "workDir", "normalizeUuids": true - } + }, + "postValidate": { "script": "form-validate/scripts/form-validate", "flag": "-FormPath", "pathFrom": "validatePath" } } diff --git a/tests/skills/cases/form-compile/attributes-types.json b/tests/skills/cases/form-compile/attributes-types.json index 0c14764e..869df26e 100644 --- a/tests/skills/cases/form-compile/attributes-types.json +++ b/tests/skills/cases/form-compile/attributes-types.json @@ -12,6 +12,7 @@ } ], "params": { "outputPath": "DataProcessors/Типы/Forms/Форма/Ext/Form.xml" }, + "validatePath": "DataProcessors/Типы/Forms/Форма/Ext/Form.xml", "input": { "title": "Разные типы", "elements": [ diff --git a/tests/skills/cases/form-compile/catalog-form.json b/tests/skills/cases/form-compile/catalog-form.json index 6f429691..4fb48196 100644 --- a/tests/skills/cases/form-compile/catalog-form.json +++ b/tests/skills/cases/form-compile/catalog-form.json @@ -12,6 +12,7 @@ } ], "params": { "outputPath": "Catalogs/Товары/Forms/ФормаЭлемента/Ext/Form.xml" }, + "validatePath": "Catalogs/Товары/Forms/ФормаЭлемента/Ext/Form.xml", "input": { "title": "Товар", "attributes": [ diff --git a/tests/skills/cases/form-compile/commands.json b/tests/skills/cases/form-compile/commands.json index f2e9fc66..45136914 100644 --- a/tests/skills/cases/form-compile/commands.json +++ b/tests/skills/cases/form-compile/commands.json @@ -12,6 +12,7 @@ } ], "params": { "outputPath": "DataProcessors/Команды/Forms/Форма/Ext/Form.xml" }, + "validatePath": "DataProcessors/Команды/Forms/Форма/Ext/Form.xml", "input": { "title": "Форма с командами", "elements": [ diff --git a/tests/skills/cases/form-compile/events.json b/tests/skills/cases/form-compile/events.json index 91226838..ba625ad5 100644 --- a/tests/skills/cases/form-compile/events.json +++ b/tests/skills/cases/form-compile/events.json @@ -12,6 +12,7 @@ } ], "params": { "outputPath": "DataProcessors/События/Forms/Форма/Ext/Form.xml" }, + "validatePath": "DataProcessors/События/Forms/Форма/Ext/Form.xml", "input": { "title": "События", "events": { "OnCreateAtServer": "ПриСозданииНаСервере", "OnOpen": "ПриОткрытии" }, diff --git a/tests/skills/cases/form-compile/file-dialog.json b/tests/skills/cases/form-compile/file-dialog.json index b550d0ce..c12b848b 100644 --- a/tests/skills/cases/form-compile/file-dialog.json +++ b/tests/skills/cases/form-compile/file-dialog.json @@ -12,6 +12,7 @@ } ], "params": { "outputPath": "DataProcessors/ЗагрузкаИзФайла/Forms/Форма/Ext/Form.xml" }, + "validatePath": "DataProcessors/ЗагрузкаИзФайла/Forms/Форма/Ext/Form.xml", "input": { "title": "Загрузка из файла", "properties": { "autoTitle": false }, diff --git a/tests/skills/cases/form-compile/groups.json b/tests/skills/cases/form-compile/groups.json index 9a24702b..6b4c91d1 100644 --- a/tests/skills/cases/form-compile/groups.json +++ b/tests/skills/cases/form-compile/groups.json @@ -12,6 +12,7 @@ } ], "params": { "outputPath": "DataProcessors/СГруппами/Forms/Форма/Ext/Form.xml" }, + "validatePath": "DataProcessors/СГруппами/Forms/Форма/Ext/Form.xml", "input": { "title": "Группы", "elements": [ diff --git a/tests/skills/cases/form-compile/input-fields.json b/tests/skills/cases/form-compile/input-fields.json index 31325b1e..44c9f237 100644 --- a/tests/skills/cases/form-compile/input-fields.json +++ b/tests/skills/cases/form-compile/input-fields.json @@ -12,6 +12,7 @@ } ], "params": { "outputPath": "DataProcessors/ПоляВвода/Forms/Форма/Ext/Form.xml" }, + "validatePath": "DataProcessors/ПоляВвода/Forms/Форма/Ext/Form.xml", "input": { "title": "Поля ввода", "elements": [ diff --git a/tests/skills/cases/form-compile/minimal.json b/tests/skills/cases/form-compile/minimal.json index 724d1245..de66ff6a 100644 --- a/tests/skills/cases/form-compile/minimal.json +++ b/tests/skills/cases/form-compile/minimal.json @@ -12,6 +12,7 @@ } ], "params": { "outputPath": "DataProcessors/Минимальная/Forms/Форма/Ext/Form.xml" }, + "validatePath": "DataProcessors/Минимальная/Forms/Форма/Ext/Form.xml", "input": { "title": "Минимальная форма" } diff --git a/tests/skills/cases/form-compile/pages.json b/tests/skills/cases/form-compile/pages.json index 98712855..93c23bce 100644 --- a/tests/skills/cases/form-compile/pages.json +++ b/tests/skills/cases/form-compile/pages.json @@ -12,6 +12,7 @@ } ], "params": { "outputPath": "DataProcessors/Мастер/Forms/Форма/Ext/Form.xml" }, + "validatePath": "DataProcessors/Мастер/Forms/Форма/Ext/Form.xml", "input": { "title": "Мастер настройки", "properties": { "autoTitle": false }, diff --git a/tests/skills/cases/form-compile/table.json b/tests/skills/cases/form-compile/table.json index 1cb1bc33..025d12aa 100644 --- a/tests/skills/cases/form-compile/table.json +++ b/tests/skills/cases/form-compile/table.json @@ -12,6 +12,7 @@ } ], "params": { "outputPath": "DataProcessors/Таблица/Forms/Форма/Ext/Form.xml" }, + "validatePath": "DataProcessors/Таблица/Forms/Форма/Ext/Form.xml", "input": { "title": "Просмотр данных", "elements": [ diff --git a/tests/skills/cases/form-edit/_skill.json b/tests/skills/cases/form-edit/_skill.json index ccad83ee..309618a0 100644 --- a/tests/skills/cases/form-edit/_skill.json +++ b/tests/skills/cases/form-edit/_skill.json @@ -8,5 +8,6 @@ "snapshot": { "root": "workDir", "normalizeUuids": true - } + }, + "postValidate": { "script": "form-validate/scripts/form-validate", "flag": "-FormPath", "pathFrom": "formPath" } } diff --git a/tests/skills/cases/form-edit/add-element.json b/tests/skills/cases/form-edit/add-element.json index 8cd36b45..e29d0c7a 100644 --- a/tests/skills/cases/form-edit/add-element.json +++ b/tests/skills/cases/form-edit/add-element.json @@ -23,6 +23,7 @@ } ], "params": { "formPath": "DataProcessors/Тест/Forms/Форма/Ext/Form.xml" }, + "skipValidation": true, "input": { "elements": [ { "input": "Поле2", "path": "Поле2", "title": "Поле 2" } diff --git a/tests/skills/cases/form-edit/add-group-with-fields.json b/tests/skills/cases/form-edit/add-group-with-fields.json index 2b29b832..c98f0bf7 100644 --- a/tests/skills/cases/form-edit/add-group-with-fields.json +++ b/tests/skills/cases/form-edit/add-group-with-fields.json @@ -23,6 +23,7 @@ } ], "params": { "formPath": "DataProcessors/Группа/Forms/Форма/Ext/Form.xml" }, + "skipValidation": true, "input": { "elements": [ { "group": "horizontal", "name": "ГруппаНовая", "title": "Новая группа", "showTitle": true, "children": [ diff --git a/tests/skills/cases/interface-edit/_skill.json b/tests/skills/cases/interface-edit/_skill.json index 345cb1c6..ead3e884 100644 --- a/tests/skills/cases/interface-edit/_skill.json +++ b/tests/skills/cases/interface-edit/_skill.json @@ -9,5 +9,6 @@ "snapshot": { "root": "workDir", "normalizeUuids": true - } + }, + "postValidate": { "script": "interface-validate/scripts/interface-validate", "flag": "-CIPath", "pathFrom": "ciPath" } } diff --git a/tests/skills/cases/meta-compile/_skill.json b/tests/skills/cases/meta-compile/_skill.json index 646169eb..7bfa687b 100644 --- a/tests/skills/cases/meta-compile/_skill.json +++ b/tests/skills/cases/meta-compile/_skill.json @@ -8,5 +8,10 @@ "snapshot": { "root": "workDir", "normalizeUuids": true + }, + "postValidate": { + "script": "meta-validate/scripts/meta-validate", + "flag": "-ObjectPath", + "pathFrom": "validatePath" } } diff --git a/tests/skills/cases/meta-compile/accounting-register.json b/tests/skills/cases/meta-compile/accounting-register.json index 0299acec..ade1fee5 100644 --- a/tests/skills/cases/meta-compile/accounting-register.json +++ b/tests/skills/cases/meta-compile/accounting-register.json @@ -9,6 +9,7 @@ "resources": ["Сумма: Number(15,2)"], "attributes": ["Содержание: String(200)"] }, + "validatePath": "AccountingRegisters/Хозрасчетный", "expect": { "files": ["AccountingRegisters/Хозрасчетный.xml", "AccountingRegisters/Хозрасчетный/Ext/RecordSetModule.bsl"] } diff --git a/tests/skills/cases/meta-compile/accumulation-register.json b/tests/skills/cases/meta-compile/accumulation-register.json index 9cd6b56d..ead3e88f 100644 --- a/tests/skills/cases/meta-compile/accumulation-register.json +++ b/tests/skills/cases/meta-compile/accumulation-register.json @@ -7,6 +7,7 @@ "dimensions": ["Номенклатура: CatalogRef.Номенклатура", "Склад: CatalogRef.Склады"], "resources": ["Количество: Number(15,3)"] }, + "validatePath": "AccumulationRegisters/ОстаткиТоваров", "expect": { "files": ["AccumulationRegisters/ОстаткиТоваров.xml", "AccumulationRegisters/ОстаткиТоваров/Ext/RecordSetModule.bsl"] } diff --git a/tests/skills/cases/meta-compile/business-process.json b/tests/skills/cases/meta-compile/business-process.json index 35ae46b4..4c477f4d 100644 --- a/tests/skills/cases/meta-compile/business-process.json +++ b/tests/skills/cases/meta-compile/business-process.json @@ -16,6 +16,7 @@ } ] }, + "validatePath": "BusinessProcesses/СогласованиеДокумента", "expect": { "files": [ "BusinessProcesses/СогласованиеДокумента.xml", diff --git a/tests/skills/cases/meta-compile/calculation-register.json b/tests/skills/cases/meta-compile/calculation-register.json index 5acf52ff..30dae748 100644 --- a/tests/skills/cases/meta-compile/calculation-register.json +++ b/tests/skills/cases/meta-compile/calculation-register.json @@ -10,6 +10,7 @@ "dimensions": ["Сотрудник: CatalogRef.Сотрудники"], "resources": ["Результат: Number(15,2)", "ОтработаноДней: Number(5,0)"] }, + "validatePath": "CalculationRegisters/Начисления", "expect": { "files": ["CalculationRegisters/Начисления.xml", "CalculationRegisters/Начисления/Ext/RecordSetModule.bsl"] } diff --git a/tests/skills/cases/meta-compile/catalog-basic.json b/tests/skills/cases/meta-compile/catalog-basic.json index 8c3e4f20..abb73e93 100644 --- a/tests/skills/cases/meta-compile/catalog-basic.json +++ b/tests/skills/cases/meta-compile/catalog-basic.json @@ -1,6 +1,7 @@ { "name": "Простой справочник без реквизитов", "input": { "type": "Catalog", "name": "Валюты" }, + "validatePath": "Catalogs/Валюты", "expect": { "files": ["Catalogs/Валюты.xml", "Catalogs/Валюты/Ext/ObjectModule.bsl"] } diff --git a/tests/skills/cases/meta-compile/catalog-hierarchical.json b/tests/skills/cases/meta-compile/catalog-hierarchical.json index 164ea07a..d845bbdb 100644 --- a/tests/skills/cases/meta-compile/catalog-hierarchical.json +++ b/tests/skills/cases/meta-compile/catalog-hierarchical.json @@ -7,6 +7,7 @@ "hierarchyType": "HierarchyFoldersAndItems", "descriptionLength": 100 }, + "validatePath": "Catalogs/Подразделения", "expect": { "files": ["Catalogs/Подразделения.xml"] } diff --git a/tests/skills/cases/meta-compile/catalog-minimal.json b/tests/skills/cases/meta-compile/catalog-minimal.json index 0aa999e4..70f22210 100644 --- a/tests/skills/cases/meta-compile/catalog-minimal.json +++ b/tests/skills/cases/meta-compile/catalog-minimal.json @@ -1,4 +1,5 @@ { "name": "Минимальный справочник — только type и name", - "input": { "type": "Catalog", "name": "А" } + "input": { "type": "Catalog", "name": "А" }, + "validatePath": "Catalogs/А" } diff --git a/tests/skills/cases/meta-compile/catalog-mixed-types.json b/tests/skills/cases/meta-compile/catalog-mixed-types.json index 04bc92a3..b7568f21 100644 --- a/tests/skills/cases/meta-compile/catalog-mixed-types.json +++ b/tests/skills/cases/meta-compile/catalog-mixed-types.json @@ -13,6 +13,7 @@ "Статус: EnumRef.СтатусыКонтрагентов" ] }, + "validatePath": "Catalogs/Контрагенты", "expect": { "files": ["Catalogs/Контрагенты.xml"] } diff --git a/tests/skills/cases/meta-compile/catalog-tabparts.json b/tests/skills/cases/meta-compile/catalog-tabparts.json index 4f38ef2a..2a9735e5 100644 --- a/tests/skills/cases/meta-compile/catalog-tabparts.json +++ b/tests/skills/cases/meta-compile/catalog-tabparts.json @@ -15,6 +15,7 @@ } ] }, + "validatePath": "Catalogs/Товары", "expect": { "files": ["Catalogs/Товары.xml", "Catalogs/Товары/Ext/ObjectModule.bsl"] } diff --git a/tests/skills/cases/meta-compile/chart-of-accounts.json b/tests/skills/cases/meta-compile/chart-of-accounts.json index 879faa17..b835e0f5 100644 --- a/tests/skills/cases/meta-compile/chart-of-accounts.json +++ b/tests/skills/cases/meta-compile/chart-of-accounts.json @@ -9,6 +9,7 @@ "accountingFlags": ["Валютный", "Количественный"], "extDimensionAccountingFlags": ["СуммовойУчет"] }, + "validatePath": "ChartsOfAccounts/Хозрасчетный", "expect": { "files": ["ChartsOfAccounts/Хозрасчетный.xml", "ChartsOfAccounts/Хозрасчетный/Ext/ObjectModule.bsl"] } diff --git a/tests/skills/cases/meta-compile/chart-of-calculation-types.json b/tests/skills/cases/meta-compile/chart-of-calculation-types.json index 72e9683d..9de4665f 100644 --- a/tests/skills/cases/meta-compile/chart-of-calculation-types.json +++ b/tests/skills/cases/meta-compile/chart-of-calculation-types.json @@ -6,9 +6,10 @@ "codeLength": 5, "descriptionLength": 50, "actionPeriodUse": true, - "dependenceOnCalculationTypes": "NotDependOnCalculationTypes", + "dependenceOnCalculationTypes": "DontUse", "attributes": ["Формула: String(200)"] }, + "validatePath": "ChartsOfCalculationTypes/ВидыНачислений", "expect": { "files": ["ChartsOfCalculationTypes/ВидыНачислений.xml", "ChartsOfCalculationTypes/ВидыНачислений/Ext/ObjectModule.bsl"] } diff --git a/tests/skills/cases/meta-compile/chart-of-characteristic-types.json b/tests/skills/cases/meta-compile/chart-of-characteristic-types.json index 6db9ca50..cddf38b1 100644 --- a/tests/skills/cases/meta-compile/chart-of-characteristic-types.json +++ b/tests/skills/cases/meta-compile/chart-of-characteristic-types.json @@ -7,6 +7,7 @@ "valueTypes": ["String(200)", "Number(15,2)", "Boolean", "Date"], "attributes": ["НаборСвойств: String(100)"] }, + "validatePath": "ChartsOfCharacteristicTypes/ДополнительныеРеквизитыИСведения", "expect": { "files": ["ChartsOfCharacteristicTypes/ДополнительныеРеквизитыИСведения.xml", "ChartsOfCharacteristicTypes/ДополнительныеРеквизитыИСведения/Ext/ObjectModule.bsl"] } diff --git a/tests/skills/cases/meta-compile/common-module-client.json b/tests/skills/cases/meta-compile/common-module-client.json index a0929ebc..454b38b6 100644 --- a/tests/skills/cases/meta-compile/common-module-client.json +++ b/tests/skills/cases/meta-compile/common-module-client.json @@ -5,6 +5,7 @@ "name": "КлиентскиеФункции", "context": "client" }, + "validatePath": "CommonModules/КлиентскиеФункции", "expect": { "files": ["CommonModules/КлиентскиеФункции.xml", "CommonModules/КлиентскиеФункции/Ext/Module.bsl"] } diff --git a/tests/skills/cases/meta-compile/common-module.json b/tests/skills/cases/meta-compile/common-module.json index 5a20b7ce..e6ec010f 100644 --- a/tests/skills/cases/meta-compile/common-module.json +++ b/tests/skills/cases/meta-compile/common-module.json @@ -5,6 +5,7 @@ "name": "ОбщиеФункции", "context": "server" }, + "validatePath": "CommonModules/ОбщиеФункции", "expect": { "files": ["CommonModules/ОбщиеФункции.xml", "CommonModules/ОбщиеФункции/Ext/Module.bsl"] } diff --git a/tests/skills/cases/meta-compile/constant.json b/tests/skills/cases/meta-compile/constant.json index 61cc93f6..8ea0380b 100644 --- a/tests/skills/cases/meta-compile/constant.json +++ b/tests/skills/cases/meta-compile/constant.json @@ -5,6 +5,7 @@ "name": "ОсновнаяВалюта", "valueType": "CatalogRef.Валюты" }, + "validatePath": "Constants/ОсновнаяВалюта", "expect": { "files": ["Constants/ОсновнаяВалюта.xml"] } diff --git a/tests/skills/cases/meta-compile/data-processor.json b/tests/skills/cases/meta-compile/data-processor.json index 0f74b587..84943bdf 100644 --- a/tests/skills/cases/meta-compile/data-processor.json +++ b/tests/skills/cases/meta-compile/data-processor.json @@ -5,6 +5,7 @@ "name": "ЗагрузкаДанных", "attributes": ["ПутьКФайлу: String(500)"] }, + "validatePath": "DataProcessors/ЗагрузкаДанных", "expect": { "files": ["DataProcessors/ЗагрузкаДанных.xml", "DataProcessors/ЗагрузкаДанных/Ext/ObjectModule.bsl"] } diff --git a/tests/skills/cases/meta-compile/defined-type.json b/tests/skills/cases/meta-compile/defined-type.json index d116bbad..e6a3c781 100644 --- a/tests/skills/cases/meta-compile/defined-type.json +++ b/tests/skills/cases/meta-compile/defined-type.json @@ -5,6 +5,7 @@ "name": "ДенежныеСредства", "valueTypes": ["CatalogRef.БанковскиеСчета", "CatalogRef.Кассы"] }, + "validatePath": "DefinedTypes/ДенежныеСредства", "expect": { "files": ["DefinedTypes/ДенежныеСредства.xml"] } diff --git a/tests/skills/cases/meta-compile/document-basic.json b/tests/skills/cases/meta-compile/document-basic.json index d0ae5f13..b783e3bc 100644 --- a/tests/skills/cases/meta-compile/document-basic.json +++ b/tests/skills/cases/meta-compile/document-basic.json @@ -17,6 +17,7 @@ } ] }, + "validatePath": "Documents/ПриходнаяНакладная", "expect": { "files": ["Documents/ПриходнаяНакладная.xml"] } diff --git a/tests/skills/cases/meta-compile/document-journal.json b/tests/skills/cases/meta-compile/document-journal.json index 573cbde1..e75a1a40 100644 --- a/tests/skills/cases/meta-compile/document-journal.json +++ b/tests/skills/cases/meta-compile/document-journal.json @@ -9,6 +9,8 @@ "Контрагент" ] }, + "validatePath": "DocumentJournals/ЖурналСкладскихДокументов", + "skipValidation": true, "expect": { "files": ["DocumentJournals/ЖурналСкладскихДокументов.xml"] } diff --git a/tests/skills/cases/meta-compile/document-multiple-tabparts.json b/tests/skills/cases/meta-compile/document-multiple-tabparts.json index 27f20299..ae804b92 100644 --- a/tests/skills/cases/meta-compile/document-multiple-tabparts.json +++ b/tests/skills/cases/meta-compile/document-multiple-tabparts.json @@ -23,6 +23,7 @@ ] } }, + "validatePath": "Documents/РеализацияТоваров", "expect": { "files": ["Documents/РеализацияТоваров.xml"] } diff --git a/tests/skills/cases/meta-compile/enum.json b/tests/skills/cases/meta-compile/enum.json index d8d6718f..1d22f19e 100644 --- a/tests/skills/cases/meta-compile/enum.json +++ b/tests/skills/cases/meta-compile/enum.json @@ -5,6 +5,7 @@ "name": "ВидыНоменклатуры", "values": ["Товар", "Услуга", "Работа"] }, + "validatePath": "Enums/ВидыНоменклатуры", "expect": { "files": ["Enums/ВидыНоменклатуры.xml"] } diff --git a/tests/skills/cases/meta-compile/event-subscription.json b/tests/skills/cases/meta-compile/event-subscription.json index e95f2134..252caec1 100644 --- a/tests/skills/cases/meta-compile/event-subscription.json +++ b/tests/skills/cases/meta-compile/event-subscription.json @@ -7,6 +7,8 @@ "event": "BeforeWrite", "handler": "CommonModule.ОбработкаСобытий.ПриЗаписиДокумента" }, + "validatePath": "EventSubscriptions/ПриЗаписиДокумента", + "skipValidation": true, "expect": { "files": ["EventSubscriptions/ПриЗаписиДокумента.xml"] } diff --git a/tests/skills/cases/meta-compile/exchange-plan.json b/tests/skills/cases/meta-compile/exchange-plan.json index d3314414..c6c27ef2 100644 --- a/tests/skills/cases/meta-compile/exchange-plan.json +++ b/tests/skills/cases/meta-compile/exchange-plan.json @@ -16,6 +16,7 @@ } ] }, + "validatePath": "ExchangePlans/ОбменСФилиалами", "expect": { "files": [ "ExchangePlans/ОбменСФилиалами.xml", diff --git a/tests/skills/cases/meta-compile/http-service.json b/tests/skills/cases/meta-compile/http-service.json index 939d2fb8..e59d6a99 100644 --- a/tests/skills/cases/meta-compile/http-service.json +++ b/tests/skills/cases/meta-compile/http-service.json @@ -16,6 +16,7 @@ } } }, + "validatePath": "HTTPServices/ТоварныйAPI", "expect": { "files": ["HTTPServices/ТоварныйAPI.xml", "HTTPServices/ТоварныйAPI/Ext/Module.bsl"] } diff --git a/tests/skills/cases/meta-compile/information-register.json b/tests/skills/cases/meta-compile/information-register.json index d51c0252..374fd1ae 100644 --- a/tests/skills/cases/meta-compile/information-register.json +++ b/tests/skills/cases/meta-compile/information-register.json @@ -7,6 +7,7 @@ "dimensions": ["Валюта: CatalogRef.Валюты | master, mainFilter, denyIncomplete"], "resources": ["Курс: Number(15,4)", "Кратность: Number(10,0)"] }, + "validatePath": "InformationRegisters/КурсыВалют", "expect": { "files": ["InformationRegisters/КурсыВалют.xml", "InformationRegisters/КурсыВалют/Ext/RecordSetModule.bsl"] } diff --git a/tests/skills/cases/meta-compile/report.json b/tests/skills/cases/meta-compile/report.json index a88feddd..4c2d21a2 100644 --- a/tests/skills/cases/meta-compile/report.json +++ b/tests/skills/cases/meta-compile/report.json @@ -4,6 +4,7 @@ "type": "Report", "name": "ОстаткиТоваров" }, + "validatePath": "Reports/ОстаткиТоваров", "expect": { "files": ["Reports/ОстаткиТоваров.xml", "Reports/ОстаткиТоваров/Ext/ObjectModule.bsl"] } diff --git a/tests/skills/cases/meta-compile/scheduled-job.json b/tests/skills/cases/meta-compile/scheduled-job.json index 47016272..f5491227 100644 --- a/tests/skills/cases/meta-compile/scheduled-job.json +++ b/tests/skills/cases/meta-compile/scheduled-job.json @@ -5,6 +5,8 @@ "name": "ОбменДанными", "methodName": "ОбменДаннымиСервер.Выполнить" }, + "validatePath": "ScheduledJobs/ОбменДанными", + "skipValidation": true, "expect": { "files": ["ScheduledJobs/ОбменДанными.xml"] } diff --git a/tests/skills/cases/meta-compile/snapshots/chart-of-calculation-types/ChartsOfCalculationTypes/ВидыНачислений.xml b/tests/skills/cases/meta-compile/snapshots/chart-of-calculation-types/ChartsOfCalculationTypes/ВидыНачислений.xml index 5611c1b2..1e8b05e6 100644 --- a/tests/skills/cases/meta-compile/snapshots/chart-of-calculation-types/ChartsOfCalculationTypes/ВидыНачислений.xml +++ b/tests/skills/cases/meta-compile/snapshots/chart-of-calculation-types/ChartsOfCalculationTypes/ВидыНачислений.xml @@ -62,7 +62,7 @@ Variable 50 AsDescription - NotDependOnCalculationTypes + DontUse true diff --git a/tests/skills/cases/meta-compile/task.json b/tests/skills/cases/meta-compile/task.json index d2424042..3c63eb84 100644 --- a/tests/skills/cases/meta-compile/task.json +++ b/tests/skills/cases/meta-compile/task.json @@ -10,6 +10,7 @@ "РольИсполнителя: CatalogRef.РолиИсполнителей" ] }, + "validatePath": "Tasks/ЗадачаИсполнителя", "expect": { "files": ["Tasks/ЗадачаИсполнителя.xml", "Tasks/ЗадачаИсполнителя/Ext/ObjectModule.bsl"] } diff --git a/tests/skills/cases/meta-compile/web-service.json b/tests/skills/cases/meta-compile/web-service.json index 72e05d1b..8bde3617 100644 --- a/tests/skills/cases/meta-compile/web-service.json +++ b/tests/skills/cases/meta-compile/web-service.json @@ -17,6 +17,7 @@ } } }, + "validatePath": "WebServices/СервисОбмена", "expect": { "files": ["WebServices/СервисОбмена.xml", "WebServices/СервисОбмена/Ext/Module.bsl"] } diff --git a/tests/skills/cases/meta-edit/_skill.json b/tests/skills/cases/meta-edit/_skill.json index ed51f8f7..f3986137 100644 --- a/tests/skills/cases/meta-edit/_skill.json +++ b/tests/skills/cases/meta-edit/_skill.json @@ -8,5 +8,10 @@ "snapshot": { "root": "workDir", "normalizeUuids": true + }, + "postValidate": { + "script": "meta-validate/scripts/meta-validate", + "flag": "-ObjectPath", + "pathFrom": "objectPath" } } diff --git a/tests/skills/cases/mxl-compile/_skill.json b/tests/skills/cases/mxl-compile/_skill.json index 1f25e9ac..f41efc0e 100644 --- a/tests/skills/cases/mxl-compile/_skill.json +++ b/tests/skills/cases/mxl-compile/_skill.json @@ -9,5 +9,10 @@ "snapshot": { "root": "workDir", "normalizeUuids": false + }, + "postValidate": { + "script": "mxl-validate/scripts/mxl-validate", + "flag": "-TemplatePath", + "pathFrom": "validatePath" } } diff --git a/tests/skills/cases/mxl-compile/column-widths.json b/tests/skills/cases/mxl-compile/column-widths.json index 818024b8..b0f2509f 100644 --- a/tests/skills/cases/mxl-compile/column-widths.json +++ b/tests/skills/cases/mxl-compile/column-widths.json @@ -24,6 +24,7 @@ ] }, "params": { "outputPath": "Template.xml" }, + "validatePath": "Template.xml", "expect": { "files": ["Template.xml"] } diff --git a/tests/skills/cases/mxl-compile/empty-rows.json b/tests/skills/cases/mxl-compile/empty-rows.json index 3931bd57..0893babc 100644 --- a/tests/skills/cases/mxl-compile/empty-rows.json +++ b/tests/skills/cases/mxl-compile/empty-rows.json @@ -31,6 +31,7 @@ ] }, "params": { "outputPath": "Template.xml" }, + "validatePath": "Template.xml", "expect": { "files": ["Template.xml"] } diff --git a/tests/skills/cases/mxl-compile/format-strings.json b/tests/skills/cases/mxl-compile/format-strings.json index c05bc353..f9f2bdb8 100644 --- a/tests/skills/cases/mxl-compile/format-strings.json +++ b/tests/skills/cases/mxl-compile/format-strings.json @@ -34,6 +34,7 @@ ] }, "params": { "outputPath": "Template.xml" }, + "validatePath": "Template.xml", "expect": { "files": ["Template.xml"] } diff --git a/tests/skills/cases/mxl-compile/merged-cells.json b/tests/skills/cases/mxl-compile/merged-cells.json index 3def7eec..4ddde11b 100644 --- a/tests/skills/cases/mxl-compile/merged-cells.json +++ b/tests/skills/cases/mxl-compile/merged-cells.json @@ -40,6 +40,7 @@ ] }, "params": { "outputPath": "Template.xml" }, + "validatePath": "Template.xml", "expect": { "files": ["Template.xml"] } diff --git a/tests/skills/cases/mxl-compile/minimal.json b/tests/skills/cases/mxl-compile/minimal.json index 5eef51de..44ea94f1 100644 --- a/tests/skills/cases/mxl-compile/minimal.json +++ b/tests/skills/cases/mxl-compile/minimal.json @@ -12,6 +12,7 @@ ] }, "params": { "outputPath": "Template.xml" }, + "validatePath": "Template.xml", "expect": { "files": ["Template.xml"] } diff --git a/tests/skills/cases/mxl-compile/multiple-areas.json b/tests/skills/cases/mxl-compile/multiple-areas.json index 947667c1..3006db14 100644 --- a/tests/skills/cases/mxl-compile/multiple-areas.json +++ b/tests/skills/cases/mxl-compile/multiple-areas.json @@ -57,6 +57,7 @@ ] }, "params": { "outputPath": "Template.xml" }, + "validatePath": "Template.xml", "expect": { "files": ["Template.xml"] } diff --git a/tests/skills/cases/mxl-compile/page-a4-landscape.json b/tests/skills/cases/mxl-compile/page-a4-landscape.json index 91eeaa5a..d2bc0a76 100644 --- a/tests/skills/cases/mxl-compile/page-a4-landscape.json +++ b/tests/skills/cases/mxl-compile/page-a4-landscape.json @@ -41,6 +41,7 @@ ] }, "params": { "outputPath": "Template.xml" }, + "validatePath": "Template.xml", "expect": { "files": ["Template.xml"] } diff --git a/tests/skills/cases/mxl-compile/parameters-and-templates.json b/tests/skills/cases/mxl-compile/parameters-and-templates.json index 35efec98..081aa074 100644 --- a/tests/skills/cases/mxl-compile/parameters-and-templates.json +++ b/tests/skills/cases/mxl-compile/parameters-and-templates.json @@ -37,6 +37,7 @@ ] }, "params": { "outputPath": "Template.xml" }, + "validatePath": "Template.xml", "expect": { "files": ["Template.xml"] } diff --git a/tests/skills/cases/mxl-compile/print-form.json b/tests/skills/cases/mxl-compile/print-form.json index 3ad66923..12953054 100644 --- a/tests/skills/cases/mxl-compile/print-form.json +++ b/tests/skills/cases/mxl-compile/print-form.json @@ -102,6 +102,7 @@ ] }, "params": { "outputPath": "Template.xml" }, + "validatePath": "Template.xml", "expect": { "files": ["Template.xml"] } diff --git a/tests/skills/cases/mxl-compile/simple-template.json b/tests/skills/cases/mxl-compile/simple-template.json index b61bf805..f835932f 100644 --- a/tests/skills/cases/mxl-compile/simple-template.json +++ b/tests/skills/cases/mxl-compile/simple-template.json @@ -12,6 +12,7 @@ ] }, "params": { "outputPath": "Template.xml" }, + "validatePath": "Template.xml", "expect": { "files": ["Template.xml"] } diff --git a/tests/skills/cases/mxl-compile/styles-fonts-borders.json b/tests/skills/cases/mxl-compile/styles-fonts-borders.json index c64be86d..d7ff7873 100644 --- a/tests/skills/cases/mxl-compile/styles-fonts-borders.json +++ b/tests/skills/cases/mxl-compile/styles-fonts-borders.json @@ -86,6 +86,7 @@ ] }, "params": { "outputPath": "Template.xml" }, + "validatePath": "Template.xml", "expect": { "files": ["Template.xml"] } diff --git a/tests/skills/cases/role-compile/_skill.json b/tests/skills/cases/role-compile/_skill.json index 7737bb2f..864140f3 100644 --- a/tests/skills/cases/role-compile/_skill.json +++ b/tests/skills/cases/role-compile/_skill.json @@ -8,5 +8,6 @@ "snapshot": { "root": "workDir", "normalizeUuids": true - } + }, + "postValidate": { "script": "role-validate/scripts/role-validate", "flag": "-RightsPath", "pathFrom": "validatePath" } } diff --git a/tests/skills/cases/role-compile/basic-role.json b/tests/skills/cases/role-compile/basic-role.json index 4104ed73..8ed4937c 100644 --- a/tests/skills/cases/role-compile/basic-role.json +++ b/tests/skills/cases/role-compile/basic-role.json @@ -19,6 +19,7 @@ "Catalog.Товары: Read View" ] }, + "validatePath": "Roles/Кладовщик", "expect": { "files": [ "Roles/Кладовщик.xml", diff --git a/tests/skills/cases/role-compile/edit-preset.json b/tests/skills/cases/role-compile/edit-preset.json index f4a4c106..635a40ec 100644 --- a/tests/skills/cases/role-compile/edit-preset.json +++ b/tests/skills/cases/role-compile/edit-preset.json @@ -20,6 +20,7 @@ "Document.РеализацияТоваров: @edit" ] }, + "validatePath": "Roles/РедакторДокументов", "expect": { "files": [ "Roles/РедакторДокументов.xml", diff --git a/tests/skills/cases/role-compile/explicit-rights.json b/tests/skills/cases/role-compile/explicit-rights.json index d1d782cb..60b67ebb 100644 --- a/tests/skills/cases/role-compile/explicit-rights.json +++ b/tests/skills/cases/role-compile/explicit-rights.json @@ -20,6 +20,7 @@ "InformationRegister.Цены: Read, Update" ] }, + "validatePath": "Roles/ПравоЦен", "expect": { "files": [ "Roles/ПравоЦен.xml", diff --git a/tests/skills/cases/role-compile/minimal.json b/tests/skills/cases/role-compile/minimal.json index 090106db..25f2ddd2 100644 --- a/tests/skills/cases/role-compile/minimal.json +++ b/tests/skills/cases/role-compile/minimal.json @@ -3,6 +3,7 @@ "input": { "name": "Пустая" }, + "validatePath": "Roles/Пустая", "expect": { "files": [ "Roles/Пустая.xml", diff --git a/tests/skills/cases/role-compile/russian-types.json b/tests/skills/cases/role-compile/russian-types.json index cbf4823c..5fc30d48 100644 --- a/tests/skills/cases/role-compile/russian-types.json +++ b/tests/skills/cases/role-compile/russian-types.json @@ -20,6 +20,7 @@ "Справочник.Контрагенты: Чтение, Просмотр" ] }, + "validatePath": "Roles/ЧтениеКонтрагентов", "expect": { "files": [ "Roles/ЧтениеКонтрагентов.xml", diff --git a/tests/skills/cases/role-compile/synonym-rights.json b/tests/skills/cases/role-compile/synonym-rights.json index 8d84a891..5433c667 100644 --- a/tests/skills/cases/role-compile/synonym-rights.json +++ b/tests/skills/cases/role-compile/synonym-rights.json @@ -19,6 +19,7 @@ "Catalog.Товары: Read View" ] }, + "validatePath": "Roles/Кладовщик", "expect": { "files": [ "Roles/Кладовщик.xml", diff --git a/tests/skills/cases/role-compile/view-preset.json b/tests/skills/cases/role-compile/view-preset.json index d324024d..5aa3545a 100644 --- a/tests/skills/cases/role-compile/view-preset.json +++ b/tests/skills/cases/role-compile/view-preset.json @@ -32,6 +32,7 @@ "DataProcessor.Загрузка: @view" ] }, + "validatePath": "Roles/ЧтениеНоменклатуры", "expect": { "files": [ "Roles/ЧтениеНоменклатуры.xml", diff --git a/tests/skills/cases/role-compile/with-rls.json b/tests/skills/cases/role-compile/with-rls.json index 64784d00..922a24d4 100644 --- a/tests/skills/cases/role-compile/with-rls.json +++ b/tests/skills/cases/role-compile/with-rls.json @@ -44,6 +44,7 @@ } ] }, + "validatePath": "Roles/ЧтениеДокументовПоОрганизации", "expect": { "files": [ "Roles/ЧтениеДокументовПоОрганизации.xml", diff --git a/tests/skills/cases/skd-compile/_skill.json b/tests/skills/cases/skd-compile/_skill.json index b9ef5a6f..2a6a6557 100644 --- a/tests/skills/cases/skd-compile/_skill.json +++ b/tests/skills/cases/skd-compile/_skill.json @@ -8,5 +8,10 @@ "snapshot": { "root": "workDir", "normalizeUuids": true + }, + "postValidate": { + "script": "skd-validate/scripts/skd-validate", + "flag": "-TemplatePath", + "pathFrom": "validatePath" } } diff --git a/tests/skills/cases/skd-compile/calculated-fields.json b/tests/skills/cases/skd-compile/calculated-fields.json index 2af750a0..c60ee14d 100644 --- a/tests/skills/cases/skd-compile/calculated-fields.json +++ b/tests/skills/cases/skd-compile/calculated-fields.json @@ -12,6 +12,7 @@ { "dataPath": "Наценка", "title": "Наценка, %", "expression": "(Цена - Закупка) / Закупка * 100", "valueType": "decimal(10,2)" } ] }, + "validatePath": "Template.xml", "expect": { "files": ["Template.xml"] } diff --git a/tests/skills/cases/skd-compile/field-restrictions.json b/tests/skills/cases/skd-compile/field-restrictions.json index 19c7bb41..df29d62e 100644 --- a/tests/skills/cases/skd-compile/field-restrictions.json +++ b/tests/skills/cases/skd-compile/field-restrictions.json @@ -14,6 +14,7 @@ ] }] }, + "validatePath": "Template.xml", "expect": { "files": ["Template.xml"] } diff --git a/tests/skills/cases/skd-compile/full-example.json b/tests/skills/cases/skd-compile/full-example.json index be180aa5..68b9c9fb 100644 --- a/tests/skills/cases/skd-compile/full-example.json +++ b/tests/skills/cases/skd-compile/full-example.json @@ -18,6 +18,7 @@ } }] }, + "validatePath": "Template.xml", "expect": { "files": ["Template.xml"] } diff --git a/tests/skills/cases/skd-compile/grouping-and-totals.json b/tests/skills/cases/skd-compile/grouping-and-totals.json index ca41d98d..1c37d61d 100644 --- a/tests/skills/cases/skd-compile/grouping-and-totals.json +++ b/tests/skills/cases/skd-compile/grouping-and-totals.json @@ -21,6 +21,7 @@ } }] }, + "validatePath": "Template.xml", "expect": { "files": ["Template.xml"] } diff --git a/tests/skills/cases/skd-compile/minimal.json b/tests/skills/cases/skd-compile/minimal.json index 35ebc272..8d260ea3 100644 --- a/tests/skills/cases/skd-compile/minimal.json +++ b/tests/skills/cases/skd-compile/minimal.json @@ -7,6 +7,7 @@ "fields": ["Наименование"] }] }, + "validatePath": "Template.xml", "expect": { "files": ["Template.xml"] } diff --git a/tests/skills/cases/skd-compile/multiple-datasets.json b/tests/skills/cases/skd-compile/multiple-datasets.json index 69bf1c0d..69a99ab5 100644 --- a/tests/skills/cases/skd-compile/multiple-datasets.json +++ b/tests/skills/cases/skd-compile/multiple-datasets.json @@ -18,6 +18,7 @@ { "source": "Продажи", "dest": "Остатки", "sourceExpr": "Номенклатура", "destExpr": "Номенклатура" } ] }, + "validatePath": "Template.xml", "expect": { "files": ["Template.xml"] } diff --git a/tests/skills/cases/skd-compile/simple-query.json b/tests/skills/cases/skd-compile/simple-query.json index 92392f33..caaf6aa3 100644 --- a/tests/skills/cases/skd-compile/simple-query.json +++ b/tests/skills/cases/skd-compile/simple-query.json @@ -10,6 +10,7 @@ } ] }, + "validatePath": "Template.xml", "expect": { "files": ["Template.xml"] } diff --git a/tests/skills/cases/skd-compile/with-filters.json b/tests/skills/cases/skd-compile/with-filters.json index bed39165..d41836f2 100644 --- a/tests/skills/cases/skd-compile/with-filters.json +++ b/tests/skills/cases/skd-compile/with-filters.json @@ -27,6 +27,7 @@ }], "parameters": ["Период: StandardPeriod = LastMonth @autoDates"] }, + "validatePath": "Template.xml", "expect": { "files": ["Template.xml"] } diff --git a/tests/skills/cases/skd-compile/with-parameters.json b/tests/skills/cases/skd-compile/with-parameters.json index f38021eb..f73ab996 100644 --- a/tests/skills/cases/skd-compile/with-parameters.json +++ b/tests/skills/cases/skd-compile/with-parameters.json @@ -9,6 +9,7 @@ }], "parameters": ["Период: СтандартныйПериод = LastMonth @autoDates", "Организация: CatalogRef.Организации"] }, + "validatePath": "Template.xml", "expect": { "files": ["Template.xml"] } diff --git a/tests/skills/cases/skd-edit/_skill.json b/tests/skills/cases/skd-edit/_skill.json index 3bda55cb..2d5f093a 100644 --- a/tests/skills/cases/skd-edit/_skill.json +++ b/tests/skills/cases/skd-edit/_skill.json @@ -9,5 +9,10 @@ "snapshot": { "root": "workDir", "normalizeUuids": true + }, + "postValidate": { + "script": "skd-validate/scripts/skd-validate", + "flag": "-TemplatePath", + "pathFrom": "templatePath" } } diff --git a/tests/skills/cases/subsystem-compile/_skill.json b/tests/skills/cases/subsystem-compile/_skill.json index 6c24cfa2..5c9bf7a8 100644 --- a/tests/skills/cases/subsystem-compile/_skill.json +++ b/tests/skills/cases/subsystem-compile/_skill.json @@ -8,5 +8,6 @@ "snapshot": { "root": "workDir", "normalizeUuids": true - } + }, + "postValidate": { "script": "subsystem-validate/scripts/subsystem-validate", "flag": "-SubsystemPath", "pathFrom": "validatePath" } } diff --git a/tests/skills/cases/subsystem-compile/basic.json b/tests/skills/cases/subsystem-compile/basic.json index 0d727133..0931586d 100644 --- a/tests/skills/cases/subsystem-compile/basic.json +++ b/tests/skills/cases/subsystem-compile/basic.json @@ -12,6 +12,7 @@ "synonym": "Склад", "content": ["Catalogs.Товары"] }, + "validatePath": "Subsystems/Склад", "expect": { "files": ["Subsystems/Склад.xml"] } diff --git a/tests/skills/cases/subsystem-compile/full.json b/tests/skills/cases/subsystem-compile/full.json index 20993644..f8b12061 100644 --- a/tests/skills/cases/subsystem-compile/full.json +++ b/tests/skills/cases/subsystem-compile/full.json @@ -22,6 +22,7 @@ "content": ["Catalog.Товары", "Report.ОтчетПоПродажам"], "children": ["Настройки"] }, + "validatePath": "Subsystems/Продажи", "expect": { "files": ["Subsystems/Продажи.xml"] } diff --git a/tests/skills/cases/subsystem-compile/minimal.json b/tests/skills/cases/subsystem-compile/minimal.json index 0279f1f7..a9ba0fac 100644 --- a/tests/skills/cases/subsystem-compile/minimal.json +++ b/tests/skills/cases/subsystem-compile/minimal.json @@ -3,6 +3,7 @@ "input": { "name": "Тест" }, + "validatePath": "Subsystems/Тест", "expect": { "files": ["Subsystems/Тест.xml"] } diff --git a/tests/skills/cases/subsystem-compile/synonym-objects.json b/tests/skills/cases/subsystem-compile/synonym-objects.json index 9aa33add..40303846 100644 --- a/tests/skills/cases/subsystem-compile/synonym-objects.json +++ b/tests/skills/cases/subsystem-compile/synonym-objects.json @@ -12,6 +12,7 @@ "synonym": "Склад", "objects": ["Catalogs.Товары"] }, + "validatePath": "Subsystems/Склад", "expect": { "files": ["Subsystems/Склад.xml"] } diff --git a/tests/skills/cases/subsystem-compile/with-children.json b/tests/skills/cases/subsystem-compile/with-children.json index 31b1d7f4..4703468c 100644 --- a/tests/skills/cases/subsystem-compile/with-children.json +++ b/tests/skills/cases/subsystem-compile/with-children.json @@ -5,6 +5,7 @@ "synonym": "Администрирование", "children": ["Настройки", "Пользователи"] }, + "validatePath": "Subsystems/Администрирование", "expect": { "files": ["Subsystems/Администрирование.xml"] } diff --git a/tests/skills/cases/subsystem-compile/with-ci-flag.json b/tests/skills/cases/subsystem-compile/with-ci-flag.json index 2780e8ec..65e2c199 100644 --- a/tests/skills/cases/subsystem-compile/with-ci-flag.json +++ b/tests/skills/cases/subsystem-compile/with-ci-flag.json @@ -5,6 +5,7 @@ "synonym": "Служебная подсистема", "includeInCommandInterface": false }, + "validatePath": "Subsystems/Служебная", "expect": { "files": ["Subsystems/Служебная.xml"] } diff --git a/tests/skills/cases/subsystem-compile/with-content.json b/tests/skills/cases/subsystem-compile/with-content.json index 9020e07d..3fea5f87 100644 --- a/tests/skills/cases/subsystem-compile/with-content.json +++ b/tests/skills/cases/subsystem-compile/with-content.json @@ -17,6 +17,7 @@ "synonym": "Продажи", "content": ["Catalog.Товары", "Document.Заказ"] }, + "validatePath": "Subsystems/Продажи", "expect": { "files": ["Subsystems/Продажи.xml"] } diff --git a/tests/skills/cases/subsystem-edit/_skill.json b/tests/skills/cases/subsystem-edit/_skill.json index 5feb872f..e0a41b4c 100644 --- a/tests/skills/cases/subsystem-edit/_skill.json +++ b/tests/skills/cases/subsystem-edit/_skill.json @@ -9,5 +9,6 @@ "snapshot": { "root": "workDir", "normalizeUuids": true - } + }, + "postValidate": { "script": "subsystem-validate/scripts/subsystem-validate", "flag": "-SubsystemPath", "pathFrom": "subsystemPath" } } diff --git a/tests/skills/integration/build-cfe.test.mjs b/tests/skills/integration/build-cfe.test.mjs new file mode 100644 index 00000000..a145b8b8 --- /dev/null +++ b/tests/skills/integration/build-cfe.test.mjs @@ -0,0 +1,43 @@ +// build-cfe.test.mjs — Integration test: build a 1C extension (CFE) from scratch +// Steps: cfe-init → cfe-borrow (catalog) → cfe-patch-method (Before interceptor) → cfe-validate + +export const name = 'Сборка расширения конфигурации (CFE)'; +export const setup = 'base-config'; + +export const steps = [ + // ── 1. Init extension pointing at the base config ── + { + name: 'cfe-init: расширение ТестовоеРасширение', + script: 'cfe-init/scripts/cfe-init', + args: { '-Name': 'ТестовоеРасширение', '-OutputDir': '{workDir}/ext', '-ConfigPath': '{workDir}' }, + validate: { script: 'cfe-validate/scripts/cfe-validate', flag: '-ExtensionPath', path: 'ext' }, + }, + + // ── 2. Borrow a catalog from the base config ── + { + name: 'cfe-borrow: заимствование Catalog.Контрагенты', + script: 'cfe-borrow/scripts/cfe-borrow', + args: { '-ExtensionPath': '{workDir}/ext', '-ConfigPath': '{workDir}', '-Object': 'Catalog.Контрагенты' }, + validate: { script: 'cfe-validate/scripts/cfe-validate', flag: '-ExtensionPath', path: 'ext' }, + }, + + // ── 3. Add a Before interceptor for a method on the borrowed catalog ── + { + name: 'cfe-patch-method: перехватчик Перед для ПриЗаписи', + script: 'cfe-patch-method/scripts/cfe-patch-method', + args: { + '-ExtensionPath': '{workDir}/ext', + '-ModulePath': 'Catalog.Контрагенты.ObjectModule', + '-MethodName': 'ПриЗаписи', + '-InterceptorType': 'Before', + }, + validate: { script: 'cfe-validate/scripts/cfe-validate', flag: '-ExtensionPath', path: 'ext' }, + }, + + // ── 4. Final validation ── + { + name: 'cfe-validate: финальная валидация расширения', + script: 'cfe-validate/scripts/cfe-validate', + args: { '-ExtensionPath': '{workDir}/ext' }, + }, +]; diff --git a/tests/skills/integration/build-config.test.mjs b/tests/skills/integration/build-config.test.mjs new file mode 100644 index 00000000..7f9a772e --- /dev/null +++ b/tests/skills/integration/build-config.test.mjs @@ -0,0 +1,278 @@ +// build-config.test.mjs — Integration test: build a complete 1C configuration from scratch +// Steps: cf-init → meta-compile (catalog, document, enum, register, constant, common module, report) +// → form-add + form-compile → skd-compile → mxl-compile +// → subsystem-compile → role-compile → cf-edit (add objects to config) → cf-validate + +export const name = 'Сборка конфигурации с нуля'; +export const setup = 'none'; +export const cache = 'base-config'; + +export const steps = [ + // ── 1. Init empty configuration ── + { + name: 'cf-init: пустая конфигурация', + script: 'cf-init/scripts/cf-init', + args: { '-Name': 'ТестоваяКонфигурация', '-OutputDir': '{workDir}' }, + validate: { script: 'cf-validate/scripts/cf-validate', flag: '-ConfigPath' }, + }, + + // ── 2. Metadata objects ── + { + name: 'meta-compile: Справочник Контрагенты', + script: 'meta-compile/scripts/meta-compile', + input: { + type: 'Catalog', name: 'Контрагенты', + codeLength: 9, descriptionLength: 100, + attributes: [ + { name: 'ИНН', type: 'String', length: 12 }, + { name: 'Телефон', type: 'String', length: 20 }, + ], + }, + args: { '-JsonPath': '{inputFile}', '-OutputDir': '{workDir}' }, + validate: { script: 'meta-validate/scripts/meta-validate', flag: '-ObjectPath', path: 'Catalogs/Контрагенты' }, + }, + { + name: 'meta-compile: Справочник Номенклатура', + script: 'meta-compile/scripts/meta-compile', + input: { + type: 'Catalog', name: 'Номенклатура', + codeLength: 11, descriptionLength: 150, + attributes: [ + { name: 'Артикул', type: 'String', length: 25 }, + { name: 'ЕдиницаИзмерения', type: 'String', length: 10 }, + ], + }, + args: { '-JsonPath': '{inputFile}', '-OutputDir': '{workDir}' }, + validate: { script: 'meta-validate/scripts/meta-validate', flag: '-ObjectPath', path: 'Catalogs/Номенклатура' }, + }, + { + name: 'meta-compile: Перечисление ВидыНоменклатуры', + script: 'meta-compile/scripts/meta-compile', + input: { + type: 'Enum', name: 'ВидыНоменклатуры', + values: ['Товар', 'Услуга', 'Работа'], + }, + args: { '-JsonPath': '{inputFile}', '-OutputDir': '{workDir}' }, + validate: { script: 'meta-validate/scripts/meta-validate', flag: '-ObjectPath', path: 'Enums/ВидыНоменклатуры' }, + }, + { + name: 'meta-compile: Документ ПриходнаяНакладная', + script: 'meta-compile/scripts/meta-compile', + input: { + type: 'Document', name: 'ПриходнаяНакладная', + attributes: [ + { name: 'Контрагент', type: 'String', length: 100 }, + ], + tabularSections: [{ + name: 'Товары', + attributes: [ + { name: 'Номенклатура', type: 'String', length: 150 }, + { name: 'Количество', type: 'Number', length: 15, precision: 3 }, + { name: 'Цена', type: 'Number', length: 15, precision: 2 }, + { name: 'Сумма', type: 'Number', length: 15, precision: 2 }, + ], + }], + }, + args: { '-JsonPath': '{inputFile}', '-OutputDir': '{workDir}' }, + validate: { script: 'meta-validate/scripts/meta-validate', flag: '-ObjectPath', path: 'Documents/ПриходнаяНакладная' }, + }, + { + name: 'meta-compile: Регистр накопления ОстаткиТоваров', + script: 'meta-compile/scripts/meta-compile', + input: { + type: 'AccumulationRegister', name: 'ОстаткиТоваров', + registerType: 'Balance', + dimensions: [ + { name: 'Номенклатура', type: 'String', length: 150 }, + ], + resources: [ + { name: 'Количество', type: 'Number', length: 15, precision: 3 }, + { name: 'Сумма', type: 'Number', length: 15, precision: 2 }, + ], + }, + args: { '-JsonPath': '{inputFile}', '-OutputDir': '{workDir}' }, + validate: { script: 'meta-validate/scripts/meta-validate', flag: '-ObjectPath', path: 'AccumulationRegisters/ОстаткиТоваров' }, + }, + { + name: 'meta-compile: Регистр сведений КурсыВалют', + script: 'meta-compile/scripts/meta-compile', + input: { + type: 'InformationRegister', name: 'КурсыВалют', + writeMode: 'RecorderSubordinate', + dimensions: [ + { name: 'Валюта', type: 'String', length: 10 }, + ], + resources: [ + { name: 'Курс', type: 'Number', length: 10, precision: 4 }, + { name: 'Кратность', type: 'Number', length: 10 }, + ], + }, + args: { '-JsonPath': '{inputFile}', '-OutputDir': '{workDir}' }, + validate: { script: 'meta-validate/scripts/meta-validate', flag: '-ObjectPath', path: 'InformationRegisters/КурсыВалют' }, + }, + { + name: 'meta-compile: Константа ОсновнаяВалюта', + script: 'meta-compile/scripts/meta-compile', + input: { + type: 'Constant', name: 'ОсновнаяВалюта', + valueType: 'String', length: 10, + }, + args: { '-JsonPath': '{inputFile}', '-OutputDir': '{workDir}' }, + validate: { script: 'meta-validate/scripts/meta-validate', flag: '-ObjectPath', path: 'Constants/ОсновнаяВалюта' }, + }, + { + name: 'meta-compile: Общий модуль ОбщиеФункции', + script: 'meta-compile/scripts/meta-compile', + input: { + type: 'CommonModule', name: 'ОбщиеФункции', + server: true, clientManagedApplication: false, + }, + args: { '-JsonPath': '{inputFile}', '-OutputDir': '{workDir}' }, + validate: { script: 'meta-validate/scripts/meta-validate', flag: '-ObjectPath', path: 'CommonModules/ОбщиеФункции' }, + }, + { + name: 'meta-compile: Отчёт ОстаткиТоваров', + script: 'meta-compile/scripts/meta-compile', + input: { + type: 'Report', name: 'ОстаткиТоваров', + }, + args: { '-JsonPath': '{inputFile}', '-OutputDir': '{workDir}' }, + validate: { script: 'meta-validate/scripts/meta-validate', flag: '-ObjectPath', path: 'Reports/ОстаткиТоваров' }, + }, + + // ── 3. Form for catalog ── + { + name: 'form-add: Форма элемента Контрагенты', + script: 'form-add/scripts/form-add', + args: { '-ObjectPath': '{workDir}/Catalogs/Контрагенты.xml', '-FormName': 'ФормаЭлемента' }, + }, + { + name: 'form-compile: Форма элемента Контрагенты', + script: 'form-compile/scripts/form-compile', + input: { + title: 'Контрагент', + attributes: [ + { name: 'Объект', type: 'FormDataStructure', main: true }, + ], + elements: [ + { input: 'Наименование', path: 'Объект.Description', title: 'Наименование' }, + { input: 'ИНН', path: 'Объект.ИНН', title: 'ИНН' }, + { input: 'Телефон', path: 'Объект.Телефон', title: 'Телефон' }, + ], + }, + args: { '-JsonPath': '{inputFile}', '-OutputPath': '{workDir}/Catalogs/Контрагенты/Forms/ФормаЭлемента/Ext/Form.xml' }, + validate: { script: 'form-validate/scripts/form-validate', flag: '-FormPath', path: 'Catalogs/Контрагенты/Forms/ФормаЭлемента/Ext/Form.xml' }, + }, + + // ── 4. Form for document ── + { + name: 'form-add: Форма документа ПриходнаяНакладная', + script: 'form-add/scripts/form-add', + args: { '-ObjectPath': '{workDir}/Documents/ПриходнаяНакладная.xml', '-FormName': 'ФормаДокумента' }, + }, + { + name: 'form-compile: Форма документа ПриходнаяНакладная', + script: 'form-compile/scripts/form-compile', + input: { + title: 'Приходная накладная', + attributes: [ + { name: 'Объект', type: 'FormDataStructure', main: true }, + ], + elements: [ + { input: 'Контрагент', path: 'Объект.Контрагент', title: 'Контрагент' }, + { table: 'Товары', path: 'Объект.Товары', title: 'Товары', columns: [ + { input: 'Номенклатура', path: 'Объект.Товары.Номенклатура', title: 'Номенклатура' }, + { input: 'Количество', path: 'Объект.Товары.Количество', title: 'Количество' }, + { input: 'Цена', path: 'Объект.Товары.Цена', title: 'Цена' }, + { input: 'Сумма', path: 'Объект.Товары.Сумма', title: 'Сумма' }, + ]}, + ], + }, + args: { '-JsonPath': '{inputFile}', '-OutputPath': '{workDir}/Documents/ПриходнаяНакладная/Forms/ФормаДокумента/Ext/Form.xml' }, + validate: { script: 'form-validate/scripts/form-validate', flag: '-FormPath', path: 'Documents/ПриходнаяНакладная/Forms/ФормаДокумента/Ext/Form.xml' }, + }, + + // ── 5. DCS for report ── + { + name: 'skd-compile: Схема отчёта ОстаткиТоваров', + script: 'skd-compile/scripts/skd-compile', + input: { + dataSets: [{ + name: 'НаборДанных', + type: 'Query', + query: 'SELECT Номенклатура, Количество, Сумма FROM AccumulationRegister.ОстаткиТоваров', + }], + fields: [ + { name: 'Номенклатура', title: 'Номенклатура' }, + { name: 'Количество', title: 'Количество' }, + { name: 'Сумма', title: 'Сумма' }, + ], + }, + args: { '-DefinitionFile': '{inputFile}', '-OutputPath': '{workDir}/Reports/ОстаткиТоваров/Templates/ОсновнаяСхемаКомпоновкиДанных/Ext/Template.xml' }, + validate: { script: 'skd-validate/scripts/skd-validate', flag: '-TemplatePath', path: 'Reports/ОстаткиТоваров/Templates/ОсновнаяСхемаКомпоновкиДанных/Ext/Template.xml' }, + }, + + // ── 6. Subsystem ── + { + name: 'subsystem-compile: Подсистема Склад', + script: 'subsystem-compile/scripts/subsystem-compile', + input: { + name: 'Склад', + synonym: 'Склад', + content: [ + 'Catalogs.Контрагенты', + 'Catalogs.Номенклатура', + 'Documents.ПриходнаяНакладная', + 'AccumulationRegisters.ОстаткиТоваров', + 'Reports.ОстаткиТоваров', + ], + }, + args: { '-DefinitionFile': '{inputFile}', '-OutputDir': '{workDir}' }, + validate: { script: 'subsystem-validate/scripts/subsystem-validate', flag: '-SubsystemPath', path: 'Subsystems/Склад' }, + }, + + // ── 7. Role ── + { + name: 'role-compile: Роль Кладовщик', + script: 'role-compile/scripts/role-compile', + input: { + name: 'Кладовщик', + objects: [ + 'Catalog.Контрагенты: Read View', + 'Catalog.Номенклатура: Read View', + 'Document.ПриходнаяНакладная: Read View Add Update', + 'AccumulationRegister.ОстаткиТоваров: Read', + 'Report.ОстаткиТоваров: Use View', + ], + }, + args: { '-JsonPath': '{inputFile}', '-OutputDir': '{workDir}' }, + validate: { script: 'role-validate/scripts/role-validate', flag: '-RightsPath', path: 'Roles/Кладовщик' }, + }, + + // ── 8. Add all objects to Configuration.xml ── + { + name: 'cf-edit: Регистрация объектов в конфигурации', + script: 'cf-edit/scripts/cf-edit', + input: [ + { operation: 'add-childObject', value: 'Catalog.Контрагенты' }, + { operation: 'add-childObject', value: 'Catalog.Номенклатура' }, + { operation: 'add-childObject', value: 'Enum.ВидыНоменклатуры' }, + { operation: 'add-childObject', value: 'Document.ПриходнаяНакладная' }, + { operation: 'add-childObject', value: 'AccumulationRegister.ОстаткиТоваров' }, + { operation: 'add-childObject', value: 'InformationRegister.КурсыВалют' }, + { operation: 'add-childObject', value: 'Constant.ОсновнаяВалюта' }, + { operation: 'add-childObject', value: 'CommonModule.ОбщиеФункции' }, + { operation: 'add-childObject', value: 'Report.ОстаткиТоваров' }, + { operation: 'add-childObject', value: 'Subsystem.Склад' }, + { operation: 'add-childObject', value: 'Role.Кладовщик' }, + ], + args: { '-ConfigPath': '{workDir}', '-DefinitionFile': '{inputFile}' }, + }, + + // ── 9. Final validation ── + { + name: 'cf-validate: Финальная валидация конфигурации', + script: 'cf-validate/scripts/cf-validate', + args: { '-ConfigPath': '{workDir}' }, + }, +]; diff --git a/tests/skills/integration/build-epf.test.mjs b/tests/skills/integration/build-epf.test.mjs new file mode 100644 index 00000000..1a88de26 --- /dev/null +++ b/tests/skills/integration/build-epf.test.mjs @@ -0,0 +1,108 @@ +// build-epf.test.mjs — Integration test: build an external data processor (EPF) from scratch +// Steps: epf-init → epf-add-form → form-compile → template-add → mxl-compile → epf-validate + +export const name = 'Сборка внешней обработки с нуля'; +export const setup = 'none'; + +export const steps = [ + // ── 1. Init empty EPF ── + { + name: 'epf-init: пустая обработка ТестоваяОбработка', + script: 'epf-init/scripts/init', + args: { '-Name': 'ТестоваяОбработка', '-SrcDir': '{workDir}' }, + validate: { script: 'epf-validate/scripts/epf-validate', flag: '-ObjectPath', path: 'ТестоваяОбработка' }, + }, + + // ── 2. Add form ── + { + name: 'epf-add-form: Форма к ТестоваяОбработка', + script: 'epf-add-form/scripts/add-form', + args: { '-ProcessorName': 'ТестоваяОбработка', '-FormName': 'Форма', '-SrcDir': '{workDir}' }, + validate: { script: 'epf-validate/scripts/epf-validate', flag: '-ObjectPath', path: 'ТестоваяОбработка' }, + }, + + // ── 3. Compile form ── + { + name: 'form-compile: Форма с заголовком и полями ввода', + script: 'form-compile/scripts/form-compile', + input: { + title: 'Тестовая обработка', + attributes: [ + { name: 'Объект', type: 'FormDataStructure', main: true }, + { name: 'Наименование', type: 'String' }, + { name: 'Количество', type: 'Number' }, + ], + elements: [ + { input: 'Наименование', path: 'Наименование', title: 'Наименование' }, + { input: 'Количество', path: 'Количество', title: 'Количество' }, + ], + }, + args: { + '-JsonPath': '{inputFile}', + '-OutputPath': '{workDir}/ТестоваяОбработка/Forms/Форма/Ext/Form.xml', + }, + validate: { + script: 'form-validate/scripts/form-validate', + flag: '-FormPath', + path: 'ТестоваяОбработка/Forms/Форма/Ext/Form.xml', + }, + }, + + // ── 4. Add spreadsheet template ── + { + name: 'template-add: Макет к ТестоваяОбработка', + script: 'template-add/scripts/add-template', + args: { + '-ObjectName': 'ТестоваяОбработка', + '-TemplateName': 'Макет', + '-TemplateType': 'SpreadsheetDocument', + '-SrcDir': '{workDir}', + }, + }, + + // ── 5. Compile MXL template ── + { + name: 'mxl-compile: простой макет с двумя областями', + script: 'mxl-compile/scripts/mxl-compile', + input: { + columns: 3, + defaultWidth: 40, + areas: [ + { + name: 'Шапка', + rows: [ + { cells: [ + { col: 1, span: 3, text: 'Заголовок документа' }, + ]}, + ], + }, + { + name: 'Строка', + rows: [ + { cells: [ + { col: 1, param: 'НомерСтроки' }, + { col: 2, param: 'Наименование' }, + { col: 3, param: 'Сумма' }, + ]}, + ], + }, + ], + }, + args: { + '-JsonPath': '{inputFile}', + '-OutputPath': '{workDir}/ТестоваяОбработка/Templates/Макет/Ext/Template.xml', + }, + validate: { + script: 'mxl-validate/scripts/mxl-validate', + flag: '-TemplatePath', + path: 'ТестоваяОбработка/Templates/Макет/Ext/Template.xml', + }, + }, + + // ── 6. Final validation ── + { + name: 'epf-validate: Финальная валидация обработки', + script: 'epf-validate/scripts/epf-validate', + args: { '-ObjectPath': '{workDir}/ТестоваяОбработка' }, + }, +]; diff --git a/tests/skills/runner.mjs b/tests/skills/runner.mjs index ce21d61d..3785aa69 100644 --- a/tests/skills/runner.mjs +++ b/tests/skills/runner.mjs @@ -1,6 +1,6 @@ #!/usr/bin/env node -// skill-test-runner v0.3 — Snapshot-based regression tests for 1C skill scripts -// Usage: node tests/skills/runner.mjs [filter] [--update-snapshots] [--runtime python] [--json report.json] [--concurrency N] +// skill-test-runner v0.4 — Snapshot-based regression tests for 1C skill scripts +// Usage: node tests/skills/runner.mjs [filter] [--update-snapshots] [--runtime python] [--json report.json] [--concurrency N] [--with-validation] import { execFileSync, execFile } from 'child_process'; import { existsSync, mkdirSync, mkdtempSync, rmSync, readFileSync, writeFileSync, @@ -19,7 +19,7 @@ const CACHE = resolve(ROOT, '.cache'); // ─── CLI args ─────────────────────────────────────────────────────────────── function parseArgs(argv) { - const args = { filter: null, updateSnapshots: false, runtime: 'powershell', jsonReport: null, verbose: false, concurrency: cpus().length }; + const args = { filter: null, updateSnapshots: false, runtime: 'powershell', jsonReport: null, verbose: false, concurrency: cpus().length, withValidation: false }; const rest = argv.slice(2); for (let i = 0; i < rest.length; i++) { const a = rest[i]; @@ -28,6 +28,7 @@ function parseArgs(argv) { if (a === '--json' && rest[i + 1]) { args.jsonReport = rest[++i]; continue; } if (a === '--verbose' || a === '-v') { args.verbose = true; continue; } if (a === '--concurrency' && rest[i + 1]) { args.concurrency = parseInt(rest[++i], 10) || 1; continue; } + if (a === '--with-validation') { args.withValidation = true; continue; } if (!a.startsWith('--') && !args.filter) { args.filter = a.replace(/\\/g, '/'); continue; } } return args; @@ -389,6 +390,49 @@ function updateSnapshot(workDir, snapshotDir, snapshotConfig) { } } +// ─── Post-run validation ───────────────────────────────────────────────────── + +function resolveValidatePath(postValidate, caseData, workDir) { + const pathFrom = postValidate.pathFrom || 'validatePath'; + if (pathFrom === 'workDir') return workDir; + const relPath = caseData[pathFrom] || caseData.params?.[pathFrom]; + if (!relPath) return null; // no path — skip validation for this case + const full = join(workDir, relPath); + // For flat metadata objects (e.g. DefinedTypes/X) the path is a file, not a dir + if (!existsSync(full) && existsSync(full + '.xml')) return full + '.xml'; + return full; +} + +function runPostValidation(postValidate, caseData, workDir, runtime) { + const targetPath = resolveValidatePath(postValidate, caseData, workDir); + if (!targetPath) return null; // no validatePath in case — skip silently + + const script = resolveScript(postValidate.script, runtime); + const args = [postValidate.flag, targetPath]; + try { + execSkillRaw(runtime, script, args); + return null; // validation passed + } catch (e) { + const detail = e.stderr?.trim() || e.stdout?.trim() || e.message; + return `Validation failed (${postValidate.script}):\n${detail.substring(0, 500)}`; + } +} + +async function runPostValidationAsync(postValidate, caseData, workDir, runtime) { + const targetPath = resolveValidatePath(postValidate, caseData, workDir); + if (!targetPath) return null; + + const script = resolveScript(postValidate.script, runtime); + const args = [postValidate.flag, targetPath]; + try { + await execSkillAsync(runtime, script, args); + return null; + } catch (e) { + const detail = e.stderr?.trim() || e.stdout?.trim() || e.message; + return `Validation failed (${postValidate.script}):\n${detail.substring(0, 500)}`; + } +} + // ─── Run a single case ────────────────────────────────────────────────────── async function runCaseAsync(testCase, opts) { @@ -494,8 +538,15 @@ async function runCaseAsync(testCase, opts) { } } + // Post-run validation (on real output, before cleanup) + let validationError = null; + if (opts.withValidation && !caseData.expectError && !caseData.skipValidation && exitCode === 0 && skillConfig.postValidate) { + validationError = await runPostValidationAsync(skillConfig.postValidate, caseData, workDir, opts.runtime); + if (validationError) errors.push(validationError); + } + const elapsed = ((performance.now() - t0) / 1000).toFixed(1); - return { id: testCase.id, skill: testCase.skillDir, name: testCase.name, passed: errors.length === 0, errors, elapsed: `${elapsed}s`, snapshotUpdated: opts.updateSnapshots && !caseData.expectError && !workspace.readOnly }; + return { id: testCase.id, skill: testCase.skillDir, name: testCase.name, passed: errors.length === 0, errors, elapsed: `${elapsed}s`, snapshotUpdated: opts.updateSnapshots && !caseData.expectError && !workspace.readOnly, validationError: !!validationError }; } catch (e) { const elapsed = ((performance.now() - t0) / 1000).toFixed(1); return { id: testCase.id, skill: testCase.skillDir, name: testCase.name, passed: false, errors: [`Runner error: ${e.message}`], elapsed: `${elapsed}s` }; @@ -643,6 +694,13 @@ function runCase(testCase, opts) { } } + // Post-run validation (on real output, before cleanup) + let validationError = null; + if (opts.withValidation && !caseData.expectError && !caseData.skipValidation && exitCode === 0 && skillConfig.postValidate) { + validationError = runPostValidation(skillConfig.postValidate, caseData, workDir, opts.runtime); + if (validationError) errors.push(validationError); + } + const elapsed = ((performance.now() - t0) / 1000).toFixed(1); return { id: testCase.id, @@ -652,6 +710,7 @@ function runCase(testCase, opts) { errors, elapsed: `${elapsed}s`, snapshotUpdated: opts.updateSnapshots && !caseData.expectError && !workspace.readOnly, + validationError: !!validationError, }; } catch (e) { @@ -696,8 +755,8 @@ function printReport(results, opts, wallTime) { // Verbose: show every case with id console.log(` ${skill}`); for (const r of cases) { - const icon = r.skipped ? '\u25CB' : r.passed ? '\u2713' : '\u2717'; - const suffix = r.skipped ? ' [skipped]' : r.snapshotUpdated ? ' [snapshot updated]' : ''; + const icon = r.skipped ? '\u25CB' : r.passed ? '\u2713' : r.validationError ? '\u2717' : '\u2717'; + const suffix = r.skipped ? ' [skipped]' : r.snapshotUpdated ? ' [snapshot updated]' : r.validationError ? ' [VFAIL]' : ''; console.log(` ${icon} ${r.name} (${r.elapsed}) ${r.id}${suffix}`); if (!r.passed) { for (const err of r.errors) { @@ -727,10 +786,12 @@ function printReport(results, opts, wallTime) { } const cpuTime = results.reduce((s, r) => s + parseFloat(r.elapsed), 0).toFixed(1); + const vfails = results.filter(r => r.validationError).length; console.log(''); const skippedStr = skipped.length > 0 ? ` | Skipped: ${skipped.length}` : ''; + const vfailStr = vfails > 0 ? ` | VFail: ${vfails}` : ''; const timeStr = wallTime ? `${wallTime}s wall, ${cpuTime}s cpu` : `${cpuTime}s`; - console.log(` Passed: ${passed.length} | Failed: ${failed.length}${skippedStr} | Total: ${results.length} | Time: ${timeStr}`); + console.log(` Passed: ${passed.length} | Failed: ${failed.length}${vfailStr}${skippedStr} | Total: ${results.length} | Time: ${timeStr}`); console.log(''); if (opts.jsonReport) { @@ -776,47 +837,190 @@ async function runPool(cases, opts) { return results; } +// ─── Integration tests ────────────────────────────────────────────────────── + +const INTEGRATION = resolve(ROOT, 'integration'); + +async function discoverIntegration(filter) { + if (!existsSync(INTEGRATION)) return []; + const results = []; + for (const file of readdirSync(INTEGRATION)) { + if (!file.endsWith('.test.mjs')) continue; + const testName = file.replace(/\.test\.mjs$/, ''); + const id = `integration/${testName}`; + if (filter && !id.startsWith(filter) && !id.includes(filter)) continue; + const mod = await import(`file://${join(INTEGRATION, file).replace(/\\/g, '/')}`); + results.push({ id, name: mod.name || testName, steps: mod.steps || [], file, cache: mod.cache, setup: mod.setup || 'empty-config' }); + } + return results; +} + +async function runIntegrationTest(test, opts) { + const t0 = performance.now(); + const stepResults = []; + let workspace = null; + + try { + // Start from configured fixture or empty workspace + const fixturePath = test.setup === 'none' ? null : ensureSetup(test.setup, opts.runtime, CASES); + workspace = createWorkspace(fixturePath, false); + const workDir = workspace.path; + + for (let i = 0; i < test.steps.length; i++) { + const step = test.steps[i]; + const stepT0 = performance.now(); + + // Write input if provided + let inputFile = null; + if (step.input) { + inputFile = join(workDir, '__input.json'); + writeFileSync(inputFile, JSON.stringify(step.input, null, 2), 'utf8'); + } + + // Resolve args: replace {workDir} and {inputFile} + const script = resolveScript(step.script, opts.runtime); + const args = []; + for (const [flag, value] of Object.entries(step.args || {})) { + args.push(flag); + if (value === true) continue; // switch + args.push(String(value) + .replace('{workDir}', workDir) + .replace('{inputFile}', inputFile || '')); + } + + // Execute + let stdout = '', stderr = ''; + try { + stdout = await execSkillAsync(opts.runtime, script, args); + } catch (e) { + const detail = e.stderr?.trim() || e.stdout?.trim() || e.message; + stepResults.push({ name: step.name, passed: false, error: `Step ${i + 1} failed: ${detail.substring(0, 500)}` }); + break; // stop on first failure + } + + if (inputFile && existsSync(inputFile)) rmSync(inputFile); + + // Post-step validation + if (opts.withValidation && step.validate) { + const valScript = resolveScript(step.validate.script, opts.runtime); + let valPath = workDir; + if (step.validate.path) { + valPath = join(workDir, step.validate.path); + if (!existsSync(valPath) && existsSync(valPath + '.xml')) valPath += '.xml'; + } + try { + await execSkillAsync(opts.runtime, valScript, [step.validate.flag, valPath]); + } catch (e) { + const detail = e.stderr?.trim() || e.stdout?.trim() || e.message; + stepResults.push({ name: step.name, passed: false, error: `Validation: ${detail.substring(0, 500)}` }); + break; + } + } + + const stepElapsed = ((performance.now() - stepT0) / 1000).toFixed(1); + stepResults.push({ name: step.name, passed: true, elapsed: `${stepElapsed}s` }); + } + + // Cache result if configured + if (test.cache && stepResults.every(s => s.passed)) { + const cachePath = join(CACHE, test.cache); + if (existsSync(cachePath)) rmSync(cachePath, { recursive: true, force: true }); + cpSync(workDir, cachePath, { recursive: true }); + } + + const allPassed = stepResults.every(s => s.passed); + const elapsed = ((performance.now() - t0) / 1000).toFixed(1); + return { id: test.id, name: test.name, passed: allPassed, steps: stepResults, elapsed: `${elapsed}s`, errors: allPassed ? [] : stepResults.filter(s => !s.passed).map(s => s.error) }; + } catch (e) { + const elapsed = ((performance.now() - t0) / 1000).toFixed(1); + return { id: test.id, name: test.name, passed: false, steps: stepResults, elapsed: `${elapsed}s`, errors: [`Runner error: ${e.message}`] }; + } finally { + if (workspace) cleanupWorkspace(workspace); + } +} + +function printIntegrationReport(results, opts) { + console.log(''); + for (const r of results) { + const icon = r.passed ? '\u2713' : '\u2717'; + console.log(` ${icon} ${r.name} (${r.elapsed}) ${r.id}`); + for (const step of r.steps) { + const sIcon = step.passed ? '\u2713' : '\u2717'; + console.log(` ${sIcon} ${step.name}${step.elapsed ? ` (${step.elapsed})` : ''}`); + if (!step.passed) { + for (const line of step.error.split('\n')) { + console.log(` ${line}`); + } + } + } + } + const passed = results.filter(r => r.passed).length; + const failed = results.filter(r => !r.passed).length; + console.log(''); + console.log(` Integration: Passed: ${passed} | Failed: ${failed} | Total: ${results.length}`); + console.log(''); + return failed === 0; +} + // ─── Main ─────────────────────────────────────────────────────────────────── async function main() { const opts = parseArgs(process.argv); - const cases = discoverCases(opts.filter); - - if (cases.length === 0) { - console.log('No test cases found.' + (opts.filter ? ` Filter: "${opts.filter}"` : '')); - process.exit(0); - } - - const parallel = opts.concurrency > 1; - const modeStr = parallel ? `${opts.concurrency} workers` : 'sequential'; - console.log(`\nRunning ${cases.length} test(s)... [runtime: ${opts.runtime}, ${modeStr}]`); - - // Ensure cache dir exists mkdirSync(CACHE, { recursive: true }); - // Pre-warm shared fixtures before parallel run - const setups = new Set(cases.map(c => c.caseData.setup || c.skillConfig.setup || 'none')); - for (const setup of setups) { - if (setup === 'empty-config' || setup === 'base-config') { - try { ensureSetup(setup, opts.runtime, CASES); } catch {} + const isIntegrationFilter = opts.filter && opts.filter.startsWith('integration'); + + // Run integration tests if filter matches or no filter (run both) + let integrationOk = true; + if (isIntegrationFilter || !opts.filter) { + const integrationTests = await discoverIntegration(opts.filter); + if (integrationTests.length > 0) { + const valStr = opts.withValidation ? ', +validation' : ''; + console.log(`\nRunning ${integrationTests.length} integration test(s)... [runtime: ${opts.runtime}${valStr}]`); + const integrationResults = []; + for (const test of integrationTests) { + integrationResults.push(await runIntegrationTest(test, opts)); + } + integrationOk = printIntegrationReport(integrationResults, opts); } } - const wallStart = performance.now(); - let results; + // Run unit cases (skip if filter is purely integration) + let casesOk = true; + if (!isIntegrationFilter) { + const cases = discoverCases(opts.filter); + if (cases.length > 0) { + const parallel = opts.concurrency > 1; + const modeStr = parallel ? `${opts.concurrency} workers` : 'sequential'; + const valStr = opts.withValidation ? ', +validation' : ''; + console.log(`\nRunning ${cases.length} test(s)... [runtime: ${opts.runtime}, ${modeStr}${valStr}]`); - if (parallel) { - results = await runPool(cases, opts); - } else { - results = []; - for (const tc of cases) { - results.push(await runCaseAsync(tc, opts)); + // Pre-warm shared fixtures before parallel run + const setups = new Set(cases.map(c => c.caseData.setup || c.skillConfig.setup || 'none')); + for (const setup of setups) { + if (setup === 'empty-config' || setup === 'base-config') { + try { ensureSetup(setup, opts.runtime, CASES); } catch {} + } + } + + const wallStart = performance.now(); + let results; + if (parallel) { + results = await runPool(cases, opts); + } else { + results = []; + for (const tc of cases) { + results.push(await runCaseAsync(tc, opts)); + } + } + const wallTime = ((performance.now() - wallStart) / 1000).toFixed(1); + casesOk = printReport(results, opts, wallTime); + } else if (opts.filter && !isIntegrationFilter) { + console.log('No test cases found.' + (opts.filter ? ` Filter: "${opts.filter}"` : '')); } } - const wallTime = ((performance.now() - wallStart) / 1000).toFixed(1); - const allPassed = printReport(results, opts, wallTime); - process.exit(allPassed ? 0 : 1); + process.exit(integrationOk && casesOk ? 0 : 1); } main();