From 3c38cedaf3949018cbcbab63fc7c280481e39fa0 Mon Sep 17 00:00:00 2001 From: Andy Feller Date: Mon, 31 Mar 2025 15:33:52 -0400 Subject: [PATCH] Implement tests for muted logic, standardize reset This commit covers testing around the new ColorScheme.Muted logic based on various situations to gain confidence we get the accessible colors expected when enabled. Additionally, this commit includes a small change to the existing 8-bit color logic to standardize on the same reset sequence for testing purposes. Essentially, `ESC[m` and `ESC[0m` are equivalent but this inconsistency with our other libraries makes setting up tests a little extra confusing and difficult. --- pkg/cmd/gist/list/list_test.go | 6 ++-- pkg/iostreams/color.go | 6 ++-- pkg/iostreams/color_test.go | 64 ++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 5 deletions(-) diff --git a/pkg/cmd/gist/list/list_test.go b/pkg/cmd/gist/list/list_test.go index 4f6c8a9f7..ad6d8cdb5 100644 --- a/pkg/cmd/gist/list/list_test.go +++ b/pkg/cmd/gist/list/list_test.go @@ -487,8 +487,8 @@ func Test_listRun(t *testing.T) { }, wantOut: heredoc.Docf(` %[1]s[0;4;39mID %[1]s[0m %[1]s[0;4;39mDESCRIPTION %[1]s[0m %[1]s[0;4;39mFILES %[1]s[0m %[1]s[0;4;39mVISIBILITY%[1]s[0m %[1]s[0;4;39mUPDATED %[1]s[0m - 1234 %[1]s[0;30;43mocto%[1]s[0m%[1]s[0;1;39m match in the description%[1]s[0m 1 file %[1]s[0;32mpublic %[1]s[0m %[1]s[38;5;242mabout 6 hours ago%[1]s[m - 2345 %[1]s[0;1;39mmatch in the file name %[1]s[0m %[1]s[0;30;43m2 files%[1]s[0m %[1]s[0;31msecret %[1]s[0m %[1]s[38;5;242mabout 6 hours ago%[1]s[m + 1234 %[1]s[0;30;43mocto%[1]s[0m%[1]s[0;1;39m match in the description%[1]s[0m 1 file %[1]s[0;32mpublic %[1]s[0m %[1]s[38;5;242mabout 6 hours ago%[1]s[0m + 2345 %[1]s[0;1;39mmatch in the file name %[1]s[0m %[1]s[0;30;43m2 files%[1]s[0m %[1]s[0;31msecret %[1]s[0m %[1]s[38;5;242mabout 6 hours ago%[1]s[0m `, "\x1b"), }, { @@ -694,7 +694,7 @@ func Test_highlightMatch(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - cs := iostreams.NewColorScheme(tt.color, false, false, iostreams.NoTheme) + cs := iostreams.NewColorScheme(tt.color, false, false, false, iostreams.NoTheme) matched := false got, err := highlightMatch(tt.input, regex, &matched, cs.Blue, cs.Highlight) diff --git a/pkg/iostreams/color.go b/pkg/iostreams/color.go index 3e2d08ac2..9e6c4f7ca 100644 --- a/pkg/iostreams/color.go +++ b/pkg/iostreams/color.go @@ -37,7 +37,7 @@ var ( noThemeTableHeader = ansi.ColorFunc("default+u") gray256 = func(t string) string { - return fmt.Sprintf("\x1b[%d;5;%dm%s\x1b[m", 38, 242, t) + return fmt.Sprintf("\x1b[%d;5;%dm%s\x1b[0m", 38, 242, t) } ) @@ -91,8 +91,10 @@ func (c *ColorScheme) Muted(t string) string { switch c.theme { case LightTheme: return lightThemeMuted(t) - default: + case DarkTheme: return darkThemeMuted(t) + default: + return t } } diff --git a/pkg/iostreams/color_test.go b/pkg/iostreams/color_test.go index a399e6d58..b0cf994e3 100644 --- a/pkg/iostreams/color_test.go +++ b/pkg/iostreams/color_test.go @@ -175,3 +175,67 @@ func TestTableHeader(t *testing.T) { }) } } + +func TestMuted(t *testing.T) { + reset := "\x1b[0m" + gray4bit := "\x1b[0;90m" + gray8bit := "\x1b[38;5;242m" + brightBlack4bit := "\x1b[0;90m" + dimBlack4bit := "\x1b[0;2;37m" + + tests := []struct { + name string + cs *ColorScheme + input string + expected string + }{ + { + name: "when color is disabled but accessible colors are disabled, text is not stylized", + cs: NewColorScheme(false, false, false, false, NoTheme), + input: "this should not be stylized", + expected: "this should not be stylized", + }, + { + name: "when 4-bit color is enabled but accessible colors are disabled, legacy 4-bit gray color is used", + cs: NewColorScheme(true, false, false, false, NoTheme), + input: "this should be 4-bit gray", + expected: fmt.Sprintf("%sthis should be 4-bit gray%s", gray4bit, reset), + }, + { + name: "when 8-bit color is enabled but accessible colors are disabled, legacy 8-bit gray color is used", + cs: NewColorScheme(true, true, false, false, NoTheme), + input: "this should be 8-bit gray", + expected: fmt.Sprintf("%sthis should be 8-bit gray%s", gray8bit, reset), + }, + { + name: "when 24-bit color is enabled but accessible colors are disabled, legacy 8-bit gray color is used", + cs: NewColorScheme(true, true, true, false, NoTheme), + input: "this should be 8-bit gray", + expected: fmt.Sprintf("%sthis should be 8-bit gray%s", gray8bit, reset), + }, + { + name: "when 4-bit color is enabled and theme is dark, 4-bit light color is used", + cs: NewColorScheme(true, true, true, true, DarkTheme), + input: "this should be 4-bit dim black", + expected: fmt.Sprintf("%sthis should be 4-bit dim black%s", dimBlack4bit, reset), + }, + { + name: "when 4-bit color is enabled and theme is light, 4-bit dark color is used", + cs: NewColorScheme(true, true, true, true, LightTheme), + input: "this should be 4-bit bright black", + expected: fmt.Sprintf("%sthis should be 4-bit bright black%s", brightBlack4bit, reset), + }, + { + name: "when 4-bit color is enabled but no theme, 4-bit default color is used", + cs: NewColorScheme(true, true, true, true, NoTheme), + input: "this should have no explicit color", + expected: "this should have no explicit color", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.expected, tt.cs.Muted(tt.input)) + }) + } +}