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