1import u from 'unist-builder';
2
3import exportHeadings from './remark-export-headings';
4
5describe('exports constant', () => {
6  it('when no headers are found', () => {
7    const { data } = transform(u('root', [u('text', 'lorem ipsum')]));
8    expect(data).not.toBeNull();
9    expect(data).toHaveLength(0);
10  });
11
12  it('when single header is found', () => {
13    const { data } = transform(u('root', [u('heading', [u('text', 'lorem ipsum')])]));
14    expect(data).toHaveLength(1);
15  });
16
17  it('when multiple headers are found', () => {
18    const { data } = transform(
19      u('root', [u('heading', [u('text', 'lorem ipsum')]), u('heading', [u('text', 'sit amet')])])
20    );
21    expect(data).toHaveLength(2);
22  });
23});
24
25describe('header object', () => {
26  it('has title from text child', () => {
27    const { data } = transform(u('root', [u('heading', [u('text', 'header title')])]));
28    expect(data[0]).toHaveProperty('title', 'header title');
29  });
30
31  it('has title from multiple text children', () => {
32    const { data } = transform(
33      u('root', [u('heading', [u('text', 'header'), u('text', 'title')])])
34    );
35    expect(data[0]).toHaveProperty('title', 'header title');
36  });
37
38  it('has depth from heading', () => {
39    const { data } = transform(u('root', [u('heading', { depth: 3 }, [u('text', 'title')])]));
40    expect(data[0]).toHaveProperty('depth', 3);
41  });
42
43  it('has id when defined as data', () => {
44    const { data } = transform(
45      u('root', [u('heading', { data: { id: 'title' } }, [u('text', 'title')])])
46    );
47    expect(data[0]).toHaveProperty('id', 'title');
48  });
49
50  it('has text type from text children', () => {
51    const { data } = transform(
52      u('root', [u('heading', [u('text', 'hello there'), u('text', 'general kenobi')])])
53    );
54    expect(data[0]).toHaveProperty('type', 'text');
55  });
56
57  it('has inlineCode type from mixed children', () => {
58    const { data } = transform(
59      u('root', [u('heading', [u('text', 'hello there'), u('inlineCode', 'general kenobi')])])
60    );
61    expect(data[0]).toHaveProperty('type', 'inlineCode');
62  });
63});
64
65/**
66 * Helper function to run the MDAST transform, and find the added node.
67 *
68 * @param {import('mdast').Root} tree
69 * @param {object} [options]
70 * @param {string} [options.exportName]
71 */
72function transform(tree, options = {}) {
73  exportHeadings(options)(tree);
74
75  const value = `export const ${options.exportName || 'headings'} = `;
76  const node = tree.children
77    .reverse()
78    .find(node => node.type === 'export' && node.value.startsWith(value));
79
80  const json = node ? node.value.replace(value, '').replace(/;$/, '') : null;
81  const data = json ? JSON.parse(json) : null;
82
83  return { node, json, data };
84}
85