From 57b0f95b5ffea8543368556148d1787b2f8c569a Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sun, 9 Aug 2026 20:15:39 +0300 Subject: [PATCH] =?UTF-8?q?fix(skills):=20=D1=80=D0=B5=D0=B3=D0=B8=D1=81?= =?UTF-8?q?=D1=82=D1=80=D0=BE=D0=BD=D0=B5=D0=B7=D0=B0=D0=B2=D0=B8=D1=81?= =?UTF-8?q?=D0=B8=D0=BC=D1=8B=D0=B5=20=D0=BA=D0=BB=D1=8E=D1=87=D0=B8=20DSL?= =?UTF-8?q?=20=D0=B2=20py-=D0=BF=D0=BE=D1=80=D1=82=D0=B0=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Дорожка DSL из кампании паритета. PowerShell читает свойства объекта из ConvertFrom-Json без учёта регистра, Python — точным совпадением, поэтому "Name" вместо "name" в py-порте молча не находился: навык печатал [OK], а свойство в выход не попадало. На skd-compile это давало схему без запроса. CIDict + ci_json (эталон — meta-compile) внесены в 10 портов, читающих пользовательский DSL: cf-edit, form-compile, form-edit, interface-edit, meta-edit, mxl-compile, role-compile, skd-compile, subsystem-compile, subsystem-edit. Обёрнуты точки разбора DSL, операций и JSON, приходящего значением параметра; реестр .v8-project.json намеренно не трогаем. skd-edit в список не входит: он принимает операцию через -Operation с choices, что уже закрыто ci_parse_args. Каждому навыку добавлен кейс lenient-key-case: вход с перемешанным регистром ключей, эталон один на оба порта — раннер гоняет обе среды, поэтому кейс сам по себе проверяет паритет. Проверка: 683/683 (PS), 680+3 skipped (PY), гарды 4/4, версии портов совпадают. Co-Authored-By: Claude Opus 5 (1M context) --- .claude/skills/cf-edit/scripts/cf-edit.ps1 | 2 +- .claude/skills/cf-edit/scripts/cf-edit.py | 45 +++- .../form-compile/scripts/form-compile.ps1 | 2 +- .../form-compile/scripts/form-compile.py | 45 +++- .../skills/form-edit/scripts/form-edit.ps1 | 2 +- .claude/skills/form-edit/scripts/form-edit.py | 41 ++- .../interface-edit/scripts/interface-edit.ps1 | 2 +- .../interface-edit/scripts/interface-edit.py | 51 +++- .../skills/meta-edit/scripts/meta-edit.ps1 | 2 +- .claude/skills/meta-edit/scripts/meta-edit.py | 41 ++- .../mxl-compile/scripts/mxl-compile.ps1 | 2 +- .../skills/mxl-compile/scripts/mxl-compile.py | 41 ++- .../role-compile/scripts/role-compile.ps1 | 2 +- .../role-compile/scripts/role-compile.py | 41 ++- .../skd-compile/scripts/skd-compile.ps1 | 2 +- .../skills/skd-compile/scripts/skd-compile.py | 43 ++- .../scripts/subsystem-compile.ps1 | 2 +- .../scripts/subsystem-compile.py | 41 ++- .../subsystem-edit/scripts/subsystem-edit.ps1 | 2 +- .../subsystem-edit/scripts/subsystem-edit.py | 45 +++- .../cases/cf-edit/lenient-key-case.json | 9 + .../lenient-key-case/Configuration.xml | 251 +++++++++++++++++ .../Ext/ClientApplicationInterface.xml | 18 ++ .../lenient-key-case/Languages/Русский.xml | 16 ++ .../cases/form-compile/lenient-key-case.json | 43 +++ .../lenient-key-case/Configuration.xml | 252 ++++++++++++++++++ .../DataProcessors/ТестРегистрКлючей.xml | 34 +++ .../ТестРегистрКлючей/Ext/ManagerModule.bsl | 0 .../ТестРегистрКлючей/Ext/ObjectModule.bsl | 0 .../ТестРегистрКлючей/Forms/Форма.xml | 22 ++ .../Forms/Форма/Ext/Form.xml | 26 ++ .../Forms/Форма/Ext/Form/Module.bsl | 19 ++ .../Ext/ClientApplicationInterface.xml | 18 ++ .../lenient-key-case/Languages/Русский.xml | 16 ++ .../cases/form-edit/lenient-key-case.json | 36 +++ .../lenient-key-case/Configuration.xml | 252 ++++++++++++++++++ .../DataProcessors/РедРегистр.xml | 34 +++ .../РедРегистр/Ext/ManagerModule.bsl | 0 .../РедРегистр/Ext/ObjectModule.bsl | 0 .../DataProcessors/РедРегистр/Forms/Форма.xml | 22 ++ .../РедРегистр/Forms/Форма/Ext/Form.xml | 15 ++ .../Forms/Форма/Ext/Form/Module.bsl | 19 ++ .../Ext/ClientApplicationInterface.xml | 18 ++ .../lenient-key-case/Languages/Русский.xml | 16 ++ .../interface-edit/lenient-key-case.json | 28 ++ .../lenient-key-case/Configuration.xml | 252 ++++++++++++++++++ .../Ext/ClientApplicationInterface.xml | 18 ++ .../lenient-key-case/Languages/Русский.xml | 16 ++ .../lenient-key-case/Subsystems/Продажи.xml | 25 ++ .../Subsystems/Продажи/CommandInterface | 7 + .../Subsystems/Продажи/Subsystems/Оптовые.xml | 17 ++ .../Продажи/Subsystems/Розничные.xml | 17 ++ .../cases/meta-edit/lenient-key-case.json | 26 ++ .../lenient-key-case/Catalogs/Контрагенты.xml | 136 ++++++++++ .../Catalogs/Контрагенты/Ext/ObjectModule.bsl | 0 .../lenient-key-case/Configuration.xml | 252 ++++++++++++++++++ .../Ext/ClientApplicationInterface.xml | 18 ++ .../lenient-key-case/Languages/Русский.xml | 16 ++ .../cases/mxl-compile/lenient-key-case.json | 27 ++ .../snapshots/lenient-key-case/Template.xml | 39 +++ .../cases/role-compile/lenient-key-case.json | 14 + .../lenient-key-case/Configuration.xml | 252 ++++++++++++++++++ .../Ext/ClientApplicationInterface.xml | 18 ++ .../lenient-key-case/Languages/Русский.xml | 16 ++ .../lenient-key-case/Roles/ПустаяРоль.xml | 15 ++ .../Roles/ПустаяРоль/Ext/Rights.xml | 6 + .../cases/skd-compile/lenient-key-case.json | 21 ++ .../snapshots/lenient-key-case/Template.xml | 34 +++ .../subsystem-compile/lenient-key-case.json | 13 + .../lenient-key-case/Configuration.xml | 252 ++++++++++++++++++ .../Ext/ClientApplicationInterface.xml | 18 ++ .../lenient-key-case/Languages/Русский.xml | 16 ++ .../Subsystems/ТестРегистр.xml | 22 ++ .../subsystem-edit/lenient-key-case.json | 24 ++ .../lenient-key-case/Configuration.xml | 252 ++++++++++++++++++ .../Ext/ClientApplicationInterface.xml | 18 ++ .../lenient-key-case/Languages/Русский.xml | 16 ++ .../lenient-key-case/Subsystems/Продажи.xml | 24 ++ .../Продажи/Subsystems/Настройки.xml | 17 ++ tests/skills/check-inline-drift.mjs | 12 +- 80 files changed, 3500 insertions(+), 44 deletions(-) create mode 100644 tests/skills/cases/cf-edit/lenient-key-case.json create mode 100644 tests/skills/cases/cf-edit/snapshots/lenient-key-case/Configuration.xml create mode 100644 tests/skills/cases/cf-edit/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml create mode 100644 tests/skills/cases/cf-edit/snapshots/lenient-key-case/Languages/Русский.xml create mode 100644 tests/skills/cases/form-compile/lenient-key-case.json create mode 100644 tests/skills/cases/form-compile/snapshots/lenient-key-case/Configuration.xml create mode 100644 tests/skills/cases/form-compile/snapshots/lenient-key-case/DataProcessors/ТестРегистрКлючей.xml create mode 100644 tests/skills/cases/form-compile/snapshots/lenient-key-case/DataProcessors/ТестРегистрКлючей/Ext/ManagerModule.bsl create mode 100644 tests/skills/cases/form-compile/snapshots/lenient-key-case/DataProcessors/ТестРегистрКлючей/Ext/ObjectModule.bsl create mode 100644 tests/skills/cases/form-compile/snapshots/lenient-key-case/DataProcessors/ТестРегистрКлючей/Forms/Форма.xml create mode 100644 tests/skills/cases/form-compile/snapshots/lenient-key-case/DataProcessors/ТестРегистрКлючей/Forms/Форма/Ext/Form.xml create mode 100644 tests/skills/cases/form-compile/snapshots/lenient-key-case/DataProcessors/ТестРегистрКлючей/Forms/Форма/Ext/Form/Module.bsl create mode 100644 tests/skills/cases/form-compile/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml create mode 100644 tests/skills/cases/form-compile/snapshots/lenient-key-case/Languages/Русский.xml create mode 100644 tests/skills/cases/form-edit/lenient-key-case.json create mode 100644 tests/skills/cases/form-edit/snapshots/lenient-key-case/Configuration.xml create mode 100644 tests/skills/cases/form-edit/snapshots/lenient-key-case/DataProcessors/РедРегистр.xml create mode 100644 tests/skills/cases/form-edit/snapshots/lenient-key-case/DataProcessors/РедРегистр/Ext/ManagerModule.bsl create mode 100644 tests/skills/cases/form-edit/snapshots/lenient-key-case/DataProcessors/РедРегистр/Ext/ObjectModule.bsl create mode 100644 tests/skills/cases/form-edit/snapshots/lenient-key-case/DataProcessors/РедРегистр/Forms/Форма.xml create mode 100644 tests/skills/cases/form-edit/snapshots/lenient-key-case/DataProcessors/РедРегистр/Forms/Форма/Ext/Form.xml create mode 100644 tests/skills/cases/form-edit/snapshots/lenient-key-case/DataProcessors/РедРегистр/Forms/Форма/Ext/Form/Module.bsl create mode 100644 tests/skills/cases/form-edit/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml create mode 100644 tests/skills/cases/form-edit/snapshots/lenient-key-case/Languages/Русский.xml create mode 100644 tests/skills/cases/interface-edit/lenient-key-case.json create mode 100644 tests/skills/cases/interface-edit/snapshots/lenient-key-case/Configuration.xml create mode 100644 tests/skills/cases/interface-edit/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml create mode 100644 tests/skills/cases/interface-edit/snapshots/lenient-key-case/Languages/Русский.xml create mode 100644 tests/skills/cases/interface-edit/snapshots/lenient-key-case/Subsystems/Продажи.xml create mode 100644 tests/skills/cases/interface-edit/snapshots/lenient-key-case/Subsystems/Продажи/CommandInterface create mode 100644 tests/skills/cases/interface-edit/snapshots/lenient-key-case/Subsystems/Продажи/Subsystems/Оптовые.xml create mode 100644 tests/skills/cases/interface-edit/snapshots/lenient-key-case/Subsystems/Продажи/Subsystems/Розничные.xml create mode 100644 tests/skills/cases/meta-edit/lenient-key-case.json create mode 100644 tests/skills/cases/meta-edit/snapshots/lenient-key-case/Catalogs/Контрагенты.xml create mode 100644 tests/skills/cases/meta-edit/snapshots/lenient-key-case/Catalogs/Контрагенты/Ext/ObjectModule.bsl create mode 100644 tests/skills/cases/meta-edit/snapshots/lenient-key-case/Configuration.xml create mode 100644 tests/skills/cases/meta-edit/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml create mode 100644 tests/skills/cases/meta-edit/snapshots/lenient-key-case/Languages/Русский.xml create mode 100644 tests/skills/cases/mxl-compile/lenient-key-case.json create mode 100644 tests/skills/cases/mxl-compile/snapshots/lenient-key-case/Template.xml create mode 100644 tests/skills/cases/role-compile/lenient-key-case.json create mode 100644 tests/skills/cases/role-compile/snapshots/lenient-key-case/Configuration.xml create mode 100644 tests/skills/cases/role-compile/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml create mode 100644 tests/skills/cases/role-compile/snapshots/lenient-key-case/Languages/Русский.xml create mode 100644 tests/skills/cases/role-compile/snapshots/lenient-key-case/Roles/ПустаяРоль.xml create mode 100644 tests/skills/cases/role-compile/snapshots/lenient-key-case/Roles/ПустаяРоль/Ext/Rights.xml create mode 100644 tests/skills/cases/skd-compile/lenient-key-case.json create mode 100644 tests/skills/cases/skd-compile/snapshots/lenient-key-case/Template.xml create mode 100644 tests/skills/cases/subsystem-compile/lenient-key-case.json create mode 100644 tests/skills/cases/subsystem-compile/snapshots/lenient-key-case/Configuration.xml create mode 100644 tests/skills/cases/subsystem-compile/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml create mode 100644 tests/skills/cases/subsystem-compile/snapshots/lenient-key-case/Languages/Русский.xml create mode 100644 tests/skills/cases/subsystem-compile/snapshots/lenient-key-case/Subsystems/ТестРегистр.xml create mode 100644 tests/skills/cases/subsystem-edit/lenient-key-case.json create mode 100644 tests/skills/cases/subsystem-edit/snapshots/lenient-key-case/Configuration.xml create mode 100644 tests/skills/cases/subsystem-edit/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml create mode 100644 tests/skills/cases/subsystem-edit/snapshots/lenient-key-case/Languages/Русский.xml create mode 100644 tests/skills/cases/subsystem-edit/snapshots/lenient-key-case/Subsystems/Продажи.xml create mode 100644 tests/skills/cases/subsystem-edit/snapshots/lenient-key-case/Subsystems/Продажи/Subsystems/Настройки.xml diff --git a/.claude/skills/cf-edit/scripts/cf-edit.ps1 b/.claude/skills/cf-edit/scripts/cf-edit.ps1 index e9a3364f..27dd3b4c 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.17 — Edit 1C configuration root (Configuration.xml) +# cf-edit v1.18 — Edit 1C configuration root (Configuration.xml) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)][Alias('Path')][string]$ConfigPath, diff --git a/.claude/skills/cf-edit/scripts/cf-edit.py b/.claude/skills/cf-edit/scripts/cf-edit.py index 2c127e30..94454fce 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.17 — Edit 1C configuration root (Configuration.xml) +# cf-edit v1.18 — Edit 1C configuration root (Configuration.xml) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse @@ -14,6 +14,43 @@ from lxml import etree # Регистронезависимый ввод — паритет с PS1: в PowerShell имена параметров и [ValidateSet] # регистр не различают, в argparse совпадение точное. +class CIDict(dict): + # Ключи храним КАК ЕСТЬ: часть из них — имена объектов (табличные части, стандартные + # реквизиты), они попадают в XML. Регистронезависим только поиск. Порядок вставки + # сохраняется — от него зависит порядок эмиссии. + def _actual(self, key): + if not isinstance(key, str) or dict.__contains__(self, key): + return key + ci = self.__dict__.get('_ci') + if ci is None or len(ci) != len(self): + ci = {k.lower(): k for k in self if isinstance(k, str)} + self.__dict__['_ci'] = ci + return ci.get(key.lower(), key) + + def __getitem__(self, key): + return dict.__getitem__(self, self._actual(key)) + + def __contains__(self, key): + return dict.__contains__(self, self._actual(key)) + + def get(self, key, default=None): + return dict.get(self, self._actual(key), default) + + def pop(self, key, *default): + return dict.pop(self, self._actual(key), *default) + + def __setitem__(self, key, value): + # запись по ключу, отличающемуся регистром, обновляет существующий, а не плодит дубль + dict.__setitem__(self, self._actual(key), value) + +def ci_json(obj): + """Рекурсивно оборачивает разобранный JSON: словари → CIDict, списки обходятся.""" + if isinstance(obj, dict): + return CIDict((k, ci_json(v)) for k, v in obj.items()) + if isinstance(obj, list): + return [ci_json(v) for v in obj] + return obj + def ci_parse_args(parser, argv=None): """parse_args по правилам PS: имена параметров и значения choices регистронезависимы.""" argv = list(sys.argv[1:] if argv is None else argv) @@ -785,7 +822,7 @@ def main(): layout = value if isinstance(layout, str): try: - layout = json.loads(layout) + layout = ci_json(json.loads(layout)) except json.JSONDecodeError: print(f"set-panels value must be valid JSON object", file=sys.stderr) sys.exit(1) @@ -940,7 +977,7 @@ def main(): layout = value if isinstance(layout, str): try: - layout = json.loads(layout) + layout = ci_json(json.loads(layout)) except json.JSONDecodeError: print("set-home-page value must be valid JSON object", file=sys.stderr) sys.exit(1) @@ -1008,7 +1045,7 @@ def main(): if not os.path.isabs(def_file): def_file = os.path.join(os.getcwd(), def_file) with open(def_file, "r", encoding="utf-8-sig") as fh: - ops = json.loads(fh.read()) + ops = ci_json(json.loads(fh.read())) if isinstance(ops, list): operations = ops else: diff --git a/.claude/skills/form-compile/scripts/form-compile.ps1 b/.claude/skills/form-compile/scripts/form-compile.ps1 index 7e772354..014e9f8e 100644 --- a/.claude/skills/form-compile/scripts/form-compile.ps1 +++ b/.claude/skills/form-compile/scripts/form-compile.ps1 @@ -1,4 +1,4 @@ -# form-compile v1.190 — Compile 1C managed form from JSON or object metadata (+write_xml_file/write_utf8_bom: общий эталон записи) +# form-compile v1.191 — Compile 1C managed form from JSON or object metadata (+write_xml_file/write_utf8_bom: общий эталон записи) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$JsonPath, diff --git a/.claude/skills/form-compile/scripts/form-compile.py b/.claude/skills/form-compile/scripts/form-compile.py index 78218b29..b6cfde44 100644 --- a/.claude/skills/form-compile/scripts/form-compile.py +++ b/.claude/skills/form-compile/scripts/form-compile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# form-compile v1.190 — Compile 1C managed form from JSON or object metadata (+write_xml_file/write_utf8_bom: общий эталон записи) +# form-compile v1.191 — Compile 1C managed form from JSON or object metadata (+write_xml_file/write_utf8_bom: общий эталон записи) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import copy @@ -15,6 +15,43 @@ from lxml import etree # Регистронезависимый ввод — паритет с PS1: в PowerShell имена параметров и [ValidateSet] # регистр не различают, в argparse совпадение точное. +class CIDict(dict): + # Ключи храним КАК ЕСТЬ: часть из них — имена объектов (табличные части, стандартные + # реквизиты), они попадают в XML. Регистронезависим только поиск. Порядок вставки + # сохраняется — от него зависит порядок эмиссии. + def _actual(self, key): + if not isinstance(key, str) or dict.__contains__(self, key): + return key + ci = self.__dict__.get('_ci') + if ci is None or len(ci) != len(self): + ci = {k.lower(): k for k in self if isinstance(k, str)} + self.__dict__['_ci'] = ci + return ci.get(key.lower(), key) + + def __getitem__(self, key): + return dict.__getitem__(self, self._actual(key)) + + def __contains__(self, key): + return dict.__contains__(self, self._actual(key)) + + def get(self, key, default=None): + return dict.get(self, self._actual(key), default) + + def pop(self, key, *default): + return dict.pop(self, self._actual(key), *default) + + def __setitem__(self, key, value): + # запись по ключу, отличающемуся регистром, обновляет существующий, а не плодит дубль + dict.__setitem__(self, self._actual(key), value) + +def ci_json(obj): + """Рекурсивно оборачивает разобранный JSON: словари → CIDict, списки обходятся.""" + if isinstance(obj, dict): + return CIDict((k, ci_json(v)) for k, v in obj.items()) + if isinstance(obj, list): + return [ci_json(v) for v in obj] + return obj + def ci_parse_args(parser, argv=None): """parse_args по правилам PS: имена параметров и значения choices регистронезависимы.""" argv = list(sys.argv[1:] if argv is None else argv) @@ -506,7 +543,7 @@ def load_preset(preset_name, script_dir, out_path_resolved): built_in_path = os.path.join(preset_dir, f'{preset_name}.json') if os.path.isfile(built_in_path): with open(built_in_path, 'r', encoding='utf-8-sig') as f: - preset_data = json.load(f) + preset_data = ci_json(json.load(f)) for k in list(preset_data.keys()): defaults[k] = _deep_merge(defaults.get(k), preset_data[k]) @@ -6399,7 +6436,7 @@ def main(): json.dump(dsl, f, ensure_ascii=False, indent=2) print(f"[from-object] DSL saved: {dsl_path}") - defn = json.loads(json.dumps(dsl)) # normalize OrderedDict to regular dict + defn = ci_json(json.loads(json.dumps(dsl))) # normalize OrderedDict to regular dict # Convert dict-style elements (from generators) to list-style (expected by compiler) defn = _normalize_elements(defn) else: @@ -6410,7 +6447,7 @@ def main(): sys.exit(1) with open(json_path, 'r', encoding='utf-8-sig') as f: - defn = json.load(f) + defn = ci_json(json.load(f)) global QUERY_BASE_DIR QUERY_BASE_DIR = os.path.dirname(os.path.abspath(json_path)) diff --git a/.claude/skills/form-edit/scripts/form-edit.ps1 b/.claude/skills/form-edit/scripts/form-edit.ps1 index 5284c703..9f30e6e2 100644 --- a/.claude/skills/form-edit/scripts/form-edit.ps1 +++ b/.claude/skills/form-edit/scripts/form-edit.ps1 @@ -1,4 +1,4 @@ -# form-edit v1.13 — Edit 1C managed form elements (+esc_xml/esc_xml_text: разное экранирование атрибута и текста) +# form-edit v1.14 — Edit 1C managed form elements (+esc_xml/esc_xml_text: разное экранирование атрибута и текста) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] diff --git a/.claude/skills/form-edit/scripts/form-edit.py b/.claude/skills/form-edit/scripts/form-edit.py index cdd47d6e..b8cf7010 100644 --- a/.claude/skills/form-edit/scripts/form-edit.py +++ b/.claude/skills/form-edit/scripts/form-edit.py @@ -1,4 +1,4 @@ -# form-edit v1.13 — Edit 1C managed form elements (Python port) (+esc_xml/esc_xml_text: разное экранирование атрибута и текста) +# form-edit v1.14 — Edit 1C managed form elements (Python port) (+esc_xml/esc_xml_text: разное экранирование атрибута и текста) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import json @@ -13,6 +13,43 @@ sys.stderr.reconfigure(encoding="utf-8") # Регистронезависимый ввод — паритет с PS1: в PowerShell имена параметров и [ValidateSet] # регистр не различают, в argparse совпадение точное. +class CIDict(dict): + # Ключи храним КАК ЕСТЬ: часть из них — имена объектов (табличные части, стандартные + # реквизиты), они попадают в XML. Регистронезависим только поиск. Порядок вставки + # сохраняется — от него зависит порядок эмиссии. + def _actual(self, key): + if not isinstance(key, str) or dict.__contains__(self, key): + return key + ci = self.__dict__.get('_ci') + if ci is None or len(ci) != len(self): + ci = {k.lower(): k for k in self if isinstance(k, str)} + self.__dict__['_ci'] = ci + return ci.get(key.lower(), key) + + def __getitem__(self, key): + return dict.__getitem__(self, self._actual(key)) + + def __contains__(self, key): + return dict.__contains__(self, self._actual(key)) + + def get(self, key, default=None): + return dict.get(self, self._actual(key), default) + + def pop(self, key, *default): + return dict.pop(self, self._actual(key), *default) + + def __setitem__(self, key, value): + # запись по ключу, отличающемуся регистром, обновляет существующий, а не плодит дубль + dict.__setitem__(self, self._actual(key), value) + +def ci_json(obj): + """Рекурсивно оборачивает разобранный JSON: словари → CIDict, списки обходятся.""" + if isinstance(obj, dict): + return CIDict((k, ci_json(v)) for k, v in obj.items()) + if isinstance(obj, list): + return [ci_json(v) for v in obj] + return obj + def ci_parse_args(parser, argv=None): """parse_args по правилам PS: имена параметров и значения choices регистронезависимы.""" argv = list(sys.argv[1:] if argv is None else argv) @@ -281,7 +318,7 @@ root = tree.getroot() # ── 2. Load JSON ──────────────────────────────────────────── with open(json_path, "r", encoding="utf-8-sig") as f: - defn = json.load(f) + defn = ci_json(json.load(f)) # ── 3. Form name + header ─────────────────────────────────── diff --git a/.claude/skills/interface-edit/scripts/interface-edit.ps1 b/.claude/skills/interface-edit/scripts/interface-edit.ps1 index 79a6c85b..f875bc29 100644 --- a/.claude/skills/interface-edit/scripts/interface-edit.ps1 +++ b/.claude/skills/interface-edit/scripts/interface-edit.ps1 @@ -1,4 +1,4 @@ -# interface-edit v1.16 — Edit 1C CommandInterface.xml (+русские алиасы типов: формы с ё и без) +# interface-edit v1.17 — Edit 1C CommandInterface.xml (+русские алиасы типов: формы с ё и без) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)][Alias('Path')][string]$CIPath, diff --git a/.claude/skills/interface-edit/scripts/interface-edit.py b/.claude/skills/interface-edit/scripts/interface-edit.py index 2057e81e..c462cdd9 100644 --- a/.claude/skills/interface-edit/scripts/interface-edit.py +++ b/.claude/skills/interface-edit/scripts/interface-edit.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# interface-edit v1.16 — Edit 1C CommandInterface.xml (+русские алиасы типов: формы с ё и без) +# interface-edit v1.17 — Edit 1C CommandInterface.xml (+русские алиасы типов: формы с ё и без) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse @@ -12,6 +12,43 @@ from lxml import etree # Регистронезависимый ввод — паритет с PS1: в PowerShell имена параметров и [ValidateSet] # регистр не различают, в argparse совпадение точное. +class CIDict(dict): + # Ключи храним КАК ЕСТЬ: часть из них — имена объектов (табличные части, стандартные + # реквизиты), они попадают в XML. Регистронезависим только поиск. Порядок вставки + # сохраняется — от него зависит порядок эмиссии. + def _actual(self, key): + if not isinstance(key, str) or dict.__contains__(self, key): + return key + ci = self.__dict__.get('_ci') + if ci is None or len(ci) != len(self): + ci = {k.lower(): k for k in self if isinstance(k, str)} + self.__dict__['_ci'] = ci + return ci.get(key.lower(), key) + + def __getitem__(self, key): + return dict.__getitem__(self, self._actual(key)) + + def __contains__(self, key): + return dict.__contains__(self, self._actual(key)) + + def get(self, key, default=None): + return dict.get(self, self._actual(key), default) + + def pop(self, key, *default): + return dict.pop(self, self._actual(key), *default) + + def __setitem__(self, key, value): + # запись по ключу, отличающемуся регистром, обновляет существующий, а не плодит дубль + dict.__setitem__(self, self._actual(key), value) + +def ci_json(obj): + """Рекурсивно оборачивает разобранный JSON: словари → CIDict, списки обходятся.""" + if isinstance(obj, dict): + return CIDict((k, ci_json(v)) for k, v in obj.items()) + if isinstance(obj, list): + return [ci_json(v) for v in obj] + return obj + def ci_parse_args(parser, argv=None): """parse_args по правилам PS: имена параметров и значения choices регистронезависимы.""" argv = list(sys.argv[1:] if argv is None else argv) @@ -314,7 +351,7 @@ def import_ci_fragment(xml_string): def parse_value_list(val): val = val.strip() if val.startswith("["): - arr = json.loads(val) + arr = ci_json(json.loads(val)) return [str(item) for item in arr] return [val] @@ -610,7 +647,7 @@ def main(): def do_place(json_val): nonlocal add_count, modify_count - defn = json_val if isinstance(json_val, dict) else json.loads(json_val) + defn = ci_json(json_val if isinstance(json_val, dict) else json.loads(json_val)) cmd_name = normalize_cmd_name(str(defn["command"])) group_name = str(defn["group"]) if not cmd_name or not group_name: @@ -638,7 +675,7 @@ def main(): def do_order(json_val): nonlocal add_count, remove_count - defn = json_val if isinstance(json_val, dict) else json.loads(json_val) + defn = ci_json(json_val if isinstance(json_val, dict) else json.loads(json_val)) group_name = str(defn["group"]) commands = [normalize_cmd_name(str(c)) for c in defn["commands"]] if not group_name or not commands: @@ -672,7 +709,7 @@ def main(): def do_subsystem_order(json_val): nonlocal add_count, remove_count - parsed = json_val if isinstance(json_val, list) else json.loads(json_val) + parsed = ci_json(json_val if isinstance(json_val, list) else json.loads(json_val)) subsystems = [str(s) for s in parsed] if not subsystems: print("subsystem-order requires array of subsystem paths", file=sys.stderr) @@ -697,7 +734,7 @@ def main(): def do_group_order(json_val): nonlocal add_count, remove_count - parsed = json_val if isinstance(json_val, list) else json.loads(json_val) + parsed = ci_json(json_val if isinstance(json_val, list) else json.loads(json_val)) groups = [str(g) for g in parsed] if not groups: print("group-order requires array of group names", file=sys.stderr) @@ -727,7 +764,7 @@ def main(): if not os.path.isabs(def_file): def_file = os.path.join(os.getcwd(), def_file) with open(def_file, "r", encoding="utf-8-sig") as fh: - ops = json.loads(fh.read()) + ops = ci_json(json.loads(fh.read())) if isinstance(ops, list): operations = ops else: diff --git a/.claude/skills/meta-edit/scripts/meta-edit.ps1 b/.claude/skills/meta-edit/scripts/meta-edit.ps1 index e919b164..36c76a79 100644 --- a/.claude/skills/meta-edit/scripts/meta-edit.ps1 +++ b/.claude/skills/meta-edit/scripts/meta-edit.ps1 @@ -1,4 +1,4 @@ -# meta-edit v1.36 — Edit existing 1C metadata object XML (+esc_xml/esc_xml_text: разное экранирование атрибута и текста) +# meta-edit v1.37 — Edit existing 1C metadata object XML (+esc_xml/esc_xml_text: разное экранирование атрибута и текста) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$DefinitionFile, diff --git a/.claude/skills/meta-edit/scripts/meta-edit.py b/.claude/skills/meta-edit/scripts/meta-edit.py index 7776d0b6..6822da34 100644 --- a/.claude/skills/meta-edit/scripts/meta-edit.py +++ b/.claude/skills/meta-edit/scripts/meta-edit.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# meta-edit v1.36 — Edit existing 1C metadata object XML (+esc_xml/esc_xml_text: разное экранирование атрибута и текста) +# meta-edit v1.37 — Edit existing 1C metadata object XML (+esc_xml/esc_xml_text: разное экранирование атрибута и текста) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse @@ -13,6 +13,43 @@ from lxml import etree # Регистронезависимый ввод — паритет с PS1: в PowerShell имена параметров и [ValidateSet] # регистр не различают, в argparse совпадение точное. +class CIDict(dict): + # Ключи храним КАК ЕСТЬ: часть из них — имена объектов (табличные части, стандартные + # реквизиты), они попадают в XML. Регистронезависим только поиск. Порядок вставки + # сохраняется — от него зависит порядок эмиссии. + def _actual(self, key): + if not isinstance(key, str) or dict.__contains__(self, key): + return key + ci = self.__dict__.get('_ci') + if ci is None or len(ci) != len(self): + ci = {k.lower(): k for k in self if isinstance(k, str)} + self.__dict__['_ci'] = ci + return ci.get(key.lower(), key) + + def __getitem__(self, key): + return dict.__getitem__(self, self._actual(key)) + + def __contains__(self, key): + return dict.__contains__(self, self._actual(key)) + + def get(self, key, default=None): + return dict.get(self, self._actual(key), default) + + def pop(self, key, *default): + return dict.pop(self, self._actual(key), *default) + + def __setitem__(self, key, value): + # запись по ключу, отличающемуся регистром, обновляет существующий, а не плодит дубль + dict.__setitem__(self, self._actual(key), value) + +def ci_json(obj): + """Рекурсивно оборачивает разобранный JSON: словари → CIDict, списки обходятся.""" + if isinstance(obj, dict): + return CIDict((k, ci_json(v)) for k, v in obj.items()) + if isinstance(obj, list): + return [ci_json(v) for v in obj] + return obj + def ci_parse_args(parser, argv=None): """parse_args по правилам PS: имена параметров и значения choices регистронезависимы.""" argv = list(sys.argv[1:] if argv is None else argv) @@ -3210,7 +3247,7 @@ def main(): if not os.path.exists(args.DefinitionFile): die(f"Definition file not found: {args.DefinitionFile}") with open(args.DefinitionFile, "r", encoding="utf-8-sig") as f: - definition = json.load(f) + definition = ci_json(json.load(f)) # --- Resolve object path --- object_path = args.ObjectPath diff --git a/.claude/skills/mxl-compile/scripts/mxl-compile.ps1 b/.claude/skills/mxl-compile/scripts/mxl-compile.ps1 index 950c5b07..ffb6ffb9 100644 --- a/.claude/skills/mxl-compile/scripts/mxl-compile.ps1 +++ b/.claude/skills/mxl-compile/scripts/mxl-compile.ps1 @@ -1,4 +1,4 @@ -# mxl-compile v1.13 — Compile 1C spreadsheet from JSON (+write_xml_file/write_utf8_bom: общий эталон записи) +# mxl-compile v1.14 — Compile 1C spreadsheet from JSON (+write_xml_file/write_utf8_bom: общий эталон записи) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] diff --git a/.claude/skills/mxl-compile/scripts/mxl-compile.py b/.claude/skills/mxl-compile/scripts/mxl-compile.py index 15b0ab44..68685cf2 100644 --- a/.claude/skills/mxl-compile/scripts/mxl-compile.py +++ b/.claude/skills/mxl-compile/scripts/mxl-compile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# mxl-compile v1.13 — Compile 1C spreadsheet from JSON (+write_xml_file/write_utf8_bom: общий эталон записи) +# mxl-compile v1.14 — Compile 1C spreadsheet from JSON (+write_xml_file/write_utf8_bom: общий эталон записи) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import json @@ -12,6 +12,43 @@ from lxml import etree # Регистронезависимый ввод — паритет с PS1: в PowerShell имена параметров и [ValidateSet] # регистр не различают, в argparse совпадение точное. +class CIDict(dict): + # Ключи храним КАК ЕСТЬ: часть из них — имена объектов (табличные части, стандартные + # реквизиты), они попадают в XML. Регистронезависим только поиск. Порядок вставки + # сохраняется — от него зависит порядок эмиссии. + def _actual(self, key): + if not isinstance(key, str) or dict.__contains__(self, key): + return key + ci = self.__dict__.get('_ci') + if ci is None or len(ci) != len(self): + ci = {k.lower(): k for k in self if isinstance(k, str)} + self.__dict__['_ci'] = ci + return ci.get(key.lower(), key) + + def __getitem__(self, key): + return dict.__getitem__(self, self._actual(key)) + + def __contains__(self, key): + return dict.__contains__(self, self._actual(key)) + + def get(self, key, default=None): + return dict.get(self, self._actual(key), default) + + def pop(self, key, *default): + return dict.pop(self, self._actual(key), *default) + + def __setitem__(self, key, value): + # запись по ключу, отличающемуся регистром, обновляет существующий, а не плодит дубль + dict.__setitem__(self, self._actual(key), value) + +def ci_json(obj): + """Рекурсивно оборачивает разобранный JSON: словари → CIDict, списки обходятся.""" + if isinstance(obj, dict): + return CIDict((k, ci_json(v)) for k, v in obj.items()) + if isinstance(obj, list): + return [ci_json(v) for v in obj] + return obj + def ci_parse_args(parser, argv=None): """parse_args по правилам PS: имена параметров и значения choices регистронезависимы.""" argv = list(sys.argv[1:] if argv is None else argv) @@ -281,7 +318,7 @@ def main(): sys.exit(1) with open(json_path, 'r', encoding='utf-8-sig') as f: - defn = json.load(f) + defn = ci_json(json.load(f)) if not defn.get('columns'): print("Required field 'columns' is missing", file=sys.stderr) diff --git a/.claude/skills/role-compile/scripts/role-compile.ps1 b/.claude/skills/role-compile/scripts/role-compile.ps1 index 2e0df6ca..189853ac 100644 --- a/.claude/skills/role-compile/scripts/role-compile.ps1 +++ b/.claude/skills/role-compile/scripts/role-compile.ps1 @@ -1,4 +1,4 @@ -# role-compile v1.23 — Compile 1C role from JSON (+русские алиасы типов: формы с ё и без) +# role-compile v1.24 — Compile 1C role from JSON (+русские алиасы типов: формы с ё и без) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] diff --git a/.claude/skills/role-compile/scripts/role-compile.py b/.claude/skills/role-compile/scripts/role-compile.py index 7f7e56e2..c769e54b 100644 --- a/.claude/skills/role-compile/scripts/role-compile.py +++ b/.claude/skills/role-compile/scripts/role-compile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# role-compile v1.23 — Compile 1C role from JSON (+русские алиасы типов: формы с ё и без) +# role-compile v1.24 — Compile 1C role from JSON (+русские алиасы типов: формы с ё и без) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import json @@ -12,6 +12,43 @@ from lxml import etree # Регистронезависимый ввод — паритет с PS1: в PowerShell имена параметров и [ValidateSet] # регистр не различают, в argparse совпадение точное. +class CIDict(dict): + # Ключи храним КАК ЕСТЬ: часть из них — имена объектов (табличные части, стандартные + # реквизиты), они попадают в XML. Регистронезависим только поиск. Порядок вставки + # сохраняется — от него зависит порядок эмиссии. + def _actual(self, key): + if not isinstance(key, str) or dict.__contains__(self, key): + return key + ci = self.__dict__.get('_ci') + if ci is None or len(ci) != len(self): + ci = {k.lower(): k for k in self if isinstance(k, str)} + self.__dict__['_ci'] = ci + return ci.get(key.lower(), key) + + def __getitem__(self, key): + return dict.__getitem__(self, self._actual(key)) + + def __contains__(self, key): + return dict.__contains__(self, self._actual(key)) + + def get(self, key, default=None): + return dict.get(self, self._actual(key), default) + + def pop(self, key, *default): + return dict.pop(self, self._actual(key), *default) + + def __setitem__(self, key, value): + # запись по ключу, отличающемуся регистром, обновляет существующий, а не плодит дубль + dict.__setitem__(self, self._actual(key), value) + +def ci_json(obj): + """Рекурсивно оборачивает разобранный JSON: словари → CIDict, списки обходятся.""" + if isinstance(obj, dict): + return CIDict((k, ci_json(v)) for k, v in obj.items()) + if isinstance(obj, list): + return [ci_json(v) for v in obj] + return obj + def ci_parse_args(parser, argv=None): """parse_args по правилам PS: имена параметров и значения choices регистронезависимы.""" argv = list(sys.argv[1:] if argv is None else argv) @@ -698,7 +735,7 @@ def main(): sys.exit(1) with open(json_path, 'r', encoding='utf-8-sig') as f: - defn = json.load(f) + defn = ci_json(json.load(f)) if not defn.get('name'): print("JSON must have 'name' field (role programmatic name)", file=sys.stderr) diff --git a/.claude/skills/skd-compile/scripts/skd-compile.ps1 b/.claude/skills/skd-compile/scripts/skd-compile.ps1 index 7cc4a7df..c731b3d4 100644 --- a/.claude/skills/skd-compile/scripts/skd-compile.ps1 +++ b/.claude/skills/skd-compile/scripts/skd-compile.ps1 @@ -1,4 +1,4 @@ -# skd-compile v1.116 — Compile 1C DCS from JSON (+write_xml_file/write_utf8_bom: общий эталон записи) +# skd-compile v1.117 — Compile 1C DCS from JSON (+write_xml_file/write_utf8_bom: общий эталон записи) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$DefinitionFile, diff --git a/.claude/skills/skd-compile/scripts/skd-compile.py b/.claude/skills/skd-compile/scripts/skd-compile.py index a6165a09..9b6b2875 100644 --- a/.claude/skills/skd-compile/scripts/skd-compile.py +++ b/.claude/skills/skd-compile/scripts/skd-compile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# skd-compile v1.116 — Compile 1C DCS from JSON (+write_xml_file/write_utf8_bom: общий эталон записи) +# skd-compile v1.117 — Compile 1C DCS from JSON (+write_xml_file/write_utf8_bom: общий эталон записи) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import json @@ -12,6 +12,43 @@ from lxml import etree # Регистронезависимый ввод — паритет с PS1: в PowerShell имена параметров и [ValidateSet] # регистр не различают, в argparse совпадение точное. +class CIDict(dict): + # Ключи храним КАК ЕСТЬ: часть из них — имена объектов (табличные части, стандартные + # реквизиты), они попадают в XML. Регистронезависим только поиск. Порядок вставки + # сохраняется — от него зависит порядок эмиссии. + def _actual(self, key): + if not isinstance(key, str) or dict.__contains__(self, key): + return key + ci = self.__dict__.get('_ci') + if ci is None or len(ci) != len(self): + ci = {k.lower(): k for k in self if isinstance(k, str)} + self.__dict__['_ci'] = ci + return ci.get(key.lower(), key) + + def __getitem__(self, key): + return dict.__getitem__(self, self._actual(key)) + + def __contains__(self, key): + return dict.__contains__(self, self._actual(key)) + + def get(self, key, default=None): + return dict.get(self, self._actual(key), default) + + def pop(self, key, *default): + return dict.pop(self, self._actual(key), *default) + + def __setitem__(self, key, value): + # запись по ключу, отличающемуся регистром, обновляет существующий, а не плодит дубль + dict.__setitem__(self, self._actual(key), value) + +def ci_json(obj): + """Рекурсивно оборачивает разобранный JSON: словари → CIDict, списки обходятся.""" + if isinstance(obj, dict): + return CIDict((k, ci_json(v)) for k, v in obj.items()) + if isinstance(obj, list): + return [ci_json(v) for v in obj] + return obj + def ci_parse_args(parser, argv=None): """parse_args по правилам PS: имена параметров и значения choices регистронезависимы.""" argv = list(sys.argv[1:] if argv is None else argv) @@ -1592,7 +1629,7 @@ def load_user_styles(base_dir, output_path=None): for p in search_paths: if os.path.isfile(p): with open(p, 'r', encoding='utf-8-sig') as f: - user_styles = json.load(f) + user_styles = ci_json(json.load(f)) for name, overrides in user_styles.items(): base = dict(AREA_STYLE_PRESETS.get(name, AREA_STYLE_PRESETS['data'])) base.update(overrides) @@ -3029,7 +3066,7 @@ def main(): else: json_text = args.Value - defn = json.loads(json_text) + defn = ci_json(json.loads(json_text)) if not defn.get('dataSets') or len(defn['dataSets']) == 0: print("JSON must have at least one entry in 'dataSets'", file=sys.stderr) diff --git a/.claude/skills/subsystem-compile/scripts/subsystem-compile.ps1 b/.claude/skills/subsystem-compile/scripts/subsystem-compile.ps1 index a79a11b0..2b783c3c 100644 --- a/.claude/skills/subsystem-compile/scripts/subsystem-compile.ps1 +++ b/.claude/skills/subsystem-compile/scripts/subsystem-compile.ps1 @@ -1,4 +1,4 @@ -# subsystem-compile v1.24 — Create 1C subsystem from JSON definition (+тип Bot; cfe-diff/cfe-borrow: недостающие типы) +# subsystem-compile v1.25 — Create 1C subsystem from JSON definition (+тип Bot; cfe-diff/cfe-borrow: недостающие типы) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$DefinitionFile, diff --git a/.claude/skills/subsystem-compile/scripts/subsystem-compile.py b/.claude/skills/subsystem-compile/scripts/subsystem-compile.py index 0db65347..97360510 100644 --- a/.claude/skills/subsystem-compile/scripts/subsystem-compile.py +++ b/.claude/skills/subsystem-compile/scripts/subsystem-compile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# subsystem-compile v1.24 — Create 1C subsystem from JSON definition (+тип Bot; cfe-diff/cfe-borrow: недостающие типы) +# subsystem-compile v1.25 — Create 1C subsystem from JSON definition (+тип Bot; cfe-diff/cfe-borrow: недостающие типы) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import json @@ -13,6 +13,43 @@ from lxml import etree # Регистронезависимый ввод — паритет с PS1: в PowerShell имена параметров и [ValidateSet] # регистр не различают, в argparse совпадение точное. +class CIDict(dict): + # Ключи храним КАК ЕСТЬ: часть из них — имена объектов (табличные части, стандартные + # реквизиты), они попадают в XML. Регистронезависим только поиск. Порядок вставки + # сохраняется — от него зависит порядок эмиссии. + def _actual(self, key): + if not isinstance(key, str) or dict.__contains__(self, key): + return key + ci = self.__dict__.get('_ci') + if ci is None or len(ci) != len(self): + ci = {k.lower(): k for k in self if isinstance(k, str)} + self.__dict__['_ci'] = ci + return ci.get(key.lower(), key) + + def __getitem__(self, key): + return dict.__getitem__(self, self._actual(key)) + + def __contains__(self, key): + return dict.__contains__(self, self._actual(key)) + + def get(self, key, default=None): + return dict.get(self, self._actual(key), default) + + def pop(self, key, *default): + return dict.pop(self, self._actual(key), *default) + + def __setitem__(self, key, value): + # запись по ключу, отличающемуся регистром, обновляет существующий, а не плодит дубль + dict.__setitem__(self, self._actual(key), value) + +def ci_json(obj): + """Рекурсивно оборачивает разобранный JSON: словари → CIDict, списки обходятся.""" + if isinstance(obj, dict): + return CIDict((k, ci_json(v)) for k, v in obj.items()) + if isinstance(obj, list): + return [ci_json(v) for v in obj] + return obj + def ci_parse_args(parser, argv=None): """parse_args по правилам PS: имена параметров и значения choices регистронезависимы.""" argv = list(sys.argv[1:] if argv is None else argv) @@ -382,7 +419,7 @@ def main(): else: json_text = args.Value - defn = json.loads(json_text) + defn = ci_json(json.loads(json_text)) if not defn.get('name'): print("JSON must have 'name' field", file=sys.stderr) diff --git a/.claude/skills/subsystem-edit/scripts/subsystem-edit.ps1 b/.claude/skills/subsystem-edit/scripts/subsystem-edit.ps1 index ea29e995..adb1e86e 100644 --- a/.claude/skills/subsystem-edit/scripts/subsystem-edit.ps1 +++ b/.claude/skills/subsystem-edit/scripts/subsystem-edit.ps1 @@ -1,4 +1,4 @@ -# subsystem-edit v1.19 — Edit existing 1C subsystem XML (+тип Bot; cfe-diff/cfe-borrow: недостающие типы) +# subsystem-edit v1.20 — Edit existing 1C subsystem XML (+тип Bot; cfe-diff/cfe-borrow: недостающие типы) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)][Alias('Path')][string]$SubsystemPath, diff --git a/.claude/skills/subsystem-edit/scripts/subsystem-edit.py b/.claude/skills/subsystem-edit/scripts/subsystem-edit.py index 956a5852..b578b030 100644 --- a/.claude/skills/subsystem-edit/scripts/subsystem-edit.py +++ b/.claude/skills/subsystem-edit/scripts/subsystem-edit.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# subsystem-edit v1.19 — Edit existing 1C subsystem XML (+тип Bot; cfe-diff/cfe-borrow: недостающие типы) +# subsystem-edit v1.20 — Edit existing 1C subsystem XML (+тип Bot; cfe-diff/cfe-borrow: недостающие типы) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse @@ -13,6 +13,43 @@ from lxml import etree # Регистронезависимый ввод — паритет с PS1: в PowerShell имена параметров и [ValidateSet] # регистр не различают, в argparse совпадение точное. +class CIDict(dict): + # Ключи храним КАК ЕСТЬ: часть из них — имена объектов (табличные части, стандартные + # реквизиты), они попадают в XML. Регистронезависим только поиск. Порядок вставки + # сохраняется — от него зависит порядок эмиссии. + def _actual(self, key): + if not isinstance(key, str) or dict.__contains__(self, key): + return key + ci = self.__dict__.get('_ci') + if ci is None or len(ci) != len(self): + ci = {k.lower(): k for k in self if isinstance(k, str)} + self.__dict__['_ci'] = ci + return ci.get(key.lower(), key) + + def __getitem__(self, key): + return dict.__getitem__(self, self._actual(key)) + + def __contains__(self, key): + return dict.__contains__(self, self._actual(key)) + + def get(self, key, default=None): + return dict.get(self, self._actual(key), default) + + def pop(self, key, *default): + return dict.pop(self, self._actual(key), *default) + + def __setitem__(self, key, value): + # запись по ключу, отличающемуся регистром, обновляет существующий, а не плодит дубль + dict.__setitem__(self, self._actual(key), value) + +def ci_json(obj): + """Рекурсивно оборачивает разобранный JSON: словари → CIDict, списки обходятся.""" + if isinstance(obj, dict): + return CIDict((k, ci_json(v)) for k, v in obj.items()) + if isinstance(obj, list): + return [ci_json(v) for v in obj] + return obj + def ci_parse_args(parser, argv=None): """parse_args по правилам PS: имена параметров и значения choices регистронезависимы.""" argv = list(sys.argv[1:] if argv is None else argv) @@ -482,7 +519,7 @@ def parse_value_list(val): """Parse a string or JSON array into a list of strings.""" val = val.strip() if val.startswith("["): - arr = json.loads(val) + arr = ci_json(json.loads(val)) return [str(item) for item in arr] return [val] @@ -740,7 +777,7 @@ def main(): def do_set_property(json_val): nonlocal modify_count - prop_def = json.loads(json_val) + prop_def = ci_json(json.loads(json_val)) prop_name = str(prop_def["name"]) prop_value = str(prop_def.get("value", "")) @@ -837,7 +874,7 @@ def main(): if not os.path.isabs(def_file): def_file = os.path.join(os.getcwd(), def_file) with open(def_file, "r", encoding="utf-8-sig") as fh: - ops = json.loads(fh.read()) + ops = ci_json(json.loads(fh.read())) if isinstance(ops, list): operations = ops else: diff --git a/tests/skills/cases/cf-edit/lenient-key-case.json b/tests/skills/cases/cf-edit/lenient-key-case.json new file mode 100644 index 00000000..8d8f1ab4 --- /dev/null +++ b/tests/skills/cases/cf-edit/lenient-key-case.json @@ -0,0 +1,9 @@ +{ + "name": "Прощающий ввод: регистр ключей операции", + "input": [ + { + "Operation": "modify-property", + "Value": "Version=3.0.0" + } + ] +} diff --git a/tests/skills/cases/cf-edit/snapshots/lenient-key-case/Configuration.xml b/tests/skills/cases/cf-edit/snapshots/lenient-key-case/Configuration.xml new file mode 100644 index 00000000..afff09d4 --- /dev/null +++ b/tests/skills/cases/cf-edit/snapshots/lenient-key-case/Configuration.xml @@ -0,0 +1,251 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + UUID-012 + UUID-013 + + + UUID-014 + UUID-015 + + + + TestConfig + + + ru + TestConfig + + + + + Version8_3_24 + ManagedApplication + + PlatformApplication + + Russian + + + 3.0.0 + + false + false + false + + + + + + + + + + + + + + + + + + + + + + Biometrics + true + + + Location + false + + + BackgroundLocation + false + + + BluetoothPrinters + false + + + WiFiPrinters + false + + + Contacts + false + + + Calendars + false + + + PushNotifications + false + + + LocalNotifications + false + + + InAppPurchases + false + + + PersonalComputerFileExchange + false + + + Ads + false + + + NumberDialing + false + + + CallProcessing + false + + + CallLog + false + + + AutoSendSMS + false + + + ReceiveSMS + false + + + SMSLog + false + + + Camera + false + + + Microphone + false + + + MusicLibrary + false + + + PictureAndVideoLibraries + false + + + AudioPlaybackAndVibration + false + + + BackgroundAudioPlaybackAndVibration + false + + + InstallPackages + false + + + OSBackup + true + + + ApplicationUsageStatistics + false + + + BarcodeScanning + false + + + BackgroundAudioRecording + false + + + AllFilesAccess + false + + + Videoconferences + false + + + NFC + false + + + DocumentScanning + false + + + SpeechToText + false + + + Geofences + false + + + IncomingShareRequests + false + + + AllIncomingShareRequestsTypesProcessing + false + + + + + + Normal + + + Language.Русский + + + + + + Managed + NotAutoFree + DontUse + DontUse + TaxiEnableVersion8_2 + DontUse + Version8_3_24 + + + + Русский + + + \ No newline at end of file diff --git a/tests/skills/cases/cf-edit/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml b/tests/skills/cases/cf-edit/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml new file mode 100644 index 00000000..3c1161b2 --- /dev/null +++ b/tests/skills/cases/cf-edit/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml @@ -0,0 +1,18 @@ + + + + + UUID-002 + + + + + UUID-004 + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/cf-edit/snapshots/lenient-key-case/Languages/Русский.xml b/tests/skills/cases/cf-edit/snapshots/lenient-key-case/Languages/Русский.xml new file mode 100644 index 00000000..37c60d78 --- /dev/null +++ b/tests/skills/cases/cf-edit/snapshots/lenient-key-case/Languages/Русский.xml @@ -0,0 +1,16 @@ + + + + + Русский + + + ru + Русский + + + + ru + + + \ No newline at end of file diff --git a/tests/skills/cases/form-compile/lenient-key-case.json b/tests/skills/cases/form-compile/lenient-key-case.json new file mode 100644 index 00000000..b95dda6c --- /dev/null +++ b/tests/skills/cases/form-compile/lenient-key-case.json @@ -0,0 +1,43 @@ +{ + "name": "Прощающий ввод: регистр ключей DSL", + "preRun": [ + { + "script": "meta-compile/scripts/meta-compile", + "input": { + "type": "DataProcessor", + "name": "ТестРегистрКлючей" + }, + "args": { + "-JsonPath": "{inputFile}", + "-OutputDir": "{workDir}" + } + }, + { + "script": "form-add/scripts/form-add", + "args": { + "-ObjectPath": "{workDir}/DataProcessors/ТестРегистрКлючей.xml", + "-FormName": "Форма" + } + } + ], + "params": { + "outputPath": "DataProcessors/ТестРегистрКлючей/Forms/Форма/Ext/Form.xml" + }, + "input": { + "Title": "Регистр ключей", + "Attributes": [ + { + "Name": "Объект", + "Type": "DataProcessorObject.ТестРегистрКлючей", + "Main": true + } + ], + "Elements": [ + { + "input": "Поле", + "Name": "Поле1", + "Path": "Объект" + } + ] + } +} diff --git a/tests/skills/cases/form-compile/snapshots/lenient-key-case/Configuration.xml b/tests/skills/cases/form-compile/snapshots/lenient-key-case/Configuration.xml new file mode 100644 index 00000000..6f4ceb6b --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/lenient-key-case/Configuration.xml @@ -0,0 +1,252 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + UUID-012 + UUID-013 + + + UUID-014 + UUID-015 + + + + TestConfig + + + ru + TestConfig + + + + + Version8_3_24 + ManagedApplication + + PlatformApplication + + Russian + + + + + false + false + false + + + + + + + + + + + + + + + + + + + + + + Biometrics + true + + + Location + false + + + BackgroundLocation + false + + + BluetoothPrinters + false + + + WiFiPrinters + false + + + Contacts + false + + + Calendars + false + + + PushNotifications + false + + + LocalNotifications + false + + + InAppPurchases + false + + + PersonalComputerFileExchange + false + + + Ads + false + + + NumberDialing + false + + + CallProcessing + false + + + CallLog + false + + + AutoSendSMS + false + + + ReceiveSMS + false + + + SMSLog + false + + + Camera + false + + + Microphone + false + + + MusicLibrary + false + + + PictureAndVideoLibraries + false + + + AudioPlaybackAndVibration + false + + + BackgroundAudioPlaybackAndVibration + false + + + InstallPackages + false + + + OSBackup + true + + + ApplicationUsageStatistics + false + + + BarcodeScanning + false + + + BackgroundAudioRecording + false + + + AllFilesAccess + false + + + Videoconferences + false + + + NFC + false + + + DocumentScanning + false + + + SpeechToText + false + + + Geofences + false + + + IncomingShareRequests + false + + + AllIncomingShareRequestsTypesProcessing + false + + + + + + Normal + + + Language.Русский + + + + + + Managed + NotAutoFree + DontUse + DontUse + TaxiEnableVersion8_2 + DontUse + Version8_3_24 + + + + Русский + ТестРегистрКлючей + + + \ No newline at end of file diff --git a/tests/skills/cases/form-compile/snapshots/lenient-key-case/DataProcessors/ТестРегистрКлючей.xml b/tests/skills/cases/form-compile/snapshots/lenient-key-case/DataProcessors/ТестРегистрКлючей.xml new file mode 100644 index 00000000..bfbdf7aa --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/lenient-key-case/DataProcessors/ТестРегистрКлючей.xml @@ -0,0 +1,34 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + + ТестРегистрКлючей + + + ru + Тест регистр ключей + + + + true + DataProcessor.ТестРегистрКлючей.Form.Форма + + false + + + + +
Форма
+
+
+
\ No newline at end of file diff --git a/tests/skills/cases/form-compile/snapshots/lenient-key-case/DataProcessors/ТестРегистрКлючей/Ext/ManagerModule.bsl b/tests/skills/cases/form-compile/snapshots/lenient-key-case/DataProcessors/ТестРегистрКлючей/Ext/ManagerModule.bsl new file mode 100644 index 00000000..e69de29b diff --git a/tests/skills/cases/form-compile/snapshots/lenient-key-case/DataProcessors/ТестРегистрКлючей/Ext/ObjectModule.bsl b/tests/skills/cases/form-compile/snapshots/lenient-key-case/DataProcessors/ТестРегистрКлючей/Ext/ObjectModule.bsl new file mode 100644 index 00000000..e69de29b diff --git a/tests/skills/cases/form-compile/snapshots/lenient-key-case/DataProcessors/ТестРегистрКлючей/Forms/Форма.xml b/tests/skills/cases/form-compile/snapshots/lenient-key-case/DataProcessors/ТестРегистрКлючей/Forms/Форма.xml new file mode 100644 index 00000000..dffeea01 --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/lenient-key-case/DataProcessors/ТестРегистрКлючей/Forms/Форма.xml @@ -0,0 +1,22 @@ + + +
+ + Форма + + + ru + Форма + + + + Managed + false + + PlatformApplication + MobilePlatformApplication + + + +
+
\ No newline at end of file diff --git a/tests/skills/cases/form-compile/snapshots/lenient-key-case/DataProcessors/ТестРегистрКлючей/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/lenient-key-case/DataProcessors/ТестРегистрКлючей/Forms/Форма/Ext/Form.xml new file mode 100644 index 00000000..259ec41d --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/lenient-key-case/DataProcessors/ТестРегистрКлючей/Forms/Форма/Ext/Form.xml @@ -0,0 +1,26 @@ + +
+ + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Регистр ключей</v8:content> + </v8:item> + + false + + + + Объект + + + + + + + + cfg:DataProcessorObject.ТестРегистрКлючей + + true + + + \ No newline at end of file diff --git a/tests/skills/cases/form-compile/snapshots/lenient-key-case/DataProcessors/ТестРегистрКлючей/Forms/Форма/Ext/Form/Module.bsl b/tests/skills/cases/form-compile/snapshots/lenient-key-case/DataProcessors/ТестРегистрКлючей/Forms/Форма/Ext/Form/Module.bsl new file mode 100644 index 00000000..8ead4cec --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/lenient-key-case/DataProcessors/ТестРегистрКлючей/Forms/Форма/Ext/Form/Module.bsl @@ -0,0 +1,19 @@ +#Область ОбработчикиСобытийФормы + +#КонецОбласти + +#Область ОбработчикиСобытийЭлементовФормы + +#КонецОбласти + +#Область ОбработчикиКомандФормы + +#КонецОбласти + +#Область ОбработчикиОповещений + +#КонецОбласти + +#Область СлужебныеПроцедурыИФункции + +#КонецОбласти \ No newline at end of file diff --git a/tests/skills/cases/form-compile/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml b/tests/skills/cases/form-compile/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml new file mode 100644 index 00000000..3c1161b2 --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml @@ -0,0 +1,18 @@ + + + + + UUID-002 + + + + + UUID-004 + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/form-compile/snapshots/lenient-key-case/Languages/Русский.xml b/tests/skills/cases/form-compile/snapshots/lenient-key-case/Languages/Русский.xml new file mode 100644 index 00000000..37c60d78 --- /dev/null +++ b/tests/skills/cases/form-compile/snapshots/lenient-key-case/Languages/Русский.xml @@ -0,0 +1,16 @@ + + + + + Русский + + + ru + Русский + + + + ru + + + \ No newline at end of file diff --git a/tests/skills/cases/form-edit/lenient-key-case.json b/tests/skills/cases/form-edit/lenient-key-case.json new file mode 100644 index 00000000..55d5ad48 --- /dev/null +++ b/tests/skills/cases/form-edit/lenient-key-case.json @@ -0,0 +1,36 @@ +{ + "name": "Прощающий ввод: регистр ключей операции", + "preRun": [ + { + "script": "meta-compile/scripts/meta-compile", + "input": { + "type": "DataProcessor", + "name": "РедРегистр" + }, + "args": { + "-JsonPath": "{inputFile}", + "-OutputDir": "{workDir}" + } + }, + { + "script": "form-add/scripts/form-add", + "args": { + "-ObjectPath": "{workDir}/DataProcessors/РедРегистр.xml", + "-FormName": "Форма" + } + } + ], + "params": { + "formPath": "DataProcessors/РедРегистр/Forms/Форма/Ext/Form.xml" + }, + "input": { + "Operations": [ + { + "Op": "add-attribute", + "Name": "Рек", + "Type": "String", + "Length": 5 + } + ] + } +} diff --git a/tests/skills/cases/form-edit/snapshots/lenient-key-case/Configuration.xml b/tests/skills/cases/form-edit/snapshots/lenient-key-case/Configuration.xml new file mode 100644 index 00000000..ca0a4adc --- /dev/null +++ b/tests/skills/cases/form-edit/snapshots/lenient-key-case/Configuration.xml @@ -0,0 +1,252 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + UUID-012 + UUID-013 + + + UUID-014 + UUID-015 + + + + TestConfig + + + ru + TestConfig + + + + + Version8_3_24 + ManagedApplication + + PlatformApplication + + Russian + + + + + false + false + false + + + + + + + + + + + + + + + + + + + + + + Biometrics + true + + + Location + false + + + BackgroundLocation + false + + + BluetoothPrinters + false + + + WiFiPrinters + false + + + Contacts + false + + + Calendars + false + + + PushNotifications + false + + + LocalNotifications + false + + + InAppPurchases + false + + + PersonalComputerFileExchange + false + + + Ads + false + + + NumberDialing + false + + + CallProcessing + false + + + CallLog + false + + + AutoSendSMS + false + + + ReceiveSMS + false + + + SMSLog + false + + + Camera + false + + + Microphone + false + + + MusicLibrary + false + + + PictureAndVideoLibraries + false + + + AudioPlaybackAndVibration + false + + + BackgroundAudioPlaybackAndVibration + false + + + InstallPackages + false + + + OSBackup + true + + + ApplicationUsageStatistics + false + + + BarcodeScanning + false + + + BackgroundAudioRecording + false + + + AllFilesAccess + false + + + Videoconferences + false + + + NFC + false + + + DocumentScanning + false + + + SpeechToText + false + + + Geofences + false + + + IncomingShareRequests + false + + + AllIncomingShareRequestsTypesProcessing + false + + + + + + Normal + + + Language.Русский + + + + + + Managed + NotAutoFree + DontUse + DontUse + TaxiEnableVersion8_2 + DontUse + Version8_3_24 + + + + Русский + РедРегистр + + + \ No newline at end of file diff --git a/tests/skills/cases/form-edit/snapshots/lenient-key-case/DataProcessors/РедРегистр.xml b/tests/skills/cases/form-edit/snapshots/lenient-key-case/DataProcessors/РедРегистр.xml new file mode 100644 index 00000000..71d1dde8 --- /dev/null +++ b/tests/skills/cases/form-edit/snapshots/lenient-key-case/DataProcessors/РедРегистр.xml @@ -0,0 +1,34 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + + РедРегистр + + + ru + Ред регистр + + + + true + DataProcessor.РедРегистр.Form.Форма + + false + + + + +
Форма
+
+
+
\ No newline at end of file diff --git a/tests/skills/cases/form-edit/snapshots/lenient-key-case/DataProcessors/РедРегистр/Ext/ManagerModule.bsl b/tests/skills/cases/form-edit/snapshots/lenient-key-case/DataProcessors/РедРегистр/Ext/ManagerModule.bsl new file mode 100644 index 00000000..e69de29b diff --git a/tests/skills/cases/form-edit/snapshots/lenient-key-case/DataProcessors/РедРегистр/Ext/ObjectModule.bsl b/tests/skills/cases/form-edit/snapshots/lenient-key-case/DataProcessors/РедРегистр/Ext/ObjectModule.bsl new file mode 100644 index 00000000..e69de29b diff --git a/tests/skills/cases/form-edit/snapshots/lenient-key-case/DataProcessors/РедРегистр/Forms/Форма.xml b/tests/skills/cases/form-edit/snapshots/lenient-key-case/DataProcessors/РедРегистр/Forms/Форма.xml new file mode 100644 index 00000000..dffeea01 --- /dev/null +++ b/tests/skills/cases/form-edit/snapshots/lenient-key-case/DataProcessors/РедРегистр/Forms/Форма.xml @@ -0,0 +1,22 @@ + + +
+ + Форма + + + ru + Форма + + + + Managed + false + + PlatformApplication + MobilePlatformApplication + + + +
+
\ No newline at end of file diff --git a/tests/skills/cases/form-edit/snapshots/lenient-key-case/DataProcessors/РедРегистр/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-edit/snapshots/lenient-key-case/DataProcessors/РедРегистр/Forms/Форма/Ext/Form.xml new file mode 100644 index 00000000..5fa2555d --- /dev/null +++ b/tests/skills/cases/form-edit/snapshots/lenient-key-case/DataProcessors/РедРегистр/Forms/Форма/Ext/Form.xml @@ -0,0 +1,15 @@ + +
+ + true + + + + + + cfg:DataProcessorObject.РедРегистр + + true + + + \ No newline at end of file diff --git a/tests/skills/cases/form-edit/snapshots/lenient-key-case/DataProcessors/РедРегистр/Forms/Форма/Ext/Form/Module.bsl b/tests/skills/cases/form-edit/snapshots/lenient-key-case/DataProcessors/РедРегистр/Forms/Форма/Ext/Form/Module.bsl new file mode 100644 index 00000000..8ead4cec --- /dev/null +++ b/tests/skills/cases/form-edit/snapshots/lenient-key-case/DataProcessors/РедРегистр/Forms/Форма/Ext/Form/Module.bsl @@ -0,0 +1,19 @@ +#Область ОбработчикиСобытийФормы + +#КонецОбласти + +#Область ОбработчикиСобытийЭлементовФормы + +#КонецОбласти + +#Область ОбработчикиКомандФормы + +#КонецОбласти + +#Область ОбработчикиОповещений + +#КонецОбласти + +#Область СлужебныеПроцедурыИФункции + +#КонецОбласти \ No newline at end of file diff --git a/tests/skills/cases/form-edit/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml b/tests/skills/cases/form-edit/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml new file mode 100644 index 00000000..3c1161b2 --- /dev/null +++ b/tests/skills/cases/form-edit/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml @@ -0,0 +1,18 @@ + + + + + UUID-002 + + + + + UUID-004 + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/form-edit/snapshots/lenient-key-case/Languages/Русский.xml b/tests/skills/cases/form-edit/snapshots/lenient-key-case/Languages/Русский.xml new file mode 100644 index 00000000..37c60d78 --- /dev/null +++ b/tests/skills/cases/form-edit/snapshots/lenient-key-case/Languages/Русский.xml @@ -0,0 +1,16 @@ + + + + + Русский + + + ru + Русский + + + + ru + + + \ No newline at end of file diff --git a/tests/skills/cases/interface-edit/lenient-key-case.json b/tests/skills/cases/interface-edit/lenient-key-case.json new file mode 100644 index 00000000..89ec2b73 --- /dev/null +++ b/tests/skills/cases/interface-edit/lenient-key-case.json @@ -0,0 +1,28 @@ +{ + "name": "Прощающий ввод: регистр ключей операции", + "preRun": [ + { + "script": "subsystem-compile/scripts/subsystem-compile", + "input": { + "name": "Продажи", + "children": [ + "Оптовые", + "Розничные" + ] + }, + "args": { + "-DefinitionFile": "{inputFile}", + "-OutputDir": "{workDir}" + } + } + ], + "params": { + "ciPath": "Subsystems/Продажи/CommandInterface" + }, + "input": [ + { + "Operation": "subsystem-order", + "Value": "[\"Subsystem.Продажи.Subsystem.Розничные\",\"Subsystem.Продажи.Subsystem.Оптовые\"]" + } + ] +} diff --git a/tests/skills/cases/interface-edit/snapshots/lenient-key-case/Configuration.xml b/tests/skills/cases/interface-edit/snapshots/lenient-key-case/Configuration.xml new file mode 100644 index 00000000..212eec45 --- /dev/null +++ b/tests/skills/cases/interface-edit/snapshots/lenient-key-case/Configuration.xml @@ -0,0 +1,252 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + UUID-012 + UUID-013 + + + UUID-014 + UUID-015 + + + + TestConfig + + + ru + TestConfig + + + + + Version8_3_24 + ManagedApplication + + PlatformApplication + + Russian + + + + + false + false + false + + + + + + + + + + + + + + + + + + + + + + Biometrics + true + + + Location + false + + + BackgroundLocation + false + + + BluetoothPrinters + false + + + WiFiPrinters + false + + + Contacts + false + + + Calendars + false + + + PushNotifications + false + + + LocalNotifications + false + + + InAppPurchases + false + + + PersonalComputerFileExchange + false + + + Ads + false + + + NumberDialing + false + + + CallProcessing + false + + + CallLog + false + + + AutoSendSMS + false + + + ReceiveSMS + false + + + SMSLog + false + + + Camera + false + + + Microphone + false + + + MusicLibrary + false + + + PictureAndVideoLibraries + false + + + AudioPlaybackAndVibration + false + + + BackgroundAudioPlaybackAndVibration + false + + + InstallPackages + false + + + OSBackup + true + + + ApplicationUsageStatistics + false + + + BarcodeScanning + false + + + BackgroundAudioRecording + false + + + AllFilesAccess + false + + + Videoconferences + false + + + NFC + false + + + DocumentScanning + false + + + SpeechToText + false + + + Geofences + false + + + IncomingShareRequests + false + + + AllIncomingShareRequestsTypesProcessing + false + + + + + + Normal + + + Language.Русский + + + + + + Managed + NotAutoFree + DontUse + DontUse + TaxiEnableVersion8_2 + DontUse + Version8_3_24 + + + + Русский + Продажи + + + \ No newline at end of file diff --git a/tests/skills/cases/interface-edit/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml b/tests/skills/cases/interface-edit/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml new file mode 100644 index 00000000..3c1161b2 --- /dev/null +++ b/tests/skills/cases/interface-edit/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml @@ -0,0 +1,18 @@ + + + + + UUID-002 + + + + + UUID-004 + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/interface-edit/snapshots/lenient-key-case/Languages/Русский.xml b/tests/skills/cases/interface-edit/snapshots/lenient-key-case/Languages/Русский.xml new file mode 100644 index 00000000..37c60d78 --- /dev/null +++ b/tests/skills/cases/interface-edit/snapshots/lenient-key-case/Languages/Русский.xml @@ -0,0 +1,16 @@ + + + + + Русский + + + ru + Русский + + + + ru + + + \ No newline at end of file diff --git a/tests/skills/cases/interface-edit/snapshots/lenient-key-case/Subsystems/Продажи.xml b/tests/skills/cases/interface-edit/snapshots/lenient-key-case/Subsystems/Продажи.xml new file mode 100644 index 00000000..879e26e8 --- /dev/null +++ b/tests/skills/cases/interface-edit/snapshots/lenient-key-case/Subsystems/Продажи.xml @@ -0,0 +1,25 @@ + + + + + Продажи + + + ru + Продажи + + + + true + true + false + + + + + + Оптовые + Розничные + + + \ No newline at end of file diff --git a/tests/skills/cases/interface-edit/snapshots/lenient-key-case/Subsystems/Продажи/CommandInterface b/tests/skills/cases/interface-edit/snapshots/lenient-key-case/Subsystems/Продажи/CommandInterface new file mode 100644 index 00000000..aaf4d22b --- /dev/null +++ b/tests/skills/cases/interface-edit/snapshots/lenient-key-case/Subsystems/Продажи/CommandInterface @@ -0,0 +1,7 @@ + + + + Subsystem.Продажи.Subsystem.Розничные + Subsystem.Продажи.Subsystem.Оптовые + + \ No newline at end of file diff --git a/tests/skills/cases/interface-edit/snapshots/lenient-key-case/Subsystems/Продажи/Subsystems/Оптовые.xml b/tests/skills/cases/interface-edit/snapshots/lenient-key-case/Subsystems/Продажи/Subsystems/Оптовые.xml new file mode 100644 index 00000000..b4fbee8b --- /dev/null +++ b/tests/skills/cases/interface-edit/snapshots/lenient-key-case/Subsystems/Продажи/Subsystems/Оптовые.xml @@ -0,0 +1,17 @@ + + + + + Оптовые + + + true + true + false + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/interface-edit/snapshots/lenient-key-case/Subsystems/Продажи/Subsystems/Розничные.xml b/tests/skills/cases/interface-edit/snapshots/lenient-key-case/Subsystems/Продажи/Subsystems/Розничные.xml new file mode 100644 index 00000000..49737d5c --- /dev/null +++ b/tests/skills/cases/interface-edit/snapshots/lenient-key-case/Subsystems/Продажи/Subsystems/Розничные.xml @@ -0,0 +1,17 @@ + + + + + Розничные + + + true + true + false + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/meta-edit/lenient-key-case.json b/tests/skills/cases/meta-edit/lenient-key-case.json new file mode 100644 index 00000000..182d3897 --- /dev/null +++ b/tests/skills/cases/meta-edit/lenient-key-case.json @@ -0,0 +1,26 @@ +{ + "name": "Прощающий ввод: регистр ключей DSL", + "preRun": [ + { + "script": "meta-compile/scripts/meta-compile", + "input": { + "type": "Catalog", + "name": "Контрагенты" + }, + "args": { + "-JsonPath": "{inputFile}", + "-OutputDir": "{workDir}" + } + } + ], + "params": { + "objectPath": "Catalogs/Контрагенты" + }, + "input": { + "Add": { + "Attributes": [ + "ИНН: String(12)" + ] + } + } +} diff --git a/tests/skills/cases/meta-edit/snapshots/lenient-key-case/Catalogs/Контрагенты.xml b/tests/skills/cases/meta-edit/snapshots/lenient-key-case/Catalogs/Контрагенты.xml new file mode 100644 index 00000000..80c20dde --- /dev/null +++ b/tests/skills/cases/meta-edit/snapshots/lenient-key-case/Catalogs/Контрагенты.xml @@ -0,0 +1,136 @@ + + + + + + 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 + + Auto + InDialog + false + BothWays + + Catalog.Контрагенты.StandardAttribute.Description + Catalog.Контрагенты.StandardAttribute.Code + + Begin + DontUse + Directly + + + + + + + + + + + false + + + Managed + Use + + + + + + Use + Auto + DontUse + false + false + + + + + ИНН + + + ru + Инн + + + + + xs:string + + 12 + Variable + + + false + + + + false + + false + false + + + false + + DontCheck + Items + + + Auto + Auto + + + Auto + ForItem + DontIndex + Use + Use + + + + + \ No newline at end of file diff --git a/tests/skills/cases/meta-edit/snapshots/lenient-key-case/Catalogs/Контрагенты/Ext/ObjectModule.bsl b/tests/skills/cases/meta-edit/snapshots/lenient-key-case/Catalogs/Контрагенты/Ext/ObjectModule.bsl new file mode 100644 index 00000000..e69de29b diff --git a/tests/skills/cases/meta-edit/snapshots/lenient-key-case/Configuration.xml b/tests/skills/cases/meta-edit/snapshots/lenient-key-case/Configuration.xml new file mode 100644 index 00000000..7dd7b758 --- /dev/null +++ b/tests/skills/cases/meta-edit/snapshots/lenient-key-case/Configuration.xml @@ -0,0 +1,252 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + UUID-012 + UUID-013 + + + UUID-014 + UUID-015 + + + + TestConfig + + + ru + TestConfig + + + + + Version8_3_24 + ManagedApplication + + PlatformApplication + + Russian + + + + + false + false + false + + + + + + + + + + + + + + + + + + + + + + Biometrics + true + + + Location + false + + + BackgroundLocation + false + + + BluetoothPrinters + false + + + WiFiPrinters + false + + + Contacts + false + + + Calendars + false + + + PushNotifications + false + + + LocalNotifications + false + + + InAppPurchases + false + + + PersonalComputerFileExchange + false + + + Ads + false + + + NumberDialing + false + + + CallProcessing + false + + + CallLog + false + + + AutoSendSMS + false + + + ReceiveSMS + false + + + SMSLog + false + + + Camera + false + + + Microphone + false + + + MusicLibrary + false + + + PictureAndVideoLibraries + false + + + AudioPlaybackAndVibration + false + + + BackgroundAudioPlaybackAndVibration + false + + + InstallPackages + false + + + OSBackup + true + + + ApplicationUsageStatistics + false + + + BarcodeScanning + false + + + BackgroundAudioRecording + false + + + AllFilesAccess + false + + + Videoconferences + false + + + NFC + false + + + DocumentScanning + false + + + SpeechToText + false + + + Geofences + false + + + IncomingShareRequests + false + + + AllIncomingShareRequestsTypesProcessing + false + + + + + + Normal + + + Language.Русский + + + + + + Managed + NotAutoFree + DontUse + DontUse + TaxiEnableVersion8_2 + DontUse + Version8_3_24 + + + + Русский + Контрагенты + + + \ No newline at end of file diff --git a/tests/skills/cases/meta-edit/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml b/tests/skills/cases/meta-edit/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml new file mode 100644 index 00000000..3c1161b2 --- /dev/null +++ b/tests/skills/cases/meta-edit/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml @@ -0,0 +1,18 @@ + + + + + UUID-002 + + + + + UUID-004 + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/meta-edit/snapshots/lenient-key-case/Languages/Русский.xml b/tests/skills/cases/meta-edit/snapshots/lenient-key-case/Languages/Русский.xml new file mode 100644 index 00000000..37c60d78 --- /dev/null +++ b/tests/skills/cases/meta-edit/snapshots/lenient-key-case/Languages/Русский.xml @@ -0,0 +1,16 @@ + + + + + Русский + + + ru + Русский + + + + ru + + + \ No newline at end of file diff --git a/tests/skills/cases/mxl-compile/lenient-key-case.json b/tests/skills/cases/mxl-compile/lenient-key-case.json new file mode 100644 index 00000000..e3fa36eb --- /dev/null +++ b/tests/skills/cases/mxl-compile/lenient-key-case.json @@ -0,0 +1,27 @@ +{ + "name": "Прощающий ввод: регистр ключей DSL", + "input": { + "Columns": 3, + "Areas": [ + { + "Name": "Заголовок", + "Rows": [ + [ + "Наименование", + "Количество", + "Сумма" + ] + ] + } + ] + }, + "params": { + "outputPath": "Template.xml" + }, + "validatePath": "Template.xml", + "expect": { + "files": [ + "Template.xml" + ] + } +} diff --git a/tests/skills/cases/mxl-compile/snapshots/lenient-key-case/Template.xml b/tests/skills/cases/mxl-compile/snapshots/lenient-key-case/Template.xml new file mode 100644 index 00000000..384ee851 --- /dev/null +++ b/tests/skills/cases/mxl-compile/snapshots/lenient-key-case/Template.xml @@ -0,0 +1,39 @@ + + + + ru + ru + + ru + Русский + Русский + + + + 3 + + + 0 + + true + + + true + 1 + 1 + 1 + + Заголовок + + Rows + 0 + 0 + -1 + -1 + + + + + 10 + + \ No newline at end of file diff --git a/tests/skills/cases/role-compile/lenient-key-case.json b/tests/skills/cases/role-compile/lenient-key-case.json new file mode 100644 index 00000000..944b0b33 --- /dev/null +++ b/tests/skills/cases/role-compile/lenient-key-case.json @@ -0,0 +1,14 @@ +{ + "name": "Прощающий ввод: регистр ключей DSL", + "input": { + "Name": "ПустаяРоль", + "Rights": {} + }, + "validatePath": "Roles/ПустаяРоль", + "expect": { + "files": [ + "Roles/ПустаяРоль.xml", + "Roles/ПустаяРоль/Ext/Rights.xml" + ] + } +} diff --git a/tests/skills/cases/role-compile/snapshots/lenient-key-case/Configuration.xml b/tests/skills/cases/role-compile/snapshots/lenient-key-case/Configuration.xml new file mode 100644 index 00000000..d10b8e1e --- /dev/null +++ b/tests/skills/cases/role-compile/snapshots/lenient-key-case/Configuration.xml @@ -0,0 +1,252 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + UUID-012 + UUID-013 + + + UUID-014 + UUID-015 + + + + TestConfig + + + ru + TestConfig + + + + + Version8_3_24 + ManagedApplication + + PlatformApplication + + Russian + + + + + false + false + false + + + + + + + + + + + + + + + + + + + + + + Biometrics + true + + + Location + false + + + BackgroundLocation + false + + + BluetoothPrinters + false + + + WiFiPrinters + false + + + Contacts + false + + + Calendars + false + + + PushNotifications + false + + + LocalNotifications + false + + + InAppPurchases + false + + + PersonalComputerFileExchange + false + + + Ads + false + + + NumberDialing + false + + + CallProcessing + false + + + CallLog + false + + + AutoSendSMS + false + + + ReceiveSMS + false + + + SMSLog + false + + + Camera + false + + + Microphone + false + + + MusicLibrary + false + + + PictureAndVideoLibraries + false + + + AudioPlaybackAndVibration + false + + + BackgroundAudioPlaybackAndVibration + false + + + InstallPackages + false + + + OSBackup + true + + + ApplicationUsageStatistics + false + + + BarcodeScanning + false + + + BackgroundAudioRecording + false + + + AllFilesAccess + false + + + Videoconferences + false + + + NFC + false + + + DocumentScanning + false + + + SpeechToText + false + + + Geofences + false + + + IncomingShareRequests + false + + + AllIncomingShareRequestsTypesProcessing + false + + + + + + Normal + + + Language.Русский + + + + + + Managed + NotAutoFree + DontUse + DontUse + TaxiEnableVersion8_2 + DontUse + Version8_3_24 + + + + Русский + ПустаяРоль + + + \ No newline at end of file diff --git a/tests/skills/cases/role-compile/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml b/tests/skills/cases/role-compile/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml new file mode 100644 index 00000000..3c1161b2 --- /dev/null +++ b/tests/skills/cases/role-compile/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml @@ -0,0 +1,18 @@ + + + + + UUID-002 + + + + + UUID-004 + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/role-compile/snapshots/lenient-key-case/Languages/Русский.xml b/tests/skills/cases/role-compile/snapshots/lenient-key-case/Languages/Русский.xml new file mode 100644 index 00000000..37c60d78 --- /dev/null +++ b/tests/skills/cases/role-compile/snapshots/lenient-key-case/Languages/Русский.xml @@ -0,0 +1,16 @@ + + + + + Русский + + + ru + Русский + + + + ru + + + \ No newline at end of file diff --git a/tests/skills/cases/role-compile/snapshots/lenient-key-case/Roles/ПустаяРоль.xml b/tests/skills/cases/role-compile/snapshots/lenient-key-case/Roles/ПустаяРоль.xml new file mode 100644 index 00000000..e30c34c1 --- /dev/null +++ b/tests/skills/cases/role-compile/snapshots/lenient-key-case/Roles/ПустаяРоль.xml @@ -0,0 +1,15 @@ + + + + + ПустаяРоль + + + ru + ПустаяРоль + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/role-compile/snapshots/lenient-key-case/Roles/ПустаяРоль/Ext/Rights.xml b/tests/skills/cases/role-compile/snapshots/lenient-key-case/Roles/ПустаяРоль/Ext/Rights.xml new file mode 100644 index 00000000..9a1537d2 --- /dev/null +++ b/tests/skills/cases/role-compile/snapshots/lenient-key-case/Roles/ПустаяРоль/Ext/Rights.xml @@ -0,0 +1,6 @@ + + + false + true + false + \ No newline at end of file diff --git a/tests/skills/cases/skd-compile/lenient-key-case.json b/tests/skills/cases/skd-compile/lenient-key-case.json new file mode 100644 index 00000000..710967e8 --- /dev/null +++ b/tests/skills/cases/skd-compile/lenient-key-case.json @@ -0,0 +1,21 @@ +{ + "name": "Прощающий ввод: регистр ключей DSL", + "params": { + "outputPath": "Template.xml" + }, + "input": { + "DataSets": [ + { + "Name": "Основной", + "Type": "Query", + "Query": "SELECT 1 AS Поле" + } + ] + }, + "validatePath": "Template.xml", + "expect": { + "files": [ + "Template.xml" + ] + } +} diff --git a/tests/skills/cases/skd-compile/snapshots/lenient-key-case/Template.xml b/tests/skills/cases/skd-compile/snapshots/lenient-key-case/Template.xml new file mode 100644 index 00000000..9903fc5b --- /dev/null +++ b/tests/skills/cases/skd-compile/snapshots/lenient-key-case/Template.xml @@ -0,0 +1,34 @@ + + + + ИсточникДанных1 + Local + + + Основной + ИсточникДанных1 + SELECT 1 AS Поле + + + Основной + + + ru + Основной + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/subsystem-compile/lenient-key-case.json b/tests/skills/cases/subsystem-compile/lenient-key-case.json new file mode 100644 index 00000000..16a58b64 --- /dev/null +++ b/tests/skills/cases/subsystem-compile/lenient-key-case.json @@ -0,0 +1,13 @@ +{ + "name": "Прощающий ввод: регистр ключей DSL", + "input": { + "Name": "ТестРегистр", + "IncludeInCommandInterface": false + }, + "validatePath": "Subsystems/ТестРегистр", + "expect": { + "files": [ + "Subsystems/ТестРегистр.xml" + ] + } +} diff --git a/tests/skills/cases/subsystem-compile/snapshots/lenient-key-case/Configuration.xml b/tests/skills/cases/subsystem-compile/snapshots/lenient-key-case/Configuration.xml new file mode 100644 index 00000000..3d514842 --- /dev/null +++ b/tests/skills/cases/subsystem-compile/snapshots/lenient-key-case/Configuration.xml @@ -0,0 +1,252 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + UUID-012 + UUID-013 + + + UUID-014 + UUID-015 + + + + TestConfig + + + ru + TestConfig + + + + + Version8_3_24 + ManagedApplication + + PlatformApplication + + Russian + + + + + false + false + false + + + + + + + + + + + + + + + + + + + + + + Biometrics + true + + + Location + false + + + BackgroundLocation + false + + + BluetoothPrinters + false + + + WiFiPrinters + false + + + Contacts + false + + + Calendars + false + + + PushNotifications + false + + + LocalNotifications + false + + + InAppPurchases + false + + + PersonalComputerFileExchange + false + + + Ads + false + + + NumberDialing + false + + + CallProcessing + false + + + CallLog + false + + + AutoSendSMS + false + + + ReceiveSMS + false + + + SMSLog + false + + + Camera + false + + + Microphone + false + + + MusicLibrary + false + + + PictureAndVideoLibraries + false + + + AudioPlaybackAndVibration + false + + + BackgroundAudioPlaybackAndVibration + false + + + InstallPackages + false + + + OSBackup + true + + + ApplicationUsageStatistics + false + + + BarcodeScanning + false + + + BackgroundAudioRecording + false + + + AllFilesAccess + false + + + Videoconferences + false + + + NFC + false + + + DocumentScanning + false + + + SpeechToText + false + + + Geofences + false + + + IncomingShareRequests + false + + + AllIncomingShareRequestsTypesProcessing + false + + + + + + Normal + + + Language.Русский + + + + + + Managed + NotAutoFree + DontUse + DontUse + TaxiEnableVersion8_2 + DontUse + Version8_3_24 + + + + Русский + ТестРегистр + + + \ No newline at end of file diff --git a/tests/skills/cases/subsystem-compile/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml b/tests/skills/cases/subsystem-compile/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml new file mode 100644 index 00000000..3c1161b2 --- /dev/null +++ b/tests/skills/cases/subsystem-compile/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml @@ -0,0 +1,18 @@ + + + + + UUID-002 + + + + + UUID-004 + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/subsystem-compile/snapshots/lenient-key-case/Languages/Русский.xml b/tests/skills/cases/subsystem-compile/snapshots/lenient-key-case/Languages/Русский.xml new file mode 100644 index 00000000..37c60d78 --- /dev/null +++ b/tests/skills/cases/subsystem-compile/snapshots/lenient-key-case/Languages/Русский.xml @@ -0,0 +1,16 @@ + + + + + Русский + + + ru + Русский + + + + ru + + + \ No newline at end of file diff --git a/tests/skills/cases/subsystem-compile/snapshots/lenient-key-case/Subsystems/ТестРегистр.xml b/tests/skills/cases/subsystem-compile/snapshots/lenient-key-case/Subsystems/ТестРегистр.xml new file mode 100644 index 00000000..9bed4d36 --- /dev/null +++ b/tests/skills/cases/subsystem-compile/snapshots/lenient-key-case/Subsystems/ТестРегистр.xml @@ -0,0 +1,22 @@ + + + + + ТестРегистр + + + ru + Тест регистр + + + + true + false + false + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/subsystem-edit/lenient-key-case.json b/tests/skills/cases/subsystem-edit/lenient-key-case.json new file mode 100644 index 00000000..b245947e --- /dev/null +++ b/tests/skills/cases/subsystem-edit/lenient-key-case.json @@ -0,0 +1,24 @@ +{ + "name": "Прощающий ввод: регистр ключей операции", + "preRun": [ + { + "script": "subsystem-compile/scripts/subsystem-compile", + "input": { + "name": "Продажи" + }, + "args": { + "-DefinitionFile": "{inputFile}", + "-OutputDir": "{workDir}" + } + } + ], + "params": { + "subsystemPath": "Subsystems/Продажи.xml" + }, + "input": [ + { + "Operation": "add-child", + "Value": "Настройки" + } + ] +} diff --git a/tests/skills/cases/subsystem-edit/snapshots/lenient-key-case/Configuration.xml b/tests/skills/cases/subsystem-edit/snapshots/lenient-key-case/Configuration.xml new file mode 100644 index 00000000..212eec45 --- /dev/null +++ b/tests/skills/cases/subsystem-edit/snapshots/lenient-key-case/Configuration.xml @@ -0,0 +1,252 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + UUID-012 + UUID-013 + + + UUID-014 + UUID-015 + + + + TestConfig + + + ru + TestConfig + + + + + Version8_3_24 + ManagedApplication + + PlatformApplication + + Russian + + + + + false + false + false + + + + + + + + + + + + + + + + + + + + + + Biometrics + true + + + Location + false + + + BackgroundLocation + false + + + BluetoothPrinters + false + + + WiFiPrinters + false + + + Contacts + false + + + Calendars + false + + + PushNotifications + false + + + LocalNotifications + false + + + InAppPurchases + false + + + PersonalComputerFileExchange + false + + + Ads + false + + + NumberDialing + false + + + CallProcessing + false + + + CallLog + false + + + AutoSendSMS + false + + + ReceiveSMS + false + + + SMSLog + false + + + Camera + false + + + Microphone + false + + + MusicLibrary + false + + + PictureAndVideoLibraries + false + + + AudioPlaybackAndVibration + false + + + BackgroundAudioPlaybackAndVibration + false + + + InstallPackages + false + + + OSBackup + true + + + ApplicationUsageStatistics + false + + + BarcodeScanning + false + + + BackgroundAudioRecording + false + + + AllFilesAccess + false + + + Videoconferences + false + + + NFC + false + + + DocumentScanning + false + + + SpeechToText + false + + + Geofences + false + + + IncomingShareRequests + false + + + AllIncomingShareRequestsTypesProcessing + false + + + + + + Normal + + + Language.Русский + + + + + + Managed + NotAutoFree + DontUse + DontUse + TaxiEnableVersion8_2 + DontUse + Version8_3_24 + + + + Русский + Продажи + + + \ No newline at end of file diff --git a/tests/skills/cases/subsystem-edit/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml b/tests/skills/cases/subsystem-edit/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml new file mode 100644 index 00000000..3c1161b2 --- /dev/null +++ b/tests/skills/cases/subsystem-edit/snapshots/lenient-key-case/Ext/ClientApplicationInterface.xml @@ -0,0 +1,18 @@ + + + + + UUID-002 + + + + + UUID-004 + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/subsystem-edit/snapshots/lenient-key-case/Languages/Русский.xml b/tests/skills/cases/subsystem-edit/snapshots/lenient-key-case/Languages/Русский.xml new file mode 100644 index 00000000..37c60d78 --- /dev/null +++ b/tests/skills/cases/subsystem-edit/snapshots/lenient-key-case/Languages/Русский.xml @@ -0,0 +1,16 @@ + + + + + Русский + + + ru + Русский + + + + ru + + + \ No newline at end of file diff --git a/tests/skills/cases/subsystem-edit/snapshots/lenient-key-case/Subsystems/Продажи.xml b/tests/skills/cases/subsystem-edit/snapshots/lenient-key-case/Subsystems/Продажи.xml new file mode 100644 index 00000000..138fc6b8 --- /dev/null +++ b/tests/skills/cases/subsystem-edit/snapshots/lenient-key-case/Subsystems/Продажи.xml @@ -0,0 +1,24 @@ + + + + + Продажи + + + ru + Продажи + + + + true + true + false + + + + + + Настройки + + + \ No newline at end of file diff --git a/tests/skills/cases/subsystem-edit/snapshots/lenient-key-case/Subsystems/Продажи/Subsystems/Настройки.xml b/tests/skills/cases/subsystem-edit/snapshots/lenient-key-case/Subsystems/Продажи/Subsystems/Настройки.xml new file mode 100644 index 00000000..4b1fd73c --- /dev/null +++ b/tests/skills/cases/subsystem-edit/snapshots/lenient-key-case/Subsystems/Продажи/Subsystems/Настройки.xml @@ -0,0 +1,17 @@ + + + + + Настройки + + + true + true + false + + + + + + + \ No newline at end of file diff --git a/tests/skills/check-inline-drift.mjs b/tests/skills/check-inline-drift.mjs index 60e3ed31..e3e6633b 100644 --- a/tests/skills/check-inline-drift.mjs +++ b/tests/skills/check-inline-drift.mjs @@ -276,11 +276,19 @@ const FAMILIES = [ // не должно — ps1: null. { name: 'case-insensitive input: CIDict', py: 'CIDict', ps1: null, - variants: [{ id: 'base', authority: 'meta-compile', consumers: [] }], + variants: [ + { id: 'base', authority: 'meta-compile', + consumers: [ + 'cf-edit', 'form-compile', 'form-edit', 'interface-edit', 'meta-edit', 'mxl-compile', + 'role-compile', 'skd-compile', 'subsystem-compile', 'subsystem-edit'] }], }, { name: 'case-insensitive input: ci_json', py: 'ci_json', ps1: null, - variants: [{ id: 'base', authority: 'meta-compile', consumers: [] }], + variants: [ + { id: 'base', authority: 'meta-compile', + consumers: [ + 'cf-edit', 'form-compile', 'form-edit', 'interface-edit', 'meta-edit', 'mxl-compile', + 'role-compile', 'skd-compile', 'subsystem-compile', 'subsystem-edit'] }], }, { // Единственная из трёх, которая нужна КАЖДОМУ порту: DSL читают не все навыки, а параметры — все.