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
This commit is contained in:
229
internal/engine/colorutils_test.go
Normal file
229
internal/engine/colorutils_test.go
Normal file
@@ -0,0 +1,229 @@
|
||||
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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user