summaryrefslogtreecommitdiff
path: root/packages/integrations/markdoc/test/headings.test.js
diff options
context:
space:
mode:
authorGravatar Ben Holmes <hey@bholmes.dev> 2023-05-17 09:13:10 -0400
committerGravatar GitHub <noreply@github.com> 2023-05-17 09:13:10 -0400
commitfb84622af04f795de8d17f24192de105f70fe910 (patch)
tree11a99efdb90c17207d3adc1095e88fa8daddd7e4 /packages/integrations/markdoc/test/headings.test.js
parentc91e837e961043e92253148f0f4291856653b993 (diff)
downloadastro-fb84622af04f795de8d17f24192de105f70fe910.tar.gz
astro-fb84622af04f795de8d17f24192de105f70fe910.tar.zst
astro-fb84622af04f795de8d17f24192de105f70fe910.zip
[Markdoc] `headings` and heading IDs (#7095)
* deps: markdown-remark * wip: heading-ids function * chore: add `@astrojs/markdoc` to external * feat: `headings` support * fix: allow `render` config on headings * fix: nonexistent `userConfig` * test: headings, toc, astro component render * docs: README * chore: changeset * refactor: expose Markdoc helpers from runtime * fix: bad named exports (commonjsssss) * refactor: defaultNodes -> nodes * deps: github-slugger * fix: reset slugger cache on each render * fix: bad astroNodes import * docs: explain headingSlugger export * docs: add back double stringify comment * chore: bump to minor for internal exports change
Diffstat (limited to 'packages/integrations/markdoc/test/headings.test.js')
-rw-r--r--packages/integrations/markdoc/test/headings.test.js192
1 files changed, 192 insertions, 0 deletions
diff --git a/packages/integrations/markdoc/test/headings.test.js b/packages/integrations/markdoc/test/headings.test.js
new file mode 100644
index 000000000..5db50065c
--- /dev/null
+++ b/packages/integrations/markdoc/test/headings.test.js
@@ -0,0 +1,192 @@
+import { parseHTML } from 'linkedom';
+import { expect } from 'chai';
+import { loadFixture } from '../../../astro/test/test-utils.js';
+
+async function getFixture(name) {
+ return await loadFixture({
+ root: new URL(`./fixtures/${name}/`, import.meta.url),
+ });
+}
+
+describe('Markdoc - Headings', () => {
+ let fixture;
+
+ before(async () => {
+ fixture = await getFixture('headings');
+ });
+
+ describe('dev', () => {
+ let devServer;
+
+ before(async () => {
+ devServer = await fixture.startDevServer();
+ });
+
+ after(async () => {
+ await devServer.stop();
+ });
+
+ it('applies IDs to headings', async () => {
+ const res = await fixture.fetch('/');
+ const html = await res.text();
+ const { document } = parseHTML(html);
+
+ idTest(document);
+ });
+
+ it('generates a TOC with correct info', async () => {
+ const res = await fixture.fetch('/');
+ const html = await res.text();
+ const { document } = parseHTML(html);
+
+ tocTest(document);
+ });
+ });
+
+ describe('build', () => {
+ before(async () => {
+ await fixture.build();
+ });
+
+ it('applies IDs to headings', async () => {
+ const html = await fixture.readFile('/index.html');
+ const { document } = parseHTML(html);
+
+ idTest(document);
+ });
+
+ it('generates a TOC with correct info', async () => {
+ const html = await fixture.readFile('/index.html');
+ const { document } = parseHTML(html);
+
+ tocTest(document);
+ });
+ });
+});
+
+describe('Markdoc - Headings with custom Astro renderer', () => {
+ let fixture;
+
+ before(async () => {
+ fixture = await getFixture('headings-custom');
+ });
+
+ describe('dev', () => {
+ let devServer;
+
+ before(async () => {
+ devServer = await fixture.startDevServer();
+ });
+
+ after(async () => {
+ await devServer.stop();
+ });
+
+ it('applies IDs to headings', async () => {
+ const res = await fixture.fetch('/');
+ const html = await res.text();
+ const { document } = parseHTML(html);
+
+ idTest(document);
+ });
+
+ it('generates a TOC with correct info', async () => {
+ const res = await fixture.fetch('/');
+ const html = await res.text();
+ const { document } = parseHTML(html);
+
+ tocTest(document);
+ });
+
+ it('renders Astro component for each heading', async () => {
+ const res = await fixture.fetch('/');
+ const html = await res.text();
+ const { document } = parseHTML(html);
+
+ astroComponentTest(document);
+ });
+ });
+
+ describe('build', () => {
+ before(async () => {
+ await fixture.build();
+ });
+
+ it('applies IDs to headings', async () => {
+ const html = await fixture.readFile('/index.html');
+ const { document } = parseHTML(html);
+
+ idTest(document);
+ });
+
+ it('generates a TOC with correct info', async () => {
+ const html = await fixture.readFile('/index.html');
+ const { document } = parseHTML(html);
+
+ tocTest(document);
+ });
+
+ it('renders Astro component for each heading', async () => {
+ const html = await fixture.readFile('/index.html');
+ const { document } = parseHTML(html);
+
+ astroComponentTest(document);
+ });
+ });
+});
+
+const depthToHeadingMap = {
+ 1: {
+ slug: 'level-1-heading',
+ text: 'Level 1 heading',
+ },
+ 2: {
+ slug: 'level-2-heading',
+ text: 'Level 2 heading',
+ },
+ 3: {
+ slug: 'level-3-heading',
+ text: 'Level 3 heading',
+ },
+ 4: {
+ slug: 'level-4-heading',
+ text: 'Level 4 heading',
+ },
+ 5: {
+ slug: 'id-override',
+ text: 'Level 5 heading with override',
+ },
+ 6: {
+ slug: 'level-6-heading',
+ text: 'Level 6 heading',
+ },
+};
+
+/** @param {Document} document */
+function idTest(document) {
+ for (const [depth, info] of Object.entries(depthToHeadingMap)) {
+ expect(document.querySelector(`h${depth}`)?.getAttribute('id')).to.equal(info.slug);
+ }
+}
+
+/** @param {Document} document */
+function tocTest(document) {
+ const toc = document.querySelector('[data-toc] > ul');
+ expect(toc.children).to.have.lengthOf(Object.keys(depthToHeadingMap).length);
+
+ for (const [depth, info] of Object.entries(depthToHeadingMap)) {
+ const linkEl = toc.querySelector(`a[href="#${info.slug}"]`);
+ expect(linkEl).to.exist;
+ expect(linkEl.getAttribute('data-depth')).to.equal(depth);
+ expect(linkEl.textContent.trim()).to.equal(info.text);
+ }
+}
+
+/** @param {Document} document */
+function astroComponentTest(document) {
+ const headings = document.querySelectorAll('h1, h2, h3, h4, h5, h6');
+
+ for (const heading of headings) {
+ expect(heading.hasAttribute('data-custom-heading')).to.be.true;
+ }
+}