Files
nexarch/web/dms-browser/lib/virtualization.test.ts
T
patrickandClaude Sonnet 5 e973457d1a DOC-10: Ordner-Navigation & Dokumentenliste
internal/folderapi: neue Backend-Voraussetzung - GET /folders/{id}/
children (lazy Baum-Ladung), .../breadcrumb (ueber DOC-09s Materialized
Path), .../documents (Dokumentenliste, whitelisted Sortierspalten).
folder.go ergaenzt ListChildren/Breadcrumb (additiv, keine bestehende
Funktion geaendert).

web/dms-browser: Next.js/React/TypeScript. Navigationsbaum laedt Kinder
lazy je Ebene, Dokumentenliste ist virtualisiert (lib/virtualization.ts,
abhaengigkeitsfrei - nur sichtbarer Ausschnitt + Overscan wird gerendert),
Mehrfachauswahl (lib/selection.ts: Klick/Strg/Umschalt), Tastatur-
navigation im Baum (lib/treeKeyboard.ts). Aktueller Ordner steckt in der
URL (Catch-all-Route /browse/[[...path]]) statt nur im React-State - der
Browser verwaltet Vor-/Zurueck-Navigation selbst.

Echter Bug beim Schreiben der Virtualisierungs-Tests gefunden und
behoben: startIndex war bei scrollTop jenseits des tatsaechlichen Inhalts
nicht auf totalRows geklemmt (haette zu ungueltigem slice() gefuehrt).

Pruefungen:
1. Liste mit 10.000 Zeilen scrollt ruckelfrei - Virtualisierung rendert
   nachweislich nur ~20 statt 10.000 Zeilen
2. Navigation vollstaendig per Tastatur - 5 Vitest-Tests fuer Pfeiltasten/
   Enter im Baum
3. Zustand bleibt beim Zurueck-Navigieren erhalten - Ordner-ID in der URL,
   Browser-History uebernimmt die Wiederherstellung

Regressionsfrei: alle bestehenden Go-Pakete PASS.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-17 20:22:09 +02:00

35 lines
1.4 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { computeVisibleRange, totalContentHeight } from "./virtualization";
describe("computeVisibleRange (Akzeptanzkriterium 2 + Pflichtprüfung 1: 10.000 Zeilen ruckelfrei)", () => {
it("rendert bei 10.000 Zeilen nur einen kleinen sichtbaren Ausschnitt, nicht alle", () => {
const range = computeVisibleRange(0, 600, 32, 10000, 5);
const rendered = range.endIndex - range.startIndex;
expect(rendered).toBeLessThan(50);
expect(rendered).toBeGreaterThan(0);
});
it("verschiebt den sichtbaren Bereich beim Scrollen", () => {
const top = computeVisibleRange(0, 600, 32, 10000, 0);
const scrolled = computeVisibleRange(3200, 600, 32, 10000, 0);
expect(scrolled.startIndex).toBeGreaterThan(top.startIndex);
});
it("bleibt am Ende der Liste innerhalb der Grenzen", () => {
const range = computeVisibleRange(1_000_000, 600, 32, 100, 5);
expect(range.endIndex).toBeLessThanOrEqual(100);
expect(range.startIndex).toBeLessThanOrEqual(100);
expect(range.startIndex).toBeLessThanOrEqual(range.endIndex);
});
it("liefert eine leere Range bei 0 Zeilen, kein Fehler", () => {
const range = computeVisibleRange(0, 600, 32, 0);
expect(range.startIndex).toBe(0);
expect(range.endIndex).toBe(0);
});
it("totalContentHeight ergibt Zeilenzahl mal Zeilenhoehe (fuer den Scroll-Spacer)", () => {
expect(totalContentHeight(10000, 32)).toBe(320000);
});
});