Files
go-jdenticon/internal/engine/colorutils_test.go
Kevin McIntyre d9e84812ff Initial release: Go Jdenticon library v0.1.0
- Core library with SVG and PNG generation
- CLI tool with generate and batch commands
- Cross-platform path handling for Windows compatibility
- Comprehensive test suite with integration tests
2026-01-03 23:41:48 -05:00

230 lines
6.5 KiB
Go

package engine
import (
"image/color"
"testing"
)
func TestParseHexColorToRGBA(t *testing.T) {
tests := []struct {
name string
input string
expected color.RGBA
hasError bool
}{
// Valid cases
{"RGB short form", "#000", color.RGBA{0, 0, 0, 255}, false},
{"RGB short form white", "#fff", color.RGBA{255, 255, 255, 255}, false},
{"RGB short form mixed", "#f0a", color.RGBA{255, 0, 170, 255}, false},
{"RGBA short form", "#f0a8", color.RGBA{255, 0, 170, 136}, false},
{"RRGGBB full form", "#000000", color.RGBA{0, 0, 0, 255}, false},
{"RRGGBB full form white", "#ffffff", color.RGBA{255, 255, 255, 255}, false},
{"RRGGBB full form mixed", "#ff00aa", color.RGBA{255, 0, 170, 255}, false},
{"RRGGBBAA full form", "#ff00aa80", color.RGBA{255, 0, 170, 128}, false},
{"RRGGBBAA full form transparent", "#ff00aa00", color.RGBA{255, 0, 170, 0}, false},
{"RRGGBBAA full form opaque", "#ff00aaff", color.RGBA{255, 0, 170, 255}, false},
// Invalid cases
{"Empty string", "", color.RGBA{}, true},
{"No hash prefix", "ffffff", color.RGBA{}, true},
{"Invalid length", "#12", color.RGBA{}, true},
{"Invalid length", "#12345", color.RGBA{}, true},
{"Invalid length", "#1234567", color.RGBA{}, true},
{"Invalid hex character", "#gggggg", color.RGBA{}, true},
{"Invalid hex character short", "#ggg", color.RGBA{}, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := ParseHexColorToRGBA(tt.input)
if tt.hasError {
if err == nil {
t.Errorf("ParseHexColorToRGBA(%q) expected error, got nil", tt.input)
}
return
}
if err != nil {
t.Errorf("ParseHexColorToRGBA(%q) unexpected error: %v", tt.input, err)
return
}
if result != tt.expected {
t.Errorf("ParseHexColorToRGBA(%q) = %+v, expected %+v", tt.input, result, tt.expected)
}
})
}
}
func TestValidateHexColor(t *testing.T) {
tests := []struct {
name string
input string
hasError bool
}{
// Valid cases
{"RGB short", "#000", false},
{"RGB short uppercase", "#FFF", false},
{"RGB short mixed case", "#f0A", false},
{"RGBA short", "#f0a8", false},
{"RRGGBB", "#000000", false},
{"RRGGBB uppercase", "#FFFFFF", false},
{"RRGGBB mixed case", "#Ff00Aa", false},
{"RRGGBBAA", "#ff00aa80", false},
{"RRGGBBAA uppercase", "#FF00AA80", false},
// Invalid cases
{"Empty string", "", true},
{"No hash", "ffffff", true},
{"Too short", "#12", true},
{"Invalid length", "#12345", true},
{"Too long", "#123456789", true},
{"Invalid character", "#gggggg", true},
{"Invalid character short", "#ggg", true},
{"Space", "#fff fff", true},
{"Special character", "#fff@ff", true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := ValidateHexColor(tt.input)
if tt.hasError && err == nil {
t.Errorf("ValidateHexColor(%q) expected error, got nil", tt.input)
} else if !tt.hasError && err != nil {
t.Errorf("ValidateHexColor(%q) unexpected error: %v", tt.input, err)
}
})
}
}
func TestParseHexColorToEngine(t *testing.T) {
tests := []struct {
name string
input string
expected Color
hasError bool
}{
{"RGB short", "#000", NewColorRGBA(0, 0, 0, 255), false},
{"RGB short white", "#fff", NewColorRGBA(255, 255, 255, 255), false},
{"RRGGBB", "#ff00aa", NewColorRGBA(255, 0, 170, 255), false},
{"RRGGBBAA", "#ff00aa80", NewColorRGBA(255, 0, 170, 128), false},
{"Invalid", "#invalid", Color{}, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := ParseHexColorToEngine(tt.input)
if tt.hasError {
if err == nil {
t.Errorf("ParseHexColorToEngine(%q) expected error, got nil", tt.input)
}
return
}
if err != nil {
t.Errorf("ParseHexColorToEngine(%q) unexpected error: %v", tt.input, err)
return
}
resultR, resultG, resultB, err1 := result.ToRGB()
if err1 != nil {
t.Fatalf("result.ToRGB failed: %v", err1)
}
expectedR, expectedG, expectedB, err2 := tt.expected.ToRGB()
if err2 != nil {
t.Fatalf("expected.ToRGB failed: %v", err2)
}
if resultR != expectedR || resultG != expectedG ||
resultB != expectedB || result.A != tt.expected.A {
t.Errorf("ParseHexColorToEngine(%q) = R:%d G:%d B:%d A:%d, expected R:%d G:%d B:%d A:%d",
tt.input, resultR, resultG, resultB, result.A,
expectedR, expectedG, expectedB, tt.expected.A)
}
})
}
}
func TestParseHexColorForRenderer(t *testing.T) {
tests := []struct {
name string
input string
opacity float64
expected color.RGBA
hasError bool
}{
{"RGB with opacity 1.0", "#ff0000", 1.0, color.RGBA{255, 0, 0, 255}, false},
{"RGB with opacity 0.5", "#ff0000", 0.5, color.RGBA{255, 0, 0, 127}, false},
{"RGB with opacity 0.0", "#ff0000", 0.0, color.RGBA{255, 0, 0, 0}, false},
{"RGBA with opacity 1.0", "#ff000080", 1.0, color.RGBA{255, 0, 0, 128}, false},
{"RGBA with opacity 0.5", "#ff000080", 0.5, color.RGBA{255, 0, 0, 64}, false},
{"Invalid color", "#invalid", 1.0, color.RGBA{}, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := ParseHexColorForRenderer(tt.input, tt.opacity)
if tt.hasError {
if err == nil {
t.Errorf("ParseHexColorForRenderer(%q, %f) expected error, got nil", tt.input, tt.opacity)
}
return
}
if err != nil {
t.Errorf("ParseHexColorForRenderer(%q, %f) unexpected error: %v", tt.input, tt.opacity, err)
return
}
if result != tt.expected {
t.Errorf("ParseHexColorForRenderer(%q, %f) = %+v, expected %+v", tt.input, tt.opacity, result, tt.expected)
}
})
}
}
func TestHexToByte(t *testing.T) {
tests := []struct {
name string
input string
expected uint8
hasError bool
}{
{"Zero", "00", 0, false},
{"Max", "ff", 255, false},
{"Max uppercase", "FF", 255, false},
{"Mixed case", "Ff", 255, false},
{"Middle value", "80", 128, false},
{"Small value", "0a", 10, false},
{"Invalid length short", "f", 0, true},
{"Invalid length long", "fff", 0, true},
{"Invalid character", "gg", 0, true},
{"Empty string", "", 0, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := hexToByte(tt.input)
if tt.hasError {
if err == nil {
t.Errorf("hexToByte(%q) expected error, got nil", tt.input)
}
return
}
if err != nil {
t.Errorf("hexToByte(%q) unexpected error: %v", tt.input, err)
return
}
if result != tt.expected {
t.Errorf("hexToByte(%q) = %d, expected %d", tt.input, result, tt.expected)
}
})
}
}