From 81be3b701e116dc73bab326b5ddb6d7fe1435b6d Mon Sep 17 00:00:00 2001 From: Virgil Date: Thu, 2 Apr 2026 12:31:44 +0000 Subject: [PATCH] fix(cli): theme-aware semantic glyphs Keep section headers, check skips, and layout separators aligned with the active glyph theme. Co-Authored-By: Virgil --- pkg/cli/check.go | 2 +- pkg/cli/check_test.go | 3 +++ pkg/cli/output.go | 3 ++- pkg/cli/output_test.go | 16 ++++++++++++++++ pkg/cli/render.go | 4 ++-- pkg/cli/render_test.go | 30 ++++++++++++++++++++++++++++++ 6 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 pkg/cli/render_test.go diff --git a/pkg/cli/check.go b/pkg/cli/check.go index f2722a3..aa32898 100644 --- a/pkg/cli/check.go +++ b/pkg/cli/check.go @@ -38,7 +38,7 @@ func (c *CheckBuilder) Fail() *CheckBuilder { func (c *CheckBuilder) Skip() *CheckBuilder { c.status = "skipped" c.style = DimStyle - c.icon = "-" + c.icon = Glyph(":skip:") return c } diff --git a/pkg/cli/check_test.go b/pkg/cli/check_test.go index 55e561f..0871d4b 100644 --- a/pkg/cli/check_test.go +++ b/pkg/cli/check_test.go @@ -29,6 +29,9 @@ func TestCheckBuilder(t *testing.T) { if got == "" { t.Error("Empty output for Skip") } + if !strings.Contains(got, "[SKIP]") { + t.Error("Expected ASCII skip icon") + } // Warn c = Check("foo").Warn() diff --git a/pkg/cli/output.go b/pkg/cli/output.go index 4ddd308..e9c58e0 100644 --- a/pkg/cli/output.go +++ b/pkg/cli/output.go @@ -147,7 +147,8 @@ func Task(label, message string) { // // cli.Section("audit") // ── AUDIT ── func Section(name string) { - header := "── " + strings.ToUpper(compileGlyphs(name)) + " ──" + dash := Glyph(":dash:") + header := dash + dash + " " + strings.ToUpper(compileGlyphs(name)) + " " + dash + dash fmt.Println(AccentStyle.Render(header)) } diff --git a/pkg/cli/output_test.go b/pkg/cli/output_test.go index 48e096c..0930285 100644 --- a/pkg/cli/output_test.go +++ b/pkg/cli/output_test.go @@ -125,3 +125,19 @@ func TestSemanticOutput_GlyphShortcodes(t *testing.T) { t.Fatalf("expected progress item shortcode to be rendered, got %q", out) } } + +func TestSection_GlyphTheme(t *testing.T) { + restoreThemeAndColors(t) + UseASCII() + + out := captureOutput(func() { + Section("audit") + }) + + if !strings.Contains(out, "-- AUDIT --") { + t.Fatalf("expected ASCII section header, got %q", out) + } + if strings.Contains(out, "── AUDIT ──") { + t.Fatalf("expected glyph theme to avoid unicode dashes, got %q", out) + } +} diff --git a/pkg/cli/render.go b/pkg/cli/render.go index 95bb05c..baab337 100644 --- a/pkg/cli/render.go +++ b/pkg/cli/render.go @@ -66,9 +66,9 @@ func (c *Composite) renderSeparator(sb *strings.Builder, depth int) { indent := strings.Repeat(" ", depth) switch currentRenderStyle { case RenderBoxed: - sb.WriteString(indent + "├" + strings.Repeat("─", 40) + "┤\n") + sb.WriteString(indent + Glyph(":tee:") + strings.Repeat(Glyph(":dash:"), 40) + Glyph(":tee:") + "\n") case RenderSimple: - sb.WriteString(indent + strings.Repeat("─", 40) + "\n") + sb.WriteString(indent + strings.Repeat(Glyph(":dash:"), 40) + "\n") } } diff --git a/pkg/cli/render_test.go b/pkg/cli/render_test.go new file mode 100644 index 0000000..e99e96f --- /dev/null +++ b/pkg/cli/render_test.go @@ -0,0 +1,30 @@ +package cli + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestCompositeRender_GlyphTheme(t *testing.T) { + prevStyle := currentRenderStyle + t.Cleanup(func() { + currentRenderStyle = prevStyle + }) + + restoreThemeAndColors(t) + UseASCII() + + c := Layout("HCF") + c.H("header").C("content").F("footer") + + UseRenderSimple() + out := c.String() + assert.Contains(t, out, strings.Repeat("-", 40)) + + UseRenderBoxed() + out = c.String() + assert.Contains(t, out, "+") + assert.Contains(t, out, strings.Repeat("-", 40)) +} -- 2.45.3