Erster kleiner Schnitt aus Phase A des CodeScene-Auftrags: die Ueberlappungs- Berechnung war ein rein funktionaler, aber verschachtelter Block mitten in der Komponente. Sie liegt jetzt als layoutDaySegments/computeEventOverlapLayout in src/lib/weekly/event-layout.ts und ist mit node:test abgedeckt (einzelner Termin, Ueberschneidung, direkte Abfolge, drei gleichzeitige Termine, Reihenfolgeunabhaengigkeit). Kein sichtbares Verhalten geaendert; der Algorithmus ist unveraendert uebernommen. WeeklyView.tsx: 9683 -> 9642 Zeilen. v1.121.2 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
75 lines
3.0 KiB
TypeScript
75 lines
3.0 KiB
TypeScript
import { test, describe } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { layoutDaySegments, computeEventOverlapLayout } from "../../src/lib/weekly/event-layout.ts";
|
|
import type { CalendarEventSegment } from "../../src/lib/weekly/types.ts";
|
|
|
|
/**
|
|
* Charakterisierungstests der Spaltenaufteilung im Tagesraster.
|
|
*
|
|
* Beobachtbares Verhalten: Termine, die sich zeitlich überschneiden, stehen
|
|
* nebeneinander statt übereinander; Termine, die sich nicht berühren, bekommen
|
|
* die volle Breite.
|
|
*/
|
|
|
|
const at = (h: number, min = 0) => new Date(2026, 8, 10, h, min, 0, 0).toISOString();
|
|
|
|
const segment = (key: string, startHour: number, endHour: number): CalendarEventSegment => ({
|
|
id: key,
|
|
title: key,
|
|
startTime: at(startHour),
|
|
endTime: at(endHour),
|
|
source: "google",
|
|
segmentKey: key,
|
|
segmentIndex: 0,
|
|
segmentCount: 1,
|
|
continuesFromPreviousDay: false,
|
|
continuesOnNextDay: false,
|
|
sourceEvent: { id: key, title: key, startTime: at(startHour), endTime: at(endHour), source: "google" },
|
|
});
|
|
|
|
describe("layoutDaySegments", () => {
|
|
test("ein einzelner Termin nimmt die volle Breite ein", () => {
|
|
const layout = layoutDaySegments([segment("a", 9, 10)]);
|
|
assert.deepEqual(layout.a, { column: 0, totalColumns: 1 });
|
|
});
|
|
|
|
test("zwei überschneidende Termine teilen sich zwei Spalten", () => {
|
|
const layout = layoutDaySegments([segment("a", 9, 11), segment("b", 10, 12)]);
|
|
assert.equal(layout.a.totalColumns, 2);
|
|
assert.equal(layout.b.totalColumns, 2);
|
|
assert.notEqual(layout.a.column, layout.b.column);
|
|
});
|
|
|
|
test("aufeinanderfolgende Termine bekommen dieselbe Spalte und volle Breite", () => {
|
|
const layout = layoutDaySegments([segment("a", 9, 10), segment("b", 10, 11)]);
|
|
assert.deepEqual(layout.a, { column: 0, totalColumns: 1 });
|
|
assert.deepEqual(layout.b, { column: 0, totalColumns: 1 });
|
|
});
|
|
|
|
test("drei gleichzeitige Termine ergeben drei Spalten", () => {
|
|
const layout = layoutDaySegments([segment("a", 9, 12), segment("b", 9, 12), segment("c", 9, 12)]);
|
|
const columns = ["a", "b", "c"].map((k) => layout[k].column).sort();
|
|
assert.deepEqual(columns, [0, 1, 2]);
|
|
assert.equal(layout.a.totalColumns, 3);
|
|
});
|
|
|
|
test("die Reihenfolge der Eingabe ändert das Ergebnis nicht", () => {
|
|
const forward = layoutDaySegments([segment("a", 9, 11), segment("b", 10, 12)]);
|
|
const backward = layoutDaySegments([segment("b", 10, 12), segment("a", 9, 11)]);
|
|
assert.deepEqual(forward, backward);
|
|
});
|
|
});
|
|
|
|
describe("computeEventOverlapLayout", () => {
|
|
test("fasst mehrere Tage in einer Zuordnung zusammen", () => {
|
|
const layout = computeEventOverlapLayout(
|
|
new Map([
|
|
["2026-09-10", [segment("a", 9, 11), segment("b", 10, 12)]],
|
|
["2026-09-11", [segment("c", 9, 10)]],
|
|
]),
|
|
);
|
|
assert.equal(layout.a.totalColumns, 2);
|
|
assert.equal(layout.c.totalColumns, 1);
|
|
});
|
|
});
|