Prüfung / Lint, Typen, Tests (push) Canceled after 0s
Prüfung / Images bauen (pdf) (push) Canceled after 0s
Prüfung / Images bauen (web) (push) Canceled after 0s
Prüfung / Images bauen (worker) (push) Canceled after 0s
Images / bauen (pdf, docker/pdf.Dockerfile) (push) Canceled after 0s
Images / bauen (web, docker/web.Dockerfile) (push) Canceled after 0s
Images / bauen (worker, docker/worker.Dockerfile) (push) Canceled after 0s
375 Vorkommen in 210 Dateien. Betrifft Kommentare, Oberflaechentexte und die README; an keiner Stelle Bedeutung, nur Zeichensetzung.
47 lines
2.2 KiB
TypeScript
47 lines
2.2 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import { readFileSync } from 'node:fs'
|
|
import { join } from 'node:path'
|
|
|
|
/**
|
|
* Das Skript, das das Thema vor dem ersten Malen setzt, hängt an drei Dingen,
|
|
* die zusammenpassen müssen. Fällt eines weg, merkt es niemand sofort:
|
|
*
|
|
* 1. **Der Nonce.** Ohne ihn blockiert die Inhaltsrichtlinie das Skript, und
|
|
* beim Laden blitzt das falsche Thema auf. Sichtbar, aber leicht als
|
|
* Kleinigkeit abgetan.
|
|
* 2. **`suppressHydrationWarning`.** Der Browser leert das Nonce-Attribut
|
|
* nach dem Parsen, React vergleicht es beim Hydrieren trotzdem und meldet
|
|
* einen Unterschied, den es nicht gibt. Die Meldung steht nur in der
|
|
* Konsole des Entwicklungsservers - im Produktionsbau meldet React sie
|
|
* nicht, ein e2e-Lauf kann sie also nicht auffangen. Deshalb hier auf der
|
|
* Ebene der Quelle.
|
|
* 3. **Der Schlüssel im Speicher**, derselbe wie im Umschalter. Weichen sie
|
|
* ab, wird die Wahl bei jedem Laden vergessen.
|
|
*/
|
|
const layout = readFileSync(join(process.cwd(), 'app/layout.tsx'), 'utf8')
|
|
|
|
describe('Thema vor dem ersten Malen', () => {
|
|
it('gibt dem Skript einen Nonce und nimmt es aus dem Hydrierungsvergleich', () => {
|
|
const tag = layout.slice(layout.indexOf('<script'), layout.indexOf('THEME_SCRIPT }} />'))
|
|
|
|
expect(tag).toContain('nonce={nonce}')
|
|
expect(tag).toContain('suppressHydrationWarning')
|
|
})
|
|
|
|
it('benutzt denselben Speicherschlüssel wie der Umschalter', () => {
|
|
const toggle = readFileSync(join(process.cwd(), 'components/ThemeToggle.tsx'), 'utf8')
|
|
|
|
// Der Schlüssel wird importiert, nicht abgeschrieben - genau das prüft das
|
|
// hier: eine zweite, abgeschriebene Zeichenkette wäre der Fehler.
|
|
expect(toggle).toMatch(/export const THEME_KEY = '([^']+)'/)
|
|
expect(layout).toContain("import { THEME_KEY } from '@/components/ThemeToggle'")
|
|
expect(layout).toContain('JSON.stringify(THEME_KEY)')
|
|
})
|
|
|
|
it('setzt nur die beiden ausdrücklichen Themen, nie „wie das System"', () => {
|
|
// "system" darf kein data-theme setzen, sonst gewinnt es über die
|
|
// Medienabfrage und der Nutzer sitzt im falschen Thema.
|
|
expect(layout).toContain("t==='dark'||t==='light'")
|
|
})
|
|
})
|