• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

fyne-io / fyne / 13061161551

30 Jan 2025 09:01PM UTC coverage: 60.858% (+1.7%) from 59.117%
13061161551

Pull #5431

github

dweymouth
address review comments
Pull Request #5431: Add new callback-based settings listener API

22 of 52 new or added lines in 6 files covered. (42.31%)

528 existing lines in 26 files now uncovered.

25006 of 41089 relevant lines covered (60.86%)

817.06 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.0
/test/theme.go
1
package test
2

3
import (
4
        "fmt"
5
        "image/color"
6
        "testing"
7

8
        "github.com/stretchr/testify/assert"
9

10
        "fyne.io/fyne/v2"
11
        "fyne.io/fyne/v2/theme"
12
)
13

14
var defaultTheme fyne.Theme
15

16
// Try to keep these in sync with the existing color names at theme/color.go.
17
var knownColorNames = []fyne.ThemeColorName{
18
        theme.ColorNameBackground,
19
        theme.ColorNameButton,
20
        theme.ColorNameDisabled,
21
        theme.ColorNameDisabledButton,
22
        theme.ColorNameError,
23
        theme.ColorNameFocus,
24
        theme.ColorNameForeground,
25
        theme.ColorNameForegroundOnError,
26
        theme.ColorNameForegroundOnPrimary,
27
        theme.ColorNameForegroundOnSuccess,
28
        theme.ColorNameForegroundOnWarning,
29
        theme.ColorNameHeaderBackground,
30
        theme.ColorNameHover,
31
        theme.ColorNameHyperlink,
32
        theme.ColorNameInputBackground,
33
        theme.ColorNameInputBorder,
34
        theme.ColorNameMenuBackground,
35
        theme.ColorNameOverlayBackground,
36
        theme.ColorNamePlaceHolder,
37
        theme.ColorNamePressed,
38
        theme.ColorNamePrimary,
39
        theme.ColorNameScrollBar,
40
        theme.ColorNameSelection,
41
        theme.ColorNameSeparator,
42
        theme.ColorNameShadow,
43
        theme.ColorNameSuccess,
44
        theme.ColorNameWarning,
45
}
46

47
// AssertAllColorNamesDefined asserts that all known color names are defined for the given theme.
48
func AssertAllColorNamesDefined(t *testing.T, th fyne.Theme, themeName string) {
2✔
49
        oldApp := fyne.CurrentApp()
2✔
50
        defer fyne.SetCurrentApp(oldApp)
2✔
51

2✔
52
        for _, primaryName := range theme.PrimaryColorNames() {
18✔
53
                testApp := NewTempApp(t)
16✔
54
                testApp.Settings().(*testSettings).primaryColor = primaryName
16✔
55
                for variantName, variant := range KnownThemeVariants() {
48✔
56
                        for _, cn := range knownColorNames {
896✔
57
                                assert.NotNil(t, th.Color(cn, variant), "undefined color %s variant %s in theme %s", cn, variantName, themeName)
864✔
58
                                // Transparent is used by the default theme as fallback for unknown color names.
864✔
59
                                // Built-in color names should have well-defined non-transparent values.
864✔
60
                                assert.NotEqual(t, color.Transparent, th.Color(cn, variant), "undefined color %s variant %s in theme %s", cn, variantName, themeName)
864✔
61
                        }
864✔
62
                }
63
        }
64
}
65

66
// KnownThemeVariants returns the known theme variants mapped by a descriptive key.
67
func KnownThemeVariants() map[string]fyne.ThemeVariant {
18✔
68
        // Try to keep this in sync with the existing variants at theme/theme.go
18✔
69
        return map[string]fyne.ThemeVariant{
18✔
70
                "dark":  theme.VariantDark,
18✔
71
                "light": theme.VariantLight,
18✔
72
        }
18✔
73
}
18✔
74

