Files
onyx/Packages/OnyxKit/Tests/OnyxDesignTests/OnyxThemeTests.swift
Scarriffle 2aa60eedf9 Farben einstellbar — und erst mal überhaupt eine Farbe
Das Grün, das überall auftauchte, war die System-Akzentfarbe: `.tint` und
`.accentColor` werden ohne eigene Angabe dorthin durchgereicht, und das
betraf alle Popovers und das ganze Einstellungsfenster. Die Notch-Widgets
dagegen benutzten Onyx' eigenes Blau. Zwei Farben, ungewollt.

Jetzt eine, und die ist einstellbar. Ein neuer Reiter „Farben": Akzentfarbe
mit sechs Vorschlägen und einem Knopf, der die Systemfarbe übernimmt, dazu
das Paar für Herunter- und Hochladen samt Tauschknopf.

Die Signalfarben bleiben fest und stehen nur zur Ansicht dort. Gelb heißt
Warnung, Rot heißt kritisch, Grün heißt in Ordnung — bei Temperatur, Akku,
Lüfter und Fehlern. Wer sie umstellen kann, kann ihre Bedeutung zerstören;
ein rotes „alles gut" liest niemand richtig. Sichtbar sind sie trotzdem,
sonst sucht man die Warnfarbe im Reiter und findet sie nirgends.

Umgesetzt über die Tokens statt über vierzig Fundstellen: `Onyx.Color.accent`
ist keine Konstante mehr, sondern liest bei jedem Zugriff aus `OnyxTheme`.
Damit merkt SwiftUI die Abhängigkeit und zeichnet neu, sobald die Farbe sich
ändert. Dazu ein `.tint` an den vier Wurzeln — Panel, Popovers, Einstellungen,
Einrichtung —, damit auch Haken, Regler und Auswahlfelder mitziehen.

Nebenbei die Beschriftung: „Je Programm" heißt jetzt „Programme". Großgesetzt
las sich das als englisches „J-E".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 23:24:40 +02:00

77 lines
2.5 KiB
Swift

import Testing
import SwiftUI
@testable import OnyxDesign
@Suite("Farbwahl")
@MainActor
struct OnyxThemeTests {
private func freshDefaults(_ name: String) -> UserDefaults {
let suite = "onyx.theme.test.\(name)"
let defaults = UserDefaults(suiteName: suite)!
defaults.removePersistentDomain(forName: suite)
return defaults
}
@Test("Ohne Einstellung stehen die Werkswerte")
func defaultsAreTheFactoryColours() {
let theme = OnyxTheme(defaults: freshDefaults(#function))
#expect(theme.accent.onyxHex == OnyxTheme.defaultAccent.onyxHex)
#expect(theme.isDefault)
}
@Test("Eine gewählte Farbe übersteht den Neustart")
func choiceSurvivesRestart() {
let defaults = freshDefaults(#function)
let theme = OnyxTheme(defaults: defaults)
theme.accent = Color(onyxHex: "#FF8800")!
let restarted = OnyxTheme(defaults: defaults)
#expect(restarted.accent.onyxHex == "#FF8800")
#expect(!restarted.isDefault)
}
@Test("Herunter und Hoch sind getrennt einstellbar")
func directionsAreIndependent() {
let theme = OnyxTheme(defaults: freshDefaults(#function))
theme.download = Color(onyxHex: "#112233")!
#expect(theme.download.onyxHex == "#112233")
#expect(theme.upload.onyxHex == OnyxTheme.defaultUpload.onyxHex)
}
@Test("Zurücksetzen stellt alles wieder her")
func resetRestoresEverything() {
let theme = OnyxTheme(defaults: freshDefaults(#function))
theme.accent = Color(onyxHex: "#000000")!
theme.download = Color(onyxHex: "#000000")!
theme.upload = Color(onyxHex: "#000000")!
theme.reset()
#expect(theme.isDefault)
}
}
@Suite("Farben als Text")
struct ColourHexTests {
@Test("Hin und zurück ergibt denselben Wert")
func roundTrip() {
for hex in ["#000000", "#FFFFFF", "#7FA8FF", "#6FCF97", "#EF6D9C"] {
#expect(Color(onyxHex: hex)?.onyxHex == hex)
}
}
@Test("Ohne Doppelkreuz geht es auch")
func hashIsOptional() {
#expect(Color(onyxHex: "7FA8FF")?.onyxHex == "#7FA8FF")
}
@Test("Unsinn ergibt keine Farbe")
func garbageIsRejected() {
// Sonst stünde nach einer verkorksten Einstellung Schwarz auf Schwarz.
#expect(Color(onyxHex: nil) == nil)
#expect(Color(onyxHex: "") == nil)
#expect(Color(onyxHex: "#12345") == nil)
#expect(Color(onyxHex: "#GGGGGG") == nil)
}
}