1import { u } from 'unist-builder';
2
3import exportHeadings from './remark-export-headings.js';
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(getNodeByKey(data, 'title')).toHaveProperty('value', '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(getNodeByKey(data, 'title')).toHaveProperty('value', '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(getNodeByKey(data, 'depth')).toHaveProperty('value', 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(getNodeByKey(data, 'id')).toHaveProperty('value', '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(getNodeByKey(data, 'type')).toHaveProperty('value', '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(getNodeByKey(data, 'type')).toHaveProperty('value', '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 */
71function transform(tree, options = {}) {
72  exportHeadings(options)(tree);
73
74  const data = tree.children.find(node => node.type === 'mdxjsEsm').data.estree.body[0].declaration
75    .declarations[0].init.elements;
76
77  return { data };
78}
79
80function getNodeByKey(data, content) {
81  return data[0].properties.find(property => property?.key?.value?.includes(content))?.value;
82}
83