cli/pkg/iostreams/color_test.go
Andy Feller e067eacd81 Refactor ColorScheme initializer
This commit completely removes the iostreams.NewColorScheme() initializer function in favor of exporting the type fields for greater clarity in its use.

The result being code specifying only the fields that matter to test cases.
2025-04-04 11:57:37 -04:00

296 lines
8.1 KiB
Go

package iostreams
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
)
func TestLabel(t *testing.T) {
tests := []struct {
name string
hex string
text string
wants string
cs *ColorScheme
}{
{
name: "truecolor",
hex: "fc0303",
text: "red",
wants: "\033[38;2;252;3;3mred\033[0m",
cs: &ColorScheme{
Enabled: true,
EightBitColor: true,
TrueColor: true,
ColorLabels: true,
},
},
{
name: "no truecolor",
hex: "fc0303",
text: "red",
wants: "red",
cs: &ColorScheme{
Enabled: true,
EightBitColor: true,
ColorLabels: true,
},
},
{
name: "no color",
hex: "fc0303",
text: "red",
wants: "red",
cs: &ColorScheme{
ColorLabels: true,
},
},
{
name: "invalid hex",
hex: "fc0",
text: "red",
wants: "red",
cs: &ColorScheme{
ColorLabels: true,
},
},
{
name: "no color labels",
hex: "fc0303",
text: "red",
wants: "red",
cs: &ColorScheme{
Enabled: true,
EightBitColor: true,
ColorLabels: true,
},
},
}
for _, tt := range tests {
output := tt.cs.Label(tt.hex, tt.text)
assert.Equal(t, tt.wants, output)
}
}
func TestTableHeader(t *testing.T) {
reset := "\x1b[0m"
defaultUnderline := "\x1b[0;4;39m"
brightBlackUnderline := "\x1b[0;4;90m"
dimBlackUnderline := "\x1b[0;2;4;37m"
tests := []struct {
name string
cs *ColorScheme
input string
expected string
}{
{
name: "when color is disabled, text is not stylized",
cs: &ColorScheme{
Accessible: true,
Theme: NoTheme,
},
input: "this should not be stylized",
expected: "this should not be stylized",
},
{
name: "when 4-bit color is enabled but no theme, 4-bit default color and underline are used",
cs: &ColorScheme{
Enabled: true,
Accessible: true,
Theme: NoTheme,
},
input: "this should have no explicit color but underlined",
expected: fmt.Sprintf("%sthis should have no explicit color but underlined%s", defaultUnderline, reset),
},
{
name: "when 4-bit color is enabled and theme is light, 4-bit dark color and underline are used",
cs: &ColorScheme{
Enabled: true,
Accessible: true,
Theme: LightTheme,
},
input: "this should have dark foreground color and underlined",
expected: fmt.Sprintf("%sthis should have dark foreground color and underlined%s", brightBlackUnderline, reset),
},
{
name: "when 4-bit color is enabled and theme is dark, 4-bit light color and underline are used",
cs: &ColorScheme{
Enabled: true,
Accessible: true,
Theme: DarkTheme,
},
input: "this should have light foreground color and underlined",
expected: fmt.Sprintf("%sthis should have light foreground color and underlined%s", dimBlackUnderline, reset),
},
{
name: "when 8-bit color is enabled but no theme, 4-bit default color and underline are used",
cs: &ColorScheme{
Enabled: true,
EightBitColor: true,
Accessible: true,
Theme: NoTheme,
},
input: "this should have no explicit color but underlined",
expected: fmt.Sprintf("%sthis should have no explicit color but underlined%s", defaultUnderline, reset),
},
{
name: "when 8-bit color is enabled and theme is light, 4-bit dark color and underline are used",
cs: &ColorScheme{
Enabled: true,
EightBitColor: true,
Accessible: true,
Theme: LightTheme,
},
input: "this should have dark foreground color and underlined",
expected: fmt.Sprintf("%sthis should have dark foreground color and underlined%s", brightBlackUnderline, reset),
},
{
name: "when 8-bit color is true and theme is dark, 4-bit light color and underline are used",
cs: &ColorScheme{
Enabled: true,
EightBitColor: true,
Accessible: true,
Theme: DarkTheme,
},
input: "this should have light foreground color and underlined",
expected: fmt.Sprintf("%sthis should have light foreground color and underlined%s", dimBlackUnderline, reset),
},
{
name: "when 24-bit color is enabled but no theme, 4-bit default color and underline are used",
cs: &ColorScheme{
Enabled: true,
EightBitColor: true,
TrueColor: true,
Accessible: true,
Theme: NoTheme,
},
input: "this should have no explicit color but underlined",
expected: fmt.Sprintf("%sthis should have no explicit color but underlined%s", defaultUnderline, reset),
},
{
name: "when 24-bit color is enabled and theme is light, 4-bit dark color and underline are used",
cs: &ColorScheme{
Enabled: true,
EightBitColor: true,
TrueColor: true,
Accessible: true,
Theme: LightTheme,
},
input: "this should have dark foreground color and underlined",
expected: fmt.Sprintf("%sthis should have dark foreground color and underlined%s", brightBlackUnderline, reset),
},
{
name: "when 24-bit color is true and theme is dark, 4-bit light color and underline are used",
cs: &ColorScheme{
Enabled: true,
EightBitColor: true,
TrueColor: true,
Accessible: true,
Theme: DarkTheme,
},
input: "this should have light foreground color and underlined",
expected: fmt.Sprintf("%sthis should have light foreground color and underlined%s", dimBlackUnderline, reset),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.expected, tt.cs.TableHeader(tt.input))
})
}
}
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: &ColorScheme{},
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: &ColorScheme{
Enabled: true,
},
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: &ColorScheme{
Enabled: true,
EightBitColor: true,
},
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: &ColorScheme{
Enabled: true,
EightBitColor: true,
TrueColor: true,
},
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: &ColorScheme{
Enabled: true,
EightBitColor: true,
TrueColor: true,
Accessible: true,
Theme: 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: &ColorScheme{
Enabled: true,
EightBitColor: true,
TrueColor: true,
Accessible: true,
Theme: 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: &ColorScheme{
Enabled: true,
EightBitColor: true,
TrueColor: true,
Accessible: true,
Theme: 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))
})
}
}