mirror of
https://github.com/mermaid-js/mermaid.git
synced 2025-01-28 07:03:17 +08:00
Add tests without Intl.Segmenter
This commit is contained in:
parent
b14bcda12a
commit
d58c41dbc0
@ -14,11 +14,7 @@ function applyStyle(dom, styleFn) {
|
||||
|
||||
function addHtmlSpan(element, node, width, classes, addBackground = false) {
|
||||
const fo = element.append('foreignObject');
|
||||
// const newEl = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject');
|
||||
// const newEl = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject');
|
||||
const div = fo.append('xhtml:div');
|
||||
// const div = body.append('div');
|
||||
// const div = fo.append('div');
|
||||
|
||||
const label = node.label;
|
||||
const labelClass = node.isNode ? 'nodeLabel' : 'edgeLabel';
|
||||
@ -130,7 +126,6 @@ function updateTextContentAndStyles(tspan: any, wrappedLine: MarkdownWord[]) {
|
||||
.attr('font-style', word.type === 'emphasis' ? 'italic' : 'normal')
|
||||
.attr('class', 'text-inner-tspan')
|
||||
.attr('font-weight', word.type === 'strong' ? 'bold' : 'normal');
|
||||
// const special = ['"', "'", '.', ',', ':', ';', '!', '?', '(', ')', '[', ']', '{', '}'];
|
||||
if (index === 0) {
|
||||
innerTspan.text(word.content);
|
||||
} else {
|
||||
|
@ -1,46 +1,85 @@
|
||||
import { splitTextToChars, splitLineToFitWidth, splitLineToWords } from './splitText.js';
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { describe, it, expect, vi } from 'vitest';
|
||||
import type { CheckFitFunction, MarkdownLine, MarkdownWordType } from './types.js';
|
||||
|
||||
describe('splitText', () => {
|
||||
it.each([
|
||||
{ str: '', split: [] },
|
||||
{ str: '🏳️⚧️🏳️🌈👩🏾❤️👨🏻', split: ['🏳️⚧️', '🏳️🌈', '👩🏾❤️👨🏻'] },
|
||||
{ str: 'ok', split: ['o', 'k'] },
|
||||
{ str: 'abc', split: ['a', 'b', 'c'] },
|
||||
])('should split $str into graphemes', ({ str, split }: { str: string; split: string[] }) => {
|
||||
expect(splitTextToChars(str)).toEqual(split);
|
||||
describe('when Intl.Segmenter is available', () => {
|
||||
describe('splitText', () => {
|
||||
it.each([
|
||||
{ str: '', split: [] },
|
||||
{ str: '🏳️⚧️🏳️🌈👩🏾❤️👨🏻', split: ['🏳️⚧️', '🏳️🌈', '👩🏾❤️👨🏻'] },
|
||||
{ str: 'ok', split: ['o', 'k'] },
|
||||
{ str: 'abc', split: ['a', 'b', 'c'] },
|
||||
])('should split $str into graphemes', ({ str, split }: { str: string; split: string[] }) => {
|
||||
expect(splitTextToChars(str)).toEqual(split);
|
||||
});
|
||||
});
|
||||
|
||||
describe('split lines', () => {
|
||||
it('should create valid checkFit function', () => {
|
||||
const checkFit5 = createCheckFn(5);
|
||||
expect(checkFit5([{ content: 'hello', type: 'normal' }])).toBe(true);
|
||||
expect(
|
||||
checkFit5([
|
||||
{ content: 'hello', type: 'normal' },
|
||||
{ content: 'world', type: 'normal' },
|
||||
])
|
||||
).toBe(false);
|
||||
const checkFit1 = createCheckFn(1);
|
||||
expect(checkFit1([{ content: 'A', type: 'normal' }])).toBe(true);
|
||||
expect(checkFit1([{ content: '🏳️⚧️', type: 'normal' }])).toBe(true);
|
||||
expect(checkFit1([{ content: '🏳️⚧️🏳️⚧️', type: 'normal' }])).toBe(false);
|
||||
});
|
||||
|
||||
it.each([
|
||||
// empty string
|
||||
{ str: 'hello world', width: 7, split: ['hello', 'world'] },
|
||||
// width > full line
|
||||
{ str: 'hello world', width: 20, split: ['hello world'] },
|
||||
// width < individual word
|
||||
{ str: 'hello world', width: 3, split: ['hel', 'lo', 'wor', 'ld'] },
|
||||
{ str: 'hello 12 world', width: 4, split: ['hell', 'o 12', 'worl', 'd'] },
|
||||
{ str: 'hello 1 2 world', width: 4, split: ['hell', 'o 1', '2', 'worl', 'd'] },
|
||||
{ str: 'hello 1 2 world', width: 6, split: ['hello', ' 1 2', 'world'] },
|
||||
// width = 0, impossible, so split into individual characters
|
||||
{ str: '🏳️⚧️🏳️🌈👩🏾❤️👨🏻', width: 0, split: ['🏳️⚧️', '🏳️🌈', '👩🏾❤️👨🏻'] },
|
||||
{ str: '🏳️⚧️🏳️🌈👩🏾❤️👨🏻', width: 1, split: ['🏳️⚧️', '🏳️🌈', '👩🏾❤️👨🏻'] },
|
||||
{ str: '🏳️⚧️🏳️🌈👩🏾❤️👨🏻', width: 2, split: ['🏳️⚧️🏳️🌈', '👩🏾❤️👨🏻'] },
|
||||
{ str: '🏳️⚧️🏳️🌈👩🏾❤️👨🏻', width: 3, split: ['🏳️⚧️🏳️🌈👩🏾❤️👨🏻'] },
|
||||
{ str: '中文中', width: 1, split: ['中', '文', '中'] },
|
||||
{ str: '中文中', width: 2, split: ['中文', '中'] },
|
||||
{ str: '中文中', width: 3, split: ['中文中'] },
|
||||
{ str: 'Flag 🏳️⚧️ this 🏳️🌈', width: 6, split: ['Flag 🏳️⚧️', 'this 🏳️🌈'] },
|
||||
])(
|
||||
'should split $str into lines of $width characters',
|
||||
({ str, split, width }: { str: string; width: number; split: string[] }) => {
|
||||
const checkFn = createCheckFn(width);
|
||||
const line: MarkdownLine = getLineFromString(str);
|
||||
expect(splitLineToFitWidth(line, checkFn)).toEqual(
|
||||
split.map((str) => getLineFromString(str))
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('split lines', () => {
|
||||
/**
|
||||
* Creates a checkFunction for a given width
|
||||
* @param width - width of characters to fit in a line
|
||||
* @returns checkFunction
|
||||
*/
|
||||
const createCheckFn = (width: number): CheckFitFunction => {
|
||||
return (text: MarkdownLine) => {
|
||||
// Join all words into a single string
|
||||
const joinedContent = text.map((w) => w.content).join('');
|
||||
const characters = splitTextToChars(joinedContent);
|
||||
return characters.length <= width;
|
||||
};
|
||||
};
|
||||
describe('when Intl.segmenter is not available', () => {
|
||||
beforeAll(() => {
|
||||
vi.stubGlobal('Intl', { Segmenter: undefined });
|
||||
});
|
||||
afterAll(() => {
|
||||
vi.unstubAllGlobals();
|
||||
});
|
||||
|
||||
it('should create valid checkFit function', () => {
|
||||
const checkFit5 = createCheckFn(5);
|
||||
expect(checkFit5([{ content: 'hello', type: 'normal' }])).toBe(true);
|
||||
expect(
|
||||
checkFit5([
|
||||
{ content: 'hello', type: 'normal' },
|
||||
{ content: 'world', type: 'normal' },
|
||||
])
|
||||
).toBe(false);
|
||||
const checkFit1 = createCheckFn(1);
|
||||
expect(checkFit1([{ content: 'A', type: 'normal' }])).toBe(true);
|
||||
expect(checkFit1([{ content: '🏳️⚧️', type: 'normal' }])).toBe(true);
|
||||
expect(checkFit1([{ content: '🏳️⚧️🏳️⚧️', type: 'normal' }])).toBe(false);
|
||||
it.each([
|
||||
{ str: '', split: [] },
|
||||
{
|
||||
str: '🏳️⚧️🏳️🌈👩🏾❤️👨🏻',
|
||||
split: [...'🏳️⚧️🏳️🌈👩🏾❤️👨🏻'],
|
||||
},
|
||||
{ str: 'ok', split: ['o', 'k'] },
|
||||
{ str: 'abc', split: ['a', 'b', 'c'] },
|
||||
])('should split $str into characters', ({ str, split }: { str: string; split: string[] }) => {
|
||||
expect(splitTextToChars(str)).toEqual(split);
|
||||
});
|
||||
|
||||
it.each([
|
||||
@ -52,37 +91,34 @@ describe('split lines', () => {
|
||||
{ str: 'hello world', width: 3, split: ['hel', 'lo', 'wor', 'ld'] },
|
||||
{ str: 'hello 12 world', width: 4, split: ['hell', 'o 12', 'worl', 'd'] },
|
||||
{ str: 'hello 1 2 world', width: 4, split: ['hell', 'o 1', '2', 'worl', 'd'] },
|
||||
{ str: 'hello 1 2 world', width: 6, split: ['hello', ' 1 2', 'world'] },
|
||||
{ str: 'hello 1 2 world', width: 6, split: ['hello', ' 1 2', 'world'] },
|
||||
// width = 0, impossible, so split into individual characters
|
||||
{ str: '🏳️⚧️🏳️🌈👩🏾❤️👨🏻', width: 0, split: ['🏳️⚧️', '🏳️🌈', '👩🏾❤️👨🏻'] },
|
||||
{ str: '🏳️⚧️🏳️🌈👩🏾❤️👨🏻', width: 1, split: ['🏳️⚧️', '🏳️🌈', '👩🏾❤️👨🏻'] },
|
||||
{ str: '🏳️⚧️🏳️🌈👩🏾❤️👨🏻', width: 2, split: ['🏳️⚧️🏳️🌈', '👩🏾❤️👨🏻'] },
|
||||
{ str: '🏳️⚧️🏳️🌈👩🏾❤️👨🏻', width: 3, split: ['🏳️⚧️🏳️🌈👩🏾❤️👨🏻'] },
|
||||
{ str: 'abc', width: 0, split: ['a', 'b', 'c'] },
|
||||
{ str: '🏳️⚧️🏳️🌈👩🏾❤️👨🏻', width: 1, split: [...'🏳️⚧️🏳️🌈👩🏾❤️👨🏻'] },
|
||||
{ str: '中文中', width: 1, split: ['中', '文', '中'] },
|
||||
{ str: '中文中', width: 2, split: ['中文', '中'] },
|
||||
{ str: '中文中', width: 3, split: ['中文中'] },
|
||||
{ str: 'Flag 🏳️⚧️ this 🏳️🌈', width: 6, split: ['Flag 🏳️⚧️', 'this 🏳️🌈'] },
|
||||
])(
|
||||
'should split $str into lines of $width characters',
|
||||
({ str, split, width }: { str: string; width: number; split: string[] }) => {
|
||||
const checkFn = createCheckFn(width);
|
||||
const line: MarkdownLine = getLineFromString(str);
|
||||
expect(splitLineToFitWidth(line, checkFn)).toEqual(
|
||||
split.map((str) => splitLineToWords(str).map((content) => ({ content, type: 'normal' })))
|
||||
split.map((str) => getLineFromString(str))
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle strings with newlines', () => {
|
||||
const checkFn: CheckFitFunction = createCheckFn(6);
|
||||
const str = `Flag
|
||||
it('should handle strings with newlines', () => {
|
||||
const checkFn: CheckFitFunction = createCheckFn(6);
|
||||
const str = `Flag
|
||||
🏳️⚧️ this 🏳️🌈`;
|
||||
expect(() =>
|
||||
splitLineToFitWidth(getLineFromString(str), checkFn)
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
'"splitLineToFitWidth does not support newlines in the line"'
|
||||
);
|
||||
});
|
||||
expect(() =>
|
||||
splitLineToFitWidth(getLineFromString(str), checkFn)
|
||||
).toThrowErrorMatchingInlineSnapshot(
|
||||
'"splitLineToFitWidth does not support newlines in the line"'
|
||||
);
|
||||
});
|
||||
|
||||
const getLineFromString = (str: string, type: MarkdownWordType = 'normal'): MarkdownLine => {
|
||||
@ -91,3 +127,17 @@ const getLineFromString = (str: string, type: MarkdownWordType = 'normal'): Mark
|
||||
type,
|
||||
}));
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a checkFunction for a given width
|
||||
* @param width - width of characters to fit in a line
|
||||
* @returns checkFunction
|
||||
*/
|
||||
const createCheckFn = (width: number): CheckFitFunction => {
|
||||
return (text: MarkdownLine) => {
|
||||
// Join all words into a single string
|
||||
const joinedContent = text.map((w) => w.content).join('');
|
||||
const characters = splitTextToChars(joinedContent);
|
||||
return characters.length <= width;
|
||||
};
|
||||
};
|
||||
|
@ -22,7 +22,7 @@ export function splitLineToWords(text: string): string[] {
|
||||
// Split by ' ' removes the ' 's from the result.
|
||||
const words = text.split(' ');
|
||||
// Add the ' 's back to the result.
|
||||
const wordsWithSpaces = words.flatMap((s) => [s, ' ']);
|
||||
const wordsWithSpaces = words.flatMap((s) => [s, ' ']).filter((s) => s);
|
||||
// Remove last space.
|
||||
wordsWithSpaces.pop();
|
||||
return wordsWithSpaces;
|
||||
|
Loading…
x
Reference in New Issue
Block a user