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:
160
internal/engine/generator_graceful_degradation_test.go
Normal file
160
internal/engine/generator_graceful_degradation_test.go
Normal file
@@ -0,0 +1,160 @@
|
||||
package engine
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestSelectColors_EmptyColors tests the defensive check for empty available colors
|
||||
func TestSelectColors_EmptyColors(t *testing.T) {
|
||||
// Create a generator for testing
|
||||
generator, err := NewDefaultGenerator()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create generator: %v", err)
|
||||
}
|
||||
|
||||
// Test with empty available colors slice
|
||||
hash := "1234567890abcdef"
|
||||
emptyColors := []Color{}
|
||||
|
||||
_, err = generator.selectColors(hash, emptyColors)
|
||||
if err == nil {
|
||||
t.Fatal("expected error for empty available colors, got nil")
|
||||
}
|
||||
|
||||
expectedMsg := "no available colors"
|
||||
if !contains(err.Error(), expectedMsg) {
|
||||
t.Errorf("expected error message to contain %q, got %q", expectedMsg, err.Error())
|
||||
}
|
||||
|
||||
t.Logf("Got expected error: %v", err)
|
||||
}
|
||||
|
||||
// TestSelectColors_ValidColors tests that selectColors works correctly with valid input
|
||||
func TestSelectColors_ValidColors(t *testing.T) {
|
||||
// Create a generator for testing
|
||||
generator, err := NewDefaultGenerator()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create generator: %v", err)
|
||||
}
|
||||
|
||||
// Create a sample set of colors (similar to what GenerateColorTheme returns)
|
||||
config := DefaultColorConfig()
|
||||
availableColors := GenerateColorTheme(0.5, config)
|
||||
|
||||
if len(availableColors) == 0 {
|
||||
t.Fatal("GenerateColorTheme returned empty colors")
|
||||
}
|
||||
|
||||
hash := "1234567890abcdef"
|
||||
selectedIndexes, err := generator.selectColors(hash, availableColors)
|
||||
if err != nil {
|
||||
t.Fatalf("selectColors failed with valid input: %v", err)
|
||||
}
|
||||
|
||||
// Should return exactly numColorSelections (3) color indexes
|
||||
if len(selectedIndexes) != numColorSelections {
|
||||
t.Errorf("expected %d selected colors, got %d", numColorSelections, len(selectedIndexes))
|
||||
}
|
||||
|
||||
// All indexes should be valid (within bounds of available colors)
|
||||
for i, index := range selectedIndexes {
|
||||
if index < 0 || index >= len(availableColors) {
|
||||
t.Errorf("selected index %d at position %d is out of bounds (0-%d)", index, i, len(availableColors)-1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestGenerator_GenerateIcon_RobustnessChecks tests that generateIcon handles edge cases gracefully
|
||||
func TestGenerator_GenerateIcon_RobustnessChecks(t *testing.T) {
|
||||
generator, err := NewDefaultGenerator()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create generator: %v", err)
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
hash string
|
||||
size float64
|
||||
expectError bool
|
||||
}{
|
||||
{"valid_input", "1234567890abcdef12345", 64.0, false},
|
||||
{"minimum_size", "1234567890abcdef12345", 1.0, false},
|
||||
{"large_size", "1234567890abcdef12345", 1024.0, false},
|
||||
{"zero_size", "1234567890abcdef12345", 0.0, false}, // generateIcon doesn't validate size
|
||||
{"negative_size", "1234567890abcdef12345", -10.0, false}, // generateIcon doesn't validate size
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
icon, err := generator.generateIcon(context.Background(), tc.hash, tc.size)
|
||||
|
||||
if tc.expectError {
|
||||
if err == nil {
|
||||
t.Errorf("expected error for %s, got none", tc.name)
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error for %s: %v", tc.name, err)
|
||||
}
|
||||
|
||||
if icon == nil {
|
||||
t.Errorf("got nil icon for valid input %s", tc.name)
|
||||
}
|
||||
|
||||
// Validate icon properties
|
||||
if icon != nil {
|
||||
if icon.Size != tc.size {
|
||||
t.Errorf("icon size mismatch: expected %f, got %f", tc.size, icon.Size)
|
||||
}
|
||||
|
||||
if icon.Hash != tc.hash {
|
||||
t.Errorf("icon hash mismatch: expected %s, got %s", tc.hash, icon.Hash)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestHueExtraction_EdgeCases tests hue extraction with edge case inputs
|
||||
func TestHueExtraction_EdgeCases(t *testing.T) {
|
||||
generator, err := NewDefaultGenerator()
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create generator: %v", err)
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
hash string
|
||||
expectError bool
|
||||
}{
|
||||
{"valid_hash", "1234567890abcdef12345", false},
|
||||
{"minimum_length", "1234567890a", false}, // Exactly 11 characters
|
||||
{"hex_only", "abcdefabcdefabcdef123", false},
|
||||
{"numbers_only", "12345678901234567890", false},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
hue, err := generator.extractHue(tc.hash)
|
||||
|
||||
if tc.expectError {
|
||||
if err == nil {
|
||||
t.Errorf("expected error for %s, got none", tc.name)
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error for %s: %v", tc.name, err)
|
||||
}
|
||||
|
||||
// Hue should be in range [0, 1]
|
||||
if hue < 0 || hue > 1 {
|
||||
t.Errorf("hue out of range for %s: %f (should be 0-1)", tc.name, hue)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to check if a string contains a substring (defined in color_graceful_degradation_test.go)
|
||||
Reference in New Issue
Block a user