-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
372fe5f
commit 8c1cafc
Showing
5 changed files
with
311 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import addTableOfContents from '../src/plugins/addTableOfContents.js'; | ||
|
||
describe("addTableOfContents functionality", () => { | ||
it('generates a table of contents from headings', () => { | ||
const mockTree = { | ||
type: 'root', | ||
children: [ | ||
{ type: 'element', tagName: 'h1', properties: {}, children: [{ type: 'text', value: 'Heading 1' }] }, | ||
{ type: 'element', tagName: 'h2', properties: {}, children: [{ type: 'text', value: 'Heading 2' }] }, | ||
{ type: 'element', tagName: 'h3', properties: {}, children: [{ type: 'text', value: 'Heading 3' }] }, | ||
], | ||
}; | ||
|
||
const tocNode = addTableOfContents(mockTree, false); | ||
expect(tocNode).not.toBeNull(); | ||
expect(tocNode.tagName).toBe('ul'); | ||
expect(tocNode.children.length).toBe(3); | ||
}); | ||
|
||
it('inserts the table of contents into the tree', () => { | ||
const mockTree = { | ||
type: 'root', | ||
children: [ | ||
{ type: 'element', tagName: 'h1', properties: {}, children: [{ type: 'text', value: 'Heading 1' }] }, | ||
{ type: 'element', tagName: 'h2', properties: {}, children: [{ type: 'text', value: 'Heading 2' }] }, | ||
], | ||
}; | ||
|
||
addTableOfContents(mockTree, true); | ||
expect(mockTree.children[0].tagName).toBe('ul'); | ||
}); | ||
|
||
it('does not generate a table of contents for documents without headings', () => { | ||
const mockTree = { | ||
type: 'root', | ||
children: [ | ||
{ type: 'element', tagName: 'p', properties: {}, children: [{ type: 'text', value: 'Paragraph text' }] }, | ||
], | ||
}; | ||
|
||
const tocNode = addTableOfContents(mockTree, false); | ||
expect(tocNode).not.toBeNull(); | ||
expect(tocNode.children.length).toBe(0); | ||
}); | ||
|
||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import { fileURLToPath } from 'url'; | ||
import { dirname, join } from 'path'; | ||
|
||
const __filename = fileURLToPath(import.meta.url); | ||
const __dirname = dirname(__filename); | ||
|
||
describe('Build Exports', () => { | ||
it('should export processMarkdown for both CommonJS and ESM builds', async () => { | ||
const cjsBuild = await import(join(__dirname, '../dist/index.cjs')); | ||
const esmBuild = await import(join(__dirname, '../dist/index.esm.js')); | ||
|
||
expect(cjsBuild).toBeDefined(); | ||
expect(typeof cjsBuild.processMarkdown).toBe('function'); | ||
|
||
expect(esmBuild).toBeDefined(); | ||
expect(typeof esmBuild.processMarkdown).toBe('function'); | ||
}); | ||
|
||
it('should export addHeadingIds for both CommonJS and ESM builds', async () => { | ||
const cjsBuild = await import(join(__dirname, '../dist/index.cjs')); | ||
const esmBuild = await import(join(__dirname, '../dist/index.esm.js')); | ||
|
||
expect(cjsBuild).toBeDefined(); | ||
expect(typeof cjsBuild.addHeadingIds).toBe('function'); | ||
|
||
expect(esmBuild).toBeDefined(); | ||
expect(typeof esmBuild.addHeadingIds).toBe('function'); | ||
}); | ||
|
||
it('should export addTableOfContents for both CommonJS and ESM builds', async () => { | ||
const cjsBuild = await import(join(__dirname, '../dist/index.cjs')); | ||
const esmBuild = await import(join(__dirname, '../dist/index.esm.js')); | ||
|
||
expect(cjsBuild).toBeDefined(); | ||
expect(typeof cjsBuild.addTableOfContents).toBe('function'); | ||
|
||
expect(esmBuild).toBeDefined(); | ||
expect(typeof esmBuild.addTableOfContents).toBe('function'); | ||
}); | ||
|
||
it('should export calculateReadingTime for both CommonJS and ESM builds', async () => { | ||
const cjsBuild = await import(join(__dirname, '../dist/index.cjs')); | ||
const esmBuild = await import(join(__dirname, '../dist/index.esm.js')); | ||
|
||
expect(cjsBuild).toBeDefined(); | ||
expect(typeof cjsBuild.calculateReadingTime).toBe('function'); | ||
|
||
expect(esmBuild).toBeDefined(); | ||
expect(typeof esmBuild.calculateReadingTime).toBe('function'); | ||
}); | ||
|
||
it('should export embed for both CommonJS and ESM builds', async () => { | ||
const cjsBuild = await import(join(__dirname, '../dist/index.cjs')); | ||
const esmBuild = await import(join(__dirname, '../dist/index.esm.js')); | ||
|
||
expect(cjsBuild).toBeDefined(); | ||
expect(typeof cjsBuild.embed).toBe('function'); | ||
|
||
expect(esmBuild).toBeDefined(); | ||
expect(typeof esmBuild.embed).toBe('function'); | ||
}); | ||
|
||
it('should export wrapElements for both CommonJS and ESM builds', async () => { | ||
const cjsBuild = await import(join(__dirname, '../dist/index.cjs')); | ||
const esmBuild = await import(join(__dirname, '../dist/index.esm.js')); | ||
|
||
expect(cjsBuild).toBeDefined(); | ||
expect(typeof cjsBuild.wrapElements).toBe('function'); | ||
|
||
expect(esmBuild).toBeDefined(); | ||
expect(typeof esmBuild.wrapElements).toBe('function'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import calculateReadingTime from '../src/plugins/calculateReadingTime'; | ||
|
||
function generateRandomWord() { | ||
const possibleCharacters = "abcdefghijklmnopqrstuvwxyz"; | ||
const randomIndex = Math.floor(Math.random() * possibleCharacters.length); | ||
return possibleCharacters[randomIndex]; | ||
} | ||
|
||
// Assuming an average word count of 5 characters, this will generate 500 words | ||
const markdownContent = new Array(500).fill(`${generateRandomWord()} `).join(""); | ||
|
||
describe('calculateReadingTime functionality', () => { | ||
it('calculates reading time with default WPM', () => { | ||
const tree = { type: 'root', children: [{ type: 'text', value: markdownContent }] }; | ||
const readingTime = calculateReadingTime()(tree); | ||
// Default WPM is 250, so 500 words should take about 2 minutes, rounded up to 3 minutes | ||
expect(readingTime).toBe(3); | ||
}); | ||
|
||
it('calculates reading time with custom WPM', () => { | ||
const customWPM = 100; | ||
const tree = { type: 'root', children: [{ type: 'text', value: markdownContent }] }; | ||
const readingTime = calculateReadingTime({ wordsPerMinute: customWPM })(tree); | ||
// Custom WPM is 100, so 500 words should take about 5 minutes, rounded up to 6 | ||
expect(readingTime).toBe(6); | ||
}); | ||
|
||
it('handles empty content', () => { | ||
const tree = { type: 'root', children: [{ type: 'text', value: "" }] }; | ||
const readingTime = calculateReadingTime()(tree); | ||
// Why would you have an empty document? I don't know, but it gets rounded up to 1 minute. | ||
expect(readingTime).toBe(1); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import embed from "../src/plugins/embed"; | ||
|
||
describe("embed functionality", () => { | ||
it('embeds a GitHub Gist correctly', () => { | ||
const mockTree = { | ||
type: 'root', | ||
children: [ | ||
{ | ||
type: 'element', | ||
tagName: 'p', | ||
children: [ | ||
{ type: 'text', value: '!embed ' }, | ||
{ | ||
type: 'element', | ||
tagName: 'a', | ||
properties: { href: 'https://gist.github.com/user/gistid' }, | ||
children: [{ type: 'text', value: 'Gist link' }], | ||
}, | ||
], | ||
}, | ||
], | ||
}; | ||
embed()(mockTree); | ||
|
||
expect(mockTree.children[0].type).toBe('raw'); | ||
expect(mockTree.children[0].value).toContain('https://gist.github.com/user/gistid.pibb'); | ||
}); | ||
|
||
|
||
it('embeds a YouTube video correctly', () => { | ||
const mockTree = { | ||
type: 'root', | ||
children: [ | ||
{ | ||
type: 'element', | ||
tagName: 'p', | ||
children: [ | ||
{ type: 'text', value: '!embed ' }, | ||
{ | ||
type: 'element', | ||
tagName: 'a', | ||
properties: { href: 'https://www.youtube.com/watch?v=videoId' }, | ||
children: [{ type: 'text', value: 'YouTube link' }], | ||
}, | ||
], | ||
}, | ||
], | ||
}; | ||
|
||
embed()(mockTree); | ||
|
||
expect(mockTree.children[0].type).toBe('raw'); | ||
expect(mockTree.children[0].value).toContain('https://www.youtube.com/embed/videoId'); | ||
}); | ||
|
||
it('ignores unsupported embed types', () => { | ||
const mockTree = { | ||
type: 'root', | ||
children: [ | ||
{ | ||
type: 'element', | ||
tagName: 'p', | ||
children: [ | ||
{ type: 'text', value: '!embed ' }, | ||
{ | ||
type: 'element', | ||
tagName: 'a', | ||
properties: { href: 'https://unsupported.com' }, | ||
children: [{ type: 'text', value: 'Unsupported link' }], | ||
}, | ||
], | ||
}, | ||
], | ||
}; | ||
|
||
embed()(mockTree); | ||
|
||
expect(mockTree.children[0].type).not.toBe('raw'); | ||
expect(mockTree.children[0].tagName).toBe('p'); | ||
}); | ||
|
||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import wrapElements from '../src/plugins/wrapElements'; | ||
|
||
describe('wrapElements', () => { | ||
it('wraps specified elements with a div', () => { | ||
const mockTree = { | ||
type: 'root', | ||
children: [ | ||
{ type: 'element', tagName: 'img', properties: {}, children: [] }, | ||
{ type: 'element', tagName: 'table', properties: {}, children: [] }, | ||
], | ||
}; | ||
|
||
const options = { | ||
img: 'epic-remark-image', | ||
table: 'epic-remark-table', | ||
}; | ||
wrapElements(options)(mockTree); | ||
|
||
expect(mockTree.children[0].type).toBe('element'); | ||
expect(mockTree.children[0].tagName).toBe('div'); | ||
expect(mockTree.children[0].properties.className).toBe('epic-remark-image'); | ||
expect(mockTree.children[1].properties.className).toBe('epic-remark-table'); | ||
}); | ||
|
||
|
||
it('does not wrap elements if options is empty', () => { | ||
const mockTree = { | ||
type: 'root', | ||
children: [ | ||
{ type: 'element', tagName: 'img', properties: {}, children: [] }, | ||
{ type: 'element', tagName: 'table', properties: {}, children: [] }, | ||
], | ||
}; | ||
|
||
const emptyOptions = {}; | ||
wrapElements(emptyOptions)(mockTree); | ||
|
||
expect(mockTree.children[0].tagName).toBe('img'); | ||
expect(mockTree.children[1].tagName).toBe('table'); | ||
}); | ||
|
||
|
||
it('handles undefined or null node children safely', () => { | ||
const mockTree = { | ||
type: 'root', | ||
children: null, | ||
}; | ||
|
||
const options = { | ||
img: 'epic-remark-image', | ||
}; | ||
|
||
expect(() => wrapElements(options)(mockTree)).not.toThrow(); | ||
}); | ||
|
||
|
||
it('ignores non-element nodes', () => { | ||
const mockTree = { | ||
type: 'root', | ||
children: [ | ||
{ type: 'text', value: 'Just some text' }, | ||
{ type: 'element', tagName: 'img', properties: {}, children: [] }, | ||
], | ||
}; | ||
|
||
const options = { | ||
img: 'epic-remark-image', | ||
}; | ||
|
||
wrapElements(options)(mockTree); | ||
|
||
expect(mockTree.children[0].type).toBe('text'); | ||
expect(mockTree.children[1].tagName).toBe('div'); | ||
expect(mockTree.children[1].properties.className).toBe('epic-remark-image'); | ||
}); | ||
}); |