import { render } from '@testing-library/react'; import { describe, expect, it } from 'vitest'; import MDEditor from '@uiw/react-md-editor'; import rehypeSanitize from 'rehype-sanitize'; import { NoteCheckbox, isTaskLine, toggleTaskLine } from './note-task-list'; describe('note-task-list', () => { describe('isTaskLine', () => { it('erkennt gueltige Aufgabenzeilen', () => { expect(isTaskLine('- [ ] Milch')).toBe(true); expect(isTaskLine('- [x] Brot')).toBe(true); expect(isTaskLine('* [X] Eier')).toBe(true); expect(isTaskLine('+ [ ] Butter')).toBe(true); expect(isTaskLine('1. [ ] Mehl')).toBe(true); expect(isTaskLine('2) [x] Salz')).toBe(true); expect(isTaskLine(' - [ ] eingerueckt')).toBe(true); expect(isTaskLine('- [\t] Tab')).toBe(true); }); it('lehnt Nicht-Aufgabenzeilen ab', () => { expect(isTaskLine('- [ ]')).toBe(false); expect(isTaskLine('- [ ]Text')).toBe(false); expect(isTaskLine('- Milch')).toBe(false); expect(isTaskLine('[ ] ohne Punkt')).toBe(false); expect(isTaskLine('- [y] falsch')).toBe(false); expect(isTaskLine('')).toBe(false); }); }); describe('toggleTaskLine', () => { it('kippt genau die Zeile am angegebenen Index auf [x]', () => { const content = '- [ ] Milch\n- [ ] Brot\n- [ ] Eier'; expect(toggleTaskLine(content, 0)).toBe( '- [x] Milch\n- [ ] Brot\n- [ ] Eier', ); expect(toggleTaskLine(content, 2)).toBe( '- [ ] Milch\n- [ ] Brot\n- [x] Eier', ); }); it('kippt [x]/[X] zurueck auf [ ]', () => { expect(toggleTaskLine('- [x] Brot', 0)).toBe('- [ ] Brot'); expect(toggleTaskLine('- [X] Brot', 0)).toBe('- [ ] Brot'); }); it('zaehlt Nicht-Aufgabenzeilen nicht mit, alle anderen Zeilen bleiben unveraendert', () => { const content = '# Einkauf\n\nText\n- [ ] Milch\n- normal\n- [ ] Brot'; const result = toggleTaskLine(content, 1); expect(result).toBe('# Einkauf\n\nText\n- [ ] Milch\n- normal\n- [x] Brot'); }); it('behaelt Einrueckung und Nummerierung bei', () => { const content = '- [ ] A\n - [ ] B\n1. [ ] C'; expect(toggleTaskLine(content, 1)).toBe('- [ ] A\n - [x] B\n1. [ ] C'); expect(toggleTaskLine(content, 2)).toBe('- [ ] A\n - [ ] B\n1. [x] C'); }); it('gibt bei Index ausserhalb des Bereichs die unveraenderte Eingabe zurueck', () => { const content = '- [ ] A\n- [ ] B\n- [ ] C'; expect(toggleTaskLine(content, -1)).toBe(content); expect(toggleTaskLine(content, 3)).toBe(content); expect(toggleTaskLine('', 0)).toBe(''); }); it('ueberspringt Zeilen innerhalb von Code-Zaeunen', () => { const withBackticks = '```\n- [ ] nicht\n```\n- [ ] echt'; expect(toggleTaskLine(withBackticks, 0)).toBe( '```\n- [ ] nicht\n```\n- [x] echt', ); const withTilde = '~~~\n- [ ] nicht\n~~~\n- [ ] echt'; expect(toggleTaskLine(withTilde, 0)).toBe( '~~~\n- [ ] nicht\n~~~\n- [x] echt', ); }); }); describe('echte Vorschau (MDEditor.Markdown + rehypeSanitize + components-Override)', () => { it('rendert genau die Aufgabenzeilen als anklickbare Kaestchen', () => { const SRC = '- [ ] eins\n- [x] zwei\n* [X] drei\n- [ ]\n- [ ]kein\n1. [ ] vier'; const { container } = render( , ); const boxes = container.querySelectorAll('input[type="checkbox"]'); const expectedCount = SRC.split('\n').filter(isTaskLine).length; expect(expectedCount).toBe(4); expect(boxes.length).toBe(4); for (const box of Array.from(boxes)) { expect((box as HTMLInputElement).disabled).toBe(false); } expect((boxes[0] as HTMLInputElement).checked).toBe(false); expect((boxes[1] as HTMLInputElement).checked).toBe(true); expect((boxes[2] as HTMLInputElement).checked).toBe(true); expect((boxes[3] as HTMLInputElement).checked).toBe(false); }); }); });