// Tests der reinen Module: gjs -m dev/tests/run.js import * as D from '../../desktop@marha.de/dates.js'; import {renderMarkdown} from '../../desktop@marha.de/markdown.js'; let failed = 0; function eq(actual, expected, name) { const a = JSON.stringify(actual), e = JSON.stringify(expected); if (a === e) print(`ok ${name}`); else { failed++; print(`FAIL ${name}\n got ${a}\n expected ${e}`); } } eq(D.toDateString(new Date(2026, 8, 17)), '2026-09-17', 'toDateString'); eq(D.addDays('2026-09-30', 1), '2026-10-01', 'addDays über Monatsgrenze'); eq(D.addDays('2026-01-01', -1), '2025-12-31', 'addDays rückwärts über Jahr'); eq(D.startOfWeek('2026-09-17'), '2026-09-14', 'startOfWeek Do → Mo'); eq(D.startOfWeek('2026-09-20'), '2026-09-14', 'startOfWeek So → Mo'); eq(D.startOfWeek('2026-09-14'), '2026-09-14', 'startOfWeek Mo bleibt'); eq(D.weekDays('2026-09-17').length, 7, 'weekDays 7 Tage'); const grid = D.monthGrid(2026, 8); eq(grid[0], '2026-08-31', 'monthGrid startet Montag davor'); eq(grid.length, 42, 'monthGrid 42 Zellen'); eq(D.monthGrid(2026, 5)[0], '2026-06-01', 'monthGrid Monat beginnt Montag'); eq(D.isoWeek('2026-09-17'), 38, 'isoWeek'); eq(D.isoWeek('2027-01-01'), 53, 'isoWeek Jahreswechsel'); eq(D.formatMonth(2026, 8), 'September 2026', 'formatMonth'); eq(D.formatDate('2026-09-17'), 'Do, 17.09.2026', 'formatDate'); eq(D.formatDayMonth('2026-09-17'), '17.09.', 'formatDayMonth'); eq(D.parseDateInput('17.09.2026'), '2026-09-17', 'parseDateInput dd.mm.yyyy'); eq(D.parseDateInput('1.9.26'), '2026-09-01', 'parseDateInput kurz'); eq(D.parseDateInput('2026-09-17'), '2026-09-17', 'parseDateInput iso'); eq(D.parseDateInput('31.02.2026'), null, 'parseDateInput ungültig'); eq(D.parseDateInput('abc'), null, 'parseDateInput Müll'); eq(D.parseTimeInput('9:05'), '09:05', 'parseTimeInput h:mm'); eq(D.parseTimeInput('14'), '14:00', 'parseTimeInput nur Stunde'); eq(D.parseTimeInput('9.30'), '09:30', 'parseTimeInput Punkt'); eq(D.parseTimeInput('25:00'), null, 'parseTimeInput ungültig'); eq(D.timeToMinutes('01:30'), 90, 'timeToMinutes'); eq(D.minutesToTime(90), '01:30', 'minutesToTime'); eq(renderMarkdown('# Titel'), 'Titel', 'md h1'); eq(renderMarkdown('## A **b** c'), 'A b c', 'md h2 bold'); eq(renderMarkdown('a *kursiv* b'), 'a kursiv b', 'md italic'); eq(renderMarkdown('snake_case_name'), 'snake_case_name', 'md underscore im Wort bleibt'); eq(renderMarkdown('2 * 3 * 4'), '2 * 3 * 4', 'md einzelne Sterne bleiben'); eq(renderMarkdown('- eins\n - zwei'), ' • eins\n • zwei', 'md verschachtelte Liste'); eq(renderMarkdown('1. a\n2. b'), ' 1. a\n 2. b', 'md nummeriert'); eq(renderMarkdown('- [ ] offen\n- [x] fertig'), ' ☐ offen\n ☑ fertig', 'md checkbox'); eq(renderMarkdown('a `x < y` b'), 'a x < y b', 'md code escaped'); eq(renderMarkdown('`**nicht fett**`'), '**nicht fett**', 'md code schützt Sterne'); eq(renderMarkdown('```\nlet a = 1 & 2;\n```'), 'let a = 1 & 2;', 'md codeblock'); eq(renderMarkdown('[Link](http://x)'), 'Link', 'md link'); eq(renderMarkdown('[[Wiki]]'), 'Wiki', 'md wikilink'); eq(renderMarkdown('![Bild](a.png)'), '[Bild: Bild]', 'md image'); eq(renderMarkdown('> zitat'), '▎ zitat', 'md quote'); eq(renderMarkdown('---'), '────────────────────────────', 'md hr'); eq(renderMarkdown('~~weg~~'), 'weg', 'md strike'); eq(renderMarkdown('a\n\nb'), 'a\n\nb', 'md leere Zeile bleibt'); print(failed ? `\n${failed} FEHLER` : '\nalle Tests ok'); if (failed) imports.system.exit(1);