From caf038a192a3a1fd39843cd3a7af3b63fd5a1c4f Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Wed, 5 Aug 2026 18:53:17 +0300 Subject: [PATCH] =?UTF-8?q?fix(cfe-borrow,template-add,help-add,interface-?= =?UTF-8?q?edit):=20=D0=B2=D1=8B=D0=B2=D0=BE=D0=B4=20py-=D0=BF=D0=BE=D1=80?= =?UTF-8?q?=D1=82=D0=B0=20=D0=BD=D0=B5=20=D0=B7=D0=B0=D0=B2=D0=B8=D1=81?= =?UTF-8?q?=D0=B8=D1=82=20=D0=BE=D1=82=20=D0=9E=D0=A1=20(#57)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Тот же writer без newline="", что чинился в form-add.py, остался ещё в четырёх py-портах, и пишут они не модули, а 1С XML: заимствованные объекты и метаданные формы (cfe-borrow), Template.xml и XML-макеты (template-add), Help.xml (help-add), вновь создаваемый CommandInterface.xml (interface-edit). Контент там собирается литералами с \n, поэтому текстовый режим Python давал CRLF на Windows — «случайно правильно» — и LF на macOS, ломая канон #57 ровно там, где он только что установлен. Проверено на маке ДО фикса: cfe-borrow 0 CRLF + 33 одиночных LF, template-add 0 + 2, interface-edit 0 + 5. Порчи \r\r\n не было, но это везение: подай такой writer CRLF-контент — каждая строка стала бы \r\r\n. Почему не поймали раньше: аудит гонялся на Windows, где текстовый режим даёт канон; снэпшоты нормализуют EOL; байтовый preserves ни разу не проверялся на маке. Разделены два пути, которые я сперва смешал в cfe-borrow: - save_xml_file — канон (CRLF, без хвоста) для файлов, которые СОЗДАЁМ; - save_text_bom — пишет как есть, для файлов, которые ПРАВИМ: переводы строк уже пришли из самого файла и менять их нельзя (контракт #44/#46/#47). Туда же добавлено чтение с newline="" — иначе CRLF терялся ещё на входе. interface-edit чинится и в PS-порте: ветка -CreateIfMissing давала смешанный EOL (3 CRLF + 2 одиночных LF) уже на Windows. Аудит #57 её пропустил, потому что фильтровал файлы по расширению .xml, а кейс создаёт файл с именем без расширения. Канон, как выяснилось, зависит от типа артефакта: XML — CRLF, текстовый макет — CRLF, а HTML-макет платформа хранит с LF (корпус: 399 LF из 400). Поэтому HTML через канон-writer НЕ идёт. preserves добавлен четырём навыкам (у них его не было вовсе) + отдельно на Help.xml. Именно прогон на маке и даёт покрытие: на Windows эти кейсы зелены и без фикса. Windows 641/641 обоими портами, мак 590/0/51, дрейфа снэпшотов нет. Co-Authored-By: Claude Opus 5 --- .../skills/cfe-borrow/scripts/cfe-borrow.ps1 | 2 +- .../skills/cfe-borrow/scripts/cfe-borrow.py | 48 +++++++++++++------ .claude/skills/help-add/scripts/add-help.ps1 | 2 +- .claude/skills/help-add/scripts/add-help.py | 21 ++++++-- .../interface-edit/scripts/interface-edit.ps1 | 9 +++- .../interface-edit/scripts/interface-edit.py | 9 +++- .../template-add/scripts/add-template.ps1 | 2 +- .../template-add/scripts/add-template.py | 26 +++++++--- tests/skills/cases/cfe-borrow/catalog.json | 33 +++++++++++-- tests/skills/cases/help-add/basic.json | 32 +++++++++---- tests/skills/cases/interface-edit/basic.json | 45 ++++++++++++++--- tests/skills/cases/template-add/basic.json | 23 ++++++++- 12 files changed, 198 insertions(+), 54 deletions(-) diff --git a/.claude/skills/cfe-borrow/scripts/cfe-borrow.ps1 b/.claude/skills/cfe-borrow/scripts/cfe-borrow.ps1 index 63910871..ccf7e83e 100644 --- a/.claude/skills/cfe-borrow/scripts/cfe-borrow.ps1 +++ b/.claude/skills/cfe-borrow/scripts/cfe-borrow.ps1 @@ -1,4 +1,4 @@ -# cfe-borrow v1.12 — Borrow objects from configuration into extension (CFE) +# cfe-borrow v1.13 — Borrow objects from configuration into extension (CFE) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)][string]$ExtensionPath, diff --git a/.claude/skills/cfe-borrow/scripts/cfe-borrow.py b/.claude/skills/cfe-borrow/scripts/cfe-borrow.py index d8276db3..2625d241 100644 --- a/.claude/skills/cfe-borrow/scripts/cfe-borrow.py +++ b/.claude/skills/cfe-borrow/scripts/cfe-borrow.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# cfe-borrow v1.12 — Borrow objects from configuration into extension (CFE) +# cfe-borrow v1.13 — Borrow objects from configuration into extension (CFE) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse @@ -419,10 +419,26 @@ def save_xml_bom(tree, path): def save_text_bom(path, text): - with open(path, "w", encoding="utf-8-sig") as fh: + """Записать текст как есть, ничего не нормализуя. + + Для файлов, которые мы ПРАВИМ: переводы строк уже пришли из самого файла, и + менять их нельзя (контракт #44/#46/#47). newline="" обязателен — без него + текстовый режим Python дал бы CRLF на Windows и LF на macOS, то есть вывод + навыка зависел бы от ОС. + """ + with open(path, "w", encoding="utf-8-sig", newline="") as fh: fh.write(text) +def save_xml_file(path, text): + """XML в каноне выгрузки Конфигуратора: CRLF, без перевода строки в конце. + + Для файлов, которые мы СОЗДАЁМ. Правило: создаём — пишем канон, правим + существующий — наследуем его стиль (см. save_text_bom). + """ + save_text_bom(path, text.replace("\r\n", "\n").replace("\n", "\r\n").rstrip("\r\n")) + + def new_guid(): return str(uuid.uuid4()) @@ -997,7 +1013,9 @@ def main(): warn(f"Cannot merge attributes: {obj_file} not found") return - with open(obj_file, "r", encoding="utf-8-sig") as fh: + # newline="" => без трансляции: иначе CRLF молча схлопнется в LF при чтении + # и файл будет переписан в LF (#44/#46/#47). + with open(obj_file, "r", encoding="utf-8-sig", newline="") as fh: obj_content = fh.read() # Collect existing attribute names for dedup (text-based) @@ -1056,7 +1074,9 @@ def main(): obj_file = os.path.join(ext_dir, dir_name, f"{obj_name}.xml") # Read existing object XML (needed for dedup + enrichment) - with open(obj_file, "r", encoding="utf-8-sig") as fh: + # newline="" => без трансляции: иначе CRLF молча схлопнется в LF при чтении + # и файл будет переписан в LF (#44/#46/#47). + with open(obj_file, "r", encoding="utf-8-sig", newline="") as fh: obj_content = fh.read() # Dedup: skip attributes/TS already present in object's ChildObjects (idempotent re-borrow) @@ -1133,7 +1153,7 @@ def main(): target_dir = os.path.join(ext_dir, CHILD_TYPE_DIR_MAP[rt["TypeName"]]) os.makedirs(target_dir, exist_ok=True) target_file = os.path.join(target_dir, f"{rt['ObjName']}.xml") - save_text_bom(target_file, borrowed_xml) + save_xml_file(target_file, borrowed_xml) add_to_child_objects(rt["TypeName"], rt["ObjName"]) borrowed_files.append(target_file) info(f" Auto-borrowed: {rt['TypeName']}.{rt['ObjName']}") @@ -1198,7 +1218,7 @@ def main(): t_target_dir = os.path.join(ext_dir, CHILD_TYPE_DIR_MAP[target_type_name]) os.makedirs(t_target_dir, exist_ok=True) t_target_file = os.path.join(t_target_dir, f"{target_obj_name}.xml") - save_text_bom(t_target_file, t_borrowed_xml) + save_xml_file(t_target_file, t_borrowed_xml) add_to_child_objects(target_type_name, target_obj_name) borrowed_files.append(t_target_file) info(f" Auto-borrowed for deep path: {target_type_name}.{target_obj_name}") @@ -1222,7 +1242,7 @@ def main(): s_target_dir = os.path.join(ext_dir, CHILD_TYPE_DIR_MAP[srt["TypeName"]]) os.makedirs(s_target_dir, exist_ok=True) s_target_file = os.path.join(s_target_dir, f"{srt['ObjName']}.xml") - save_text_bom(s_target_file, s_borrowed_xml) + save_xml_file(s_target_file, s_borrowed_xml) add_to_child_objects(srt["TypeName"], srt["ObjName"]) borrowed_files.append(s_target_file) info(f" Auto-borrowed (deep): {srt['TypeName']}.{srt['ObjName']}") @@ -1279,7 +1299,7 @@ def main(): os.makedirs(form_meta_dir, exist_ok=True) form_meta_file = os.path.join(form_meta_dir, f"{form_name}.xml") - save_text_bom(form_meta_file, "\n".join(form_meta_lines)) + save_xml_file(form_meta_file, "\n".join(form_meta_lines)) info(f" Created: {form_meta_file}") # 5. Generate Form.xml with BaseForm @@ -1365,7 +1385,7 @@ def main(): target_dir = os.path.join(ext_dir, "CommonPictures") os.makedirs(target_dir, exist_ok=True) target_file = os.path.join(target_dir, f"{pic_name}.xml") - save_text_bom(target_file, borrowed_xml) + save_xml_file(target_file, borrowed_xml) add_to_child_objects("CommonPicture", pic_name) auto_borrowed_pics.append(pic_name) borrowed_files.append(target_file) @@ -1414,7 +1434,7 @@ def main(): target_dir = os.path.join(ext_dir, "StyleItems") os.makedirs(target_dir, exist_ok=True) target_file = os.path.join(target_dir, f"{style_name}.xml") - save_text_bom(target_file, borrowed_xml) + save_xml_file(target_file, borrowed_xml) add_to_child_objects("StyleItem", style_name) borrowed_files.append(target_file) info(f" Auto-borrowed: StyleItem.{style_name}") @@ -1478,7 +1498,7 @@ def main(): target_dir = os.path.join(ext_dir, "Enums") os.makedirs(target_dir, exist_ok=True) target_file = os.path.join(target_dir, f"{enum_name}.xml") - save_text_bom(target_file, borrowed_xml) + save_xml_file(target_file, borrowed_xml) add_to_child_objects("Enum", enum_name) borrowed_files.append(target_file) info(f" Auto-borrowed: Enum.{enum_name} (with {len(ev_xmls)} EnumValue(s))") @@ -1572,7 +1592,7 @@ def main(): form_xml_dir = os.path.join(form_meta_dir, form_name, "Ext") os.makedirs(form_xml_dir, exist_ok=True) form_xml_file = os.path.join(form_xml_dir, "Form.xml") - save_text_bom(form_xml_file, "".join(parts)) + save_xml_file(form_xml_file, "".join(parts)) info(f" Created: {form_xml_file}") # 6. Create empty Module.bsl — but NEVER overwrite an existing one (re-borrow must @@ -1656,7 +1676,7 @@ def main(): target_dir = os.path.join(ext_dir, dir_name) os.makedirs(target_dir, exist_ok=True) target_file = os.path.join(target_dir, f"{obj_name}.xml") - save_text_bom(target_file, borrowed_xml) + save_xml_file(target_file, borrowed_xml) info(f" Created: {target_file}") add_to_child_objects(type_name, obj_name) @@ -1683,7 +1703,7 @@ def main(): os.makedirs(target_dir, exist_ok=True) target_file = os.path.join(target_dir, f"{obj_name}.xml") - save_text_bom(target_file, borrowed_xml) + save_xml_file(target_file, borrowed_xml) info(f" Created: {target_file}") add_to_child_objects(type_name, obj_name) diff --git a/.claude/skills/help-add/scripts/add-help.ps1 b/.claude/skills/help-add/scripts/add-help.ps1 index 398aed60..a7b714b1 100644 --- a/.claude/skills/help-add/scripts/add-help.ps1 +++ b/.claude/skills/help-add/scripts/add-help.ps1 @@ -1,4 +1,4 @@ -# help-add v1.12 — Add built-in help to 1C object +# help-add v1.13 — Add built-in help to 1C object # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] diff --git a/.claude/skills/help-add/scripts/add-help.py b/.claude/skills/help-add/scripts/add-help.py index e07a2a46..aef7f272 100644 --- a/.claude/skills/help-add/scripts/add-help.py +++ b/.claude/skills/help-add/scripts/add-help.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# help-add v1.12 — Add built-in help to 1C object +# help-add v1.13 — Add built-in help to 1C object # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse @@ -253,11 +253,24 @@ def save_xml_with_bom(tree, path): def write_text_with_bom(path, text): - """Write text to file with UTF-8 BOM.""" - with open(path, "w", encoding="utf-8-sig") as f: + """Write text to file with UTF-8 BOM. + + newline="" обязателен: в текстовом режиме Python на Windows превратил бы \\n в + \\r\\n, а на macOS оставил \\n — вывод навыка зависел бы от ОС. Через эту функцию + идёт HTML-страница справки, а её платформа хранит именно с LF (корпус: 399 LF из 400). + """ + with open(path, "w", encoding="utf-8-sig", newline="") as f: f.write(text) +def write_xml_file(path, text): + """XML в каноне выгрузки Конфигуратора: CRLF, без перевода строки в конце. + + Для Help.xml. HTML-страница сюда НЕ идёт — у неё свой канон (LF). + """ + write_text_with_bom(path, text.replace("\r\n", "\n").replace("\n", "\r\n").rstrip("\r\n")) + + def main(): sys.stdout.reconfigure(encoding="utf-8") sys.stderr.reconfigure(encoding="utf-8") @@ -301,7 +314,7 @@ def main(): '' ) - write_text_with_bom(help_xml_path, help_xml) + write_xml_file(help_xml_path, help_xml) # --- 2. Help/.html --- diff --git a/.claude/skills/interface-edit/scripts/interface-edit.ps1 b/.claude/skills/interface-edit/scripts/interface-edit.ps1 index 0b3a1f95..18a02d2a 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.10 — Edit 1C CommandInterface.xml +# interface-edit v1.11 — Edit 1C CommandInterface.xml # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)][Alias('Path')][string]$CIPath, @@ -202,7 +202,12 @@ if (-not (Test-Path $CIPath)) { "@ $utf8Bom = New-Object System.Text.UTF8Encoding($true) - [System.IO.File]::WriteAllText($CIPath, $emptyCI, $utf8Bom) + # Файл СОЗДАЁМ — пишем канон выгрузки: CRLF, без перевода строки в конце. + # (Правка существующего файла, наоборот, наследует его стиль — это делает + # основной путь сохранения ниже.) Нормализация нужна потому, что here-string + # берёт переводы строк из самого .ps1, а он в репозитории хранится с LF. + $emptyCI = ($emptyCI -replace "`r`n", "`n") -replace "`n", "`r`n" + [System.IO.File]::WriteAllText($CIPath, $emptyCI.TrimEnd("`r", "`n"), $utf8Bom) Write-Host "[INFO] Created new CommandInterface.xml: $CIPath" } else { Write-Error "File not found: $CIPath (use -CreateIfMissing to create)" diff --git a/.claude/skills/interface-edit/scripts/interface-edit.py b/.claude/skills/interface-edit/scripts/interface-edit.py index bbf1585c..1bcdd521 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.10 — Edit 1C CommandInterface.xml +# interface-edit v1.11 — Edit 1C CommandInterface.xml # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse @@ -438,7 +438,12 @@ def main(): f'\tversion="{format_version}">\n' f'' ) - with open(ci_path, "w", encoding="utf-8-sig") as fh: + # Файл СОЗДАЁМ — пишем канон выгрузки: CRLF в разделителях. (Правка + # существующего файла, наоборот, наследует его стиль — это делает + # save_xml_bom через _detect_xml_style.) newline="" обязателен: без него + # текстовый режим дал бы CRLF на Windows и LF на macOS. + empty_ci = empty_ci.replace("\r\n", "\n").replace("\n", "\r\n") + with open(ci_path, "w", encoding="utf-8-sig", newline="") as fh: fh.write(empty_ci) print(f"[INFO] Created new CommandInterface.xml: {ci_path}") else: diff --git a/.claude/skills/template-add/scripts/add-template.ps1 b/.claude/skills/template-add/scripts/add-template.ps1 index bf21d82e..d7f1a02e 100644 --- a/.claude/skills/template-add/scripts/add-template.ps1 +++ b/.claude/skills/template-add/scripts/add-template.ps1 @@ -1,4 +1,4 @@ -# template-add v1.14 — Add template to 1C object +# template-add v1.15 — Add template to 1C object # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] diff --git a/.claude/skills/template-add/scripts/add-template.py b/.claude/skills/template-add/scripts/add-template.py index 2ff6883d..ef419d9b 100644 --- a/.claude/skills/template-add/scripts/add-template.py +++ b/.claude/skills/template-add/scripts/add-template.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# template-add v1.14 — Add template to 1C object +# template-add v1.15 — Add template to 1C object # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse @@ -246,11 +246,25 @@ def save_xml_with_bom(tree, path): def write_text_with_bom(path, text): - """Write text to file with UTF-8 BOM.""" - with open(path, "w", encoding="utf-8-sig") as f: + """Write text to file with UTF-8 BOM. + + newline="" обязателен: в текстовом режиме Python на Windows превратил бы \\n в + \\r\\n, а на macOS оставил \\n — вывод навыка зависел бы от ОС. Через эту функцию + идёт HTML-макет, а его платформа хранит именно с LF (корпус: 399 LF из 400). + """ + with open(path, "w", encoding="utf-8-sig", newline="") as f: f.write(text) +def write_xml_file(path, text): + """XML в каноне выгрузки Конфигуратора: CRLF, без перевода строки в конце. + + Для XML-макетов (SpreadsheetDocument, DataCompositionSchema) и Template.xml. + HTML-макет сюда НЕ идёт — у него свой канон (LF). + """ + write_text_with_bom(path, text.replace("\r\n", "\n").replace("\n", "\r\n").rstrip("\r\n")) + + def detect_format_version(d): while d: cfg_path = os.path.join(d, "Configuration.xml") @@ -376,7 +390,7 @@ def main(): '' ) - write_text_with_bom(template_meta_path, template_meta_xml) + write_xml_file(template_meta_path, template_meta_xml) # --- 2. Template content (Templates//Ext/Template.) --- @@ -408,7 +422,7 @@ def main(): ' xmlns:xs="http://www.w3.org/2001/XMLSchema">\n' '' ) - write_text_with_bom(template_file_path, content) + write_xml_file(template_file_path, content) elif template_type == "BinaryData": with open(template_file_path, "wb") as f: @@ -431,7 +445,7 @@ def main(): '\t\n' '' ) - write_text_with_bom(template_file_path, content) + write_xml_file(template_file_path, content) # --- 3. Modify root XML --- diff --git a/tests/skills/cases/cfe-borrow/catalog.json b/tests/skills/cases/cfe-borrow/catalog.json index acca0499..b164ab7c 100644 --- a/tests/skills/cases/cfe-borrow/catalog.json +++ b/tests/skills/cases/cfe-borrow/catalog.json @@ -3,13 +3,38 @@ "preRun": [ { "script": "meta-compile/scripts/meta-compile", - "input": { "type": "Catalog", "name": "Товары" }, - "args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" } + "input": { + "type": "Catalog", + "name": "Товары" + }, + "args": { + "-JsonPath": "{inputFile}", + "-OutputDir": "{workDir}" + } }, { "script": "cfe-init/scripts/cfe-init", - "args": { "-Name": "Тест", "-OutputDir": "{workDir}/ext", "-ConfigPath": "{workDir}" } + "args": { + "-Name": "Тест", + "-OutputDir": "{workDir}/ext", + "-ConfigPath": "{workDir}" + } } ], - "params": { "extensionPath": "ext", "object": "Catalog.Товары" } + "params": { + "extensionPath": "ext", + "object": "Catalog.Товары" + }, + "expect": { + "preserves": { + "file": "Ext/Catalogs/Товары.xml", + "bom": true, + "eol": "crlf", + "encoding": "UTF-8", + "finalNewline": false, + "noCR13": true, + "selfClose": "tight", + "noEmptyPairs": true + } + } } diff --git a/tests/skills/cases/help-add/basic.json b/tests/skills/cases/help-add/basic.json index 4e8ea472..69d6adef 100644 --- a/tests/skills/cases/help-add/basic.json +++ b/tests/skills/cases/help-add/basic.json @@ -13,15 +13,27 @@ "objectName": "МояОбработка" }, "expect": { - "preserves": { - "file": "МояОбработка.xml", - "bom": true, - "eol": "crlf", - "encoding": "UTF-8", - "finalNewline": false, - "noCR13": true, - "selfClose": "tight", - "noEmptyPairs": true - } + "preserves": [ + { + "file": "МояОбработка.xml", + "bom": true, + "eol": "crlf", + "encoding": "UTF-8", + "finalNewline": false, + "noCR13": true, + "selfClose": "tight", + "noEmptyPairs": true + }, + { + "file": "МояОбработка/Ext/Help.xml", + "bom": true, + "eol": "crlf", + "encoding": "UTF-8", + "finalNewline": false, + "noCR13": true, + "selfClose": "tight", + "noEmptyPairs": true + } + ] } } diff --git a/tests/skills/cases/interface-edit/basic.json b/tests/skills/cases/interface-edit/basic.json index b1453742..aea487c2 100644 --- a/tests/skills/cases/interface-edit/basic.json +++ b/tests/skills/cases/interface-edit/basic.json @@ -3,18 +3,49 @@ "preRun": [ { "script": "meta-compile/scripts/meta-compile", - "input": { "type": "Catalog", "name": "Товары" }, - "args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" } + "input": { + "type": "Catalog", + "name": "Товары" + }, + "args": { + "-JsonPath": "{inputFile}", + "-OutputDir": "{workDir}" + } }, { "script": "subsystem-compile/scripts/subsystem-compile", - "input": { "name": "Склад", "objects": ["Catalogs.Товары"] }, - "args": { "-DefinitionFile": "{inputFile}", "-OutputDir": "{workDir}" } + "input": { + "name": "Склад", + "objects": [ + "Catalogs.Товары" + ] + }, + "args": { + "-DefinitionFile": "{inputFile}", + "-OutputDir": "{workDir}" + } } ], - "params": { "ciPath": "Subsystems/Склад/CommandInterface" }, + "params": { + "ciPath": "Subsystems/Склад/CommandInterface" + }, "input": [ - { "operation": "place", "value": "{\"command\": \"Catalog.Товары\", \"group\": \"NavigationPanel.Important\"}" } + { + "operation": "place", + "value": "{\"command\": \"Catalog.Товары\", \"group\": \"NavigationPanel.Important\"}" + } ], - "CreateIfMissing": true + "CreateIfMissing": true, + "expect": { + "preserves": { + "file": "Subsystems/Склад/CommandInterface", + "bom": true, + "eol": "crlf", + "encoding": "UTF-8", + "finalNewline": false, + "noCR13": true, + "selfClose": "tight", + "noEmptyPairs": true + } + } } diff --git a/tests/skills/cases/template-add/basic.json b/tests/skills/cases/template-add/basic.json index f40a7f9d..56a4c145 100644 --- a/tests/skills/cases/template-add/basic.json +++ b/tests/skills/cases/template-add/basic.json @@ -3,8 +3,27 @@ "preRun": [ { "script": "epf-init/scripts/init", - "args": { "-Name": "МояОбработка", "-SrcDir": "{workDir}" } + "args": { + "-Name": "МояОбработка", + "-SrcDir": "{workDir}" + } } ], - "params": { "objectName": "МояОбработка", "templateName": "Макет", "templateType": "SpreadsheetDocument" } + "params": { + "objectName": "МояОбработка", + "templateName": "Макет", + "templateType": "SpreadsheetDocument" + }, + "expect": { + "preserves": { + "file": "МояОбработка/Templates/Макет/Ext/Template.xml", + "bom": true, + "eol": "crlf", + "encoding": "UTF-8", + "finalNewline": false, + "noCR13": true, + "selfClose": "tight", + "noEmptyPairs": true + } + } }