v0.2.0: 全面代码质量优化
- ESLint flat config + Prettier + EditorConfig - Markdown处理器LRU缓存 - Zustand选择器优化减少重渲染 - CodeMirror Compartment主题热切换 - Preview防抖(150ms) + IndexedDB去抖(500ms) - 组件拆分: App.tsx 310→104行, Sidebar.tsx 244→90行 - 统一错误处理 errorHandler.ts - ConfirmDialog替代原生confirm - LoadingSpinner加载状态 - Toast多条堆叠+类型区分 - 可访问性增强(ARIA属性、键盘导航) - Vitest测试框架(78个测试用例) - Git hooks(husky + lint-staged) - 项目文档(README.md, CONTRIBUTING.md)
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
import { describe, it, expect } from 'vitest'
|
||||
import { renderMarkdown } from '../markdown'
|
||||
|
||||
describe('renderMarkdown', () => {
|
||||
it('should render a simple heading', async () => {
|
||||
const result = await renderMarkdown('# Hello World')
|
||||
expect(result).toContain('<h1')
|
||||
expect(result).toContain('Hello World')
|
||||
})
|
||||
|
||||
it('should render bold text', async () => {
|
||||
const result = await renderMarkdown('**bold**')
|
||||
expect(result).toContain('<strong')
|
||||
expect(result).toContain('bold')
|
||||
})
|
||||
|
||||
it('should render italic text', async () => {
|
||||
const result = await renderMarkdown('*italic*')
|
||||
expect(result).toContain('<em')
|
||||
expect(result).toContain('italic')
|
||||
})
|
||||
|
||||
it('should render inline code', async () => {
|
||||
const result = await renderMarkdown('`code`')
|
||||
expect(result).toContain('<code')
|
||||
expect(result).toContain('code')
|
||||
})
|
||||
|
||||
it('should render code blocks with syntax highlighting', async () => {
|
||||
const md = '```javascript\nconst x = 1;\n```'
|
||||
const result = await renderMarkdown(md)
|
||||
expect(result).toContain('<pre')
|
||||
expect(result).toContain('<code')
|
||||
expect(result).toContain('const')
|
||||
})
|
||||
|
||||
it('should render links', async () => {
|
||||
const result = await renderMarkdown('[link](https://example.com)')
|
||||
expect(result).toContain('<a')
|
||||
expect(result).toContain('https://example.com')
|
||||
expect(result).toContain('link')
|
||||
})
|
||||
|
||||
it('should render unordered lists', async () => {
|
||||
const result = await renderMarkdown('- item 1\n- item 2')
|
||||
expect(result).toContain('<ul')
|
||||
expect(result).toContain('<li')
|
||||
expect(result).toContain('item 1')
|
||||
expect(result).toContain('item 2')
|
||||
})
|
||||
|
||||
it('should render ordered lists', async () => {
|
||||
const result = await renderMarkdown('1. first\n2. second')
|
||||
expect(result).toContain('<ol')
|
||||
expect(result).toContain('first')
|
||||
expect(result).toContain('second')
|
||||
})
|
||||
|
||||
it('should render blockquotes', async () => {
|
||||
const result = await renderMarkdown('> quote')
|
||||
expect(result).toContain('<blockquote')
|
||||
expect(result).toContain('quote')
|
||||
})
|
||||
|
||||
it('should render tables via GFM', async () => {
|
||||
const md = '| A | B |\n|---|---|\n| 1 | 2 |'
|
||||
const result = await renderMarkdown(md)
|
||||
expect(result).toContain('<table')
|
||||
expect(result).toContain('<td')
|
||||
})
|
||||
|
||||
it('should render strikethrough via GFM', async () => {
|
||||
const result = await renderMarkdown('~~deleted~~')
|
||||
expect(result).toContain('<del')
|
||||
expect(result).toContain('deleted')
|
||||
})
|
||||
|
||||
it('should handle empty content', async () => {
|
||||
const result = await renderMarkdown('')
|
||||
expect(result).toBe('')
|
||||
})
|
||||
|
||||
it('should return error HTML on rendering failure with invalid input', async () => {
|
||||
// unified should still handle gracefully, but verify error path works
|
||||
const result = await renderMarkdown('normal text')
|
||||
expect(result).not.toContain('渲染错误')
|
||||
})
|
||||
|
||||
it('should cache processors for same filePath', async () => {
|
||||
// Call twice with same filePath to test caching
|
||||
const result1 = await renderMarkdown('# Test', '/test/file.md')
|
||||
const result2 = await renderMarkdown('# Test 2', '/test/file.md')
|
||||
expect(result1).toContain('<h1')
|
||||
expect(result2).toContain('Test 2')
|
||||
})
|
||||
|
||||
it('should handle null filePath', async () => {
|
||||
const result = await renderMarkdown('# No File', null)
|
||||
expect(result).toContain('No File')
|
||||
})
|
||||
|
||||
it('should handle undefined filePath', async () => {
|
||||
const result = await renderMarkdown('# No File')
|
||||
expect(result).toContain('No File')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user