文件
chen 301194963b
一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
feat: Initial clean release of CHM
2026-11-04 11:29:39 +08:00

110 行
3.5 KiB
TypeScript

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,
});
});
});