mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-06 05:25:41 -05:00
728 lines
17 KiB
Go
728 lines
17 KiB
Go
package dank16
|
|
|
|
import (
|
|
"encoding/json"
|
|
"math"
|
|
"testing"
|
|
)
|
|
|
|
func TestHexToRGB(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input string
|
|
expected RGB
|
|
}{
|
|
{
|
|
name: "black with hash",
|
|
input: "#000000",
|
|
expected: RGB{R: 0.0, G: 0.0, B: 0.0},
|
|
},
|
|
{
|
|
name: "white with hash",
|
|
input: "#ffffff",
|
|
expected: RGB{R: 1.0, G: 1.0, B: 1.0},
|
|
},
|
|
{
|
|
name: "red without hash",
|
|
input: "ff0000",
|
|
expected: RGB{R: 1.0, G: 0.0, B: 0.0},
|
|
},
|
|
{
|
|
name: "purple",
|
|
input: "#625690",
|
|
expected: RGB{R: 0.3843137254901961, G: 0.33725490196078434, B: 0.5647058823529412},
|
|
},
|
|
{
|
|
name: "mid gray",
|
|
input: "#808080",
|
|
expected: RGB{R: 0.5019607843137255, G: 0.5019607843137255, B: 0.5019607843137255},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := HexToRGB(tt.input)
|
|
if !floatEqual(result.R, tt.expected.R) || !floatEqual(result.G, tt.expected.G) || !floatEqual(result.B, tt.expected.B) {
|
|
t.Errorf("HexToRGB(%s) = %v, expected %v", tt.input, result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRGBToHex(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input RGB
|
|
expected string
|
|
}{
|
|
{
|
|
name: "black",
|
|
input: RGB{R: 0.0, G: 0.0, B: 0.0},
|
|
expected: "#000000",
|
|
},
|
|
{
|
|
name: "white",
|
|
input: RGB{R: 1.0, G: 1.0, B: 1.0},
|
|
expected: "#ffffff",
|
|
},
|
|
{
|
|
name: "red",
|
|
input: RGB{R: 1.0, G: 0.0, B: 0.0},
|
|
expected: "#ff0000",
|
|
},
|
|
{
|
|
name: "clamping above 1.0",
|
|
input: RGB{R: 1.5, G: 0.5, B: 0.5},
|
|
expected: "#ff7f7f",
|
|
},
|
|
{
|
|
name: "clamping below 0.0",
|
|
input: RGB{R: -0.5, G: 0.5, B: 0.5},
|
|
expected: "#007f7f",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := RGBToHex(tt.input)
|
|
if result != tt.expected {
|
|
t.Errorf("RGBToHex(%v) = %s, expected %s", tt.input, result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRGBToHSV(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input RGB
|
|
expected HSV
|
|
}{
|
|
{
|
|
name: "black",
|
|
input: RGB{R: 0.0, G: 0.0, B: 0.0},
|
|
expected: HSV{H: 0.0, S: 0.0, V: 0.0},
|
|
},
|
|
{
|
|
name: "white",
|
|
input: RGB{R: 1.0, G: 1.0, B: 1.0},
|
|
expected: HSV{H: 0.0, S: 0.0, V: 1.0},
|
|
},
|
|
{
|
|
name: "red",
|
|
input: RGB{R: 1.0, G: 0.0, B: 0.0},
|
|
expected: HSV{H: 0.0, S: 1.0, V: 1.0},
|
|
},
|
|
{
|
|
name: "green",
|
|
input: RGB{R: 0.0, G: 1.0, B: 0.0},
|
|
expected: HSV{H: 0.3333333333333333, S: 1.0, V: 1.0},
|
|
},
|
|
{
|
|
name: "blue",
|
|
input: RGB{R: 0.0, G: 0.0, B: 1.0},
|
|
expected: HSV{H: 0.6666666666666666, S: 1.0, V: 1.0},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := RGBToHSV(tt.input)
|
|
if !floatEqual(result.H, tt.expected.H) || !floatEqual(result.S, tt.expected.S) || !floatEqual(result.V, tt.expected.V) {
|
|
t.Errorf("RGBToHSV(%v) = %v, expected %v", tt.input, result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHSVToRGB(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input HSV
|
|
expected RGB
|
|
}{
|
|
{
|
|
name: "black",
|
|
input: HSV{H: 0.0, S: 0.0, V: 0.0},
|
|
expected: RGB{R: 0.0, G: 0.0, B: 0.0},
|
|
},
|
|
{
|
|
name: "white",
|
|
input: HSV{H: 0.0, S: 0.0, V: 1.0},
|
|
expected: RGB{R: 1.0, G: 1.0, B: 1.0},
|
|
},
|
|
{
|
|
name: "red",
|
|
input: HSV{H: 0.0, S: 1.0, V: 1.0},
|
|
expected: RGB{R: 1.0, G: 0.0, B: 0.0},
|
|
},
|
|
{
|
|
name: "green",
|
|
input: HSV{H: 0.3333333333333333, S: 1.0, V: 1.0},
|
|
expected: RGB{R: 0.0, G: 1.0, B: 0.0},
|
|
},
|
|
{
|
|
name: "blue",
|
|
input: HSV{H: 0.6666666666666666, S: 1.0, V: 1.0},
|
|
expected: RGB{R: 0.0, G: 0.0, B: 1.0},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := HSVToRGB(tt.input)
|
|
if !floatEqual(result.R, tt.expected.R) || !floatEqual(result.G, tt.expected.G) || !floatEqual(result.B, tt.expected.B) {
|
|
t.Errorf("HSVToRGB(%v) = %v, expected %v", tt.input, result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLuminance(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input string
|
|
expected float64
|
|
}{
|
|
{
|
|
name: "black",
|
|
input: "#000000",
|
|
expected: 0.0,
|
|
},
|
|
{
|
|
name: "white",
|
|
input: "#ffffff",
|
|
expected: 1.0,
|
|
},
|
|
{
|
|
name: "red",
|
|
input: "#ff0000",
|
|
expected: 0.2126,
|
|
},
|
|
{
|
|
name: "green",
|
|
input: "#00ff00",
|
|
expected: 0.7152,
|
|
},
|
|
{
|
|
name: "blue",
|
|
input: "#0000ff",
|
|
expected: 0.0722,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := Luminance(tt.input)
|
|
if !floatEqual(result, tt.expected) {
|
|
t.Errorf("Luminance(%s) = %f, expected %f", tt.input, result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestContrastRatio(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
fg string
|
|
bg string
|
|
expected float64
|
|
}{
|
|
{
|
|
name: "black on white",
|
|
fg: "#000000",
|
|
bg: "#ffffff",
|
|
expected: 21.0,
|
|
},
|
|
{
|
|
name: "white on black",
|
|
fg: "#ffffff",
|
|
bg: "#000000",
|
|
expected: 21.0,
|
|
},
|
|
{
|
|
name: "same color",
|
|
fg: "#808080",
|
|
bg: "#808080",
|
|
expected: 1.0,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := ContrastRatio(tt.fg, tt.bg)
|
|
if !floatEqual(result, tt.expected) {
|
|
t.Errorf("ContrastRatio(%s, %s) = %f, expected %f", tt.fg, tt.bg, result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestEnsureContrast(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
color string
|
|
bg string
|
|
minRatio float64
|
|
isLightMode bool
|
|
}{
|
|
{
|
|
name: "already sufficient contrast dark mode",
|
|
color: "#ffffff",
|
|
bg: "#000000",
|
|
minRatio: 4.5,
|
|
isLightMode: false,
|
|
},
|
|
{
|
|
name: "already sufficient contrast light mode",
|
|
color: "#000000",
|
|
bg: "#ffffff",
|
|
minRatio: 4.5,
|
|
isLightMode: true,
|
|
},
|
|
{
|
|
name: "needs adjustment dark mode",
|
|
color: "#404040",
|
|
bg: "#1a1a1a",
|
|
minRatio: 4.5,
|
|
isLightMode: false,
|
|
},
|
|
{
|
|
name: "needs adjustment light mode",
|
|
color: "#c0c0c0",
|
|
bg: "#f8f8f8",
|
|
minRatio: 4.5,
|
|
isLightMode: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := EnsureContrast(tt.color, tt.bg, tt.minRatio, tt.isLightMode)
|
|
actualRatio := ContrastRatio(result, tt.bg)
|
|
if actualRatio < tt.minRatio {
|
|
t.Errorf("EnsureContrast(%s, %s, %f, %t) = %s with ratio %f, expected ratio >= %f",
|
|
tt.color, tt.bg, tt.minRatio, tt.isLightMode, result, actualRatio, tt.minRatio)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGeneratePalette(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
base string
|
|
opts PaletteOptions
|
|
}{
|
|
{
|
|
name: "dark theme default",
|
|
base: "#625690",
|
|
opts: PaletteOptions{IsLight: false},
|
|
},
|
|
{
|
|
name: "light theme default",
|
|
base: "#625690",
|
|
opts: PaletteOptions{IsLight: true},
|
|
},
|
|
{
|
|
name: "light theme with custom background",
|
|
base: "#625690",
|
|
opts: PaletteOptions{
|
|
IsLight: true,
|
|
Background: "#fafafa",
|
|
},
|
|
},
|
|
{
|
|
name: "dark theme with custom background",
|
|
base: "#625690",
|
|
opts: PaletteOptions{
|
|
IsLight: false,
|
|
Background: "#0a0a0a",
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := GeneratePalette(tt.base, tt.opts)
|
|
|
|
if len(result) != 16 {
|
|
t.Errorf("GeneratePalette returned %d colors, expected 16", len(result))
|
|
}
|
|
|
|
for i, color := range result {
|
|
if len(color) != 7 || color[0] != '#' {
|
|
t.Errorf("Color at index %d (%s) is not a valid hex color", i, color)
|
|
}
|
|
}
|
|
|
|
if tt.opts.Background != "" && result[0] != tt.opts.Background {
|
|
t.Errorf("Background color = %s, expected %s", result[0], tt.opts.Background)
|
|
} else if !tt.opts.IsLight && tt.opts.Background == "" && result[0] != "#1a1a1a" {
|
|
t.Errorf("Dark mode background = %s, expected #1a1a1a", result[0])
|
|
} else if tt.opts.IsLight && tt.opts.Background == "" && result[0] != "#f8f8f8" {
|
|
t.Errorf("Light mode background = %s, expected #f8f8f8", result[0])
|
|
}
|
|
|
|
if tt.opts.IsLight && result[15] != "#1a1a1a" {
|
|
t.Errorf("Light mode foreground = %s, expected #1a1a1a", result[15])
|
|
} else if !tt.opts.IsLight && result[15] != "#ffffff" {
|
|
t.Errorf("Dark mode foreground = %s, expected #ffffff", result[15])
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestEnrichVSCodeTheme(t *testing.T) {
|
|
colors := GeneratePalette("#625690", PaletteOptions{IsLight: false})
|
|
|
|
baseTheme := map[string]interface{}{
|
|
"name": "Test Theme",
|
|
"type": "dark",
|
|
"colors": map[string]interface{}{
|
|
"editor.background": "#000000",
|
|
},
|
|
}
|
|
|
|
themeJSON, err := json.Marshal(baseTheme)
|
|
if err != nil {
|
|
t.Fatalf("Failed to marshal base theme: %v", err)
|
|
}
|
|
|
|
result, err := EnrichVSCodeTheme(themeJSON, colors)
|
|
if err != nil {
|
|
t.Fatalf("EnrichVSCodeTheme failed: %v", err)
|
|
}
|
|
|
|
var enriched map[string]interface{}
|
|
if err := json.Unmarshal(result, &enriched); err != nil {
|
|
t.Fatalf("Failed to unmarshal result: %v", err)
|
|
}
|
|
|
|
colorsMap, ok := enriched["colors"].(map[string]interface{})
|
|
if !ok {
|
|
t.Fatal("colors is not a map")
|
|
}
|
|
|
|
terminalColors := []string{
|
|
"terminal.ansiBlack",
|
|
"terminal.ansiRed",
|
|
"terminal.ansiGreen",
|
|
"terminal.ansiYellow",
|
|
"terminal.ansiBlue",
|
|
"terminal.ansiMagenta",
|
|
"terminal.ansiCyan",
|
|
"terminal.ansiWhite",
|
|
"terminal.ansiBrightBlack",
|
|
"terminal.ansiBrightRed",
|
|
"terminal.ansiBrightGreen",
|
|
"terminal.ansiBrightYellow",
|
|
"terminal.ansiBrightBlue",
|
|
"terminal.ansiBrightMagenta",
|
|
"terminal.ansiBrightCyan",
|
|
"terminal.ansiBrightWhite",
|
|
}
|
|
|
|
for i, key := range terminalColors {
|
|
if val, ok := colorsMap[key]; !ok {
|
|
t.Errorf("Missing terminal color: %s", key)
|
|
} else if val != colors[i] {
|
|
t.Errorf("%s = %s, expected %s", key, val, colors[i])
|
|
}
|
|
}
|
|
|
|
if colorsMap["editor.background"] != "#000000" {
|
|
t.Error("Original theme colors should be preserved")
|
|
}
|
|
}
|
|
|
|
func TestEnrichVSCodeThemeInvalidJSON(t *testing.T) {
|
|
colors := GeneratePalette("#625690", PaletteOptions{IsLight: false})
|
|
invalidJSON := []byte("{invalid json")
|
|
|
|
_, err := EnrichVSCodeTheme(invalidJSON, colors)
|
|
if err == nil {
|
|
t.Error("Expected error for invalid JSON, got nil")
|
|
}
|
|
}
|
|
|
|
func TestRoundTripConversion(t *testing.T) {
|
|
testColors := []string{"#000000", "#ffffff", "#ff0000", "#00ff00", "#0000ff", "#625690", "#808080"}
|
|
|
|
for _, hex := range testColors {
|
|
t.Run(hex, func(t *testing.T) {
|
|
rgb := HexToRGB(hex)
|
|
result := RGBToHex(rgb)
|
|
if result != hex {
|
|
t.Errorf("Round trip %s -> RGB -> %s failed", hex, result)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRGBHSVRoundTrip(t *testing.T) {
|
|
testCases := []RGB{
|
|
{R: 0.0, G: 0.0, B: 0.0},
|
|
{R: 1.0, G: 1.0, B: 1.0},
|
|
{R: 1.0, G: 0.0, B: 0.0},
|
|
{R: 0.0, G: 1.0, B: 0.0},
|
|
{R: 0.0, G: 0.0, B: 1.0},
|
|
{R: 0.5, G: 0.5, B: 0.5},
|
|
{R: 0.3843137254901961, G: 0.33725490196078434, B: 0.5647058823529412},
|
|
}
|
|
|
|
for _, rgb := range testCases {
|
|
t.Run("", func(t *testing.T) {
|
|
hsv := RGBToHSV(rgb)
|
|
result := HSVToRGB(hsv)
|
|
if !floatEqual(result.R, rgb.R) || !floatEqual(result.G, rgb.G) || !floatEqual(result.B, rgb.B) {
|
|
t.Errorf("Round trip RGB->HSV->RGB failed: %v -> %v -> %v", rgb, hsv, result)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func floatEqual(a, b float64) bool {
|
|
return math.Abs(a-b) < 1e-9
|
|
}
|
|
|
|
func TestDeltaPhiStar(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
fg string
|
|
bg string
|
|
negativePolarity bool
|
|
minExpected float64
|
|
}{
|
|
{
|
|
name: "white on black (negative polarity)",
|
|
fg: "#ffffff",
|
|
bg: "#000000",
|
|
negativePolarity: true,
|
|
minExpected: 100.0,
|
|
},
|
|
{
|
|
name: "black on white (positive polarity)",
|
|
fg: "#000000",
|
|
bg: "#ffffff",
|
|
negativePolarity: false,
|
|
minExpected: 100.0,
|
|
},
|
|
{
|
|
name: "low contrast same color",
|
|
fg: "#808080",
|
|
bg: "#808080",
|
|
negativePolarity: false,
|
|
minExpected: -40.0,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := DeltaPhiStar(tt.fg, tt.bg, tt.negativePolarity)
|
|
if result < tt.minExpected {
|
|
t.Errorf("DeltaPhiStar(%s, %s, %v) = %f, expected >= %f",
|
|
tt.fg, tt.bg, tt.negativePolarity, result, tt.minExpected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDeltaPhiStarContrast(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
fg string
|
|
bg string
|
|
isLightMode bool
|
|
minExpected float64
|
|
}{
|
|
{
|
|
name: "white on black (dark mode)",
|
|
fg: "#ffffff",
|
|
bg: "#000000",
|
|
isLightMode: false,
|
|
minExpected: 100.0,
|
|
},
|
|
{
|
|
name: "black on white (light mode)",
|
|
fg: "#000000",
|
|
bg: "#ffffff",
|
|
isLightMode: true,
|
|
minExpected: 100.0,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := DeltaPhiStarContrast(tt.fg, tt.bg, tt.isLightMode)
|
|
if result < tt.minExpected {
|
|
t.Errorf("DeltaPhiStarContrast(%s, %s, %v) = %f, expected >= %f",
|
|
tt.fg, tt.bg, tt.isLightMode, result, tt.minExpected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestEnsureContrastDPS(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
color string
|
|
bg string
|
|
minLc float64
|
|
isLightMode bool
|
|
}{
|
|
{
|
|
name: "already sufficient contrast dark mode",
|
|
color: "#ffffff",
|
|
bg: "#000000",
|
|
minLc: 60.0,
|
|
isLightMode: false,
|
|
},
|
|
{
|
|
name: "already sufficient contrast light mode",
|
|
color: "#000000",
|
|
bg: "#ffffff",
|
|
minLc: 60.0,
|
|
isLightMode: true,
|
|
},
|
|
{
|
|
name: "needs adjustment dark mode",
|
|
color: "#404040",
|
|
bg: "#1a1a1a",
|
|
minLc: 60.0,
|
|
isLightMode: false,
|
|
},
|
|
{
|
|
name: "needs adjustment light mode",
|
|
color: "#c0c0c0",
|
|
bg: "#f8f8f8",
|
|
minLc: 60.0,
|
|
isLightMode: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := EnsureContrastDPS(tt.color, tt.bg, tt.minLc, tt.isLightMode)
|
|
actualLc := DeltaPhiStarContrast(result, tt.bg, tt.isLightMode)
|
|
if actualLc < tt.minLc {
|
|
t.Errorf("EnsureContrastDPS(%s, %s, %f, %t) = %s with Lc %f, expected Lc >= %f",
|
|
tt.color, tt.bg, tt.minLc, tt.isLightMode, result, actualLc, tt.minLc)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGeneratePaletteWithDPS(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
base string
|
|
opts PaletteOptions
|
|
}{
|
|
{
|
|
name: "dark theme with DPS",
|
|
base: "#625690",
|
|
opts: PaletteOptions{IsLight: false, UseDPS: true},
|
|
},
|
|
{
|
|
name: "light theme with DPS",
|
|
base: "#625690",
|
|
opts: PaletteOptions{IsLight: true, UseDPS: true},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := GeneratePalette(tt.base, tt.opts)
|
|
|
|
if len(result) != 16 {
|
|
t.Errorf("GeneratePalette returned %d colors, expected 16", len(result))
|
|
}
|
|
|
|
for i, color := range result {
|
|
if len(color) != 7 || color[0] != '#' {
|
|
t.Errorf("Color at index %d (%s) is not a valid hex color", i, color)
|
|
}
|
|
}
|
|
|
|
bgColor := result[0]
|
|
for i := 1; i < 8; i++ {
|
|
lc := DeltaPhiStarContrast(result[i], bgColor, tt.opts.IsLight)
|
|
minLc := 30.0
|
|
if lc < minLc && lc > 0 {
|
|
t.Errorf("Color %d (%s) has insufficient DPS contrast %f with background %s (expected >= %f)",
|
|
i, result[i], lc, bgColor, minLc)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDeriveContainer(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
primary string
|
|
isLight bool
|
|
expected string
|
|
}{
|
|
{
|
|
name: "dark mode",
|
|
primary: "#ccbdff",
|
|
isLight: false,
|
|
expected: "#4a3e76",
|
|
},
|
|
{
|
|
name: "light mode",
|
|
primary: "#625690",
|
|
isLight: true,
|
|
expected: "#e7deff",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := DeriveContainer(tt.primary, tt.isLight)
|
|
|
|
resultRGB := HexToRGB(result)
|
|
expectedRGB := HexToRGB(tt.expected)
|
|
|
|
rDiff := math.Abs(resultRGB.R - expectedRGB.R)
|
|
gDiff := math.Abs(resultRGB.G - expectedRGB.G)
|
|
bDiff := math.Abs(resultRGB.B - expectedRGB.B)
|
|
|
|
tolerance := 0.02
|
|
if rDiff > tolerance || gDiff > tolerance || bDiff > tolerance {
|
|
t.Errorf("DeriveContainer(%s, %v) = %s, expected %s (RGB diff: R:%.4f G:%.4f B:%.4f)",
|
|
tt.primary, tt.isLight, result, tt.expected, rDiff, gDiff, bDiff)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestContrastAlgorithmComparison(t *testing.T) {
|
|
base := "#625690"
|
|
|
|
optsWCAG := PaletteOptions{IsLight: false, UseDPS: false}
|
|
optsDPS := PaletteOptions{IsLight: false, UseDPS: true}
|
|
|
|
paletteWCAG := GeneratePalette(base, optsWCAG)
|
|
paletteDPS := GeneratePalette(base, optsDPS)
|
|
|
|
if len(paletteWCAG) != 16 || len(paletteDPS) != 16 {
|
|
t.Fatal("Both palettes should have 16 colors")
|
|
}
|
|
|
|
if paletteWCAG[0] != paletteDPS[0] {
|
|
t.Errorf("Background colors differ: WCAG=%s, DPS=%s", paletteWCAG[0], paletteDPS[0])
|
|
}
|
|
|
|
differentCount := 0
|
|
for i := 0; i < 16; i++ {
|
|
if paletteWCAG[i] != paletteDPS[i] {
|
|
differentCount++
|
|
}
|
|
}
|
|
|
|
t.Logf("WCAG and DPS palettes differ in %d/16 colors", differentCount)
|
|
}
|