411c6d84a2
Persist /model tier choice to ~/.local/share/flynn/preferences.json so it survives restarts. Decode HTML entities (e.g. ') in markdown renderer output. Suppress noisy logger.info and punycode deprecation warnings in TUI startup. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
119 lines
4.0 KiB
TypeScript
119 lines
4.0 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { renderMarkdown } from './markdown.js';
|
|
|
|
describe('renderMarkdown', () => {
|
|
it('renders plain text unchanged', () => {
|
|
const result = renderMarkdown('Hello world');
|
|
expect(result).toContain('Hello world');
|
|
});
|
|
|
|
it('renders bold text with ANSI bold code', () => {
|
|
const result = renderMarkdown('This is **bold** text');
|
|
expect(result).toContain('\x1b[1m');
|
|
expect(result).toContain('bold');
|
|
expect(result).toContain('\x1b[0m');
|
|
});
|
|
|
|
it('renders italic text with ANSI italic code', () => {
|
|
const result = renderMarkdown('This is *italic* text');
|
|
expect(result).toContain('\x1b[3m');
|
|
expect(result).toContain('italic');
|
|
expect(result).toContain('\x1b[0m');
|
|
});
|
|
|
|
it('renders inline code with ANSI cyan code', () => {
|
|
const result = renderMarkdown('Use `console.log()` for debugging');
|
|
expect(result).toContain('\x1b[36m');
|
|
expect(result).toContain('console.log()');
|
|
expect(result).toContain('\x1b[0m');
|
|
});
|
|
|
|
it('renders headings with bold + underline', () => {
|
|
const result = renderMarkdown('# My Heading');
|
|
expect(result).toContain('\x1b[1m\x1b[4m');
|
|
expect(result).toContain('My Heading');
|
|
expect(result).toContain('\x1b[0m');
|
|
});
|
|
|
|
it('renders heading with inline formatting', () => {
|
|
const result = renderMarkdown('## A **bold** heading');
|
|
expect(result).toContain('\x1b[1m');
|
|
expect(result).toContain('bold');
|
|
});
|
|
|
|
it('renders code blocks', () => {
|
|
const result = renderMarkdown('```javascript\nconst x = 1;\n```');
|
|
expect(result).toContain('const');
|
|
expect(result).toContain('x');
|
|
});
|
|
|
|
it('renders code blocks with unknown language without crashing', () => {
|
|
const result = renderMarkdown('```madeuplang\nsome code\n```');
|
|
expect(result).toContain('some code');
|
|
});
|
|
|
|
it('renders unordered lists', () => {
|
|
const result = renderMarkdown('- Item 1\n- Item 2');
|
|
expect(result).toContain('•');
|
|
expect(result).toContain('Item 1');
|
|
expect(result).toContain('Item 2');
|
|
});
|
|
|
|
it('renders inline formatting inside list items', () => {
|
|
const result = renderMarkdown('- **bold** item\n- `code` item');
|
|
expect(result).toContain('\x1b[1m');
|
|
expect(result).toContain('bold');
|
|
expect(result).toContain('\x1b[36m');
|
|
expect(result).toContain('code');
|
|
});
|
|
|
|
it('renders blockquotes with │ prefix', () => {
|
|
const result = renderMarkdown('> This is a quote');
|
|
expect(result).toContain('│');
|
|
expect(result).toContain('This is a quote');
|
|
});
|
|
|
|
it('renders inline formatting inside blockquotes', () => {
|
|
const result = renderMarkdown('> A **bold** quote');
|
|
expect(result).toContain('│');
|
|
expect(result).toContain('\x1b[1m');
|
|
expect(result).toContain('bold');
|
|
});
|
|
|
|
it('renders tables with │ separator', () => {
|
|
const result = renderMarkdown('| Col A | Col B |\n|-------|-------|\n| 1 | 2 |\n| 3 | 4 |');
|
|
expect(result).toContain('│');
|
|
expect(result).toContain('Col A');
|
|
expect(result).toContain('Col B');
|
|
expect(result).toContain('1');
|
|
expect(result).toContain('4');
|
|
});
|
|
|
|
it('renders table headers in bold', () => {
|
|
const result = renderMarkdown('| Name | Value |\n|------|-------|\n| a | b |');
|
|
// Header cells should have bold ANSI
|
|
const lines = result.split('\n');
|
|
const headerLine = lines[0];
|
|
expect(headerLine).toContain('\x1b[1m');
|
|
});
|
|
|
|
it('renders horizontal rules', () => {
|
|
const result = renderMarkdown('---');
|
|
expect(result).toContain('─');
|
|
});
|
|
|
|
it('renders links with underline and blue URL', () => {
|
|
const result = renderMarkdown('[click here](https://example.com)');
|
|
expect(result).toContain('\x1b[4m');
|
|
expect(result).toContain('click here');
|
|
expect(result).toContain('\x1b[34m');
|
|
expect(result).toContain('https://example.com');
|
|
});
|
|
|
|
it('decodes HTML entities like apostrophes', () => {
|
|
const result = renderMarkdown("I'm here. What's up?");
|
|
expect(result).toContain("I'm here");
|
|
expect(result).not.toContain(''');
|
|
});
|
|
});
|