From df47d4d34f171169e718f2edfa0977891d532086 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Tue, 22 Sep 2026 20:06:46 +0300 Subject: [PATCH] =?UTF-8?q?test(check-inline-drift):=20=D0=B2=D0=B7=D1=8F?= =?UTF-8?q?=D1=82=D1=8C=20=D0=B0=D0=B2=D1=82=D0=BE-=D0=B2=D1=8B=D0=B2?= =?UTF-8?q?=D0=BE=D0=B4=20=D0=B7=D0=B0=D0=B3=D0=BE=D0=BB=D0=BE=D0=B2=D0=BA?= =?UTF-8?q?=D0=B0=20title=5Ffrom=5Fname=20=D0=BF=D0=BE=D0=B4=20=D0=B3?= =?UTF-8?q?=D0=B2=D0=B0=D1=80=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Title-FromName/title_from_name продублирован в form-compile и form-decompile: компилятор пишет заголовок, которого нет в DSL, а декомпилятор на этом же выводе решает, можно ли заголовок опустить. В комментарии копия заявлена «ТОЧНЫМ зеркалом», но ничем не держалась. Разъедутся копии — заголовок либо теряется, либо дублируется, и в обоих случаях текст на форме меняется молча, без ошибки платформы. Эталон варианта — form-compile: компилятор авторитетен, декомпилятор его зеркалит. Тело копии приведено к эталону без смены поведения (разбиение строк в ps1; в py — выражение вместо индексного цикла и `not parts` вместо `len(parts) == 0`; `p.isupper()` и `p == p.upper()` расходятся только на частях без буквенных символов, а после двух разделяющих регулярок такая часть недостижима). Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01SSyRNwSiuAAEQCLSCUGEzQ --- .../skills/form-decompile/scripts/form-decompile.ps1 | 7 +++++-- .../skills/form-decompile/scripts/form-decompile.py | 10 +++------- tests/skills/check-inline-drift.mjs | 9 +++++++++ 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/.claude/skills/form-decompile/scripts/form-decompile.ps1 b/.claude/skills/form-decompile/scripts/form-decompile.ps1 index ae9b1edf0..3acc5f3f5 100644 --- a/.claude/skills/form-decompile/scripts/form-decompile.ps1 +++ b/.claude/skills/form-decompile/scripts/form-decompile.ps1 @@ -413,8 +413,11 @@ function Title-FromName { [void]$out.Add($parts[0]) for ($i = 1; $i -lt $parts.Count; $i++) { $p = $parts[$i] - if ($p.Length -gt 1 -and $p -ceq $p.ToUpper()) { [void]$out.Add($p) } - else { [void]$out.Add($p.ToLower()) } + if ($p.Length -gt 1 -and $p -ceq $p.ToUpper()) { + [void]$out.Add($p) + } else { + [void]$out.Add($p.ToLower()) + } } return ($out -join ' ') } diff --git a/.claude/skills/form-decompile/scripts/form-decompile.py b/.claude/skills/form-decompile/scripts/form-decompile.py index da93ba014..9fee24ec2 100644 --- a/.claude/skills/form-decompile/scripts/form-decompile.py +++ b/.claude/skills/form-decompile/scripts/form-decompile.py @@ -460,15 +460,11 @@ def title_from_name(name): s = re.sub(r'([А-ЯA-Z])([А-ЯA-Z][а-яa-z])', r'\1 \2', name) s = re.sub(r'([а-яa-z0-9])([А-ЯA-Z])', r'\1 \2', s) parts = s.split(' ') - if len(parts) == 0: + if not parts: return s out = [parts[0]] - for i in range(1, len(parts)): - p = parts[i] - if len(p) > 1 and p == p.upper(): - out.append(p) - else: - out.append(p.lower()) + for p in parts[1:]: + out.append(p if (len(p) > 1 and p.isupper()) else p.lower()) return ' '.join(out) diff --git a/tests/skills/check-inline-drift.mjs b/tests/skills/check-inline-drift.mjs index 24d440a6e..418499cfc 100644 --- a/tests/skills/check-inline-drift.mjs +++ b/tests/skills/check-inline-drift.mjs @@ -525,6 +525,15 @@ const FAMILIES = [ ], }, + // ─── Авто-вывод заголовка из имени элемента формы ──────────────────────── + // Компилятор пишет заголовок, которого нет в DSL, декомпилятор на этом же выводе решает, можно + // ли заголовок опустить. Разъехались копии — заголовок либо теряется, либо дублируется, и в + // обоих случаях текст на форме меняется молча, без ошибки платформы (PR #91). + { + name: 'авто-заголовок из имени: title_from_name', py: 'title_from_name', ps1: 'Title-FromName', + variants: [{ id: 'base', authority: 'form-compile', consumers: ['form-decompile'] }], + }, + // ─── Компактный JSON декомпиляторов ───────────────────────────────────── // Штатные сериализаторы не годятся: ConvertTo-Json (PS5.1) выравнивает ключи по самому // длинному и эскейпит кириллицу в \uXXXX, json.dumps даёт иную раскладку inline/multiline.