import Testing import AppKit @testable import OnyxMenuBar @Suite("Breite in der Menüleiste") struct MenuBarTextTests { @Test("Die Breite folgt dem Text und nicht einer Schätzung") func widthFollowsText() { // Genau das war der Fehler: eine feste Zahl je Darstellungsart, so // großzügig, dass neben jedem Wert Platz für ein weiteres Symbol blieb. let short = MenuBarText.itemWidth(textWidth: 20, includesSymbol: false) let long = MenuBarText.itemWidth(textWidth: 60, includesSymbol: false) #expect(long > short) #expect(short == 20 + 2 * MenuBarText.sidePadding) } @Test("Ein Symbol daneben braucht seinen Platz") func symbolAddsWidth() { let without = MenuBarText.itemWidth(textWidth: 40, includesSymbol: false) let with = MenuBarText.itemWidth(textWidth: 40, includesSymbol: true) #expect(with - without == MenuBarText.symbolWidth + MenuBarText.innerGap) } @Test("Ohne Text bleibt die Mindestbreite") func emptyKeepsMinimum() { // Ein Element ohne Zahl zeigt ein Glyph. Schrumpfte es auf null, // verschwände es aus der Leiste. #expect(MenuBarText.itemWidth(textWidth: 0, includesSymbol: false) == MenuBarText.minimumWidth) } @Test("Die Breite wird aufgerundet") func roundsUp() { // Gebrochene Breiten führen zu unscharfem Text, weil die Zeichenfolge // dann auf einem halben Bildpunkt sitzt. let width = MenuBarText.itemWidth(textWidth: 20.3, includesSymbol: false) #expect(width == width.rounded()) } @Test("Ein längerer Verweistext ergibt ein breiteres Element") func referenceDrivesWidth() { #expect(MenuBarText.width(for: "100 %") > MenuBarText.width(for: "9 %")) } @Test("Gleich lange Zahlen sind gleich breit") func digitsAreMonospaced() { // Ohne feste Ziffernbreite springt die Leiste bei jedem Messwert. #expect(MenuBarText.width(of: "111") == MenuBarText.width(of: "888")) } } // Ein Menüleistenelement darf seine Breite **nicht** ändern, wenn sich der // Messwert ändert — sonst rutschen alle Symbole rechts davon mit. Das gilt auch // dann, wenn eine Stelle dazukommt: aus „14 KB/s" wird „431 KB/s", und die // halbe Leiste wandert. // // Also eine feste Breite je Darstellung, bemessen am breitesten Wert, der // vorkommen kann. Der frühere Fehler war nicht die feste Breite, sondern ein // falscher Bezugswert: „100 °C" statt „100°" ist rund 15 Punkte zu viel. @Suite("Feste Breite") struct FixedWidthTests { @Test("Der Bezugswert hängt nicht vom Messwert ab") func referenceIsIndependentOfValue() { #expect(MenuBarText.width(for: "100 %") == MenuBarText.width(for: "100 %")) } @Test("Ein Bezugswert deckt alle kürzeren ab") func referenceCoversShorterValues() { // Was hineinpasst, wird nicht abgeschnitten. for value in ["0 %", "9 %", "34 %", "100 %"] { #expect(MenuBarText.width(of: value) <= MenuBarText.width(of: "100 %")) } } @Test("Grad ohne Einheitenbuchstaben ist deutlich schmaler") func degreeWithoutUnitIsNarrower() { // Der eigentliche Fund: gezeichnet wird „63°", bemessen wurde früher // „100 °C". #expect(MenuBarText.width(of: "100°") < MenuBarText.width(of: "100 °C") - 10) } }