import { describe, it, expect } from 'vitest'; import { extractSection } from './extractSections'; import { detectActiveTabs } from './detectActiveTabs'; import { processCircuitEmbeds, processFlowchartEmbeds } from './processEmbeds'; import { parseSlides } from './parseSlides'; import { parseFlashcards } from './parseFlashcards'; import { renderMarkdownPreview } from './index'; describe('Markdown Renderer & Extractor Tests', () => { describe('extractSection', () => { it('should extract section between markers and return remaining text', () => { const input = 'Before\n---EXPECTED_OUTPUT---\nexpected content\n---END_EXPECTED_OUTPUT---\nAfter'; const [extracted, remaining] = extractSection(input, '---EXPECTED_OUTPUT---', '---END_EXPECTED_OUTPUT---'); expect(extracted).toBe('expected content'); expect(remaining).toBe('Before\n\nAfter'); }); it('should return empty string and original text if markers are not present', () => { const input = 'Some random content without markers'; const [extracted, remaining] = extractSection(input, '---START---', '---END---'); expect(extracted).toBe(''); expect(remaining).toBe(input); }); }); describe('detectActiveTabs', () => { it('should detect velxio mode exclusively if INITIAL_CODE_ARDUINO is present', () => { const input = '---INITIAL_CODE_ARDUINO---\nvoid setup() {}\n---END_INITIAL_CODE_ARDUINO---\n---INITIAL_CODE---\nint main() {}\n---END_INITIAL_CODE---'; const tabs = detectActiveTabs(input); expect(tabs).toContain('velxio'); expect(tabs).not.toContain('c'); }); it('should detect c and python tabs if present', () => { const input = '---INITIAL_CODE---\nint main() {}\n---END_INITIAL_CODE---\n---INITIAL_PYTHON---\ndef main(): pass\n---END_INITIAL_PYTHON---'; const tabs = detectActiveTabs(input); expect(tabs).toContain('c'); expect(tabs).toContain('python'); }); it('should fallback to c tab if no markers match but ---EXERCISE--- is present', () => { const input = 'Plain lesson here\n---EXERCISE---\nDo this exercise'; const tabs = detectActiveTabs(input); expect(tabs).toEqual(['c']); }); }); describe('processCircuitEmbeds', () => { it('should replace circuit fences with div placeholders', () => { const input = '```circuit\ncircuit_data_here\n```'; const output = processCircuitEmbeds(input); expect(output).toContain('class="circuit-embed"'); expect(output).toContain('data-width="100%"'); expect(output).toContain('data-height="400px"'); expect(output).toContain('circuit_data_here'); }); it('should handle height parameter', () => { const input = '```circuit,500px\ncircuit_data_here\n```'; const output = processCircuitEmbeds(input); expect(output).toContain('data-height="500px"'); }); it('should handle width and height parameters', () => { const input = '```circuit,80%,600px\ncircuit_data_here\n```'; const output = processCircuitEmbeds(input); expect(output).toContain('data-width="80%"'); expect(output).toContain('data-height="600px"'); }); }); describe('parseSlides', () => { it('should extract slides, mount point, and render individual slides', () => { const input = 'Before slides\n---slide-start---\n# Slide 1\nContent 1\n---\n# Slide 2\nContent 2\n---slide-end---\nAfter slides'; const { slides, contentWithoutSlides } = parseSlides(input); expect(contentWithoutSlides).toBe('Before slides\n
\nAfter slides'); expect(slides).toHaveLength(2); expect(slides[0]).toContain('This is the theory.
'); expect(res.exercise_content).toContain('This is the exercise.
'); }); it('should catch validation errors from flashcards and report success: false', () => { const input = `# Lesson with invalid quiz ---QUIZ_FLASHCARD--- ### Question without correct choice - [] A - [] B ---END_QUIZ_FLASHCARD---`; const res = renderMarkdownPreview(input); expect(res.success).toBe(false); expect(res.message).toContain('wajib punya tepat satu opsi benar'); }); }); });