// @vitest-environment node /** * Größe und Lage des Hauptfensters. * * **Der Anlass.** Das Fenster startete bis 0.22.0 immer mit 1180 × 820 an der * Systemposition. Wer maximiert arbeitet oder es – wie der Kommentar in * `main/fenster.ts` selbst als Anwendungsfall nennt – schmal neben eine * Bildschirmlupe oder ein zweites Programm stellt, richtete das bei jedem * Start neu ein. Das ist Standard-Erwartung an jede Windows-Anwendung und * trifft besonders die Lupen- und Split-Screen-Nutzer, also genau die * Zielgruppe des Barrierefreiheitsanspruchs. * * **Der gefährliche Fall** ist nicht die Größe, sondern die Lage: Ein Fenster, * dessen gespeicherte Position auf einem inzwischen abgesteckten Monitor * liegt, ginge außerhalb jeder sichtbaren Fläche auf – vorhanden, aber * unerreichbar. Und ohne Fenster gibt es keinen Weg, die Einstellung * zurückzusetzen. Deshalb ist die Prüfung eine reine Funktion: So lässt sie * sich messen, ohne einen zweiten Monitor abzustecken. */ import { describe, expect, it } from 'vitest'; import { FENSTER_MINDESTBREITE, FENSTER_MINDESTHOEHE, FENSTER_VORGABE, fensterlageBereinigen, lageIstErreichbar, startlage, type Flaeche, } from '../src/shared/fensterlage'; /** Ein gewöhnlicher Einzelbildschirm. */ const HAUPTSCHIRM: Flaeche = { x: 0, y: 0, width: 1920, height: 1040 }; /** Ein zweiter Schirm links daneben – negative Koordinaten sind normal. */ const ZWEITSCHIRM: Flaeche = { x: -1920, y: 0, width: 1920, height: 1040 }; describe('Gespeicherte Lage bereinigen', () => { it('nimmt eine gewöhnliche Lage unverändert', () => { expect(fensterlageBereinigen({ breite: 1400, hoehe: 900, x: 100, y: 50 })).toEqual({ breite: 1400, hoehe: 900, x: 100, y: 50, }); }); it('merkt sich den maximierten Zustand', () => { expect(fensterlageBereinigen({ breite: 1400, hoehe: 900, maximiert: true })).toMatchObject({ maximiert: true, }); }); it('verwirft, was keine Lage ist', () => { expect(fensterlageBereinigen(null)).toBeNull(); expect(fensterlageBereinigen('groß')).toBeNull(); expect(fensterlageBereinigen({})).toBeNull(); expect(fensterlageBereinigen({ breite: 'viel', hoehe: 900 })).toBeNull(); }); it('hebt eine unbedienbar kleine Größe an', () => { /* Nach unten gekappt, nicht nach oben: Ein zu großes Fenster schiebt das Betriebssystem selbst zurecht, ein zu kleines wäre unbedienbar – und niemand könnte es wieder vergrößern, wenn die Ränder fehlen. */ const lage = fensterlageBereinigen({ breite: 10, hoehe: 10 }); expect(lage?.breite).toBe(FENSTER_MINDESTBREITE); expect(lage?.hoehe).toBe(FENSTER_MINDESTHOEHE); }); it('lässt eine Position ohne Angabe einfach weg', () => { const lage = fensterlageBereinigen({ breite: 1400, hoehe: 900 }); expect(lage).not.toBeNull(); expect(lage?.x).toBeUndefined(); }); }); describe('Erreichbarkeit auf den vorhandenen Bildschirmen', () => { it('lässt eine Lage mitten auf dem Schirm zu', () => { expect(lageIstErreichbar({ breite: 800, hoehe: 600, x: 200, y: 100 }, [HAUPTSCHIRM])).toBe( true, ); }); it('lässt ein Fenster zu, das ein Stück über den Rand ragt', () => { /* Alltäglich und gewollt – verlangt wird nur, dass ein greifbarer Teil sichtbar bleibt. */ expect(lageIstErreichbar({ breite: 800, hoehe: 600, x: 1600, y: 900 }, [HAUPTSCHIRM])).toBe( true, ); }); it('weist eine Lage auf einem abgesteckten Monitor ab', () => { /* Der eigentliche Schadensfall: Das Fenster ginge auf und bliebe unsichtbar – und ohne Fenster ließe sich die Einstellung nicht mehr zurücksetzen. */ const aufZweitschirm = { breite: 800, hoehe: 600, x: -1500, y: 100 }; expect(lageIstErreichbar(aufZweitschirm, [HAUPTSCHIRM, ZWEITSCHIRM])).toBe(true); expect(lageIstErreichbar(aufZweitschirm, [HAUPTSCHIRM])).toBe(false); }); it('weist eine Lage ab, von der nur ein Zipfel sichtbar wäre', () => { /* Ein Fenster, das mit zehn Pixeln in den Schirm ragt, lässt sich nicht mehr anfassen, um es zurückzuholen. */ expect(lageIstErreichbar({ breite: 800, hoehe: 600, x: 1910, y: 100 }, [HAUPTSCHIRM])).toBe( false, ); }); it('lässt eine Lage ohne Position immer zu', () => { /* Dann entscheidet das Betriebssystem – das ist nie falsch. */ expect(lageIstErreichbar({ breite: 800, hoehe: 600 }, [])).toBe(true); }); }); describe('Startlage', () => { it('nimmt die Vorgabe, wenn nichts gespeichert ist', () => { expect(startlage(undefined, [HAUPTSCHIRM])).toEqual({ ...FENSTER_VORGABE }); }); it('nimmt die Vorgabe, wenn die gespeicherte Lage nicht mehr erreichbar ist', () => { const verloren = { breite: 800, hoehe: 600, x: -1500, y: 100 }; expect(startlage(verloren, [HAUPTSCHIRM])).toEqual({ ...FENSTER_VORGABE }); }); it('nimmt die gespeicherte Lage, wenn sie trägt', () => { const gespeichert = { breite: 1400, hoehe: 900, x: 100, y: 50, maximiert: true }; expect(startlage(gespeichert, [HAUPTSCHIRM])).toEqual(gespeichert); }); it('kommt ohne jeden Bildschirm aus', () => { /* Sollte nicht vorkommen – aber ein Absturz beim Fensterbau wäre die schlechteste Antwort darauf. */ expect(() => startlage({ breite: 800, hoehe: 600, x: 0, y: 0 }, [])).not.toThrow(); expect(startlage({ breite: 800, hoehe: 600, x: 0, y: 0 }, [])).toEqual({ ...FENSTER_VORGABE }); }); });