Files
go-jdenticon/internal/engine/shapes_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

258 lines
5.8 KiB
Go

package engine
import (
"testing"
)
// MockRenderer implements the Renderer interface for testing
type MockRenderer struct {
Polygons [][]Point
Circles []MockCircle
}
type MockCircle struct {
TopLeft Point
Size float64
Invert bool
}
func (m *MockRenderer) AddPolygon(points []Point) {
m.Polygons = append(m.Polygons, points)
}
func (m *MockRenderer) AddCircle(topLeft Point, size float64, invert bool) {
m.Circles = append(m.Circles, MockCircle{
TopLeft: topLeft,
Size: size,
Invert: invert,
})
}
func (m *MockRenderer) Reset() {
m.Polygons = nil
m.Circles = nil
}
func TestGraphicsAddRectangle(t *testing.T) {
mock := &MockRenderer{}
g := NewGraphics(mock)
g.AddRectangle(10, 20, 30, 40, false)
if len(mock.Polygons) != 1 {
t.Errorf("Expected 1 polygon, got %d", len(mock.Polygons))
return
}
expected := []Point{
{X: 10, Y: 20},
{X: 40, Y: 20},
{X: 40, Y: 60},
{X: 10, Y: 60},
}
polygon := mock.Polygons[0]
if len(polygon) != len(expected) {
t.Errorf("Expected %d points, got %d", len(expected), len(polygon))
return
}
for i, point := range expected {
if polygon[i].X != point.X || polygon[i].Y != point.Y {
t.Errorf("Point %d: expected (%f, %f), got (%f, %f)",
i, point.X, point.Y, polygon[i].X, polygon[i].Y)
}
}
}
func TestGraphicsAddCircle(t *testing.T) {
mock := &MockRenderer{}
g := NewGraphics(mock)
g.AddCircle(10, 20, 30, false)
if len(mock.Circles) != 1 {
t.Errorf("Expected 1 circle, got %d", len(mock.Circles))
return
}
circle := mock.Circles[0]
expectedTopLeft := Point{X: 10, Y: 20}
expectedSize := float64(30)
if circle.TopLeft.X != expectedTopLeft.X || circle.TopLeft.Y != expectedTopLeft.Y {
t.Errorf("Expected top-left (%f, %f), got (%f, %f)",
expectedTopLeft.X, expectedTopLeft.Y, circle.TopLeft.X, circle.TopLeft.Y)
}
if circle.Size != expectedSize {
t.Errorf("Expected size %f, got %f", expectedSize, circle.Size)
}
if circle.Invert != false {
t.Errorf("Expected invert false, got %t", circle.Invert)
}
}
func TestGraphicsAddRhombus(t *testing.T) {
mock := &MockRenderer{}
g := NewGraphics(mock)
g.AddRhombus(0, 0, 20, 30, false)
if len(mock.Polygons) != 1 {
t.Errorf("Expected 1 polygon, got %d", len(mock.Polygons))
return
}
expected := []Point{
{X: 10, Y: 0}, // top
{X: 20, Y: 15}, // right
{X: 10, Y: 30}, // bottom
{X: 0, Y: 15}, // left
}
polygon := mock.Polygons[0]
if len(polygon) != len(expected) {
t.Errorf("Expected %d points, got %d", len(expected), len(polygon))
return
}
for i, point := range expected {
if polygon[i].X != point.X || polygon[i].Y != point.Y {
t.Errorf("Point %d: expected (%f, %f), got (%f, %f)",
i, point.X, point.Y, polygon[i].X, polygon[i].Y)
}
}
}
func TestRenderCenterShape(t *testing.T) {
mock := &MockRenderer{}
g := NewGraphics(mock)
cell := float64(60)
// Test each center shape
for i := 0; i < 14; i++ {
mock.Reset()
RenderCenterShape(g, i, cell, 0)
// Verify that some drawing commands were issued
if len(mock.Polygons) == 0 && len(mock.Circles) == 0 {
// Shape 13 at position != 0 doesn't draw anything, which is expected
if i == 13 {
continue
}
t.Errorf("Shape %d: expected some drawing commands, got none", i)
}
}
}
func TestRenderCenterShapeSpecific(t *testing.T) {
mock := &MockRenderer{}
g := NewGraphics(mock)
cell := float64(60)
// Test shape 2 (rectangle)
mock.Reset()
RenderCenterShape(g, 2, cell, 0)
if len(mock.Polygons) != 1 {
t.Errorf("Shape 2: expected 1 polygon, got %d", len(mock.Polygons))
}
// Test shape 4 (circle)
mock.Reset()
RenderCenterShape(g, 4, cell, 0)
if len(mock.Circles) != 1 {
t.Errorf("Shape 4: expected 1 circle, got %d", len(mock.Circles))
}
// Test shape 13 at position 0 (should draw)
mock.Reset()
RenderCenterShape(g, 13, cell, 0)
if len(mock.Circles) != 1 {
t.Errorf("Shape 13 at position 0: expected 1 circle, got %d", len(mock.Circles))
}
// Test shape 13 at position 1 (should not draw)
mock.Reset()
RenderCenterShape(g, 13, cell, 1)
if len(mock.Circles) != 0 {
t.Errorf("Shape 13 at position 1: expected 0 circles, got %d", len(mock.Circles))
}
}
func TestRenderOuterShape(t *testing.T) {
mock := &MockRenderer{}
g := NewGraphics(mock)
cell := float64(60)
// Test each outer shape
for i := 0; i < 4; i++ {
mock.Reset()
RenderOuterShape(g, i, cell)
// Verify that some drawing commands were issued
if len(mock.Polygons) == 0 && len(mock.Circles) == 0 {
t.Errorf("Outer shape %d: expected some drawing commands, got none", i)
}
}
}
func TestRenderOuterShapeSpecific(t *testing.T) {
mock := &MockRenderer{}
g := NewGraphics(mock)
cell := float64(60)
// Test outer shape 2 (rhombus)
mock.Reset()
RenderOuterShape(g, 2, cell)
if len(mock.Polygons) != 1 {
t.Errorf("Outer shape 2: expected 1 polygon, got %d", len(mock.Polygons))
}
// Test outer shape 3 (circle)
mock.Reset()
RenderOuterShape(g, 3, cell)
if len(mock.Circles) != 1 {
t.Errorf("Outer shape 3: expected 1 circle, got %d", len(mock.Circles))
}
}
func TestShapeIndexModulo(t *testing.T) {
mock := &MockRenderer{}
g := NewGraphics(mock)
cell := float64(60)
// Test that shape indices wrap around correctly
mock.Reset()
RenderCenterShape(g, 0, cell, 0)
polygonsShape0 := len(mock.Polygons)
circlesShape0 := len(mock.Circles)
mock.Reset()
RenderCenterShape(g, 14, cell, 0) // Should be same as shape 0
if len(mock.Polygons) != polygonsShape0 || len(mock.Circles) != circlesShape0 {
t.Errorf("Shape 14 should be equivalent to shape 0")
}
// Test outer shapes
mock.Reset()
RenderOuterShape(g, 0, cell)
polygonsOuter0 := len(mock.Polygons)
circlesOuter0 := len(mock.Circles)
mock.Reset()
RenderOuterShape(g, 4, cell) // Should be same as outer shape 0
if len(mock.Polygons) != polygonsOuter0 || len(mock.Circles) != circlesOuter0 {
t.Errorf("Outer shape 4 should be equivalent to outer shape 0")
}
}