mirror of
https://github.com/vxcontrol/pentagi.git
synced 2026-08-28 14:06:36 +00:00
test(markdown-editor): close four coverage gaps found in review
- history: assert resetUndoHistory actually empties the undo stack (editor.can().undo() === false), not just that it doesn't throw — a silent no-op regression would otherwise pass. - field: assert insertAtCursor is a no-op (no onChange) when the field is disabled — the documented "a mid-save variable click can't dirty the form" guard was untested. - content-integrity: the pipe-table generative test now also asserts each pipe-bearing atom survives as an escaped code span, not just the row sentinels. - code-fence: fix the pinned-limitation comment — an upstream fix turns this test RED (the canary), it does not "flip green". Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
786e416dc5
commit
2835fd3302
@@ -33,8 +33,9 @@ describe('code-block fence lengthening — a block documenting a ``` fence stays
|
||||
// delimiter by rendering it around a fixed placeholder (getMarkOpening/getMarkClosing), so the `code` mark's
|
||||
// real content is never seen at delimiter time and it always emits a SINGLE backtick. A code span whose
|
||||
// content contains a backtick therefore collapses on save and never converges. A NODE (codeBlock, above) DOES
|
||||
// receive its real content and is content-aware — hence the fence widening is fixable but this is not. Pinned so the gap stays
|
||||
// visible and this test flips green if a future @tiptap/markdown makes mark delimiters content-aware.
|
||||
// receive its real content and is content-aware — hence the fence widening is fixable but this is not. Pinned so
|
||||
// the gap stays visible: this test turns RED (the canary to revisit it) if a future @tiptap/markdown makes mark
|
||||
// delimiters content-aware and the span starts round-tripping.
|
||||
describe('inline code containing a backtick — known lossy on save (upstream mark-delimiter limitation)', () => {
|
||||
it('collapses a backtick-containing code span (does not round-trip)', () => {
|
||||
const out = roundTrip('x ``a `b` c`` y');
|
||||
|
||||
+10
@@ -151,12 +151,14 @@ describe('generative content-integrity — atoms survive load↔serialize across
|
||||
const wrap = (cells: string) => (outerPipe ? `| ${cells} |` : cells);
|
||||
const rows: string[] = [];
|
||||
const sentinels: string[] = [];
|
||||
const atoms: string[] = [];
|
||||
|
||||
for (let row = 0; row < rowCount; row++) {
|
||||
const atom = pipeAtoms[Math.floor(rng() * pipeAtoms.length)] as string;
|
||||
const sentinel = `${WORDS[Math.floor(rng() * WORDS.length)]}${row}`;
|
||||
|
||||
sentinels.push(sentinel);
|
||||
atoms.push(atom);
|
||||
rows.push(wrap(`\`${atom}\` | ${sentinel}`));
|
||||
}
|
||||
|
||||
@@ -168,6 +170,14 @@ describe('generative content-integrity — atoms survive load↔serialize across
|
||||
for (const sentinel of sentinels) {
|
||||
expect(out.includes(sentinel), `cell "${sentinel}" dropped (i=${i}):\n${doc}\n-->\n${out}`).toBe(true);
|
||||
}
|
||||
|
||||
// The atom itself must survive as a code span with its structural pipes escaped for the table — the
|
||||
// sentinel guards the row's cell count, this guards the pipe-bearing content from silent corruption.
|
||||
for (const atom of atoms) {
|
||||
const span = `\`${atom.replace(/\|/g, '\\|')}\``;
|
||||
|
||||
expect(out.includes(span), `atom ${span} corrupted (i=${i}):\n${doc}\n-->\n${out}`).toBe(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -54,6 +54,25 @@ describe('MarkdownEditorField raw-mode handle', () => {
|
||||
ref.current!.insertAtCursor('{{.Bar}}');
|
||||
expect(onChange).toHaveBeenCalledWith(expect.stringContaining('{{.Bar}}'));
|
||||
});
|
||||
|
||||
it('insertAtCursor is a no-op when the field is disabled (a mid-save variable click cannot dirty it)', () => {
|
||||
const onChange = vi.fn();
|
||||
const ref = createRef<MarkdownEditorFieldHandle>();
|
||||
const { container } = render(
|
||||
<MarkdownEditorField
|
||||
disabled
|
||||
mode="raw"
|
||||
onChange={onChange}
|
||||
ref={ref}
|
||||
value="seed"
|
||||
/>,
|
||||
);
|
||||
|
||||
container.querySelector('textarea')!.setSelectionRange(0, 0);
|
||||
ref.current!.insertAtCursor('{{.Bar}}');
|
||||
|
||||
expect(onChange).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('MarkdownEditorField rich-mode handle', () => {
|
||||
|
||||
@@ -64,3 +64,17 @@ it('resetUndoHistory survives view.state advancing during updateState', () => {
|
||||
|
||||
editor.destroy();
|
||||
});
|
||||
|
||||
it('resetUndoHistory actually clears the undo stack', () => {
|
||||
const editor = new Editor({ content: 'seed', contentType: 'markdown', extensions: createMarkdownExtensions() });
|
||||
|
||||
editor.commands.insertContent(' more');
|
||||
|
||||
expect(editor.can().undo()).toBe(true);
|
||||
|
||||
resetUndoHistory(editor);
|
||||
|
||||
expect(editor.can().undo()).toBe(false);
|
||||
|
||||
editor.destroy();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user