From 79a461f79df6ce3041e2ac2741c6b3b6b35ae562 Mon Sep 17 00:00:00 2001 From: agent_coder Date: Mon, 6 Jul 2026 06:26:56 +0300 Subject: [PATCH] =?UTF-8?q?test(converter):=20=D0=B2=D0=BB=D0=BE=D0=B6?= =?UTF-8?q?=D0=B5=D0=BD=D0=BD=D1=8B=D0=B9=20variant-A=20=D0=B3=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D1=80=D0=B0=D1=82=D0=BE=D1=80=20+=20P4-=D1=84=D0=B0?= =?UTF-8?q?=D0=B7=D0=B7,=20=D0=B8=20=D1=84=D0=B8=D0=BA=D1=81=20=D0=B2?= =?UTF-8?q?=D1=81=D0=B5=D1=85=20=D0=BD=D0=B0=D0=B9=D0=B4=D0=B5=D0=BD=D0=BD?= =?UTF-8?q?=D1=8B=D1=85=20round-trip=20=D0=B1=D0=B0=D0=B3=D0=BE=D0=B2=20(#?= =?UTF-8?q?351)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Финальная ступень #351: генератор ЦЕЛЫХ вложенных документов (random walk по ContentMatch схемы, min-depth fixpoint для терминирования, глубина/размер ограничены) + инвариант P4 (фазз парсера: для ЛЮБОЙ строки markdownToProseMirror не бросает и результат валиден по схеме). Инварианты P1 (семантический round-trip), P2 (байтовый fixpoint со 2-го прохода), P3 (тотальность) — строгие. Генератор сразу нашёл классы реальных багов конвертера; все починены (инварианты НЕ ослаблялись — чинился конвертер): - loose (много-блочные) контейнеры (listItem/taskItem/callout/detailsContent) склеивали блоки при реимпорте — ТИХАЯ ПОТЕРЯ ДАННЫХ; теперь blank-line разделитель между блок-детьми (по образцу blockquote). - соседние sibling-списки одного marker-family (task+bullet и т.п.) сливались в один список с ПОТЕРЕЙ чекбокса — теперь между ними эмитится инертный `` разделитель (byte-stable round-trip). - paragraph textAlign терялся во вложенных li/td/th. - вложенный codeBlock терял хвостовой перевод строки. - pageBreak/pageEmbed/subpages/transclusion дропались во вложении (blockquote/callout/details/li). - медиа в columns: number→string ширины/высоты и лишний data-align (churn). - callout `> [!type]`, вложенный в список/цитату, парсился неверно (prefix-aware regex). Golden-обновления (6) — прямые следствия loose-container фикса, каждое round-trip'ится. 2100+ сгенерированных документов (3 seed) — 0 падений P1/P2. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../src/lib/markdown-converter.ts | 123 +++++- .../src/lib/markdown-to-prosemirror.ts | 161 ++++--- .../src/lib/media-html.ts | 28 +- .../test/generative/doc-generator.ts | 392 ++++++++++++++++++ .../nested-roundtrip.property.test.ts | 185 +++++++++ .../test/markdown-converter-gaps.test.ts | 4 +- .../test/markdown-converter.test.ts | 47 ++- 7 files changed, 849 insertions(+), 91 deletions(-) create mode 100644 packages/prosemirror-markdown/test/generative/doc-generator.ts create mode 100644 packages/prosemirror-markdown/test/generative/nested-roundtrip.property.test.ts diff --git a/packages/prosemirror-markdown/src/lib/markdown-converter.ts b/packages/prosemirror-markdown/src/lib/markdown-converter.ts index 2d173e52..481c3691 100644 --- a/packages/prosemirror-markdown/src/lib/markdown-converter.ts +++ b/packages/prosemirror-markdown/src/lib/markdown-converter.ts @@ -48,6 +48,52 @@ export interface ConvertProseMirrorToMarkdownOptions { dropResolvedCommentAnchors?: boolean; } +/** + * Adjacent sibling lists that share a markdown MARKER FAMILY re-parse as ONE + * merged list — bulletList and taskList both emit `- ` markers (→ a single + * `