1package daemon
2
3import (
4 "testing"
5
6 "github.com/stretchr/testify/require"
7
8 renderer "github.com/bnema/vev-vt"
9 "github.com/bnema/vev/internal/domain"
10 "github.com/bnema/vev/internal/domain/terminalcap"
11 themeui "github.com/bnema/vev/internal/usecase/theme"
12)
13
14func TestBarBackgroundConfigResolvesBarSurface(t *testing.T) {
15 paletteColors := [16]renderer.RGB{}
16 paletteColors[4] = renderer.RGB{R: 40, G: 90, B: 220}
17 raw := themeui.Theme{
18 Foreground: renderer.RGB{R: 230, G: 230, B: 230}, Background: renderer.RGB{R: 8, G: 9, B: 10},
19 HasFG: true, HasBG: true, Known: true, UsePalette: true,
20 Palette: paletteColors, PaletteKnown: 1 << 4,
21 }
22
23 tests := []struct {
24 name string
25 mode domain.ThemeMode
26 paletteOff bool
27 transparent bool
28 }{
29 {name: "accent themed"},
30 {name: "accent transparent", transparent: true},
31 {name: "palette off transparent", paletteOff: true, transparent: true},
32 {name: "forced dark transparent", mode: domain.ThemeDark, transparent: true},
33 }
34 for _, tt := range tests {
35 t.Run(tt.name, func(t *testing.T) {
36 cfg := domain.Defaults()
37 cfg.Theme = tt.mode
38 cfg.ThemePalette = !tt.paletteOff
39 cfg.Bar.Transparent = tt.transparent
40 d := newTestDaemon(t, nil, stubClock{})
41 d.ApplyConfig(cfg)
42
43 themedCfg := themeConfigSnapshot{mode: cfg.Theme, paletteOff: tt.paletteOff, accent: cfg.ThemeAccent}
44 themed := themeui.ResolveForColor(effectiveThemeForConfig(raw, themedCfg), cfg.ThemeAccent, terminalcap.ColorCapabilities{}).Styles
45 require.False(t, themed.SurfaceBar.Equal(renderer.DefaultStyle()), "fixture must produce a tinted bar")
46
47 got := d.resolveAppliedTheme(raw, terminalcap.ColorCapabilities{}).Resolved.Styles
48
49 if tt.transparent {
50 require.True(t, got.SurfaceBar.Equal(renderer.DefaultStyle()), "bar fill uses the terminal background")
51 } else {
52 require.True(t, got.SurfaceBar.Equal(themed.SurfaceBar))
53 }
54 // Every other role keeps its theme colors.
55 require.True(t, got.SurfaceInactive.Equal(themed.SurfaceInactive))
56 require.True(t, got.TabActive.Equal(themed.TabActive))
57 require.True(t, got.MRUStyle(0, 2).Equal(themed.MRUStyle(0, 2)))
58 require.True(t, got.CopyStatus.Equal(themed.CopyStatus))
59 require.True(t, got.StatusBar.Equal(themed.StatusBar))
60 })
61 }
62}
63
64func TestApplyConfigBarBackgroundRepaintsBars(t *testing.T) {
65 p, releasePTY := newBlockingPTY(t)
66 d, sess, ac, _ := newManualSessionWithPTYs(t, p)
67 defer releasePTY()
68 d.ApplyConfig(domain.Config{Theme: domain.ThemeDark})
69
70 win := testAttachmentTab(sess)
71 win.mu.Lock()
72 win.size = domain.Size{Cols: 40, Rows: 4}
73 win.mu.Unlock()
74 pane := win.focusedPane()
75 pane.mu.Lock()
76 pane.screen.Resize(40, 4)
77 pane.mu.Unlock()
78
79 d.paint(sess, ac, true, nil)
80 ac.sendMu.Lock()
81 require.True(t, ac.render.cache.valid)
82 themedFill := ac.render.cache.frame.At(39, 0).Style
83 themedTab := ac.render.cache.frame.At(1, 0).Style
84 ac.sendMu.Unlock()
85 require.False(t, themedFill.Equal(renderer.DefaultStyle()), "themed bar fill is tinted")
86
87 d.ApplyConfig(domain.Config{Theme: domain.ThemeDark, Bar: domain.BarConfig{Transparent: true}})
88
89 ac.sendMu.Lock()
90 defer ac.sendMu.Unlock()
91 require.True(t, ac.render.cache.valid)
92 require.True(t, ac.render.cache.frame.At(39, 0).Style.Equal(renderer.DefaultStyle()), "reload clears the bar fill")
93 require.True(t, ac.render.cache.frame.At(1, 0).Style.Equal(themedTab), "tab keeps its theme style")
94}