1package theme
2
3import (
4 "context"
5 "testing"
6
7 "github.com/bnema/dumber/internal/domain/entity"
8 "github.com/stretchr/testify/assert"
9 "github.com/stretchr/testify/require"
10)
11
12func resolvedThemeFixture(prefersDark bool) entity.ResolvedTheme {
13 light := entity.ColorPalette{
14 Background: "#ffffff",
15 Surface: "#f8f8f8",
16 SurfaceVariant: "#eeeeee",
17 Text: "#111111",
18 Muted: "#666666",
19 Accent: "#0055ff",
20 Border: "#dddddd",
21 }
22 dark := entity.ColorPalette{
23 Background: "#101010",
24 Surface: "#181818",
25 SurfaceVariant: "#242424",
26 Text: "#f5f5f5",
27 Muted: "#999999",
28 Accent: "#66aaff",
29 Border: "#333333",
30 }
31 active := light
32 if prefersDark {
33 active = dark
34 }
35 return entity.ResolvedTheme{
36 LightPalette: light,
37 DarkPalette: dark,
38 ActivePalette: active,
39 PrefersDark: prefersDark,
40 ColorSchemeSource: "test",
41 ThemeSource: entity.ThemeSourceMetadata{Kind: entity.ThemeSourceConfig},
42 Fonts: entity.ThemeFonts{
43 SansFont: "Inter",
44 SerifFont: "Georgia",
45 MonospaceFont: "JetBrains Mono",
46 GtkFont: "Adwaita Sans",
47 DefaultSize: 16,
48 },
49 UIScale: 1.5,
50 ModeColors: entity.ThemeModeColors{
51 PaneMode: "#ff0000",
52 TabMode: "#00ff00",
53 SessionMode: "#0000ff",
54 ResizeMode: "#ffff00",
55 },
56 }
57}
58
59func TestNewManager_UsesResolvedThemeFields(t *testing.T) {
60 ctx := context.Background()
61 resolved := resolvedThemeFixture(true)
62
63 manager := NewManager(ctx, resolved)
64
65 require.NotNil(t, manager)
66 assert.True(t, manager.PrefersDark())
67 assert.Equal(t, "#ffffff", manager.GetLightPalette().Background)
68 assert.Equal(t, "#101010", manager.GetDarkPalette().Background)
69 assert.Equal(t, manager.GetDarkPalette(), manager.GetCurrentPalette())
70 assert.Equal(t, "#ff0000", manager.GetModeColors().PaneMode)
71 assert.Equal(t, FontConfig{SansFont: "Inter", MonospaceFont: "JetBrains Mono", GtkFont: "Adwaita Sans"}, manager.fonts)
72 assert.Equal(t, "Adwaita Sans", manager.gtkFont)
73 assert.InDelta(t, 1.5, manager.uiScale, 0.000001)
74}
75
76func TestNewManager_DefaultsInvalidScaleToOne(t *testing.T) {
77 ctx := context.Background()
78 resolved := resolvedThemeFixture(true)
79 resolved.UIScale = 0
80
81 manager := NewManager(ctx, resolved)
82
83 require.NotNil(t, manager)
84 assert.InDelta(t, 1.0, manager.uiScale, 0.000001)
85}
86
87func TestManager_UpdateFromResolvedReplacesResolvedValues(t *testing.T) {
88 ctx := context.Background()
89 manager := NewManager(ctx, resolvedThemeFixture(true))
90 updated := resolvedThemeFixture(false)
91 updated.LightPalette.Background = "#abcdef"
92 updated.DarkPalette.Background = "#123456"
93 updated.Fonts.SansFont = "Recursive"
94 updated.UIScale = 2.0
95 updated.ModeColors.PaneMode = "#654321"
96
97 manager.UpdateFromResolved(ctx, updated, nil)
98
99 assert.False(t, manager.PrefersDark())
100 assert.Equal(t, "#abcdef", manager.GetLightPalette().Background)
101 assert.Equal(t, "#123456", manager.GetDarkPalette().Background)
102 assert.Equal(t, manager.GetLightPalette(), manager.GetCurrentPalette())
103 assert.Equal(t, "Recursive", manager.fonts.SansFont)
104 assert.InDelta(t, 2.0, manager.uiScale, 0.000001)
105 assert.Equal(t, "#654321", manager.GetModeColors().PaneMode)
106}
107
108func TestManager_GetWebUIThemeCSS(t *testing.T) {
109 ctx := context.Background()
110 manager := NewManager(ctx, resolvedThemeFixture(true))
111
112 css := manager.GetWebUIThemeCSS()
113
114 assert.Contains(t, css, ":root{")
115 assert.Contains(t, css, ".dark{")
116 assert.Contains(t, css, "--background: #ffffff")
117 assert.Contains(t, css, "--background: #101010")
118}
119
120func TestManager_GetBackgroundRGBAUsesCurrentPalette(t *testing.T) {
121 ctx := context.Background()
122 manager := NewManager(ctx, resolvedThemeFixture(true))
123
124 r, g, b, a := manager.GetBackgroundRGBA()
125
126 assert.InDelta(t, float32(0x10)/255, r, 0.0001)
127 assert.InDelta(t, float32(0x10)/255, g, 0.0001)
128 assert.InDelta(t, float32(0x10)/255, b, 0.0001)
129 assert.InDelta(t, float32(1), a, 0.0001)
130}
131
132func TestPaletteFromEntityAddsSemanticDefaults(t *testing.T) {
133 palette := PaletteFromEntity(entity.ColorPalette{Background: "#ffffff", Text: "#111111"}, false)
134
135 assert.Equal(t, "#ffffff", palette.Background)
136 assert.Equal(t, "#111111", palette.Text)
137 assert.Equal(t, DefaultLightPalette().Success, palette.Success)
138 assert.Equal(t, DefaultLightPalette().Warning, palette.Warning)
139 assert.Equal(t, DefaultLightPalette().Destructive, palette.Destructive)
140}
141
142func TestModeColorsFromEntity(t *testing.T) {
143 modeColors := ModeColorsFromEntity(entity.ThemeModeColors{
144 PaneMode: "#111111",
145 TabMode: "#222222",
146 SessionMode: "#333333",
147 ResizeMode: "#444444",
148 })
149
150 assert.Equal(t, "#111111", modeColors.PaneMode)
151 assert.Equal(t, "#222222", modeColors.TabMode)
152 assert.Equal(t, "#333333", modeColors.SessionMode)
153 assert.Equal(t, "#444444", modeColors.ResizeMode)
154}
155
156func TestFontConfigFromEntity(t *testing.T) {
157 fonts := FontConfigFromEntity(entity.ThemeFonts{
158 SansFont: "Inter",
159 MonospaceFont: "JetBrains Mono",
160 GtkFont: "Adwaita Sans",
161 })
162
163 assert.Equal(t, FontConfig{SansFont: "Inter", MonospaceFont: "JetBrains Mono", GtkFont: "Adwaita Sans"}, fonts)
164}
165
166func TestDefaultGTKFont(t *testing.T) {
167 assert.Equal(t, "Adwaita Sans", DefaultGTKFont())
168}
169
170func TestFormatGTKFontName_UsesScaledConfiguredGTKFont(t *testing.T) {
171 assert.Equal(t, "Adwaita Sans 14", formatGTKFontName("Adwaita Sans", 1.3))
172}
173
174func TestFormatGTKFontName_DefaultsScaleAndRoundsToNearestPoint(t *testing.T) {
175 assert.Equal(t, "Inter 11", formatGTKFontName("Inter", 0))
176 assert.Equal(t, "Inter 12", formatGTKFontName("Inter", 1.05))
177 assert.Equal(t, "Adwaita Sans 11", formatGTKFontName("", 1.0))
178}
179
180func TestShouldApplyGTKFontName(t *testing.T) {
181 assert.True(t, shouldApplyGTKFontName("", "Fira Sans 14"))
182 assert.False(t, shouldApplyGTKFontName("Fira Sans 14", "Fira Sans 14"))
183 assert.False(t, shouldApplyGTKFontName("Fira Sans 14", ""))
184}