import { EditState, insertTextAtSelection, toggleCodeBlock, toggleLinePrefix, toggleWrap, wrapWithLink } from './markdownEditing'; const state = (content: string, selectionStart: number, selectionEnd = selectionStart): EditState => { return { content, selectionStart, selectionEnd }; }; describe('markdownEditing', () => { test('insertTextAtSelection inserts at the cursor and moves it', () => { expect(insertTextAtSelection(state('ac', 1), 'b')).toEqual({ content: 'abc', selectionStart: 2, selectionEnd: 2, }); }); test('insertTextAtSelection replaces the selection', () => { expect(insertTextAtSelection(state('aXYb', 1, 3), 'Z')).toEqual({ content: 'aZb', selectionStart: 2, selectionEnd: 2, }); }); test('toggleWrap wraps and unwraps a selection', () => { const wrapped = toggleWrap(state('hello', 0, 5), '**', 'strong text'); expect(wrapped).toEqual({ content: '**hello**', selectionStart: 2, selectionEnd: 7 }); expect(toggleWrap(wrapped, '**', 'strong text')).toEqual({ content: 'hello', selectionStart: 0, selectionEnd: 5, }); }); test('toggleWrap unwraps markers included in the selection', () => { expect(toggleWrap(state('**hello**', 0, 9), '**', 'strong text')).toEqual({ content: 'hello', selectionStart: 0, selectionEnd: 5, }); }); test('toggleWrap inserts the placeholder when there is no selection', () => { expect(toggleWrap(state('', 0), '_', 'italic text')).toEqual({ content: '_italic text_', selectionStart: 1, selectionEnd: 12, }); }); test('toggleLinePrefix adds and removes a prefix on the selected lines', () => { const prefixed = toggleLinePrefix(state('one\ntwo', 0, 7), { add: '- ', detect: /^[-*+] / }); expect(prefixed.content).toBe('- one\n- two'); expect(toggleLinePrefix(prefixed, { add: '- ', detect: /^[-*+] / }).content).toBe('one\ntwo'); }); test('toggleLinePrefix skips empty lines and keeps the cursor after the prefix', () => { const result = toggleLinePrefix(state('one\n\ntwo', 0, 8), { add: '- ', detect: /^[-*+] / }); expect(result.content).toBe('- one\n\n- two'); const cursor = toggleLinePrefix(state('one', 0), { add: '# ', detect: /^#{1,6} / }); expect(cursor).toEqual({ content: '# one', selectionStart: 2, selectionEnd: 2 }); }); test('toggleLinePrefix only affects the line under the cursor', () => { expect(toggleLinePrefix(state('one\ntwo', 4), { add: '> ', detect: /^> ?/ }).content).toBe('one\n> two'); }); test('toggleLinePrefix shifts a selection that starts mid-line', () => { expect(toggleLinePrefix(state('one', 1, 3), { add: '- ', detect: /^[-*+] / })).toEqual({ content: '- one', selectionStart: 3, selectionEnd: 5, }); }); test('toggleCodeBlock wraps a selection in a fenced block', () => { expect(toggleCodeBlock(state('code', 0, 4))).toEqual({ content: '```\ncode\n```', selectionStart: 4, selectionEnd: 8, }); }); test('toggleCodeBlock inserts empty fences with the cursor inside', () => { expect(toggleCodeBlock(state('', 0))).toEqual({ content: '```\n\n```', selectionStart: 4, selectionEnd: 4, }); }); test('wrapWithLink wraps the selection and keeps it selected', () => { expect(wrapWithLink(state('hello', 0, 5), 'https://example.com')).toEqual({ content: '[hello](https://example.com)', selectionStart: 1, selectionEnd: 6, }); }); test('wrapWithLink places the cursor inside the brackets when empty', () => { expect(wrapWithLink(state('', 0), 'https://example.com')).toEqual({ content: '[](https://example.com)', selectionStart: 1, selectionEnd: 1, }); }); });