75
// NewTheme returns a new test theme using quiet ugly colors.
76
func NewTheme() fyne.Theme {
2✔
77
        blue := func(alpha uint8) color.Color {
18✔
78
                return &color.NRGBA{R: 0, G: 0, B: 255, A: alpha}
16✔
79
        }
16✔
80
        gray := func(level uint8) color.Color {
14✔
81
                return &color.Gray{Y: level}
12✔
82
        }
12✔
83
        green := func(alpha uint8) color.Color {
8✔
84
                return &color.NRGBA{R: 0, G: 255, B: 0, A: alpha}
6✔
85
        }
6✔
86
        red := func(alpha uint8) color.Color {
22✔
87
                return &color.NRGBA{R: 200, G: 0, B: 0, A: alpha}
20✔
88
        }
20✔
89

90
        return &configurableTheme{
2✔
91
                colors: map[fyne.ThemeColorName]color.Color{
2✔
92
                        theme.ColorNameBackground:          red(255),
2✔
93
                        theme.ColorNameButton:              gray(100),
2✔
94
                        theme.ColorNameDisabled:            gray(20),
2✔
95
                        theme.ColorNameDisabledButton:      gray(230),
2✔
96
                        theme.ColorNameError:               blue(255),
2✔
97
                        theme.ColorNameFocus:               red(66),
2✔
98
                        theme.ColorNameForeground:          gray(255),
2✔
99
                        theme.ColorNameForegroundOnError:   red(210),
2✔
100
                        theme.ColorNameForegroundOnPrimary: red(200),
2✔
101
                        theme.ColorNameForegroundOnSuccess: blue(201),
2✔
102
                        theme.ColorNameForegroundOnWarning: blue(202),
2✔
103
                        theme.ColorNameHeaderBackground:    red(22),
2✔
104
                        theme.ColorNameHover:               green(200),
2✔
105
                        theme.ColorNameHyperlink:           blue(240),
2✔
106
                        theme.ColorNameInputBackground:     red(30),
2✔
107
                        theme.ColorNameInputBorder:         gray(10),
2✔
108
                        theme.ColorNameMenuBackground:      red(50),
2✔
109
                        theme.ColorNameOverlayBackground:   red(44),
2✔
110
                        theme.ColorNamePlaceHolder:         blue(200),
2✔
111
                        theme.ColorNamePressed:             blue(250),
2✔
112
                        theme.ColorNamePrimary:             green(255),
2✔
113
                        theme.ColorNameScrollBar:           blue(220),
2✔
114
                        theme.ColorNameSelection:           red(55),
2✔
115
                        theme.ColorNameSeparator:           gray(30),
2✔
116
                        theme.ColorNameShadow:              blue(150),
2✔
117
                        theme.ColorNameSuccess:             green(150),
2✔
118
                        theme.ColorNameWarning:             red(100),
2✔
119
                },
2✔
120
                fonts: map[fyne.TextStyle]fyne.Resource{
2✔
121
                        {}:                         theme.DefaultTextBoldFont(),
2✔
122
                        {Bold: true}:               theme.DefaultTextItalicFont(),
2✔
123
                        {Bold: true, Italic: true}: theme.DefaultTextMonospaceFont(),
2✔
124
                        {Italic: true}:             theme.DefaultTextBoldItalicFont(),
2✔
125
                        {Monospace: true}:          theme.DefaultTextFont(),
2✔
126
                        {Symbol: true}:             theme.DefaultSymbolFont(),
2✔
127
                },
2✔
128
                name: "Ugly Test Theme",
2✔
129
                sizes: map[fyne.ThemeSizeName]float32{
2✔
130
                        theme.SizeNameInlineIcon:         float32(24),
2✔
131
                        theme.SizeNameInnerPadding:       float32(20),
2✔
132
                        theme.SizeNameLineSpacing:        float32(6),
2✔
133
                        theme.SizeNamePadding:            float32(10),
2✔
134
                        theme.SizeNameScrollBar:          float32(10),
2✔
135
                        theme.SizeNameScrollBarSmall:     float32(2),
2✔
136
                        theme.SizeNameSeparatorThickness: float32(1),
2✔
137
                        theme.SizeNameText:               float32(18),
2✔
138
                        theme.SizeNameHeadingText:        float32(30.6),
2✔
139
                        theme.SizeNameSubHeadingText:     float32(24),
2✔
140
                        theme.SizeNameCaptionText:        float32(15),
2✔
141
                        theme.SizeNameInputBorder:        float32(5),
2✔
142
                        theme.SizeNameInputRadius:        float32(2),
2✔
143
                        theme.SizeNameSelectionRadius:    float32(6),
2✔
144
                        theme.SizeNameScrollBarRadius:    float32(2),
2✔
145
                },
2✔
146
        }
2✔
147
}
148

