Files
Mind-o-Mat/tests/indexer-edge-cases.test.ts
T
Jannik c717353037
CI / test (push) Canceled after 0s
CI / webapp (push) Canceled after 0s
fix: beheben von Lint- und Prettier-Fehlern in Tests und Config
2026-09-08 16:54:21 +02:00

150 lines
5.0 KiB
TypeScript

// Edge-Case-Tests fuer den Indexer
// Phase 2.5-erweitert
import { describe, it, expect, afterEach } from 'vitest';
import { execSync } from 'node:child_process';
import { mkdtempSync, mkdirSync, writeFileSync, rmSync, readFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
const TOOL = 'C:/GitHub/Mind-o-Mat';
const CLI = `node ${TOOL}/bin/mindomat.mjs`;
function setupVault(files: Record<string, string> = {}, includeKonfig = true): string {
const vault = mkdtempSync(join(tmpdir(), 'mindomat-edge-'));
for (const d of [
'00_Inbox',
'00_Inbox/Verarbeitet',
'00_Inbox/Problemfaelle',
'01_Daily',
'10_Wiki',
'10_Wiki/Seiten',
'20_Projekte',
'90_Templates',
'99_System',
'99_System/Skripte',
'99_System/Logs',
'99_System/Cache',
]) {
mkdirSync(join(vault, d), { recursive: true });
}
if (includeKonfig) {
writeFileSync(
join(vault, '99_System/Konfig.md'),
'---\nveraltet_schwellwert_monate: 12\n---\n',
);
}
for (const [rel, content] of Object.entries(files)) {
const full = join(vault, rel);
mkdirSync(join(full, '..'), { recursive: true });
writeFileSync(full, content);
}
return vault;
}
function runIndexer(vault: string): void {
execSync(`${CLI} index --vault "${vault}"`, { stdio: 'pipe' });
}
const vaults: string[] = [];
afterEach(() => {
for (const v of vaults) {
rmSync(v, { recursive: true, force: true });
}
});
describe('Indexer Edge Cases', () => {
it('leerer Vault: keine Notizen, leere Outputs', () => {
const vault = setupVault({}, false);
vaults.push(vault);
runIndexer(vault);
const landkarte = JSON.parse(readFileSync(join(vault, 'landkarte.json'), 'utf-8'));
expect(landkarte.nodes.length).toBe(0);
expect(landkarte.edges.length).toBe(0);
const sysIndex = readFileSync(join(vault, '99_System/Index.md'), 'utf-8');
expect(sysIndex).toContain('Vault-Katalog');
expect(sysIndex).toContain('0 Notizen');
});
it('Notiz ohne Frontmatter: Typ wird aus Pfad erkannt, Frontmatter-Titel fehlt', () => {
const vault = setupVault({
'01_Daily/2026-09-05_Plain.md': '# Reiner Markdown\n\nKein Frontmatter.',
});
vaults.push(vault);
runIndexer(vault);
const landkarte = JSON.parse(readFileSync(join(vault, 'landkarte.json'), 'utf-8'));
expect(landkarte.nodes.length).toBe(1);
// 01_Daily/ mit YYYY-MM-DD-Pattern wird korrekt als 'daily' typisiert
expect(landkarte.nodes[0].type).toBe('daily');
// title faellt auf vollen Pfad ohne .md zurueck
expect(landkarte.nodes[0].title).toBe('01_Daily/2026-09-05_Plain');
});
it('Unicode im Titel wird korrekt verarbeitet', () => {
const vault = setupVault({
'00_Inbox/2026-09-05_Kaffee_ÄÖÜ.md':
'---\ntitle: Größere Übung\ncreated: 2026-09-05\n---\n\n# Größere Übung\n\nß und ö.',
});
vaults.push(vault);
runIndexer(vault);
const landkarte = JSON.parse(readFileSync(join(vault, 'landkarte.json'), 'utf-8'));
expect(landkarte.nodes[0].title).toBe('Größere Übung');
});
it('tote Wikilinks erscheinen in Index.md', () => {
const vault = setupVault({
'00_Inbox/2026-09-05_A.md': '---\ntitle: A\n---\n\nVerweist auf [[B_Datei_Nicht_Da]].',
});
vaults.push(vault);
runIndexer(vault);
const sysIndex = readFileSync(join(vault, '99_System/Index.md'), 'utf-8');
expect(sysIndex).toContain('Verwaiste Links');
expect(sysIndex).toContain('B_Datei_Nicht_Da');
});
it('zirkulaere Wikilinks (A->B->A) ergeben 2 Edges', () => {
const vault = setupVault({
'00_Inbox/2026-09-05_A.md': '---\ntitle: A\n---\n\nVerweist auf [[B]].',
'00_Inbox/2026-09-05_B.md': '---\ntitle: B\n---\n\nVerweist auf [[A]].',
});
vaults.push(vault);
runIndexer(vault);
const landkarte = JSON.parse(readFileSync(join(vault, 'landkarte.json'), 'utf-8'));
// 2 Knoten, 2 Edges (A->B und B->A), dedupliziert bleibt 2
expect(landkarte.nodes.length).toBe(2);
expect(landkarte.edges.length).toBe(2);
});
it('mehrfache Wikilinks zum gleichen Ziel werden dedupliziert', () => {
const vault = setupVault({
'00_Inbox/2026-09-05_A.md': '---\ntitle: A\n---\n\n[[B]] und nochmal [[B]] und [[B]].',
'00_Inbox/2026-09-05_B.md': '---\ntitle: B\n---\n\nInhalt.',
});
vaults.push(vault);
runIndexer(vault);
const landkarte = JSON.parse(readFileSync(join(vault, 'landkarte.json'), 'utf-8'));
// 3 Wikilinks im Text, aber nur 1 Edge (dedupliziert)
expect(landkarte.edges.length).toBe(1);
});
it('Wikilink mit Anzeige-Text [[A|Alias]] wird korrekt extrahiert', () => {
const vault = setupVault({
'00_Inbox/2026-09-05_A.md': '---\ntitle: A\n---\n\nSiehe [[B_Datei|Zeige dies]].',
'00_Inbox/2026-09-05_B_Datei.md': '---\ntitle: B_Datei\n---\n\nInhalt.',
});
vaults.push(vault);
runIndexer(vault);
const landkarte = JSON.parse(readFileSync(join(vault, 'landkarte.json'), 'utf-8'));
expect(landkarte.edges.length).toBe(1);
expect(landkarte.edges[0].to).toBe('B_Datei.md');
});
});