Files
joplin/packages/editor/CodeMirror/extensions/markdownHighlightExtension.test.ts

107 lines
3.5 KiB
TypeScript

import { EditorSelection, EditorState } from '@codemirror/state';
import createTestEditor from '../testing/createTestEditor';
import findNodesWithName from '../testing/findNodesWithName';
import { highlightMarkerTagName, highlightTagName, insertMarkerTagName, insertTagName } from './markdownHighlightExtension';
const createEditorState = async (initialText: string, expectedTags: string[]): Promise<EditorState> => {
return (await createTestEditor(initialText, EditorSelection.cursor(0), expectedTags)).state;
};
describe('MarkdownHighlightExtension', () => {
jest.retryTimes(2);
it.each([
{ // Should support single-word highlights
text: '==highlight==',
expectedHighlightRanges: [{ from: 0, to: '==highlight=='.length }],
expectedMarkerRanges: [
{ from: 0, to: 2 },
{ from: '==highlight'.length, to: '==highlight=='.length },
],
},
{ // Should support multi-word highlights
text: '==highlight test==',
expectedHighlightRanges: [{ from: 0, to: '==highlight test=='.length }],
expectedMarkerRanges: [
{ from: 0, to: 2 },
{ from: '==highlight test'.length, to: '==highlight test=='.length },
],
},
{ // Should support within-word highlights
text: 'test==ing==',
expectedHighlightRanges: [{ from: 'test'.length, to: 'test==ing=='.length }],
},
{ // Should not highlight if just one =
text: 'test==ing=',
expectedHighlightRanges: [],
},
{ // Should not highlight within code
text: '`==highlight test==`',
expectedHighlightRanges: [],
expectedMarkerRanges: [],
},
{ // Should highlight across line breaks
text: '==highlight\ntest== test',
expectedHighlightRanges: [{ from: 0, to: '==highlight\ntest=='.length }],
},
{ // Should not highlight across paragraph breaks
text: '==highlight\n\ntest== test',
expectedHighlightRanges: [],
expectedMarkerRanges: [],
},
])('should parse inline highlights (case %#: %j)', async ({ text, expectedHighlightRanges, expectedMarkerRanges }) => {
const expectedNodes: string[] = [];
if (expectedHighlightRanges.length) {
expectedNodes.push(highlightTagName);
}
if (expectedMarkerRanges?.length) {
expectedNodes.push(highlightMarkerTagName);
}
const editor = await createEditorState(text, expectedNodes);
const highlightNodes = findNodesWithName(editor, highlightTagName);
expect(highlightNodes).toMatchObject(expectedHighlightRanges);
if (expectedMarkerRanges) {
const markerNodes = findNodesWithName(editor, highlightMarkerTagName);
expect(markerNodes).toMatchObject(expectedMarkerRanges);
}
});
it.each([
{ // Should support single-word insert
text: '++insert++',
expectedInsertRanges: [{ from: 0, to: '++insert++'.length }],
expectedMarkerRanges: [
{ from: 0, to: 2 },
{ from: '++insert'.length, to: '++insert++'.length },
],
},
{ // Should not parse if only one +
text: 'test++ing+',
expectedInsertRanges: [],
},
])('should parse inline insert (case %#: %j)', async ({ text, expectedInsertRanges, expectedMarkerRanges }) => {
const expectedNodes: string[] = [];
if (expectedInsertRanges.length) {
expectedNodes.push(insertTagName);
}
if (expectedMarkerRanges?.length) {
expectedNodes.push(insertMarkerTagName);
}
const editor = await createEditorState(text, expectedNodes);
const insertNodes = findNodesWithName(editor, insertTagName);
expect(insertNodes).toMatchObject(expectedInsertRanges);
if (expectedMarkerRanges) {
const markerNodes = findNodesWithName(editor, insertMarkerTagName);
expect(markerNodes).toMatchObject(expectedMarkerRanges);
}
});
});