- 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
258 lines
5.8 KiB
Go
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")
|
|
}
|
|
}
|