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") } }