Skip to content

Commit cff935e

Browse files
committed
chore: add unit tests for getQuickFormatList
1 parent bb714f1 commit cff935e

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import { describe, it, expect } from 'vitest';
2+
import { getQuickFormatList } from './helpers.js';
3+
4+
describe('getQuickFormatList', () => {
5+
it('returns [] when editor is missing', () => {
6+
expect(getQuickFormatList(undefined)).toEqual([]);
7+
expect(getQuickFormatList(null)).toEqual([]);
8+
expect(getQuickFormatList({})).toEqual([]);
9+
expect(getQuickFormatList({ converter: {} })).toEqual([]);
10+
expect(getQuickFormatList({ converter: { linkedStyles: null } })).toEqual([]);
11+
});
12+
13+
it('returns [] when linkedStyles is empty', () => {
14+
const editor = { converter: { linkedStyles: [] } };
15+
expect(getQuickFormatList(editor)).toEqual([]);
16+
});
17+
18+
it('filters to paragraph styles with definition.attrs present', () => {
19+
const editor = {
20+
converter: {
21+
linkedStyles: [
22+
// kept: paragraph + attrs
23+
{ type: 'paragraph', definition: { attrs: { name: 'Para A', foo: 1 } } },
24+
// dropped: not paragraph
25+
{ type: 'heading', definition: { attrs: { name: 'Heading 1' } } },
26+
// dropped: paragraph without attrs
27+
{ type: 'paragraph', definition: {} },
28+
// dropped: paragraph with no definition
29+
{ type: 'paragraph' },
30+
],
31+
},
32+
};
33+
34+
const out = getQuickFormatList(editor);
35+
expect(out).toHaveLength(1);
36+
expect(out[0].definition.attrs.name).toBe('Para A');
37+
});
38+
39+
it('sorts by attrs.name (undefined treated as empty string)', () => {
40+
const editor = {
41+
converter: {
42+
linkedStyles: [
43+
// name undefined -> treated as ''
44+
{ type: 'paragraph', definition: { attrs: {} } },
45+
{ type: 'paragraph', definition: { attrs: { name: 'Zebra' } } },
46+
{ type: 'paragraph', definition: { attrs: { name: 'alpha' } } },
47+
{ type: 'paragraph', definition: { attrs: { name: 'Beta' } } },
48+
// non-paragraph should be ignored regardless of name
49+
{ type: 'heading', definition: { attrs: { name: 'AAA' } } },
50+
],
51+
},
52+
};
53+
54+
const out = getQuickFormatList(editor);
55+
const names = out.map((s) => s.definition.attrs.name ?? '');
56+
// Expect empty-string entry first, then ascending by localeCompare
57+
expect(names[0]).toBe(''); // the undefined-name entry
58+
// The rest should be sorted lexicographically per localeCompare
59+
expect(names.slice(1)).toEqual([...names.slice(1)].sort((a, b) => a.localeCompare(b)));
60+
});
61+
62+
it('does not throw if some items lack definition entirely (they are filtered out)', () => {
63+
const editor = {
64+
converter: {
65+
linkedStyles: [
66+
{ type: 'paragraph' },
67+
{ type: 'paragraph', definition: null },
68+
{ type: 'paragraph', definition: { attrs: { name: 'Keep me' } } },
69+
],
70+
},
71+
};
72+
73+
const out = getQuickFormatList(editor);
74+
expect(out).toHaveLength(1);
75+
expect(out[0].definition.attrs.name).toBe('Keep me');
76+
});
77+
78+
it('does not mutate the original linkedStyles array', () => {
79+
const linkedStyles = [
80+
{ type: 'paragraph', definition: { attrs: { name: 'B' } } },
81+
{ type: 'paragraph', definition: { attrs: { name: 'A' } } },
82+
];
83+
const editor = { converter: { linkedStyles } };
84+
85+
const before = JSON.stringify(linkedStyles);
86+
const out = getQuickFormatList(editor);
87+
88+
expect(out.map((s) => s.definition.attrs.name)).toEqual(['A', 'B']); // sorted
89+
expect(JSON.stringify(linkedStyles)).toBe(before); // original unchanged
90+
});
91+
});

0 commit comments

Comments
 (0)