From 5d5a1bc36a7fb348510e62ea6f404f307f7b6855 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sun, 26 Jul 2026 14:51:08 +0300 Subject: [PATCH] =?UTF-8?q?fix(xdto):=20=D1=82=D1=80=D0=B8=20=D0=B4=D0=B5?= =?UTF-8?q?=D1=84=D0=B5=D0=BA=D1=82=D0=B0,=20=D0=BD=D0=B0=D0=B9=D0=B4?= =?UTF-8?q?=D0=B5=D0=BD=D0=BD=D1=8B=D1=85=20=D0=BF=D0=BB=D0=B0=D1=82=D1=84?= =?UTF-8?q?=D0=BE=D1=80=D0=BC=D0=B5=D0=BD=D0=BD=D0=BE=D0=B9=20=D0=B2=D0=B5?= =?UTF-8?q?=D1=80=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1=86=D0=B8=D0=B5=D0=B9=20?= =?UTF-8?q?=D1=81=D0=BD=D1=8D=D0=BF=D1=88=D0=BE=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit verify-snapshots загружает результат каждого кейса в 1С. Раньше навыки xdto через него не проходили вовсе; первый прогон дал 5 из 9. Ни корпусная сверка, ни валидатор такого не ловили: корпус состоит из заведомо валидных пакетов, а синтетические кейсы до сих пор в базу не грузились. 1. fixed. В модели XDTO это булев флаг, значение лежит в default; в XSD наоборот — fixed="V" несёт значение. Компилятор писал значение прямо в fixed, и платформа отвергала пакет («Отсутствует фиксированное значение свойства»). Перевод сделан в обе стороны; по принципу прощающего ввода принимается и модельная форма через зеркало xdto:fixed. Отображение выведено по корпусу: fixed встречается только вместе с default, значений всего два. 2. Импорт на несуществующий пакет платформа отвергает («xdto-package-3.3 … не определен»), а у нас проверки не было. Добавлена ошибка валидатора и, что важнее, предупреждение прямо на сборке — отказ при db-update дешевле поймать на шаг раньше. Правило пришлось калибровать корпусом: сначала оно дало 67 ложных срабатываний на платформенных пространствах имён, их список выведен и исключён. 3. localName проверяется как NCName — фикстура с пробелом в имени была негодной, заменена на реалистичный дефис (name="alpha_3" localName="alpha-3"). Харнесс получил skipPlatformVerify с обязательной причиной: результат set-namespace невалиден by design, операция намеренно оставляет висящий импорт у зависящего пакета. Итог: 9/9 компилятора, 9/10 + 1 осознанный пропуск у edit, round-trip 760/760, валидатор 0 ложных, 40 тестов на обоих рантаймах. Co-Authored-By: Claude Opus 5 (1M context) --- .../xdto-compile/scripts/xdto-compile.ps1 | 49 ++++++++++++++++++- .../xdto-compile/scripts/xdto-compile.py | 44 ++++++++++++++++- .../xdto-decompile/scripts/xdto-decompile.ps1 | 13 ++++- .../xdto-decompile/scripts/xdto-decompile.py | 13 ++++- .../xdto-validate/scripts/xdto-validate.ps1 | 34 +++++++++++++ .../xdto-validate/scripts/xdto-validate.py | 32 ++++++++++++ .../skills/cases/xdto-compile/annotations.xsd | 2 +- tests/skills/cases/xdto-compile/other.xsd | 5 ++ tests/skills/cases/xdto-compile/refs.json | 25 ++++++++-- .../ПакетСАннотациями/Ext/Package.bin | 2 +- .../snapshots/annotations/annotations.xsd | 2 +- .../XDTOPackages/cardinality/Ext/Package.bin | 2 +- .../snapshots/refs/Configuration.xml | 1 + .../snapshots/refs/XDTOPackages/other.xml | 16 ++++++ .../refs/XDTOPackages/other/Ext/Package.bin | 5 ++ .../xdto-compile/snapshots/refs/other.xsd | 5 ++ .../top-level-order/Configuration.xml | 1 + .../top-level-order/XDTOPackages/other.xml | 16 ++++++ .../XDTOPackages/other/Ext/Package.bin | 5 ++ .../snapshots/top-level-order/other.xsd | 5 ++ .../cases/xdto-compile/top-level-order.json | 24 +++++++-- .../cases/xdto-decompile/annotations.xsd | 2 +- .../ПакетСАннотациями/Ext/Package.bin | 2 +- .../snapshots/annotations/annotations.xsd | 2 +- .../snapshots/annotations/roundtrip.xsd | 2 +- tests/skills/cases/xdto-edit/add-import.json | 10 +++- .../skills/cases/xdto-edit/set-namespace.json | 3 +- .../snapshots/add-import/Configuration.xml | 1 + .../add-import/XDTOPackages/common.xml | 16 ++++++ .../XDTOPackages/common/Ext/Package.bin | 6 +++ .../XDTOPackages/types/Ext/Package.bin | 2 +- .../xdto-edit/snapshots/add-import/common.xsd | 8 +++ tests/skills/verify-snapshots.mjs | 18 ++++++- 33 files changed, 344 insertions(+), 29 deletions(-) create mode 100644 tests/skills/cases/xdto-compile/other.xsd create mode 100644 tests/skills/cases/xdto-compile/snapshots/refs/XDTOPackages/other.xml create mode 100644 tests/skills/cases/xdto-compile/snapshots/refs/XDTOPackages/other/Ext/Package.bin create mode 100644 tests/skills/cases/xdto-compile/snapshots/refs/other.xsd create mode 100644 tests/skills/cases/xdto-compile/snapshots/top-level-order/XDTOPackages/other.xml create mode 100644 tests/skills/cases/xdto-compile/snapshots/top-level-order/XDTOPackages/other/Ext/Package.bin create mode 100644 tests/skills/cases/xdto-compile/snapshots/top-level-order/other.xsd create mode 100644 tests/skills/cases/xdto-edit/snapshots/add-import/XDTOPackages/common.xml create mode 100644 tests/skills/cases/xdto-edit/snapshots/add-import/XDTOPackages/common/Ext/Package.bin create mode 100644 tests/skills/cases/xdto-edit/snapshots/add-import/common.xsd diff --git a/.claude/skills/xdto-compile/scripts/xdto-compile.ps1 b/.claude/skills/xdto-compile/scripts/xdto-compile.ps1 index 8e981806..3d211d41 100644 --- a/.claude/skills/xdto-compile/scripts/xdto-compile.ps1 +++ b/.claude/skills/xdto-compile/scripts/xdto-compile.ps1 @@ -15,6 +15,19 @@ param( ) $ErrorActionPreference = "Stop" + +# Эти пространства имён предоставляет сама платформа — пакетов в конфигурации +# для них нет и быть не должно (выведено по корпусу: импортируются, но +# targetNamespace с таким значением ни у одного пакета нет) +$PLATFORM_NS = @( + "http://v8.1c.ru/8.1/data/core", + "http://v8.1c.ru/8.1/data/enterprise", + "http://v8.1c.ru/8.1/data/enterprise/current-config", + "http://v8.1c.ru/8.1/data-composition-system/settings", + "http://v8.1c.ru/8.3/data/ext", + "http://www.w3.org/2001/XMLSchema" +) + [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 $XDTO_NS = "http://v8.1c.ru/8.1/xdto" @@ -446,8 +459,18 @@ function Build-Property([System.Xml.XmlElement]$el, [bool]$isAttribute) { Add-Attr $p "nillable" (XA $el "nillable") } - Add-Attr $p "fixed" (XA $el "fixed") - Add-Attr $p "default" (XA $el "default") + # XSD-шный fixed="V" несёт значение, в модели это fixed="true" + default="V". + # Прощающий ввод: модельная форма через зеркало xdto:fixed тоже принимается. + $mFixed = MA $el "fixed" + if ($null -ne $mFixed) { + Add-Attr $p "fixed" $mFixed + Add-Attr $p "default" (XA $el "default") + } elseif ($null -ne (XA $el "fixed")) { + Add-Attr $p "fixed" "true" + Add-Attr $p "default" (XA $el "fixed") + } else { + Add-Attr $p "default" (XA $el "default") + } if ($isAttribute) { Add-Attr $p "form" "Attribute" @@ -839,6 +862,28 @@ M "`t" # --- Register in Configuration.xml --- +# Ранняя диагностика: отказ платформы при db-update дешевле поймать на сборке +$xdtoRootDir = Join-Path $OutputDir "XDTOPackages" +$declaredImports = @() +foreach ($c in $pkgNode.Children) { if ($c.Tag -eq "import") { foreach ($a in $c.Attrs) { if ($a.Name -eq "namespace") { $declaredImports += $a.Value } } } } +if ($declaredImports.Count -gt 0 -and (Test-Path $xdtoRootDir)) { + $knownNs = @{} + foreach ($other in (Get-ChildItem $xdtoRootDir -Directory -ErrorAction SilentlyContinue)) { + $ob = Join-Path (Join-Path $other.FullName "Ext") "Package.bin" + if (-not (Test-Path $ob)) { continue } + try { + $od = New-Object System.Xml.XmlDocument + $od.Load($ob) + $knownNs[$od.DocumentElement.GetAttribute("targetNamespace")] = $true + } catch {} + } + foreach ($imp in $declaredImports) { + if (-not $knownNs.ContainsKey($imp) -and $PLATFORM_NS -notcontains $imp) { + Warn "Импорт `"$imp`" не разрешается: пакета с таким namespace в конфигурации нет. Платформа отвергнет пакет при обновлении — соберите зависимость первой" + } + } +} + $configXmlPath = Join-Path $OutputDir "Configuration.xml" $regResult = "no-config" if (Test-Path $configXmlPath) { diff --git a/.claude/skills/xdto-compile/scripts/xdto-compile.py b/.claude/skills/xdto-compile/scripts/xdto-compile.py index 13ef5500..d02da784 100644 --- a/.claude/skills/xdto-compile/scripts/xdto-compile.py +++ b/.claude/skills/xdto-compile/scripts/xdto-compile.py @@ -9,6 +9,18 @@ import uuid from lxml import etree +# Эти пространства имён предоставляет сама платформа — пакетов в конфигурации +# для них нет и быть не должно (выведено по корпусу) +PLATFORM_NS = { + "http://v8.1c.ru/8.1/data/core", + "http://v8.1c.ru/8.1/data/enterprise", + "http://v8.1c.ru/8.1/data/enterprise/current-config", + "http://v8.1c.ru/8.1/data-composition-system/settings", + "http://v8.1c.ru/8.3/data/ext", + "http://www.w3.org/2001/XMLSchema", +} + + sys.stdout.reconfigure(encoding="utf-8") sys.stderr.reconfigure(encoding="utf-8") @@ -498,8 +510,17 @@ def build_property(el, is_attribute): add_attr(p, "upperBound", "-1" if max_occ == "unbounded" else max_occ) add_attr(p, "nillable", el.get("nillable")) - add_attr(p, "fixed", el.get("fixed")) - add_attr(p, "default", el.get("default")) + # XSD-шный fixed="V" несёт значение, в модели это fixed="true" + default="V". + # Прощающий ввод: модельная форма через зеркало xdto:fixed тоже принимается. + m_fixed = MA(el, "fixed") + if m_fixed is not None: + add_attr(p, "fixed", m_fixed) + add_attr(p, "default", el.get("default")) + elif el.get("fixed") is not None: + add_attr(p, "fixed", "true") + add_attr(p, "default", el.get("fixed")) + else: + add_attr(p, "default", el.get("default")) if is_attribute: add_attr(p, "form", "Attribute") @@ -869,6 +890,25 @@ with open(md_file, "wb") as f: # ── register in Configuration.xml ──────────────────────────── +# Ранняя диагностика: отказ платформы при db-update дешевле поймать на сборке +xdto_root_dir = os.path.join(args.OutputDir, "XDTOPackages") +declared_imports = [a["value"] for c in pkg_node.children if c.tag == "import" + for a in c.attrs if a["name"] == "namespace"] +if declared_imports and os.path.isdir(xdto_root_dir): + known_ns = set() + for other in sorted(os.listdir(xdto_root_dir)): + ob = os.path.join(xdto_root_dir, other, "Ext", "Package.bin") + if not os.path.exists(ob): + continue + try: + known_ns.add(_parse_xml(ob).getroot().get("targetNamespace")) + except Exception: # noqa: BLE001 + pass + for imp in declared_imports: + if imp not in known_ns and imp not in PLATFORM_NS: + warn(f'Импорт "{imp}" не разрешается: пакета с таким namespace в конфигурации нет. ' + "Платформа отвергнет пакет при обновлении — соберите зависимость первой") + config_xml = os.path.join(args.OutputDir, "Configuration.xml") reg_result = "no-config" if os.path.exists(config_xml): diff --git a/.claude/skills/xdto-decompile/scripts/xdto-decompile.ps1 b/.claude/skills/xdto-decompile/scripts/xdto-decompile.ps1 index bca5ac44..06180359 100644 --- a/.claude/skills/xdto-decompile/scripts/xdto-decompile.ps1 +++ b/.claude/skills/xdto-decompile/scripts/xdto-decompile.ps1 @@ -302,6 +302,13 @@ function Emit-Property([System.Xml.XmlElement]$p, [string]$indent, [bool]$isGlob $nill = A $p "nillable" $def = A $p "default" $fix = A $p "fixed" + # В модели fixed — булев флаг, значение лежит в default; в XSD наоборот: + # fixed="V" несёт само значение. Переводим, а не копируем. + $defOut = $def + $fixOut = $null + $fixMirror = "" + if ($fix -eq "true" -and $null -ne $def) { $fixOut = $def; $defOut = $null } + elseif ($null -ne $fix) { $fixMirror = Mirror "fixed" $fix } $anon = Get-AnonTypeDef $p # qualified записан как атрибут в пространстве имён XDTO $qual = $p.GetAttribute("qualified", $XDTO_NS) @@ -326,7 +333,8 @@ function Emit-Property([System.Xml.XmlElement]$p, [string]$indent, [bool]$isGlob if ($null -ne $lower) { $m += Mirror "lowerBound" $lower } if ($null -ne $upper) { $m += Mirror "upperBound" $upper } $m += $mirrorName - $body = Attrs @('name', $xmlName, 'ref', $ref, 'type', $type, 'default', $def, 'fixed', $fix) + $m += $fixMirror + $body = Attrs @('name', $xmlName, 'ref', $ref, 'type', $type, 'default', $defOut, 'fixed', $fixOut) if ($anon) { X "$indent" X "$indent`t" @@ -349,10 +357,11 @@ function Emit-Property([System.Xml.XmlElement]$p, [string]$indent, [bool]$isGlob if ($null -ne $qual) { $m += Mirror "qualified" $qual } $m += $mirrorName $m += (Mirror-Prefix $p) + $m += $fixMirror $body = Attrs @('name', $xmlName, 'ref', $ref, 'type', $type, 'minOccurs', $minOccurs, 'maxOccurs', $maxOccurs, - 'nillable', $nill, 'default', $def, 'fixed', $fix) + 'nillable', $nill, 'default', $defOut, 'fixed', $fixOut) if ($anon) { X "$indent" diff --git a/.claude/skills/xdto-decompile/scripts/xdto-decompile.py b/.claude/skills/xdto-decompile/scripts/xdto-decompile.py index 249a43bb..75e711cf 100644 --- a/.claude/skills/xdto-decompile/scripts/xdto-decompile.py +++ b/.claude/skills/xdto-decompile/scripts/xdto-decompile.py @@ -308,6 +308,13 @@ def emit_property(p, indent): nill = p.get("nillable") default = p.get("default") fixed = p.get("fixed") + # В модели fixed — булев флаг, значение лежит в default; в XSD наоборот: + # fixed="V" несёт само значение. Переводим, а не копируем. + def_out, fix_out, fix_mirror = default, None, "" + if fixed == "true" and default is not None: + fix_out, def_out = default, None + elif fixed is not None: + fix_mirror = mirror("fixed", fixed) anon = anon_type_def(p) qual = p.get(f"{{{XDTO_NS}}}qualified") @@ -330,7 +337,8 @@ def emit_property(p, indent): if upper is not None: m += mirror("upperBound", upper) m += mirror_name - body = attrs(["name", xml_name, "ref", ref, "type", type_, "default", default, "fixed", fixed]) + m += fix_mirror + body = attrs(["name", xml_name, "ref", ref, "type", type_, "default", def_out, "fixed", fix_out]) if anon is not None: X(f"{indent}") X(f"{indent}\t") @@ -351,10 +359,11 @@ def emit_property(p, indent): m += mirror("qualified", qual) m += mirror_name m += mirror_prefix(p) + m += fix_mirror body = attrs(["name", xml_name, "ref", ref, "type", type_, "minOccurs", min_occurs, "maxOccurs", max_occurs, - "nillable", nill, "default", default, "fixed", fixed]) + "nillable", nill, "default", def_out, "fixed", fix_out]) if anon is not None: X(f"{indent}") diff --git a/.claude/skills/xdto-validate/scripts/xdto-validate.ps1 b/.claude/skills/xdto-validate/scripts/xdto-validate.ps1 index d8deff02..3a79b0ef 100644 --- a/.claude/skills/xdto-validate/scripts/xdto-validate.ps1 +++ b/.claude/skills/xdto-validate/scripts/xdto-validate.ps1 @@ -15,6 +15,19 @@ param( ) $ErrorActionPreference = "Stop" + +# Эти пространства имён предоставляет сама платформа — пакетов в конфигурации +# для них нет и быть не должно (выведено по корпусу: импортируются, но +# targetNamespace с таким значением ни у одного пакета нет) +$PLATFORM_NS = @( + "http://v8.1c.ru/8.1/data/core", + "http://v8.1c.ru/8.1/data/enterprise", + "http://v8.1c.ru/8.1/data/enterprise/current-config", + "http://v8.1c.ru/8.1/data-composition-system/settings", + "http://v8.1c.ru/8.3/data/ext", + "http://www.w3.org/2001/XMLSchema" +) + [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 $XS_NS = "http://www.w3.org/2001/XMLSchema" @@ -504,6 +517,27 @@ if (Test-Path $configXml) { if ($od.DocumentElement.GetAttribute("targetNamespace") -eq $targetNs) { $clash += $other.Name } } catch {} } + # Платформа отвергает пакет, если импортируемого namespace нет в конфигурации: + # «Ошибка проверки модели XDTO: xdto-package-3.3 … не определен» + $knownNs = @{} + foreach ($other in (Get-ChildItem $pkgRoot -Directory -ErrorAction SilentlyContinue)) { + $ob = Join-Path (Join-Path $other.FullName "Ext") "Package.bin" + if (-not (Test-Path $ob)) { continue } + try { + $od = New-Object System.Xml.XmlDocument + $od.Load($ob) + $knownNs[$od.DocumentElement.GetAttribute("targetNamespace")] = $other.Name + } catch {} + } + $missing = @() + foreach ($imp in $imports) { if (-not $knownNs.ContainsKey($imp) -and $PLATFORM_NS -notcontains $imp) { $missing += $imp } } + if ($missing.Count -gt 0) { + Report-Error ("Импортируемые пакеты не определены в конфигурации: " + ($missing -join ", ") + + ". Платформа отвергнет пакет при обновлении конфигурации — соберите зависимости первыми") + } elseif ($imports.Count -gt 0) { + Report-OK "Все импорты разрешаются в пакеты конфигурации" + } + if ($clash.Count -gt 0) { Report-Warn "targetNamespace `"$targetNs`" объявлен также в пакет(ах): $($clash -join ', '). Платформа это допускает, но на это пространство имён становится неоднозначным" } else { diff --git a/.claude/skills/xdto-validate/scripts/xdto-validate.py b/.claude/skills/xdto-validate/scripts/xdto-validate.py index 2e3c0bc9..57437cc7 100644 --- a/.claude/skills/xdto-validate/scripts/xdto-validate.py +++ b/.claude/skills/xdto-validate/scripts/xdto-validate.py @@ -6,6 +6,18 @@ import sys from lxml import etree +# Эти пространства имён предоставляет сама платформа — пакетов в конфигурации +# для них нет и быть не должно (выведено по корпусу) +PLATFORM_NS = { + "http://v8.1c.ru/8.1/data/core", + "http://v8.1c.ru/8.1/data/enterprise", + "http://v8.1c.ru/8.1/data/enterprise/current-config", + "http://v8.1c.ru/8.1/data-composition-system/settings", + "http://v8.1c.ru/8.3/data/ext", + "http://www.w3.org/2001/XMLSchema", +} + + sys.stdout.reconfigure(encoding="utf-8") sys.stderr.reconfigure(encoding="utf-8") @@ -510,6 +522,26 @@ if os.path.exists(config_xml): clash.append(other) except Exception: # noqa: BLE001 pass + # Платформа отвергает пакет, если импортируемого namespace нет в конфигурации: + # «Ошибка проверки модели XDTO: xdto-package-3.3 … не определен» + known_ns = {} + for other in sorted(os.listdir(pkg_root)): + ob = os.path.join(pkg_root, other, "Ext", "Package.bin") + if not os.path.exists(ob): + continue + try: + known_ns[_parse_xml(ob).getroot().get("targetNamespace")] = other + except Exception: # noqa: BLE001 + pass + missing_imports = [i for i in imports if i not in known_ns and i not in PLATFORM_NS] + if missing_imports: + report_error("Импортируемые пакеты не определены в конфигурации: " + + ", ".join(missing_imports) + + ". Платформа отвергнет пакет при обновлении конфигурации — " + "соберите зависимости первыми") + elif imports: + report_ok("Все импорты разрешаются в пакеты конфигурации") + if clash: report_warn(f'targetNamespace "{target_ns}" объявлен также в пакет(ах): {", ".join(clash)}. ' "Платформа это допускает, но на это пространство имён становится неоднозначным") diff --git a/tests/skills/cases/xdto-compile/annotations.xsd b/tests/skills/cases/xdto-compile/annotations.xsd index 346709ed..8d5521c3 100644 --- a/tests/skills/cases/xdto-compile/annotations.xsd +++ b/tests/skills/cases/xdto-compile/annotations.xsd @@ -15,7 +15,7 @@ - + diff --git a/tests/skills/cases/xdto-compile/other.xsd b/tests/skills/cases/xdto-compile/other.xsd new file mode 100644 index 00000000..22cc60ed --- /dev/null +++ b/tests/skills/cases/xdto-compile/other.xsd @@ -0,0 +1,5 @@ + + + + + diff --git a/tests/skills/cases/xdto-compile/refs.json b/tests/skills/cases/xdto-compile/refs.json index 74c069b5..ea7ce4b0 100644 --- a/tests/skills/cases/xdto-compile/refs.json +++ b/tests/skills/cases/xdto-compile/refs.json @@ -1,9 +1,26 @@ { "name": "ссылки на типы: свой ns (dNpN), голое имя, чужой ns с импортом, ref", - "caseFiles": ["refs.xsd"], - "params": { "xsdFile": "refs.xsd" }, + "caseFiles": [ + "other.xsd", + "refs.xsd" + ], + "params": { + "xsdFile": "refs.xsd" + }, "validatePath": "XDTOPackages/refs", "expect": { - "files": ["XDTOPackages/refs.xml", "XDTOPackages/refs/Ext/Package.bin"] - } + "files": [ + "XDTOPackages/refs.xml", + "XDTOPackages/refs/Ext/Package.bin" + ] + }, + "preRun": [ + { + "script": "xdto-compile/scripts/xdto-compile", + "args": { + "-XsdPath": "{workDir}/other.xsd", + "-OutputDir": "{workDir}" + } + } + ] } diff --git a/tests/skills/cases/xdto-compile/snapshots/annotations/XDTOPackages/ПакетСАннотациями/Ext/Package.bin b/tests/skills/cases/xdto-compile/snapshots/annotations/XDTOPackages/ПакетСАннотациями/Ext/Package.bin index 3540686c..374cb880 100644 --- a/tests/skills/cases/xdto-compile/snapshots/annotations/XDTOPackages/ПакетСАннотациями/Ext/Package.bin +++ b/tests/skills/cases/xdto-compile/snapshots/annotations/XDTOPackages/ПакетСАннотациями/Ext/Package.bin @@ -2,7 +2,7 @@ - + diff --git a/tests/skills/cases/xdto-compile/snapshots/annotations/annotations.xsd b/tests/skills/cases/xdto-compile/snapshots/annotations/annotations.xsd index 346709ed..8d5521c3 100644 --- a/tests/skills/cases/xdto-compile/snapshots/annotations/annotations.xsd +++ b/tests/skills/cases/xdto-compile/snapshots/annotations/annotations.xsd @@ -15,7 +15,7 @@ - + diff --git a/tests/skills/cases/xdto-compile/snapshots/cardinality/XDTOPackages/cardinality/Ext/Package.bin b/tests/skills/cases/xdto-compile/snapshots/cardinality/XDTOPackages/cardinality/Ext/Package.bin index 3cb2e162..bc2389c6 100644 --- a/tests/skills/cases/xdto-compile/snapshots/cardinality/XDTOPackages/cardinality/Ext/Package.bin +++ b/tests/skills/cases/xdto-compile/snapshots/cardinality/XDTOPackages/cardinality/Ext/Package.bin @@ -8,7 +8,7 @@ - + \ No newline at end of file diff --git a/tests/skills/cases/xdto-compile/snapshots/refs/Configuration.xml b/tests/skills/cases/xdto-compile/snapshots/refs/Configuration.xml index e37817d2..dea2eafe 100644 --- a/tests/skills/cases/xdto-compile/snapshots/refs/Configuration.xml +++ b/tests/skills/cases/xdto-compile/snapshots/refs/Configuration.xml @@ -246,6 +246,7 @@ Русский + other refs diff --git a/tests/skills/cases/xdto-compile/snapshots/refs/XDTOPackages/other.xml b/tests/skills/cases/xdto-compile/snapshots/refs/XDTOPackages/other.xml new file mode 100644 index 00000000..36edcb78 --- /dev/null +++ b/tests/skills/cases/xdto-compile/snapshots/refs/XDTOPackages/other.xml @@ -0,0 +1,16 @@ + + + + + other + + + ru + other + + + + urn:test:other + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-compile/snapshots/refs/XDTOPackages/other/Ext/Package.bin b/tests/skills/cases/xdto-compile/snapshots/refs/XDTOPackages/other/Ext/Package.bin new file mode 100644 index 00000000..ff0faaae --- /dev/null +++ b/tests/skills/cases/xdto-compile/snapshots/refs/XDTOPackages/other/Ext/Package.bin @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-compile/snapshots/refs/other.xsd b/tests/skills/cases/xdto-compile/snapshots/refs/other.xsd new file mode 100644 index 00000000..22cc60ed --- /dev/null +++ b/tests/skills/cases/xdto-compile/snapshots/refs/other.xsd @@ -0,0 +1,5 @@ + + + + + diff --git a/tests/skills/cases/xdto-compile/snapshots/top-level-order/Configuration.xml b/tests/skills/cases/xdto-compile/snapshots/top-level-order/Configuration.xml index bf0d487b..ae2082f7 100644 --- a/tests/skills/cases/xdto-compile/snapshots/top-level-order/Configuration.xml +++ b/tests/skills/cases/xdto-compile/snapshots/top-level-order/Configuration.xml @@ -246,6 +246,7 @@ Русский + other top_level_order diff --git a/tests/skills/cases/xdto-compile/snapshots/top-level-order/XDTOPackages/other.xml b/tests/skills/cases/xdto-compile/snapshots/top-level-order/XDTOPackages/other.xml new file mode 100644 index 00000000..36edcb78 --- /dev/null +++ b/tests/skills/cases/xdto-compile/snapshots/top-level-order/XDTOPackages/other.xml @@ -0,0 +1,16 @@ + + + + + other + + + ru + other + + + + urn:test:other + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-compile/snapshots/top-level-order/XDTOPackages/other/Ext/Package.bin b/tests/skills/cases/xdto-compile/snapshots/top-level-order/XDTOPackages/other/Ext/Package.bin new file mode 100644 index 00000000..ff0faaae --- /dev/null +++ b/tests/skills/cases/xdto-compile/snapshots/top-level-order/XDTOPackages/other/Ext/Package.bin @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-compile/snapshots/top-level-order/other.xsd b/tests/skills/cases/xdto-compile/snapshots/top-level-order/other.xsd new file mode 100644 index 00000000..22cc60ed --- /dev/null +++ b/tests/skills/cases/xdto-compile/snapshots/top-level-order/other.xsd @@ -0,0 +1,5 @@ + + + + + diff --git a/tests/skills/cases/xdto-compile/top-level-order.json b/tests/skills/cases/xdto-compile/top-level-order.json index 81325940..1ef880ba 100644 --- a/tests/skills/cases/xdto-compile/top-level-order.json +++ b/tests/skills/cases/xdto-compile/top-level-order.json @@ -1,9 +1,25 @@ { "name": "порядок верхнего уровня: import→property→valueType→objectType независимо от порядка в XSD", - "caseFiles": ["top-level-order.xsd"], - "params": { "xsdFile": "top-level-order.xsd" }, + "caseFiles": [ + "other.xsd", + "top-level-order.xsd" + ], + "params": { + "xsdFile": "top-level-order.xsd" + }, "validatePath": "XDTOPackages/top_level_order", "expect": { - "files": ["XDTOPackages/top_level_order/Ext/Package.bin"] - } + "files": [ + "XDTOPackages/top_level_order/Ext/Package.bin" + ] + }, + "preRun": [ + { + "script": "xdto-compile/scripts/xdto-compile", + "args": { + "-XsdPath": "{workDir}/other.xsd", + "-OutputDir": "{workDir}" + } + } + ] } diff --git a/tests/skills/cases/xdto-decompile/annotations.xsd b/tests/skills/cases/xdto-decompile/annotations.xsd index 346709ed..8d5521c3 100644 --- a/tests/skills/cases/xdto-decompile/annotations.xsd +++ b/tests/skills/cases/xdto-decompile/annotations.xsd @@ -15,7 +15,7 @@ - + diff --git a/tests/skills/cases/xdto-decompile/snapshots/annotations/XDTOPackages/ПакетСАннотациями/Ext/Package.bin b/tests/skills/cases/xdto-decompile/snapshots/annotations/XDTOPackages/ПакетСАннотациями/Ext/Package.bin index 3540686c..374cb880 100644 --- a/tests/skills/cases/xdto-decompile/snapshots/annotations/XDTOPackages/ПакетСАннотациями/Ext/Package.bin +++ b/tests/skills/cases/xdto-decompile/snapshots/annotations/XDTOPackages/ПакетСАннотациями/Ext/Package.bin @@ -2,7 +2,7 @@ - + diff --git a/tests/skills/cases/xdto-decompile/snapshots/annotations/annotations.xsd b/tests/skills/cases/xdto-decompile/snapshots/annotations/annotations.xsd index 346709ed..8d5521c3 100644 --- a/tests/skills/cases/xdto-decompile/snapshots/annotations/annotations.xsd +++ b/tests/skills/cases/xdto-decompile/snapshots/annotations/annotations.xsd @@ -15,7 +15,7 @@ - + diff --git a/tests/skills/cases/xdto-decompile/snapshots/annotations/roundtrip.xsd b/tests/skills/cases/xdto-decompile/snapshots/annotations/roundtrip.xsd index 017d000f..a3834302 100644 --- a/tests/skills/cases/xdto-decompile/snapshots/annotations/roundtrip.xsd +++ b/tests/skills/cases/xdto-decompile/snapshots/annotations/roundtrip.xsd @@ -12,7 +12,7 @@ - + diff --git a/tests/skills/cases/xdto-edit/add-import.json b/tests/skills/cases/xdto-edit/add-import.json index 36b06818..cecd7f60 100644 --- a/tests/skills/cases/xdto-edit/add-import.json +++ b/tests/skills/cases/xdto-edit/add-import.json @@ -1,9 +1,17 @@ { "name": "добавление импорта", "caseFiles": [ + "common.xsd", "types.xsd" ], "preRun": [ + { + "script": "xdto-compile/scripts/xdto-compile", + "args": { + "-XsdPath": "{workDir}/common.xsd", + "-OutputDir": "{workDir}" + } + }, { "script": "xdto-compile/scripts/xdto-compile", "args": { @@ -19,7 +27,7 @@ "-Operation", "add-import", "-Value", - "urn:test:other", + "urn:test:common", "-NoValidate" ], "expect": { diff --git a/tests/skills/cases/xdto-edit/set-namespace.json b/tests/skills/cases/xdto-edit/set-namespace.json index db7c2d74..5dde23ed 100644 --- a/tests/skills/cases/xdto-edit/set-namespace.json +++ b/tests/skills/cases/xdto-edit/set-namespace.json @@ -35,5 +35,6 @@ "XDTOPackages/common/Ext/Package.bin", "XDTOPackages/common.xml" ] - } + }, + "skipPlatformVerify": "смена namespace намеренно оставляет импорт зависящего пакета висящим — это документированное поведение операции" } diff --git a/tests/skills/cases/xdto-edit/snapshots/add-import/Configuration.xml b/tests/skills/cases/xdto-edit/snapshots/add-import/Configuration.xml index 389a4b4c..5af04010 100644 --- a/tests/skills/cases/xdto-edit/snapshots/add-import/Configuration.xml +++ b/tests/skills/cases/xdto-edit/snapshots/add-import/Configuration.xml @@ -246,6 +246,7 @@ Русский + common types diff --git a/tests/skills/cases/xdto-edit/snapshots/add-import/XDTOPackages/common.xml b/tests/skills/cases/xdto-edit/snapshots/add-import/XDTOPackages/common.xml new file mode 100644 index 00000000..32189b9d --- /dev/null +++ b/tests/skills/cases/xdto-edit/snapshots/add-import/XDTOPackages/common.xml @@ -0,0 +1,16 @@ + + + + + common + + + ru + common + + + + urn:test:common + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-edit/snapshots/add-import/XDTOPackages/common/Ext/Package.bin b/tests/skills/cases/xdto-edit/snapshots/add-import/XDTOPackages/common/Ext/Package.bin new file mode 100644 index 00000000..9e6187bb --- /dev/null +++ b/tests/skills/cases/xdto-edit/snapshots/add-import/XDTOPackages/common/Ext/Package.bin @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-edit/snapshots/add-import/XDTOPackages/types/Ext/Package.bin b/tests/skills/cases/xdto-edit/snapshots/add-import/XDTOPackages/types/Ext/Package.bin index 45055d34..09880c7e 100644 --- a/tests/skills/cases/xdto-edit/snapshots/add-import/XDTOPackages/types/Ext/Package.bin +++ b/tests/skills/cases/xdto-edit/snapshots/add-import/XDTOPackages/types/Ext/Package.bin @@ -1,5 +1,5 @@ - + [0-9]{20} diff --git a/tests/skills/cases/xdto-edit/snapshots/add-import/common.xsd b/tests/skills/cases/xdto-edit/snapshots/add-import/common.xsd new file mode 100644 index 00000000..927c85dd --- /dev/null +++ b/tests/skills/cases/xdto-edit/snapshots/add-import/common.xsd @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tests/skills/verify-snapshots.mjs b/tests/skills/verify-snapshots.mjs index 9dc2a752..21f86602 100644 --- a/tests/skills/verify-snapshots.mjs +++ b/tests/skills/verify-snapshots.mjs @@ -686,6 +686,15 @@ async function verifyCase(skillName, caseName, skillConfig, caseData, opts) { const workDir = mkdtempSync(join(tmpdir(), `verify-${skillName}-${caseName}-`)); result.workDir = workDir; + // Кейс может осознанно исключаться из платформенной проверки — когда его + // результат невалиден by design (например, операция намеренно оставляет + // висящий импорт). Причина обязательна, молча пропускать нельзя. + if (caseData.skipPlatformVerify) { + result.skipped = true; + result.skipReason = String(caseData.skipPlatformVerify); + return result; + } + // caseFiles — файловый вход кейса (напр. XSD для xdto-compile), как в runner.mjs for (const rel of caseData.caseFiles || []) { const src = join(CASES, skillName, rel); @@ -1434,9 +1443,14 @@ async function main() { } const passed = results.filter(r => r.passed).length; - const failed = results.filter(r => !r.passed).length; + const skipped = results.filter(r => r.skipped).length; + const failed = results.filter(r => !r.passed && !r.skipped).length; console.log(`\n${'='.repeat(60)}`); - console.log(`Results: ${passed} passed, ${failed} failed out of ${results.length}`); + console.log(`Results: ${passed} passed, ${failed} failed` + + (skipped ? `, ${skipped} skipped` : '') + ` out of ${results.length}`); + for (const r of results.filter(x => x.skipped)) { + console.log(` \u25cb ${r.skill}/${r.case} \u2014 ${r.skipReason}`); + } writeReport(results); process.exit(failed > 0 ? 1 : 0);