package renderer import ( "fmt" "strings" "testing" "gitea.dockr.co/kev/go-jdenticon/internal/engine" ) func TestSVGPath_AddPolygon(t *testing.T) { path := &SVGPath{} points := []engine.Point{ {X: 0, Y: 0}, {X: 10, Y: 0}, {X: 10, Y: 10}, {X: 0, Y: 10}, } path.AddPolygon(points) expected := "M0 0L10 0L10 10L0 10Z" if got := path.DataString(); got != expected { t.Errorf("AddPolygon() = %v, want %v", got, expected) } } func TestSVGPath_AddPolygonEmpty(t *testing.T) { path := &SVGPath{} path.AddPolygon([]engine.Point{}) if got := path.DataString(); got != "" { t.Errorf("AddPolygon([]) = %v, want empty string", got) } } func TestSVGPath_AddCircle(t *testing.T) { path := &SVGPath{} topLeft := engine.Point{X: 25, Y: 25} // Top-left corner to get center at (50, 50) size := 50.0 // Size 50 gives radius 25 path.AddCircle(topLeft, size, false) // Should start at left side of circle and draw two arcs result := path.DataString() if !strings.HasPrefix(result, "M25 50") { t.Errorf("Circle should start at left side, got: %s", result) } if !strings.Contains(result, "a25,25 0 1,1") { t.Errorf("Circle should contain clockwise arc, got: %s", result) } } func TestSVGPath_AddCircleCounterClockwise(t *testing.T) { path := &SVGPath{} topLeft := engine.Point{X: 25, Y: 25} // Top-left corner to get center at (50, 50) size := 50.0 // Size 50 gives radius 25 path.AddCircle(topLeft, size, true) result := path.DataString() if !strings.Contains(result, "a25,25 0 1,0") { t.Errorf("Counter-clockwise circle should have sweep flag 0, got: %s", result) } } func TestSVGRenderer_NewSVGRenderer(t *testing.T) { renderer := NewSVGRenderer(100) if renderer.iconSize != 100 { t.Errorf("NewSVGRenderer(100).iconSize = %v, want 100", renderer.iconSize) } if renderer.pathsByColor == nil { t.Error("pathsByColor should be initialized") } } func TestSVGRenderer_BeginEndShape(t *testing.T) { renderer := NewSVGRenderer(100) renderer.BeginShape("#ff0000") if renderer.currentColor != "#ff0000" { t.Errorf("BeginShape should set currentColor, got %v", renderer.currentColor) } if _, exists := renderer.pathsByColor["#ff0000"]; !exists { t.Error("BeginShape should create path for color") } renderer.EndShape() // EndShape is a no-op for SVG, just verify it doesn't panic } func TestSVGRenderer_AddPolygon(t *testing.T) { renderer := NewSVGRenderer(100) renderer.BeginShape("#ff0000") points := []engine.Point{ {X: 0, Y: 0}, {X: 10, Y: 0}, {X: 5, Y: 10}, } renderer.AddPolygon(points) path := renderer.pathsByColor["#ff0000"] expected := "M0 0L10 0L5 10Z" if got := path.DataString(); got != expected { t.Errorf("AddPolygon() = %v, want %v", got, expected) } } func TestSVGRenderer_AddCircle(t *testing.T) { renderer := NewSVGRenderer(100) renderer.BeginShape("#00ff00") topLeft := engine.Point{X: 30, Y: 30} // Top-left corner to get center at (50, 50) size := 40.0 // Size 40 gives radius 20 renderer.AddCircle(topLeft, size, false) path := renderer.pathsByColor["#00ff00"] result := path.DataString() if !strings.HasPrefix(result, "M30 50") { t.Errorf("Circle should start at correct position, got: %s", result) } } func TestSVGRenderer_ToSVG(t *testing.T) { renderer := NewSVGRenderer(100) renderer.SetBackground("#ffffff", 1.0) renderer.BeginShape("#ff0000") points := []engine.Point{ {X: 0, Y: 0}, {X: 10, Y: 0}, {X: 10, Y: 10}, } renderer.AddPolygon(points) svg := renderer.ToSVG() // Check SVG structure if !strings.Contains(svg, ``) { t.Error("SVG should contain background rect") } if !strings.Contains(svg, ``) { t.Error("SVG should contain path with correct data") } if !strings.HasSuffix(svg, "") { t.Error("SVG should end with closing tag") } } func TestSVGRenderer_ToSVGWithoutBackground(t *testing.T) { renderer := NewSVGRenderer(50) renderer.BeginShape("#0000ff") center := engine.Point{X: 25, Y: 25} renderer.AddCircle(center, 10, false) svg := renderer.ToSVG() // Should not contain background rect if strings.Contains(svg, "