Files
florian.wildeandClaude Opus 5.5 88b5697cc9 feat(ui): Design-Tokens, Schriften und Datumsformate (#002)
Die Farben des Tresor-Designs stehen als CSS-Variablen in :root und
werden per @theme inline an Tailwind gereicht, damit Inline-SVGs und
Utility-Klassen dieselbe Quelle nutzen. Schriften kommen selbst gehostet
aus @fontsource, nur in den benutzten Gewichten und im Latin-Ausschnitt.

src/lib/format.ts rechnet fest in Europe/Berlin: der Server laeuft im
Container auf UTC, die Anzeige soll aber ueberall dieselbe Ortszeit
zeigen. relativ() nimmt den Bezugspunkt als Parameter, damit statische
Seiten und Tests deterministisch bleiben.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 09:20:22 +02:00

92 lines
3.5 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, expect, it } from "vitest";
import { datum, datumZeit, relativ, tageBis, uhrzeit, ZEITZONE } from "@/lib/format";
// Alle Erwartungen gelten für Europe/Berlin, unabhängig von der Zeitzone des Testprozesses.
describe("Formate (#002)", () => {
it("nutzt fest Europe/Berlin", () => {
expect(ZEITZONE).toBe("Europe/Berlin");
});
describe("datum()", () => {
it("schreibt TT.MM.JJJJ mit führenden Nullen", () => {
expect(datum("2026-03-05T10:00:00Z")).toBe("05.03.2026");
});
it("rechnet in Berliner Zeit – 23:30 UTC ist dort schon der nächste Tag", () => {
expect(datum("2026-10-12T23:30:00Z")).toBe("13.10.2026");
});
it("nimmt Date, Zeitstempel und ISO-Text", () => {
const d = new Date("2026-01-01T12:00:00Z");
expect(datum(d)).toBe("01.01.2026");
expect(datum(d.getTime())).toBe("01.01.2026");
});
it("lehnt ungültige Eingaben ab", () => {
expect(() => datum("kein Datum")).toThrow(RangeError);
});
});
describe("uhrzeit() und datumZeit()", () => {
it("zeigt 24-h-Zeit in Sommerzeit (UTC+2)", () => {
expect(uhrzeit("2026-07-01T13:05:00Z")).toBe("15:05");
});
it("zeigt 24-h-Zeit in Winterzeit (UTC+1)", () => {
expect(uhrzeit("2026-12-01T22:59:00Z")).toBe("23:59");
});
it("Mitternacht ist 00:00, nicht 24:00", () => {
expect(uhrzeit("2026-12-01T23:00:00Z")).toBe("00:00");
});
it("verbindet Datum und Zeit", () => {
expect(datumZeit("2026-10-12T06:42:00Z")).toBe("12.10.2026, 08:42");
});
it("berücksichtigt die Zeitumstellung am 25.10.2026", () => {
expect(datumZeit("2026-10-25T00:30:00Z")).toBe("25.10.2026, 02:30");
expect(datumZeit("2026-10-25T01:30:00Z")).toBe("25.10.2026, 02:30");
});
});
describe("relativ()", () => {
const jetzt = new Date("2026-10-12T10:00:00Z");
const vor = (ms: number) => new Date(jetzt.getTime() - ms);
const MIN = 60_000;
const STD = 60 * MIN;
const TAG = 24 * STD;
it("unter einer Minute: gerade eben", () => {
expect(relativ(vor(30_000), jetzt)).toBe("gerade eben");
expect(relativ(jetzt, jetzt)).toBe("gerade eben");
});
it("Minuten", () => {
expect(relativ(vor(5 * MIN), jetzt)).toBe("vor 5 Min.");
expect(relativ(vor(59 * MIN), jetzt)).toBe("vor 59 Min.");
});
it("Stunden", () => {
expect(relativ(vor(3 * STD), jetzt)).toBe("vor 3 Std.");
expect(relativ(vor(23 * STD + 59 * MIN), jetzt)).toBe("vor 23 Std.");
});
it("Tage mit Einzahl und Mehrzahl", () => {
expect(relativ(vor(TAG), jetzt)).toBe("vor 1 Tag");
expect(relativ(vor(4 * TAG), jetzt)).toBe("vor 4 Tagen");
});
it("Zukunft", () => {
expect(relativ(vor(-12 * TAG), jetzt)).toBe("in 12 Tagen");
expect(relativ(vor(-2 * STD), jetzt)).toBe("in 2 Std.");
});
it("ab 30 Tagen das Datum", () => {
expect(relativ(vor(40 * TAG), jetzt)).toBe("am 02.09.2026");
});
it("nimmt ohne Bezugspunkt die aktuelle Zeit", () => {
expect(relativ(new Date())).toBe("gerade eben");
});
});
describe("tageBis()", () => {
const jetzt = "2026-10-12T21:00:00Z"; // in Berlin schon 23:00 am 12.10.
it("zählt Kalendertage in Berliner Zeit", () => {
expect(tageBis("2026-10-12T22:30:00Z", jetzt)).toBe(1); // 00:30 am 13.10.
expect(tageBis("2026-11-11T12:00:00Z", jetzt)).toBe(30);
});
it("ist negativ für Vergangenes", () => {
expect(tageBis("2026-10-10T12:00:00Z", jetzt)).toBe(-2);
});
});
});