summaryrefslogtreecommitdiff
path: root/packages/integrations/markdoc/test
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
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')
-rw-r--r--packages/integrations/markdoc/test/fixtures/headings-custom/astro.config.mjs7
-rw-r--r--packages/integrations/markdoc/test/fixtures/headings-custom/markdoc.config.mjs11
-rw-r--r--packages/integrations/markdoc/test/fixtures/headings-custom/package.json9
-rw-r--r--packages/integrations/markdoc/test/fixtures/headings-custom/src/components/Heading.astro14
-rw-r--r--packages/integrations/markdoc/test/fixtures/headings-custom/src/content/docs/headings.mdoc11
-rw-r--r--packages/integrations/markdoc/test/fixtures/headings-custom/src/pages/index.astro28
-rw-r--r--packages/integrations/markdoc/test/fixtures/headings/astro.config.mjs7
-rw-r--r--packages/integrations/markdoc/test/fixtures/headings/markdoc.config.mjs3
-rw-r--r--packages/integrations/markdoc/test/fixtures/headings/package.json9
-rw-r--r--packages/integrations/markdoc/test/fixtures/headings/src/content/docs/headings.mdoc11
-rw-r--r--packages/integrations/markdoc/test/fixtures/headings/src/pages/index.astro28
-rw-r--r--packages/integrations/markdoc/test/headings.test.js192
12 files changed, 330 insertions, 0 deletions
diff --git a/packages/integrations/markdoc/test/fixtures/headings-custom/astro.config.mjs b/packages/integrations/markdoc/test/fixtures/headings-custom/astro.config.mjs
new file mode 100644
index 000000000..29d846359
--- /dev/null
+++ b/packages/integrations/markdoc/test/fixtures/headings-custom/astro.config.mjs
@@ -0,0 +1,7 @@
+import { defineConfig } from 'astro/config';
+import markdoc from '@astrojs/markdoc';
+
+// https://astro.build/config
+export default defineConfig({
+ integrations: [markdoc()],
+});
diff --git a/packages/integrations/markdoc/test/fixtures/headings-custom/markdoc.config.mjs b/packages/integrations/markdoc/test/fixtures/headings-custom/markdoc.config.mjs
new file mode 100644
index 000000000..32fcf61e2
--- /dev/null
+++ b/packages/integrations/markdoc/test/fixtures/headings-custom/markdoc.config.mjs
@@ -0,0 +1,11 @@
+import { defineMarkdocConfig, nodes } from '@astrojs/markdoc/config';
+import Heading from './src/components/Heading.astro';
+
+export default defineMarkdocConfig({
+ nodes: {
+ heading: {
+ ...nodes.heading,
+ render: Heading,
+ }
+ }
+});
diff --git a/packages/integrations/markdoc/test/fixtures/headings-custom/package.json b/packages/integrations/markdoc/test/fixtures/headings-custom/package.json
new file mode 100644
index 000000000..67a974912
--- /dev/null
+++ b/packages/integrations/markdoc/test/fixtures/headings-custom/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "@test/headings-custom",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "@astrojs/markdoc": "workspace:*",
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/integrations/markdoc/test/fixtures/headings-custom/src/components/Heading.astro b/packages/integrations/markdoc/test/fixtures/headings-custom/src/components/Heading.astro
new file mode 100644
index 000000000..ec6fa8305
--- /dev/null
+++ b/packages/integrations/markdoc/test/fixtures/headings-custom/src/components/Heading.astro
@@ -0,0 +1,14 @@
+---
+type Props = {
+ level: number;
+ id: string;
+};
+
+const { level, id }: Props = Astro.props;
+
+const Tag = `h${level}`;
+---
+
+<Tag data-custom-heading {id}>
+ <slot />
+</Tag>
diff --git a/packages/integrations/markdoc/test/fixtures/headings-custom/src/content/docs/headings.mdoc b/packages/integrations/markdoc/test/fixtures/headings-custom/src/content/docs/headings.mdoc
new file mode 100644
index 000000000..3eb66580a
--- /dev/null
+++ b/packages/integrations/markdoc/test/fixtures/headings-custom/src/content/docs/headings.mdoc
@@ -0,0 +1,11 @@
+# Level 1 heading
+
+## Level **2 heading**
+
+### Level _3 heading_
+
+#### Level [4 heading](/with-a-link)
+
+##### Level 5 heading with override {% #id-override %}
+
+###### Level 6 heading
diff --git a/packages/integrations/markdoc/test/fixtures/headings-custom/src/pages/index.astro b/packages/integrations/markdoc/test/fixtures/headings-custom/src/pages/index.astro
new file mode 100644
index 000000000..5880be0e3
--- /dev/null
+++ b/packages/integrations/markdoc/test/fixtures/headings-custom/src/pages/index.astro
@@ -0,0 +1,28 @@
+---
+import { getEntryBySlug } from "astro:content";
+
+const post = await getEntryBySlug('docs', 'headings');
+const { Content, headings } = await post.render();
+---
+
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Content</title>
+</head>
+<body>
+ <nav data-toc>
+ <ul>
+ {headings.map(heading => (
+ <li>
+ <a href={`#${heading.slug}`} data-depth={heading.depth}>{heading.text}</a>
+ </li>
+ ))}
+ </ul>
+ </nav>
+ <Content />
+</body>
+</html>
diff --git a/packages/integrations/markdoc/test/fixtures/headings/astro.config.mjs b/packages/integrations/markdoc/test/fixtures/headings/astro.config.mjs
new file mode 100644
index 000000000..29d846359
--- /dev/null
+++ b/packages/integrations/markdoc/test/fixtures/headings/astro.config.mjs
@@ -0,0 +1,7 @@
+import { defineConfig } from 'astro/config';
+import markdoc from '@astrojs/markdoc';
+
+// https://astro.build/config
+export default defineConfig({
+ integrations: [markdoc()],
+});
diff --git a/packages/integrations/markdoc/test/fixtures/headings/markdoc.config.mjs b/packages/integrations/markdoc/test/fixtures/headings/markdoc.config.mjs
new file mode 100644
index 000000000..a5863ec12
--- /dev/null
+++ b/packages/integrations/markdoc/test/fixtures/headings/markdoc.config.mjs
@@ -0,0 +1,3 @@
+import { defineMarkdocConfig } from '@astrojs/markdoc/config';
+
+export default defineMarkdocConfig({});
diff --git a/packages/integrations/markdoc/test/fixtures/headings/package.json b/packages/integrations/markdoc/test/fixtures/headings/package.json
new file mode 100644
index 000000000..1daaae400
--- /dev/null
+++ b/packages/integrations/markdoc/test/fixtures/headings/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "@test/headings",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "@astrojs/markdoc": "workspace:*",
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/integrations/markdoc/test/fixtures/headings/src/content/docs/headings.mdoc b/packages/integrations/markdoc/test/fixtures/headings/src/content/docs/headings.mdoc
new file mode 100644
index 000000000..3eb66580a
--- /dev/null
+++ b/packages/integrations/markdoc/test/fixtures/headings/src/content/docs/headings.mdoc
@@ -0,0 +1,11 @@
+# Level 1 heading
+
+## Level **2 heading**
+
+### Level _3 heading_
+
+#### Level [4 heading](/with-a-link)
+
+##### Level 5 heading with override {% #id-override %}
+
+###### Level 6 heading
diff --git a/packages/integrations/markdoc/test/fixtures/headings/src/pages/index.astro b/packages/integrations/markdoc/test/fixtures/headings/src/pages/index.astro
new file mode 100644
index 000000000..5880be0e3
--- /dev/null
+++ b/packages/integrations/markdoc/test/fixtures/headings/src/pages/index.astro
@@ -0,0 +1,28 @@
+---
+import { getEntryBySlug } from "astro:content";
+
+const post = await getEntryBySlug('docs', 'headings');
+const { Content, headings } = await post.render();
+---
+
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Content</title>
+</head>
+<body>
+ <nav data-toc>
+ <ul>
+ {headings.map(heading => (
+ <li>
+ <a href={`#${heading.slug}`} data-depth={heading.depth}>{heading.text}</a>
+ </li>
+ ))}
+ </ul>
+ </nav>
+ <Content />
+</body>
+</html>
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;
+ }
+}