149
// Theme returns a test theme useful for image based tests.
150
func Theme() fyne.Theme {
37✔
151
        if defaultTheme == nil {
38✔
152
                defaultTheme = &configurableTheme{
1✔
153
                        colors: map[fyne.ThemeColorName]color.Color{
1✔
154
                                theme.ColorNameBackground:          color.NRGBA{R: 0x44, G: 0x44, B: 0x44, A: 0xff},
1✔
155
                                theme.ColorNameButton:              color.NRGBA{R: 0x33, G: 0x33, B: 0x33, A: 0xff},
1✔
156
                                theme.ColorNameDisabled:            color.NRGBA{R: 0x88, G: 0x88, B: 0x88, A: 0xff},
1✔
157
                                theme.ColorNameDisabledButton:      color.NRGBA{R: 0x22, G: 0x22, B: 0x22, A: 0xff},
1✔
158
                                theme.ColorNameError:               color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0xff},
1✔
159
                                theme.ColorNameFocus:               color.NRGBA{R: 0x78, G: 0x3a, B: 0x3a, A: 0xff},
1✔
160
                                theme.ColorNameForeground:          color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff},
1✔
161
                                theme.ColorNameForegroundOnError:   color.NRGBA{R: 0x08, G: 0x0a, B: 0x0f, A: 0xff},
1✔
162
                                theme.ColorNameForegroundOnPrimary: color.NRGBA{R: 0x08, G: 0x0c, B: 0x0f, A: 0xff},
1✔
163
                                theme.ColorNameForegroundOnSuccess: color.NRGBA{R: 0x0a, G: 0x0c, B: 0x0f, A: 0xff},
1✔
164
                                theme.ColorNameForegroundOnWarning: color.NRGBA{R: 0x08, G: 0x0c, B: 0x0a, A: 0xff},
1✔
165
                                theme.ColorNameHeaderBackground:    color.NRGBA{R: 0x25, G: 0x25, B: 0x25, A: 0xff},
1✔
166
                                theme.ColorNameHover:               color.NRGBA{R: 0x88, G: 0xff, B: 0xff, A: 0x22},
1✔
167
                                theme.ColorNameHyperlink:           color.NRGBA{R: 0xff, G: 0xcc, B: 0x80, A: 0xff},
1✔
168
                                theme.ColorNameInputBackground:     color.NRGBA{R: 0x66, G: 0x66, B: 0x66, A: 0xff},
1✔
169
                                theme.ColorNameInputBorder:         color.NRGBA{R: 0x86, G: 0x86, B: 0x86, A: 0xff},
1✔
170
                                theme.ColorNameMenuBackground:      color.NRGBA{R: 0x56, G: 0x56, B: 0x56, A: 0xff},
1✔
171
                                theme.ColorNameOverlayBackground:   color.NRGBA{R: 0x28, G: 0x28, B: 0x28, A: 0xff},
1✔
172
                                theme.ColorNamePlaceHolder:         color.NRGBA{R: 0xaa, G: 0xaa, B: 0xaa, A: 0xff},
1✔
173
                                theme.ColorNamePressed:             color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x33},
1✔
174
                                theme.ColorNamePrimary:             color.NRGBA{R: 0xff, G: 0xc0, B: 0x80, A: 0xff},
1✔
175
                                theme.ColorNameScrollBar:           color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0xaa},
1✔
176
                                theme.ColorNameSelection:           color.NRGBA{R: 0x78, G: 0x3a, B: 0x3a, A: 0x99},
1✔
177
                                theme.ColorNameSeparator:           color.NRGBA{R: 0x90, G: 0x90, B: 0x90, A: 0xff},
1✔
178
                                theme.ColorNameShadow:              color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x88},
