Skip to content

Commit e0ae404

Browse files
committed
fix(cli): use pre-separated fixture for continuePrevious/join conformance tests
1 parent 286ee88 commit e0ae404

4 files changed

Lines changed: 39 additions & 39 deletions

File tree

apps/cli/src/__tests__/conformance/harness.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ import { copyFile, mkdtemp, mkdir, rm } from 'node:fs/promises';
22
import { tmpdir } from 'node:os';
33
import path from 'node:path';
44
import { run } from '../../index';
5-
import { resolveListDocFixture, resolveSourceDocFixture, resolveTocDocFixture } from '../fixtures';
5+
import {
6+
resolveListDocFixture,
7+
resolvePreSeparatedListFixture,
8+
resolveSourceDocFixture,
9+
resolveTocDocFixture,
10+
} from '../fixtures';
611

712
type RunResult = {
813
code: number;
@@ -125,6 +130,12 @@ export class ConformanceHarness {
125130
return filePath;
126131
}
127132

133+
async copyPreSeparatedListDoc(label: string): Promise<string> {
134+
const filePath = path.join(this.docsDir, `${this.nextId()}-${label}.docx`);
135+
await copyFile(await resolvePreSeparatedListFixture(), filePath);
136+
return filePath;
137+
}
138+
128139
async copyTocFixtureDoc(label: string, stateDir: string): Promise<string> {
129140
const filePath = path.join(this.docsDir, `${this.nextId()}-${label}.docx`);
130141

apps/cli/src/__tests__/conformance/scenarios.ts

Lines changed: 16 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -156,56 +156,34 @@ type ListTargetPreparation = {
156156
target: Record<string, unknown>;
157157
};
158158

159+
/**
160+
* Load a pre-separated list fixture (two adjacent lists that share the same
161+
* abstractNumId) and resolve the second list item as the target.
162+
*
163+
* This avoids a runtime `lists separate` → DOCX export → re-import round-trip
164+
* which can lose numbering definition compatibility on some platforms.
165+
*/
159166
async function prepareSeparatedSecondListTarget(
160167
harness: ConformanceHarness,
161168
stateDir: string,
162169
label: string,
163170
): Promise<ListTargetPreparation> {
164-
const sourceDoc = await harness.copyListFixtureDoc(`${label}-source`);
171+
const docPath = await harness.copyPreSeparatedListDoc(label);
172+
const items = await listDiscoveryItems(harness, stateDir, docPath, 10);
165173

166-
// Discover source items for diagnostics.
167-
const sourceItems = await listDiscoveryItems(harness, stateDir, sourceDoc, 10);
168-
if (sourceItems.length < 2) {
174+
if (items.length < 2) {
169175
throw new Error(
170-
`[${label}] Source fixture has fewer than 2 list items (found ${sourceItems.length}). ` +
171-
`Items: ${JSON.stringify(sourceItems)}`,
176+
`[${label}] Pre-separated fixture has fewer than 2 list items (found ${items.length}). ` +
177+
`Items: ${JSON.stringify(items)}`,
172178
);
173179
}
174180

175-
const secondItem = sourceItems[1]?.address;
176-
if (!secondItem || typeof secondItem !== 'object') {
177-
throw new Error(`[${label}] Second list item has no address. Items: ${JSON.stringify(sourceItems)}`);
181+
const target = items[1]?.address;
182+
if (!target || typeof target !== 'object') {
183+
throw new Error(`[${label}] Second list item has no address. Items: ${JSON.stringify(items)}`);
178184
}
179185

180-
const separatedDoc = harness.createOutputPath(`${label}-separated`);
181-
const separated = await harness.runCli(
182-
['lists', 'separate', sourceDoc, '--target-json', JSON.stringify(secondItem), '--out', separatedDoc],
183-
stateDir,
184-
);
185-
if (separated.result.code !== 0 || separated.envelope.ok !== true) {
186-
throw new Error(
187-
`[${label}] lists separate failed. code=${separated.result.code} ` +
188-
`envelope=${JSON.stringify(separated.envelope)} ` +
189-
`target=${JSON.stringify(secondItem)} ` +
190-
`stderr=${separated.result.stderr.trim() || '<empty>'}`,
191-
);
192-
}
193-
194-
// Re-resolve from the output document (node IDs may change across write/reload).
195-
const postItems = await listDiscoveryItems(harness, stateDir, separatedDoc, 10);
196-
if (postItems.length < 2) {
197-
throw new Error(
198-
`[${label}] Post-separation doc has fewer than 2 list items (found ${postItems.length}). ` +
199-
`Items: ${JSON.stringify(postItems)}`,
200-
);
201-
}
202-
203-
const separatedSecondItem = postItems[1]?.address;
204-
if (!separatedSecondItem || typeof separatedSecondItem !== 'object') {
205-
throw new Error(`[${label}] Post-separation second item has no address. Items: ${JSON.stringify(postItems)}`);
206-
}
207-
208-
return { docPath: separatedDoc, target: separatedSecondItem };
186+
return { docPath, target };
209187
}
210188

211189
function sectionMutationScenario(

apps/cli/src/__tests__/fixtures.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ const LIST_SOURCE_DOC_CANDIDATES = [
1515
path.join(REPO_ROOT, 'e2e-tests/test-data/basic-documents/lists-complex-items.docx'),
1616
];
1717

18+
const PRE_SEPARATED_LIST_CANDIDATES = [
19+
path.join(REPO_ROOT, 'packages/super-editor/src/tests/data/pre-separated-list.docx'),
20+
];
21+
1822
const TOC_SOURCE_DOC_CANDIDATES = [
1923
path.join(REPO_ROOT, 'test-corpus/basic/table-of-contents.docx'),
2024
path.join(REPO_ROOT, 'test-corpus/basic/table-of-contents-sdt.docx'),
@@ -23,6 +27,7 @@ const TOC_SOURCE_DOC_CANDIDATES = [
2327

2428
let resolvedSourceDoc: string | null = null;
2529
let resolvedListSourceDoc: string | null = null;
30+
let resolvedPreSeparatedListDoc: string | null = null;
2631
let resolvedTocSourceDoc: string | null = null;
2732

2833
async function resolveFixture(candidates: string[], fixtureLabel: string): Promise<string> {
@@ -50,6 +55,12 @@ export async function resolveListDocFixture(): Promise<string> {
5055
return resolvedListSourceDoc;
5156
}
5257

58+
export async function resolvePreSeparatedListFixture(): Promise<string> {
59+
if (resolvedPreSeparatedListDoc != null) return resolvedPreSeparatedListDoc;
60+
resolvedPreSeparatedListDoc = await resolveFixture(PRE_SEPARATED_LIST_CANDIDATES, 'pre-separated list');
61+
return resolvedPreSeparatedListDoc;
62+
}
63+
5364
export async function resolveTocDocFixture(): Promise<string> {
5465
if (resolvedTocSourceDoc != null) return resolvedTocSourceDoc;
5566
resolvedTocSourceDoc = await resolveFixture(TOC_SOURCE_DOC_CANDIDATES, 'table-of-contents');
13.5 KB
Binary file not shown.

0 commit comments

Comments
 (0)