mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-07-28 07:31:00 +03:00
feat(xdto-compile,xdto-decompile,xdto-validate): пакеты XDTO из XML-схемы
Три навыка для работы с пакетами XDTO. Формат описания — обычная XSD, своего DSL нет: рутину снимает конвертер (локальные объявления префиксов dNpM на каждой ссылке, инвертированная кратность lowerBound/upperBound, фасеты атрибутами вместо дочерних элементов, обязательный порядок элементов верхнего уровня). То, чего XSD выразить не может — nillable у атрибута, qualified у свойства, «атрибут записан явно» — едет атрибутами из пространства имён модели XDTO по правилу «то же имя, что в Package.bin». Свойства объекта метаданных живут в xs:appinfo, поэтому пара decompile → compile замыкается без потерь. Инвариант bin → xsd → bin проверен побайтово на 760 пакетах выгрузок Бухгалтерии и ERP 8.3.24 (харнесс debug/xdto/roundtrip-corpus.mjs). Сборка из рукописной XSD проверена загрузкой в базу 8.3.24 — именно она вскрыла обязательный порядок import→property→valueType→objectType, невидимый для корпусной сверки: все выгрузки уже канонические. xdto-validate ловит два класса тихих дефектов, которые платформа не диагностирует: подмену неразрешённого чужого типа на xs:anyType при импорте XML-схемы и nillable у свойства-атрибута, теряемый экспортом схемы в Конфигураторе. Тесты: 18 снэпшот-кейсов на синтетических схемах (типовые конфигурации в репозиторий не тащим), паритет PS↔PY на общих эталонах. Раннер получил caseFiles — копирование файлов кейса в workDir для навыков с файловым, а не JSON входом. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
d544071b1e
commit
d05aef54b4
@@ -603,6 +603,7 @@ async function runCaseAsync(testCase, opts) {
|
||||
const isExternal = typeof setupName === 'string' && setupName.startsWith('external:');
|
||||
workspace = createWorkspace(fixturePath, isExternal);
|
||||
workDir = workspace.path;
|
||||
copyCaseFiles(caseData, workDir, skillCasesDir);
|
||||
|
||||
// Pre-run steps
|
||||
if (caseData.preRun) {
|
||||
@@ -742,6 +743,22 @@ async function runCaseAsync(testCase, opts) {
|
||||
}
|
||||
}
|
||||
|
||||
// Скопировать файлы из каталога кейса в workDir — для навыков, вход которых
|
||||
// не JSON, а файл (например XSD для xdto-compile). Так эталонные входы остаются
|
||||
// читаемыми файлами, а не строками внутри JSON кейса.
|
||||
function copyCaseFiles(caseData, workDir, skillCasesDir) {
|
||||
if (!caseData.caseFiles) return;
|
||||
for (const rel of caseData.caseFiles) {
|
||||
const src = join(skillCasesDir, rel);
|
||||
if (!existsSync(src)) throw new Error(`caseFiles: файл не найден: ${src}`);
|
||||
// Путь со слэшем сохраняет структуру каталогов (напр. дерево пакета),
|
||||
// простое имя кладётся в корень workDir
|
||||
const dst = rel.includes('/') ? join(workDir, rel) : join(workDir, basename(rel));
|
||||
mkdirSync(dirname(dst), { recursive: true });
|
||||
copyFileSync(src, dst);
|
||||
}
|
||||
}
|
||||
|
||||
function runCase(testCase, opts) {
|
||||
const { skillConfig, caseData, snapshotDir } = testCase;
|
||||
const t0 = performance.now();
|
||||
@@ -769,6 +786,7 @@ function runCase(testCase, opts) {
|
||||
const isExternal = typeof setupName === 'string' && setupName.startsWith('external:');
|
||||
workspace = createWorkspace(fixturePath, isExternal);
|
||||
workDir = workspace.path;
|
||||
copyCaseFiles(caseData, workDir, skillCasesDir);
|
||||
|
||||
// 2. Pre-run steps (setup prerequisites like creating objects)
|
||||
if (caseData.preRun) {
|
||||
|
||||
Reference in New Issue
Block a user