1✔
179
                                theme.ColorNameSuccess:             color.NRGBA{R: 0x00, G: 0x99, B: 0x00, A: 0xff},
1✔
180
                                theme.ColorNameWarning:             color.NRGBA{R: 0xee, G: 0xee, B: 0x00, A: 0xff},
1✔
181
                        },
1✔
182
                        fonts: map[fyne.TextStyle]fyne.Resource{
1✔
183
                                {}:                         theme.DefaultTextFont(),
1✔
184
                                {Bold: true}:               theme.DefaultTextBoldFont(),
1✔
185
                                {Bold: true, Italic: true}: theme.DefaultTextBoldItalicFont(),
1✔
186
                                {Italic: true}:             theme.DefaultTextItalicFont(),
1✔
187
                                {Monospace: true}:          theme.DefaultTextMonospaceFont(),
1✔
188
                                {Symbol: true}:             theme.DefaultSymbolFont(),
1✔
189
                        },
1✔
190
                        name: "Default Test Theme",
1✔
191
                        sizes: map[fyne.ThemeSizeName]float32{
1✔
192
                                theme.SizeNameInlineIcon:         float32(20),
1✔
193
                                theme.SizeNameInnerPadding:       float32(8),
1✔
194
                                theme.SizeNameLineSpacing:        float32(4),
1✔
195
                                theme.SizeNamePadding:            float32(4),
1✔
196
                                theme.SizeNameScrollBar:          float32(16),
1✔
197
                                theme.SizeNameScrollBarSmall:     float32(3),
1✔
198
                                theme.SizeNameSeparatorThickness: float32(1),
1✔
199
                                theme.SizeNameText:               float32(14),
1✔
200
                                theme.SizeNameHeadingText:        float32(23.8),
1✔
201
                                theme.SizeNameSubHeadingText:     float32(18),
1✔
202
                                theme.SizeNameCaptionText:        float32(11),
1✔
203
                                theme.SizeNameInputBorder:        float32(2),
1✔
204
                                theme.SizeNameInputRadius:        float32(4),
1✔
205
                                theme.SizeNameSelectionRadius:    float32(4),
1✔
206
                                theme.SizeNameScrollBarRadius:    float32(3),
1✔
207
                        },
1✔
208
                }
1✔
209
        }
1✔
210
        return defaultTheme
1✔
211
}
1✔
212

1✔
213
type configurableTheme struct {
1✔
214
        colors map[fyne.ThemeColorName]color.Color
37✔
215
        fonts  map[fyne.TextStyle]fyne.Resource
216
        name   string
217
        sizes  map[fyne.ThemeSizeName]float32
218
}
219

220
var _ fyne.Theme = (*configurableTheme)(nil)
221

222
func (t *configurableTheme) Color(n fyne.ThemeColorName, _ fyne.ThemeVariant) color.Color {
223
        if t.colors[n] == nil {
224
                fyne.LogError(fmt.Sprintf("color %s not defined in theme %s", n, t.name), nil)
225
        }
226

3,498✔
227
        return t.colors[n]
3,498✔
UNCOV
228
}
×
UNCOV
229

×
230
func (t *configurableTheme) Font(style fyne.TextStyle) fyne.Resource {
231
        if t.fonts[style] == nil {
3,498✔
232
                fyne.LogError(fmt.Sprintf("font for style %#v not defined in theme %s", style, t.name), nil)
233
        }
234

6✔
235
        return t.fonts[style]
6✔
UNCOV
236
}
×
UNCOV
237

×
238
func (t *configurableTheme) Icon(n fyne.ThemeIconName) fyne.Resource {
239
        return theme.DefaultTheme().Icon(n)
6✔
240
}
241

242
func (t *configurableTheme) Size(s fyne.ThemeSizeName) float32 {
1,370✔
243
        if _, ok := t.sizes[s]; !ok {
1,370✔
244
                fyne.LogError(fmt.Sprintf("size %s not defined in theme %s", s, t.name), nil)
1,370✔
245
                return 0
246
        }
108✔
247

108✔
UNCOV
248
        return t.sizes[s]
×
UNCOV
249
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc