Skip to content

Commit a3ea5ea

Browse files
committed
fix: proper style precedence slide > preset > global
feat: use explicit builtin themes on documentation presentation to always be available
1 parent 2bcb27e commit a3ea5ea

File tree

4 files changed

+387
-55
lines changed

4 files changed

+387
-55
lines changed

docs/presentation.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ title: Welcome
33
image_backend: docs
44
style:
55
border: hidden
6+
theme: dark
67
---
78

89
![img|43x10](kyma_logo.png)
@@ -90,6 +91,7 @@ style:
9091
title: Style usage
9192
style:
9293
border: hidden
94+
theme: dracula
9395
transition: swipeLeft
9496
---
9597

@@ -110,7 +112,8 @@ style:
110112
----
111113
---
112114
title: Config
113-
preset: dark
115+
style:
116+
theme: dracula
114117
---
115118
116119
# Configuration
@@ -143,6 +146,8 @@ presets:
143146
----
144147
---
145148
title: Global styles
149+
style:
150+
theme: dracula
146151
---
147152

148153
# Global styles
@@ -175,6 +180,8 @@ presets:
175180
----
176181
---
177182
title: Presets
183+
style:
184+
theme: dracula
178185
---
179186

180187
# Presets
@@ -207,6 +214,8 @@ presets:
207214
----
208215
---
209216
title: More ways to navigate
217+
style:
218+
theme: dracula
210219
---
211220

212221
# More ways to navigate
@@ -221,6 +230,8 @@ title: More ways to navigate
221230
title: Achievements
222231
transition: swipeLeft
223232
image_backend: docs
233+
style:
234+
theme: dracula
224235
---
225236

226237
# Achievements

internal/config/config_test.go

Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@ import (
55
"path/filepath"
66
"testing"
77

8+
glamourStyles "github.com/charmbracelet/glamour/styles"
9+
"github.com/charmbracelet/lipgloss"
10+
"github.com/goccy/go-yaml"
811
"github.com/spf13/viper"
12+
13+
"github.com/museslabs/kyma/internal/tui/transitions"
914
)
1015

