import { describe, expect, it } from 'bun:test'
import { markdownToHtml, stripMarkdown } from './markdown-to-html'
describe('markdownToHtml', () => {
it('converts bold text', () => {
expect(markdownToHtml('**bold**')).toBe('bold')
})
it('converts italic text', () => {
expect(markdownToHtml('_italic_')).toBe('italic')
})
it('does not italicize mid-word underscores', () => {
expect(markdownToHtml('some_variable_name')).toBe('some_variable_name')
})
it('converts bold and italic text', () => {
expect(markdownToHtml('***both***')).toBe('both')
})
it('converts inline code', () => {
expect(markdownToHtml('Use `code` here')).toBe('Use code here')
})
it('converts code blocks with language', () => {
expect(markdownToHtml('```ts\nconst x = 1 < 2\n```')).toBe(
'
const x = 1 < 2',
)
})
it('converts code blocks without language', () => {
expect(markdownToHtml('```\nconst x = 1 & 2\n```')).toBe('const x = 1 & 2')
})
it('does not process markdown inside code blocks', () => {
expect(markdownToHtml('```\n**bold** _italic_\n```')).toBe('**bold** _italic_')
})
it('converts links', () => {
expect(markdownToHtml('[Webex](https://example.com?a=1&b=2)')).toBe(
'Webex',
)
})
it('strips unsafe javascript: URLs to plain text', () => {
expect(markdownToHtml('[click](javascript:void)')).toBe('click')
})
it('strips unsafe data: URLs to plain text', () => {
expect(markdownToHtml('[x](data:text/html,payload)')).toBe('x')
})
it('allows mailto: links', () => {
expect(markdownToHtml('[email](mailto:a@b.com)')).toBe('email')
})
it('escapes quotes in URLs to prevent attribute breakout', () => {
expect(markdownToHtml('[x](https://a.com?q="test")')).toBe('x')
})
it('converts unordered lists', () => {
expect(markdownToHtml('- one\n- two')).toBe('one') }) it('converts headings', () => { expect(markdownToHtml('# one\n###### six')).toBe('
two
const x = 1',
)
})
it('returns empty string for empty input', () => {
expect(markdownToHtml('')).toBe('')
})
it('returns plain text when there is no markdown', () => {
expect(markdownToHtml('hello world')).toBe('hello world')
})
it('preserves whitespace-only input', () => {
expect(markdownToHtml(' ')).toBe(' ')
})
})
describe('stripMarkdown', () => {
it('strips inline markdown syntax', () => {
expect(stripMarkdown('**bold** _italic_ `code`')).toBe('bold italic code')
})
it('strips links to their labels', () => {
expect(stripMarkdown('[Webex](https://example.com)')).toBe('Webex')
})
it('strips block markdown syntax', () => {
expect(stripMarkdown('# Title\n> quote\n- item\n1. first\n---')).toBe('Title\nquote\nitem\nfirst\n')
})
it('keeps code block content', () => {
expect(stripMarkdown('```ts\nconst x = 1\n```')).toBe('const x = 1')
})
it('handles nested formatting', () => {
expect(stripMarkdown('**bold _and italic_**')).toBe('bold and italic')
})
it('returns plain text unchanged', () => {
expect(stripMarkdown('hello world')).toBe('hello world')
})
})