From 0d5d3451ff5559252dbf6d7d61d1daaf90ea9b8f Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sat, 11 Apr 2026 20:18:05 +0300 Subject: [PATCH] fix(cf-edit): reject add-childObject when object file is missing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cf-edit add-childObject was a low-level XML-manipulation operation with no file-existence validation — callers could register a reference to any Type.Name in Configuration.xml's ChildObjects without the underlying file existing on disk. Platform then refused to load: "Файл объекта не существует". The 4 failing tests (add-objects, remove-object, add-default-role, set-default-roles) all used this operation with fake references in either main input or preRun, and had no way to pass verify-snapshots because the cf-init-ed config had no actual object files. User observation: this is the tests being wrong, not the skill. meta-compile/role-compile/subsystem-compile already auto-register every new object in Configuration.xml as part of their normal flow (meta-compile.ps1:2949-3068, role-compile.ps1:667-747, subsystem-compile.ps1:430-506). Nobody should be calling cf-edit add-childObject to create a new object — they should be calling the profile skill. cf-edit add-childObject is only for rare recovery scenarios: rolled-back Configuration.xml with intact object files, re-import from DB dump that clobbered the root but left srcfiles. Changes: 1. cf-edit.ps1/py: Do-AddChildObject now checks that the target file exists at {ConfigDir}/{PluralDir}/{Name}.xml before registering. On miss, exits 1 with a message that names the expected path and points the user at the right skill (/meta-compile, /role-compile, or /subsystem-compile depending on type). TYPE_TO_DIR mapping for all 44 metadata types covers irregular plurals (FilterCriteria, BusinessProcesses, ChartsOfAccounts, ChartsOfCharacteristicTypes, ChartsOfCalculationTypes). 2. Tests: 4 existing cases rewritten to build realistic fixtures via meta-compile/role-compile preRun (both skills auto-register, so the resulting Configuration.xml already references the preRun objects). add-objects now exercises the round-trip recovery scenario: meta-compile creates Catalog.Товары and Document.ПриходТоваров (auto-registered) → cf-edit remove-childObject un-registers both (files remain) → main run re-registers via add-childObject. This tests exactly the rollback-recovery use case the operation exists for. 3. New add-missing-errors case: negative test with expectError: "Object file not found". Verifies the new hard-error path. 4. verify-snapshots.mjs: added symmetric expectError handling (runner.mjs already had it at line 514). If caseData.expectError is set, expect skill to fail; check stderr substring match; skip db-load and mark passed. Without this, negative tests would go red in verify-snapshots even though runner.mjs accepts them. 5. SKILL.md / reference.md: documented the new constraint and the redirection to profile skills. Kept mention of legitimate use case (rollback recovery). Bumped cf-edit.ps1/py v1.0→v1.1. Verification: - runner --filter cf-edit (PS1): 2/6 → 7/7 (6 positive + 1 negative) - runner --filter cf-edit --runtime python: 7/7 (dual-port clean) - verify-snapshots --skill cf-edit: 2/6 → 7/7 With this landed P3 from debug/snapshot-verify/NEXT-STEPS.md is closed. Co-Authored-By: Claude Opus 4.6 (1M context) --- .claude/skills/cf-edit/SKILL.md | 2 +- .claude/skills/cf-edit/reference.md | 4 + .claude/skills/cf-edit/scripts/cf-edit.ps1 | 42 ++- .claude/skills/cf-edit/scripts/cf-edit.py | 38 +- .../cases/cf-edit/add-default-role.json | 6 +- .../cases/cf-edit/add-missing-errors.json | 7 + tests/skills/cases/cf-edit/add-objects.json | 19 +- tests/skills/cases/cf-edit/remove-object.json | 11 +- .../cases/cf-edit/set-default-roles.json | 11 +- .../add-default-role/Roles/ПолныеПрава.xml | 32 ++ .../Roles/ПолныеПрава/Ext/Rights.xml | 9 + .../snapshots/add-objects/Catalogs/Товары.xml | 327 ++++++++++++++++++ .../Catalogs/Товары/Ext/ObjectModule.bsl | 0 .../add-objects/Documents/ПриходТоваров.xml | 214 ++++++++++++ .../ПриходТоваров/Ext/ObjectModule.bsl | 0 .../remove-object/Catalogs/Остающийся.xml | 327 ++++++++++++++++++ .../Catalogs/Остающийся/Ext/ObjectModule.bsl | 0 .../remove-object/Catalogs/Удаляемый.xml | 327 ++++++++++++++++++ .../Catalogs/Удаляемый/Ext/ObjectModule.bsl | 0 .../set-default-roles/Configuration.xml | 2 +- .../set-default-roles/Roles/Администратор.xml | 32 ++ .../Roles/Администратор/Ext/Rights.xml | 9 + .../set-default-roles/Roles/ПолныеПрава.xml | 32 ++ .../Roles/ПолныеПрава/Ext/Rights.xml | 9 + tests/skills/verify-snapshots.mjs | 15 + 25 files changed, 1461 insertions(+), 14 deletions(-) create mode 100644 tests/skills/cases/cf-edit/add-missing-errors.json create mode 100644 tests/skills/cases/cf-edit/snapshots/add-default-role/Roles/ПолныеПрава.xml create mode 100644 tests/skills/cases/cf-edit/snapshots/add-default-role/Roles/ПолныеПрава/Ext/Rights.xml create mode 100644 tests/skills/cases/cf-edit/snapshots/add-objects/Catalogs/Товары.xml create mode 100644 tests/skills/cases/cf-edit/snapshots/add-objects/Catalogs/Товары/Ext/ObjectModule.bsl create mode 100644 tests/skills/cases/cf-edit/snapshots/add-objects/Documents/ПриходТоваров.xml create mode 100644 tests/skills/cases/cf-edit/snapshots/add-objects/Documents/ПриходТоваров/Ext/ObjectModule.bsl create mode 100644 tests/skills/cases/cf-edit/snapshots/remove-object/Catalogs/Остающийся.xml create mode 100644 tests/skills/cases/cf-edit/snapshots/remove-object/Catalogs/Остающийся/Ext/ObjectModule.bsl create mode 100644 tests/skills/cases/cf-edit/snapshots/remove-object/Catalogs/Удаляемый.xml create mode 100644 tests/skills/cases/cf-edit/snapshots/remove-object/Catalogs/Удаляемый/Ext/ObjectModule.bsl create mode 100644 tests/skills/cases/cf-edit/snapshots/set-default-roles/Roles/Администратор.xml create mode 100644 tests/skills/cases/cf-edit/snapshots/set-default-roles/Roles/Администратор/Ext/Rights.xml create mode 100644 tests/skills/cases/cf-edit/snapshots/set-default-roles/Roles/ПолныеПрава.xml create mode 100644 tests/skills/cases/cf-edit/snapshots/set-default-roles/Roles/ПолныеПрава/Ext/Rights.xml diff --git a/.claude/skills/cf-edit/SKILL.md b/.claude/skills/cf-edit/SKILL.md index 34809a3e..e2c0e395 100644 --- a/.claude/skills/cf-edit/SKILL.md +++ b/.claude/skills/cf-edit/SKILL.md @@ -32,7 +32,7 @@ powershell.exe -NoProfile -File .claude/skills/cf-edit/scripts/cf-edit.ps1 -Conf | Операция | Формат Value | Описание | |----------|-------------|----------| | `modify-property` | `Ключ=Значение` (batch `;;`) | Изменить свойство | -| `add-childObject` | `Type.Name` (batch `;;`) | Добавить объект в ChildObjects | +| `add-childObject` | `Type.Name` (batch `;;`) | Зарегистрировать уже существующий файл объекта в ChildObjects. Для создания нового объекта используй `/meta-compile`, `/role-compile`, `/subsystem-compile` — они регистрируют автоматически | | `remove-childObject` | `Type.Name` (batch `;;`) | Удалить объект из ChildObjects | | `add-defaultRole` | `Role.Name` или `Name` | Добавить роль по умолчанию | | `remove-defaultRole` | `Role.Name` или `Name` | Удалить роль по умолчанию | diff --git a/.claude/skills/cf-edit/reference.md b/.claude/skills/cf-edit/reference.md index 02c6a36a..aaa6d99e 100644 --- a/.claude/skills/cf-edit/reference.md +++ b/.claude/skills/cf-edit/reference.md @@ -35,6 +35,10 @@ Формат: `Type.Name` — XML-тип и имя объекта через точку. +**Важно про `add-childObject`**: операция регистрирует в `` Configuration.xml только объект, **файл которого уже существует на диске** (например `Catalogs/Товары.xml`). Если файла нет — скрипт падает с exit 1 и подсказкой. Для создания нового объекта используй профильный навык — `/meta-compile` (Catalog, Document, Enum, Report, регистры и т.д.), `/role-compile` (Role), `/subsystem-compile` (Subsystem). Они создают файл И регистрируют его в Configuration.xml за один вызов. + +Когда `add-childObject` всё-таки нужен: откатили Configuration.xml (или перезаписали из выгрузки БД), а файлы объектов остались — нужно восстановить ссылки в ``. + При добавлении объект вставляется в каноническую позицию: 1. Находит последний элемент того же типа → вставляет после 2. Если тип отсутствует → находит последний элемент предшествующего типа → вставляет после diff --git a/.claude/skills/cf-edit/scripts/cf-edit.ps1 b/.claude/skills/cf-edit/scripts/cf-edit.ps1 index fcf91b47..f1b15576 100644 --- a/.claude/skills/cf-edit/scripts/cf-edit.ps1 +++ b/.claude/skills/cf-edit/scripts/cf-edit.ps1 @@ -1,4 +1,4 @@ -# cf-edit v1.0 — Edit 1C configuration root (Configuration.xml) +# cf-edit v1.1 — Edit 1C configuration root (Configuration.xml) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)][string]$ConfigPath, @@ -27,6 +27,7 @@ if (Test-Path $ConfigPath -PathType Container) { } if (-not (Test-Path $ConfigPath)) { Write-Error "File not found: $ConfigPath"; exit 1 } $resolvedPath = (Resolve-Path $ConfigPath).Path +$script:configDir = [System.IO.Path]::GetDirectoryName($resolvedPath) # --- Load XML with PreserveWhitespace --- $script:xmlDoc = New-Object System.Xml.XmlDocument @@ -87,6 +88,22 @@ $script:typeOrder = @( "BusinessProcess","Task","IntegrationService" ) +# --- Type → on-disk directory name (plural) --- +$script:typeToDir = @{ + "Language"="Languages"; "Subsystem"="Subsystems"; "StyleItem"="StyleItems"; "Style"="Styles" + "CommonPicture"="CommonPictures"; "SessionParameter"="SessionParameters"; "Role"="Roles"; "CommonTemplate"="CommonTemplates" + "FilterCriterion"="FilterCriteria"; "CommonModule"="CommonModules"; "CommonAttribute"="CommonAttributes"; "ExchangePlan"="ExchangePlans" + "XDTOPackage"="XDTOPackages"; "WebService"="WebServices"; "HTTPService"="HTTPServices"; "WSReference"="WSReferences" + "EventSubscription"="EventSubscriptions"; "ScheduledJob"="ScheduledJobs"; "SettingsStorage"="SettingsStorages"; "FunctionalOption"="FunctionalOptions" + "FunctionalOptionsParameter"="FunctionalOptionsParameters"; "DefinedType"="DefinedTypes"; "CommonCommand"="CommonCommands"; "CommandGroup"="CommandGroups" + "Constant"="Constants"; "CommonForm"="CommonForms"; "Catalog"="Catalogs"; "Document"="Documents" + "DocumentNumerator"="DocumentNumerators"; "Sequence"="Sequences"; "DocumentJournal"="DocumentJournals"; "Enum"="Enums" + "Report"="Reports"; "DataProcessor"="DataProcessors"; "InformationRegister"="InformationRegisters"; "AccumulationRegister"="AccumulationRegisters" + "ChartOfCharacteristicTypes"="ChartsOfCharacteristicTypes"; "ChartOfAccounts"="ChartsOfAccounts"; "AccountingRegister"="AccountingRegisters" + "ChartOfCalculationTypes"="ChartsOfCalculationTypes"; "CalculationRegister"="CalculationRegisters" + "BusinessProcess"="BusinessProcesses"; "Task"="Tasks"; "IntegrationService"="IntegrationServices" +} + # --- XML manipulation helpers (from subsystem-edit pattern) --- function Get-ChildIndent($container) { foreach ($child in $container.ChildNodes) { @@ -247,6 +264,29 @@ function Do-AddChildObject([string]$batchVal) { exit 1 } + # Check that the referenced object actually exists on disk. + # cf-edit add-childObject is a low-level operation for rare scenarios + # (e.g. restoring a rolled-back Configuration.xml when object files are intact). + # For creating NEW objects, meta-compile/role-compile/subsystem-compile already + # auto-register in Configuration.xml — calling cf-edit add-childObject there is + # unnecessary and error-prone. + $typeDir = $script:typeToDir[$typeName] + $objFile = Join-Path (Join-Path $script:configDir $typeDir) "$objNameVal.xml" + if (-not (Test-Path $objFile)) { + $hintSkill = switch ($typeName) { + "Subsystem" { "subsystem-compile" } + "Role" { "role-compile" } + default { "meta-compile" } + } + Write-Error @" +Object file not found: $typeDir/$objNameVal.xml +cf-edit add-childObject only references objects that already exist on disk. +To create a new $typeName, use $hintSkill (auto-registers in Configuration.xml): + /$hintSkill with {"type":"$typeName","name":"$objNameVal"} +"@ + exit 1 + } + # Dedup check $existing = $false foreach ($child in $script:childObjsEl.ChildNodes) { diff --git a/.claude/skills/cf-edit/scripts/cf-edit.py b/.claude/skills/cf-edit/scripts/cf-edit.py index 39313f06..30757246 100644 --- a/.claude/skills/cf-edit/scripts/cf-edit.py +++ b/.claude/skills/cf-edit/scripts/cf-edit.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# cf-edit v1.0 — Edit 1C configuration root (Configuration.xml) +# cf-edit v1.1 — Edit 1C configuration root (Configuration.xml) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse @@ -32,6 +32,22 @@ TYPE_ORDER = [ "BusinessProcess", "Task", "IntegrationService", ] +# Type → on-disk directory name (plural) +TYPE_TO_DIR = { + "Language": "Languages", "Subsystem": "Subsystems", "StyleItem": "StyleItems", "Style": "Styles", + "CommonPicture": "CommonPictures", "SessionParameter": "SessionParameters", "Role": "Roles", "CommonTemplate": "CommonTemplates", + "FilterCriterion": "FilterCriteria", "CommonModule": "CommonModules", "CommonAttribute": "CommonAttributes", "ExchangePlan": "ExchangePlans", + "XDTOPackage": "XDTOPackages", "WebService": "WebServices", "HTTPService": "HTTPServices", "WSReference": "WSReferences", + "EventSubscription": "EventSubscriptions", "ScheduledJob": "ScheduledJobs", "SettingsStorage": "SettingsStorages", "FunctionalOption": "FunctionalOptions", + "FunctionalOptionsParameter": "FunctionalOptionsParameters", "DefinedType": "DefinedTypes", "CommonCommand": "CommonCommands", "CommandGroup": "CommandGroups", + "Constant": "Constants", "CommonForm": "CommonForms", "Catalog": "Catalogs", "Document": "Documents", + "DocumentNumerator": "DocumentNumerators", "Sequence": "Sequences", "DocumentJournal": "DocumentJournals", "Enum": "Enums", + "Report": "Reports", "DataProcessor": "DataProcessors", "InformationRegister": "InformationRegisters", "AccumulationRegister": "AccumulationRegisters", + "ChartOfCharacteristicTypes": "ChartsOfCharacteristicTypes", "ChartOfAccounts": "ChartsOfAccounts", "AccountingRegister": "AccountingRegisters", + "ChartOfCalculationTypes": "ChartsOfCalculationTypes", "CalculationRegister": "CalculationRegisters", + "BusinessProcess": "BusinessProcesses", "Task": "Tasks", "IntegrationService": "IntegrationServices", +} + ML_PROPS = ["Synonym", "BriefInformation", "DetailedInformation", "Copyright", "VendorInformationAddress", "ConfigurationInformationAddress"] SCALAR_PROPS = ["Name", "Version", "Vendor", "Comment", "NamePrefix", "UpdateCatalogAddress"] REF_PROPS = ["DefaultLanguage"] @@ -171,6 +187,7 @@ def main(): print(f"File not found: {config_path}", file=sys.stderr) sys.exit(1) resolved_path = os.path.abspath(config_path) + config_dir = os.path.dirname(resolved_path) xml_parser = etree.XMLParser(remove_blank_text=False) tree = etree.parse(resolved_path, xml_parser) @@ -285,6 +302,25 @@ def main(): sys.exit(1) type_idx = TYPE_ORDER.index(type_name) + # Check that the referenced object actually exists on disk. + # cf-edit add-childObject is a low-level operation for rare scenarios + # (e.g. restoring a rolled-back Configuration.xml when object files are intact). + # For creating NEW objects, meta-compile/role-compile/subsystem-compile already + # auto-register in Configuration.xml — calling cf-edit add-childObject there is + # unnecessary and error-prone. + type_dir = TYPE_TO_DIR.get(type_name) + obj_file = os.path.join(config_dir, type_dir, f"{obj_name_val}.xml") + if not os.path.exists(obj_file): + hint_skill = {"Subsystem": "subsystem-compile", "Role": "role-compile"}.get(type_name, "meta-compile") + print( + f"Object file not found: {type_dir}/{obj_name_val}.xml\n" + f"cf-edit add-childObject only references objects that already exist on disk.\n" + f"To create a new {type_name}, use {hint_skill} (auto-registers in Configuration.xml):\n" + f' /{hint_skill} with {{"type":"{type_name}","name":"{obj_name_val}"}}', + file=sys.stderr + ) + sys.exit(1) + # Dedup exists = False for child in child_objs_el: diff --git a/tests/skills/cases/cf-edit/add-default-role.json b/tests/skills/cases/cf-edit/add-default-role.json index eb41e7ef..bbbcc9ab 100644 --- a/tests/skills/cases/cf-edit/add-default-role.json +++ b/tests/skills/cases/cf-edit/add-default-role.json @@ -2,9 +2,9 @@ "name": "Добавление роли по умолчанию", "preRun": [ { - "script": "cf-edit/scripts/cf-edit", - "input": [{ "operation": "add-childObject", "value": "Role.ПолныеПрава" }], - "args": { "-ConfigPath": "{workDir}", "-DefinitionFile": "{inputFile}" } + "script": "role-compile/scripts/role-compile", + "input": { "name": "ПолныеПрава" }, + "args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" } } ], "input": [ diff --git a/tests/skills/cases/cf-edit/add-missing-errors.json b/tests/skills/cases/cf-edit/add-missing-errors.json new file mode 100644 index 00000000..2d2b759b --- /dev/null +++ b/tests/skills/cases/cf-edit/add-missing-errors.json @@ -0,0 +1,7 @@ +{ + "name": "Ошибка при попытке добавить несуществующий объект", + "input": [ + { "operation": "add-childObject", "value": "Catalog.НесуществующийКаталог" } + ], + "expectError": "Object file not found" +} diff --git a/tests/skills/cases/cf-edit/add-objects.json b/tests/skills/cases/cf-edit/add-objects.json index ba2b860f..ce67c54f 100644 --- a/tests/skills/cases/cf-edit/add-objects.json +++ b/tests/skills/cases/cf-edit/add-objects.json @@ -1,5 +1,22 @@ { - "name": "Добавление объектов в конфигурацию", + "name": "Повторная регистрация объектов после отката Configuration.xml", + "preRun": [ + { + "script": "meta-compile/scripts/meta-compile", + "input": { "type": "Catalog", "name": "Товары" }, + "args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" } + }, + { + "script": "meta-compile/scripts/meta-compile", + "input": { "type": "Document", "name": "ПриходТоваров" }, + "args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" } + }, + { + "script": "cf-edit/scripts/cf-edit", + "input": [{ "operation": "remove-childObject", "value": "Catalog.Товары ;; Document.ПриходТоваров" }], + "args": { "-ConfigPath": "{workDir}", "-DefinitionFile": "{inputFile}" } + } + ], "input": [ { "operation": "add-childObject", "value": "Catalog.Товары ;; Document.ПриходТоваров" } ] diff --git a/tests/skills/cases/cf-edit/remove-object.json b/tests/skills/cases/cf-edit/remove-object.json index 3044b413..9f00ce00 100644 --- a/tests/skills/cases/cf-edit/remove-object.json +++ b/tests/skills/cases/cf-edit/remove-object.json @@ -2,9 +2,14 @@ "name": "Удаление объекта из конфигурации", "preRun": [ { - "script": "cf-edit/scripts/cf-edit", - "input": [{ "operation": "add-childObject", "value": "Catalog.Удаляемый ;; Catalog.Остающийся" }], - "args": { "-ConfigPath": "{workDir}", "-DefinitionFile": "{inputFile}" } + "script": "meta-compile/scripts/meta-compile", + "input": { "type": "Catalog", "name": "Удаляемый" }, + "args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" } + }, + { + "script": "meta-compile/scripts/meta-compile", + "input": { "type": "Catalog", "name": "Остающийся" }, + "args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" } } ], "input": [ diff --git a/tests/skills/cases/cf-edit/set-default-roles.json b/tests/skills/cases/cf-edit/set-default-roles.json index 77ccdb2b..3226689d 100644 --- a/tests/skills/cases/cf-edit/set-default-roles.json +++ b/tests/skills/cases/cf-edit/set-default-roles.json @@ -2,9 +2,14 @@ "name": "Замена списка ролей по умолчанию", "preRun": [ { - "script": "cf-edit/scripts/cf-edit", - "input": [{ "operation": "add-childObject", "value": "Role.ПолныеПрава ;; Role.Администратор" }], - "args": { "-ConfigPath": "{workDir}", "-DefinitionFile": "{inputFile}" } + "script": "role-compile/scripts/role-compile", + "input": { "name": "ПолныеПрава" }, + "args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" } + }, + { + "script": "role-compile/scripts/role-compile", + "input": { "name": "Администратор" }, + "args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" } } ], "input": [ diff --git a/tests/skills/cases/cf-edit/snapshots/add-default-role/Roles/ПолныеПрава.xml b/tests/skills/cases/cf-edit/snapshots/add-default-role/Roles/ПолныеПрава.xml new file mode 100644 index 00000000..083b0338 --- /dev/null +++ b/tests/skills/cases/cf-edit/snapshots/add-default-role/Roles/ПолныеПрава.xml @@ -0,0 +1,32 @@ + + + + + ПолныеПрава + + + ru + ПолныеПрава + + + + + + diff --git a/tests/skills/cases/cf-edit/snapshots/add-default-role/Roles/ПолныеПрава/Ext/Rights.xml b/tests/skills/cases/cf-edit/snapshots/add-default-role/Roles/ПолныеПрава/Ext/Rights.xml new file mode 100644 index 00000000..bc171791 --- /dev/null +++ b/tests/skills/cases/cf-edit/snapshots/add-default-role/Roles/ПолныеПрава/Ext/Rights.xml @@ -0,0 +1,9 @@ + + + false + true + false + diff --git a/tests/skills/cases/cf-edit/snapshots/add-objects/Catalogs/Товары.xml b/tests/skills/cases/cf-edit/snapshots/add-objects/Catalogs/Товары.xml new file mode 100644 index 00000000..15a89376 --- /dev/null +++ b/tests/skills/cases/cf-edit/snapshots/add-objects/Catalogs/Товары.xml @@ -0,0 +1,327 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + + Товары + + + ru + Товары + + + + false + HierarchyFoldersAndItems + false + 2 + true + true + + ToItems + 9 + 25 + String + Variable + WholeCatalog + false + true + AsDescription + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + Auto + InDialog + true + BothWays + + Catalog.Товары.StandardAttribute.Description + Catalog.Товары.StandardAttribute.Code + + Begin + DontUse + Directly + + + + + + + + + + + false + + + Automatic + Use + + + + + + DontUse + Auto + DontUse + false + false + + + + diff --git a/tests/skills/cases/cf-edit/snapshots/add-objects/Catalogs/Товары/Ext/ObjectModule.bsl b/tests/skills/cases/cf-edit/snapshots/add-objects/Catalogs/Товары/Ext/ObjectModule.bsl new file mode 100644 index 00000000..e69de29b diff --git a/tests/skills/cases/cf-edit/snapshots/add-objects/Documents/ПриходТоваров.xml b/tests/skills/cases/cf-edit/snapshots/add-objects/Documents/ПриходТоваров.xml new file mode 100644 index 00000000..93cbb4f1 --- /dev/null +++ b/tests/skills/cases/cf-edit/snapshots/add-objects/Documents/ПриходТоваров.xml @@ -0,0 +1,214 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + + ПриходТоваров + + + ru + Приход товаров + + + + true + + String + 11 + Variable + Year + true + true + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + + + Document.ПриходТоваров.StandardAttribute.Number + + DontUse + Begin + DontUse + Directly + + + + + + + Allow + Deny + AutoDelete + WriteModified + AutoFill + + true + true + false + + Automatic + Use + + + + + + Auto + DontUse + false + false + + + + diff --git a/tests/skills/cases/cf-edit/snapshots/add-objects/Documents/ПриходТоваров/Ext/ObjectModule.bsl b/tests/skills/cases/cf-edit/snapshots/add-objects/Documents/ПриходТоваров/Ext/ObjectModule.bsl new file mode 100644 index 00000000..e69de29b diff --git a/tests/skills/cases/cf-edit/snapshots/remove-object/Catalogs/Остающийся.xml b/tests/skills/cases/cf-edit/snapshots/remove-object/Catalogs/Остающийся.xml new file mode 100644 index 00000000..be5e69ab --- /dev/null +++ b/tests/skills/cases/cf-edit/snapshots/remove-object/Catalogs/Остающийся.xml @@ -0,0 +1,327 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + + Остающийся + + + ru + Остающийся + + + + false + HierarchyFoldersAndItems + false + 2 + true + true + + ToItems + 9 + 25 + String + Variable + WholeCatalog + false + true + AsDescription + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + Auto + InDialog + true + BothWays + + Catalog.Остающийся.StandardAttribute.Description + Catalog.Остающийся.StandardAttribute.Code + + Begin + DontUse + Directly + + + + + + + + + + + false + + + Automatic + Use + + + + + + DontUse + Auto + DontUse + false + false + + + + diff --git a/tests/skills/cases/cf-edit/snapshots/remove-object/Catalogs/Остающийся/Ext/ObjectModule.bsl b/tests/skills/cases/cf-edit/snapshots/remove-object/Catalogs/Остающийся/Ext/ObjectModule.bsl new file mode 100644 index 00000000..e69de29b diff --git a/tests/skills/cases/cf-edit/snapshots/remove-object/Catalogs/Удаляемый.xml b/tests/skills/cases/cf-edit/snapshots/remove-object/Catalogs/Удаляемый.xml new file mode 100644 index 00000000..a3532443 --- /dev/null +++ b/tests/skills/cases/cf-edit/snapshots/remove-object/Catalogs/Удаляемый.xml @@ -0,0 +1,327 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + + Удаляемый + + + ru + Удаляемый + + + + false + HierarchyFoldersAndItems + false + 2 + true + true + + ToItems + 9 + 25 + String + Variable + WholeCatalog + false + true + AsDescription + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + Auto + InDialog + true + BothWays + + Catalog.Удаляемый.StandardAttribute.Description + Catalog.Удаляемый.StandardAttribute.Code + + Begin + DontUse + Directly + + + + + + + + + + + false + + + Automatic + Use + + + + + + DontUse + Auto + DontUse + false + false + + + + diff --git a/tests/skills/cases/cf-edit/snapshots/remove-object/Catalogs/Удаляемый/Ext/ObjectModule.bsl b/tests/skills/cases/cf-edit/snapshots/remove-object/Catalogs/Удаляемый/Ext/ObjectModule.bsl new file mode 100644 index 00000000..e69de29b diff --git a/tests/skills/cases/cf-edit/snapshots/set-default-roles/Configuration.xml b/tests/skills/cases/cf-edit/snapshots/set-default-roles/Configuration.xml index 818ce369..8c0418de 100644 --- a/tests/skills/cases/cf-edit/snapshots/set-default-roles/Configuration.xml +++ b/tests/skills/cases/cf-edit/snapshots/set-default-roles/Configuration.xml @@ -249,8 +249,8 @@ Русский - Администратор ПолныеПрава + Администратор \ No newline at end of file diff --git a/tests/skills/cases/cf-edit/snapshots/set-default-roles/Roles/Администратор.xml b/tests/skills/cases/cf-edit/snapshots/set-default-roles/Roles/Администратор.xml new file mode 100644 index 00000000..2f9b3f1f --- /dev/null +++ b/tests/skills/cases/cf-edit/snapshots/set-default-roles/Roles/Администратор.xml @@ -0,0 +1,32 @@ + + + + + Администратор + + + ru + Администратор + + + + + + diff --git a/tests/skills/cases/cf-edit/snapshots/set-default-roles/Roles/Администратор/Ext/Rights.xml b/tests/skills/cases/cf-edit/snapshots/set-default-roles/Roles/Администратор/Ext/Rights.xml new file mode 100644 index 00000000..bc171791 --- /dev/null +++ b/tests/skills/cases/cf-edit/snapshots/set-default-roles/Roles/Администратор/Ext/Rights.xml @@ -0,0 +1,9 @@ + + + false + true + false + diff --git a/tests/skills/cases/cf-edit/snapshots/set-default-roles/Roles/ПолныеПрава.xml b/tests/skills/cases/cf-edit/snapshots/set-default-roles/Roles/ПолныеПрава.xml new file mode 100644 index 00000000..083b0338 --- /dev/null +++ b/tests/skills/cases/cf-edit/snapshots/set-default-roles/Roles/ПолныеПрава.xml @@ -0,0 +1,32 @@ + + + + + ПолныеПрава + + + ru + ПолныеПрава + + + + + + diff --git a/tests/skills/cases/cf-edit/snapshots/set-default-roles/Roles/ПолныеПрава/Ext/Rights.xml b/tests/skills/cases/cf-edit/snapshots/set-default-roles/Roles/ПолныеПрава/Ext/Rights.xml new file mode 100644 index 00000000..bc171791 --- /dev/null +++ b/tests/skills/cases/cf-edit/snapshots/set-default-roles/Roles/ПолныеПрава/Ext/Rights.xml @@ -0,0 +1,9 @@ + + + false + true + false + diff --git a/tests/skills/verify-snapshots.mjs b/tests/skills/verify-snapshots.mjs index 9b459a17..d514c4fc 100644 --- a/tests/skills/verify-snapshots.mjs +++ b/tests/skills/verify-snapshots.mjs @@ -470,9 +470,24 @@ async function verifyCase(skillName, caseName, skillConfig, caseData, opts) { const { args } = buildSkillArgs(skillConfig, caseData, workDir, inputFile, opts.runtime); const output = execSkill(opts.runtime, skillConfig.script, args); const lastLine = output.trim().split('\n').pop(); + if (caseData.expectError) { + log(skillName, false, 'expected non-zero exit but got success'); + result.errors.push(`${skillName}: expected error but got success`); + return result; + } log(skillName, true, lastLine); } catch (e) { const detail = (e.stderr || e.stdout || e.message).trim(); + if (caseData.expectError) { + if (typeof caseData.expectError === 'string' && !detail.includes(caseData.expectError)) { + log(skillName, false, `expected "${caseData.expectError}" in stderr, got: ${detail.substring(0, 200)}`); + result.errors.push(`${skillName}: stderr does not contain "${caseData.expectError}"`); + return result; + } + log(skillName, true, `(expected error) ${detail.substring(0, 100)}`); + result.passed = true; + return result; + } log(skillName, false, detail); result.errors.push(`${skillName} failed: ${detail.substring(0, 500)}`); return result;