1116
func TestLoad(t *testing.T) {
@@ -234,3 +239,282 @@ func TestCreateDefaultConfig(t *testing.T) {
234239
)
235240
}
236241
}
242+
243+
func TestPrecedence(t *testing.T) {
244+
tmpDir := t.TempDir()
245+
246+
testConfig := `global:
247+
style:
248+
border: rounded
249+
border_color: "#FF0000"
250+
layout: center
251+
theme: dark
252+
253+
presets:
254+
test:
255+
style:
256+
border: hidden
257+
theme: notty
258+
border_color: "#fff"
259+
layout: center
260+
`
261+
testConfigPath := filepath.Join(tmpDir, "kyma.yaml")
262+
if err := os.WriteFile(testConfigPath, []byte(testConfig), 0644); err != nil {
263+
t.Fatalf("Failed to write test config: %v", err)
264+
}
265+
266+
if err := Load(testConfigPath); err != nil {
267+
t.Fatalf("Load() error = %v", err)
268+
}
269+
270+
tests := []struct {
271+
name string
272+
properties string
273+
want Properties
274+
}{
275+
{
276+
name: "slide properties should override global ones",
277+
properties: `style:
278+
border: hidden
279+
border_color: "#000"
280+
layout: left
281+
theme: dracula`,
282+
want: Properties{
283+
Title: "",
284+
Style: StyleConfig{
285+
Layout: func() *lipgloss.Style {
286+
s := lipgloss.NewStyle().Align(lipgloss.Left, lipgloss.Left)
287+
return &s
288+
}(),
289+
Border: func() *lipgloss.Border {
290+
b := lipgloss.HiddenBorder()
291+
return &b
292+
}(),
293+
BorderColor: "#000",
294+
Theme: &GlamourTheme{
295+
Style: *glamourStyles.DefaultStyles["dracula"],
296+
Name: "dracula",
297+
},
298+
},
299+
Transition: transitions.Get("none", transitions.Fps),
300+
Notes: "",
301+
ImageBackend: "chafa",
302+
},
303+
},
304+
{
305+
name: "border from default styles",
306+
properties: `style:
307+
border_color: "#000"
308+
layout: left
309+
theme: dracula`,
310+
want: Properties{
311+
Title: "",
312+
Style: StyleConfig{
313+
Layout: func() *lipgloss.Style {
314+
s := lipgloss.NewStyle().Align(lipgloss.Left, lipgloss.Left)
315+
return &s
316+
}(),
317+
Border: func() *lipgloss.Border {
318+
b := lipgloss.RoundedBorder()
319+
return &b
320+
}(),
321+
BorderColor: "#000",
322+
Theme: &GlamourTheme{
323+
Style: *glamourStyles.DefaultStyles["dracula"],
324+
Name: "dracula",
325+
},
326+
},
327+
Transition: transitions.Get("none", transitions.Fps),
328+
Notes: "",
329+
ImageBackend: "chafa",
330+
},
331+
},
332+
{
333+
name: "border color from default styles",
334+
properties: `style:
335+
border: hidden
336+
layout: left
337+
theme: dracula`,
338+
want: Properties{
339+
Title: "",
340+
Style: StyleConfig{
341+
Layout: func() *lipgloss.Style {
342+
s := lipgloss.NewStyle().Align(lipgloss.Left, lipgloss.Left)
343+
return &s
344+
}(),
345+
Border: func() *lipgloss.Border {
346+
b := lipgloss.HiddenBorder()
347+
return &b
348+
}(),
349+
BorderColor: "#FF0000",
350+
Theme: &GlamourTheme{
351+
Style: *glamourStyles.DefaultStyles["dracula"],
352+
Name: "dracula",
353+
},
354+
},
355+
Transition: transitions.Get("none", transitions.Fps),
356+
Notes: "",
357+
ImageBackend: "chafa",
358+
},
359+
},
360+
{
361+
name: "layout from default styles",
362+
properties: `style:
363+
border: hidden
364+
border_color: "#000"
365+
theme: dracula`,
366+
want: Properties{
367+
Title: "",
368+
Style: StyleConfig{
369+
Layout: func() *lipgloss.Style {
370+
s := lipgloss.NewStyle().Align(lipgloss.Center, lipgloss.Center)
371+
return &s
372+
}(),
373+
Border: func() *lipgloss.Border {
374+
b := lipgloss.HiddenBorder()
375+
return &b
376+
}(),
377+
BorderColor: "#000",
378+
Theme: &GlamourTheme{
379+
Style: *glamourStyles.DefaultStyles["dracula"],
380+
Name: "dracula",
381+
},
382+
},
383+
Transition: transitions.Get("none", transitions.Fps),
384+
Notes: "",
385+
ImageBackend: "chafa",
386+
},
387+
},
388+
{
389+
name: "theme from default styles",
390+
properties: `style:
391+
border: hidden
392+
border_color: "#000"
393+
layout: left`,
394+
want: Properties{
395+
Title: "",
396+
Style: StyleConfig{
397+
Layout: func() *lipgloss.Style {
398+
s := lipgloss.NewStyle().Align(lipgloss.Left, lipgloss.Left)
399+
return &s
400+
}(),
401+
Border: func() *lipgloss.Border {
402+
b := lipgloss.HiddenBorder()
403+
return &b
404+
}(),
405+
BorderColor: "#000",
406+
Theme: &GlamourTheme{
407+
Style: *glamourStyles.DefaultStyles["dark"],
408+
Name: "dark",
409+
},
410+
},
411+
Transition: transitions.Get("none", transitions.Fps),
412+
Notes: "",
413+
ImageBackend: "chafa",
414+
},
415+
},
416+
{
417+
name: "use a preset",
418+
properties: `preset: test`,
419+
want: Properties{
420+
Title: "",
421+
Style: StyleConfig{
422+
Layout: func() *lipgloss.Style {
423+
s := lipgloss.NewStyle().Align(lipgloss.Center, lipgloss.Center)
424+
return &s
425+
}(),
426+
Border: func() *lipgloss.Border {
427+
b := lipgloss.HiddenBorder()
428+
return &b
429+
}(),
430+
BorderColor: "#fff",
431+
Theme: &GlamourTheme{
432+
Style: *glamourStyles.DefaultStyles["notty"],
433+
Name: "notty",
434+
},
435+
},
436+
Transition: transitions.Get("none", transitions.Fps),
437+
Notes: "",
438+
ImageBackend: "chafa",
439+
},
440+
},
441+
{
442+
name: "use a preset and override border",
443+
properties: `preset: test
444+
style:
445+
border: rounded`,
446+
want: Properties{
447+
Title: "",
448+
Style: StyleConfig{
449+
Layout: func() *lipgloss.Style {
450+
s := lipgloss.NewStyle().Align(lipgloss.Center, lipgloss.Center)
451+
return &s
452+
}(),
453+
Border: func() *lipgloss.Border {
454+
b := lipgloss.RoundedBorder()
455+
return &b
456+
}(),
457+
BorderColor: "#fff",
458+
Theme: &GlamourTheme{
459+
Style: *glamourStyles.DefaultStyles["notty"],
460+
Name: "notty",
461+
},
462+
},
463+
Transition: transitions.Get("none", transitions.Fps),
464+
Notes: "",
465+
ImageBackend: "chafa",
466+
},
467+
},
468+
}
469+
for _, tt := range tests {
470+
t.Run(tt.name, func(t *testing.T) {
471+
var p Properties
472+
if err := yaml.Unmarshal([]byte(tt.properties), &p); err != nil {
473+
t.Fatalf("yaml.Unmarshal() error = %v", err)
474+
}
475+
476+
if p.Title != tt.want.Title {
477+
t.Errorf("p.Title = %s, want = %s", p.Title, tt.want.Title)
478+
}
479+
480+
if p.Transition != tt.want.Transition {
481+
t.Errorf("p.Transition = %s, want = %s", p.Transition, tt.want.Transition)
482+
}
483+
484+
if p.Notes != tt.want.Notes {
485+
t.Errorf("p.Notes = %s, want = %s", p.Notes, tt.want.Notes)
486+
}
487+
488+
if p.ImageBackend != tt.want.ImageBackend {
489+
t.Errorf("p.ImageBackend = %s, want = %s", p.ImageBackend, tt.want.ImageBackend)
490+
}
491+
492+
if p.Style.BorderColor != tt.want.Style.BorderColor {
493+
t.Errorf(
494+
"p.Style.BorderColor = %s, want = %s",
495+
p.Style.BorderColor,
496+
tt.want.Style.BorderColor,
497+
)
498+
}
499+
500+
if *p.Style.Border != *tt.want.Style.Border {
501+
t.Errorf("p.Style.Border = %v, want = %v", p.Style.Border, tt.want.Style.Border)
502+
}
503+
504+
if *p.Style.Theme != *tt.want.Style.Theme {
505+
t.Errorf("p.Style.Theme = %v, want = %v", p.Style.Theme, tt.want.Style.Theme)
506+
}
507+
508+
if p.Style.Layout.GetAlignHorizontal() != tt.want.Style.Layout.GetAlignHorizontal() ||
509+
p.Style.Layout.GetAlignVertical() != tt.want.Style.Layout.GetAlignVertical() {
510+
t.Errorf(
511+
"p.Style.Layout = %f, %f, want = %f, %f",
512+
p.Style.Layout.GetAlignHorizontal(),
513+
p.Style.Layout.GetAlignVertical(),
514+
tt.want.Style.Layout.GetAlignHorizontal(),
515+
tt.want.Style.Layout.GetAlignVertical(),
516+
)
517+
}
518+
})
519+
}
520+
}

0 commit comments

Comments
 (0)