init
This commit is contained in:
380
internal/engine/layout_test.go
Normal file
380
internal/engine/layout_test.go
Normal file
@@ -0,0 +1,380 @@
|
||||
package engine
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewGrid(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
iconSize float64
|
||||
paddingRatio float64
|
||||
wantPadding int
|
||||
wantCell int
|
||||
}{
|
||||
{
|
||||
name: "standard 64px icon with 8% padding",
|
||||
iconSize: 64.0,
|
||||
paddingRatio: 0.08,
|
||||
wantPadding: 5, // 0.5 + 64 * 0.08 = 5.62, rounded to 5
|
||||
wantCell: 13, // (64 - 5*2) / 4 = 54/4 = 13.5, truncated to 13
|
||||
},
|
||||
{
|
||||
name: "large 256px icon with 10% padding",
|
||||
iconSize: 256.0,
|
||||
paddingRatio: 0.10,
|
||||
wantPadding: 26, // 0.5 + 256 * 0.10 = 26.1, rounded to 26
|
||||
wantCell: 51, // (256 - 26*2) / 4 = 204/4 = 51
|
||||
},
|
||||
{
|
||||
name: "small 32px icon with 5% padding",
|
||||
iconSize: 32.0,
|
||||
paddingRatio: 0.05,
|
||||
wantPadding: 2, // 0.5 + 32 * 0.05 = 2.1, rounded to 2
|
||||
wantCell: 7, // (32 - 2*2) / 4 = 28/4 = 7
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
grid := NewGrid(tt.iconSize, tt.paddingRatio)
|
||||
|
||||
if grid.Padding != tt.wantPadding {
|
||||
t.Errorf("NewGrid() padding = %v, want %v", grid.Padding, tt.wantPadding)
|
||||
}
|
||||
|
||||
if grid.Cell != tt.wantCell {
|
||||
t.Errorf("NewGrid() cell = %v, want %v", grid.Cell, tt.wantCell)
|
||||
}
|
||||
|
||||
// Verify that the grid is centered
|
||||
expectedSize := tt.iconSize - float64(tt.wantPadding*2)
|
||||
if math.Abs(grid.Size-expectedSize) > 0.1 {
|
||||
t.Errorf("NewGrid() size = %v, want %v", grid.Size, expectedSize)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGridCellToCoordinate(t *testing.T) {
|
||||
grid := NewGrid(64.0, 0.08)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
cellX int
|
||||
cellY int
|
||||
wantX float64
|
||||
wantY float64
|
||||
}{
|
||||
{
|
||||
name: "origin cell (0,0)",
|
||||
cellX: 0,
|
||||
cellY: 0,
|
||||
wantX: float64(grid.X),
|
||||
wantY: float64(grid.Y),
|
||||
},
|
||||
{
|
||||
name: "center cell (1,1)",
|
||||
cellX: 1,
|
||||
cellY: 1,
|
||||
wantX: float64(grid.X + grid.Cell),
|
||||
wantY: float64(grid.Y + grid.Cell),
|
||||
},
|
||||
{
|
||||
name: "corner cell (3,3)",
|
||||
cellX: 3,
|
||||
cellY: 3,
|
||||
wantX: float64(grid.X + 3*grid.Cell),
|
||||
wantY: float64(grid.Y + 3*grid.Cell),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
gotX, gotY := grid.CellToCoordinate(tt.cellX, tt.cellY)
|
||||
|
||||
if gotX != tt.wantX {
|
||||
t.Errorf("CellToCoordinate() x = %v, want %v", gotX, tt.wantX)
|
||||
}
|
||||
|
||||
if gotY != tt.wantY {
|
||||
t.Errorf("CellToCoordinate() y = %v, want %v", gotY, tt.wantY)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLayoutEngineGetShapePositions(t *testing.T) {
|
||||
le := NewLayoutEngine(64.0, 0.08)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
shapeType string
|
||||
wantLen int
|
||||
wantFirst Position
|
||||
wantLast Position
|
||||
}{
|
||||
{
|
||||
name: "sides positions",
|
||||
shapeType: "sides",
|
||||
wantLen: 8,
|
||||
wantFirst: Position{1, 0},
|
||||
wantLast: Position{0, 2},
|
||||
},
|
||||
{
|
||||
name: "corners positions",
|
||||
shapeType: "corners",
|
||||
wantLen: 4,
|
||||
wantFirst: Position{0, 0},
|
||||
wantLast: Position{0, 3},
|
||||
},
|
||||
{
|
||||
name: "center positions",
|
||||
shapeType: "center",
|
||||
wantLen: 4,
|
||||
wantFirst: Position{1, 1},
|
||||
wantLast: Position{1, 2},
|
||||
},
|
||||
{
|
||||
name: "invalid shape type",
|
||||
shapeType: "invalid",
|
||||
wantLen: 0,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
positions := le.GetShapePositions(tt.shapeType)
|
||||
|
||||
if len(positions) != tt.wantLen {
|
||||
t.Errorf("GetShapePositions() len = %v, want %v", len(positions), tt.wantLen)
|
||||
}
|
||||
|
||||
if tt.wantLen > 0 {
|
||||
if positions[0] != tt.wantFirst {
|
||||
t.Errorf("GetShapePositions() first = %v, want %v", positions[0], tt.wantFirst)
|
||||
}
|
||||
|
||||
if positions[len(positions)-1] != tt.wantLast {
|
||||
t.Errorf("GetShapePositions() last = %v, want %v", positions[len(positions)-1], tt.wantLast)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLayoutEngineGetTransformedPosition(t *testing.T) {
|
||||
le := NewLayoutEngine(64.0, 0.08)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
cellX int
|
||||
cellY int
|
||||
rotation int
|
||||
wantX int // Expected cell X after rotation
|
||||
wantY int // Expected cell Y after rotation
|
||||
}{
|
||||
{
|
||||
name: "no rotation",
|
||||
cellX: 1,
|
||||
cellY: 0,
|
||||
rotation: 0,
|
||||
wantX: 1,
|
||||
wantY: 0,
|
||||
},
|
||||
{
|
||||
name: "90 degree rotation",
|
||||
cellX: 1,
|
||||
cellY: 0,
|
||||
rotation: 1,
|
||||
wantX: 0,
|
||||
wantY: 2, // 3-1 = 2
|
||||
},
|
||||
{
|
||||
name: "180 degree rotation",
|
||||
cellX: 1,
|
||||
cellY: 0,
|
||||
rotation: 2,
|
||||
wantX: 2, // 3-1 = 2
|
||||
wantY: 3, // 3-0 = 3
|
||||
},
|
||||
{
|
||||
name: "270 degree rotation",
|
||||
cellX: 1,
|
||||
cellY: 0,
|
||||
rotation: 3,
|
||||
wantX: 3, // 3-0 = 3
|
||||
wantY: 1,
|
||||
},
|
||||
{
|
||||
name: "rotation overflow (4 = 0)",
|
||||
cellX: 1,
|
||||
cellY: 0,
|
||||
rotation: 4,
|
||||
wantX: 1,
|
||||
wantY: 0,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
gotX, gotY, gotCellSize := le.GetTransformedPosition(tt.cellX, tt.cellY, tt.rotation)
|
||||
|
||||
// Convert back to cell coordinates to verify rotation
|
||||
expectedX, expectedY := le.grid.CellToCoordinate(tt.wantX, tt.wantY)
|
||||
|
||||
if gotX != expectedX {
|
||||
t.Errorf("GetTransformedPosition() x = %v, want %v", gotX, expectedX)
|
||||
}
|
||||
|
||||
if gotY != expectedY {
|
||||
t.Errorf("GetTransformedPosition() y = %v, want %v", gotY, expectedY)
|
||||
}
|
||||
|
||||
if gotCellSize != float64(le.grid.Cell) {
|
||||
t.Errorf("GetTransformedPosition() cellSize = %v, want %v", gotCellSize, float64(le.grid.Cell))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplySymmetry(t *testing.T) {
|
||||
positions := []Position{{0, 0}, {1, 0}, {2, 0}, {3, 0}}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
index int
|
||||
want int // expected length
|
||||
}{
|
||||
{
|
||||
name: "valid index",
|
||||
index: 1,
|
||||
want: 4,
|
||||
},
|
||||
{
|
||||
name: "index out of bounds",
|
||||
index: 10,
|
||||
want: 4,
|
||||
},
|
||||
{
|
||||
name: "negative index",
|
||||
index: -1,
|
||||
want: 4,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := ApplySymmetry(positions, tt.index)
|
||||
|
||||
if len(result) != tt.want {
|
||||
t.Errorf("ApplySymmetry() len = %v, want %v", len(result), tt.want)
|
||||
}
|
||||
|
||||
// Verify that the positions are unchanged (current implementation)
|
||||
for i, pos := range result {
|
||||
if pos != positions[i] {
|
||||
t.Errorf("ApplySymmetry() changed position at index %d: got %v, want %v", i, pos, positions[i])
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGridValidateGrid(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
grid *Grid
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "valid grid",
|
||||
grid: &Grid{Size: 64, Cell: 16, Padding: 4},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "zero cell size",
|
||||
grid: &Grid{Size: 64, Cell: 0, Padding: 4},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "zero size",
|
||||
grid: &Grid{Size: 0, Cell: 16, Padding: 4},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "negative padding",
|
||||
grid: &Grid{Size: 64, Cell: 16, Padding: -1},
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := tt.grid.ValidateGrid(); got != tt.want {
|
||||
t.Errorf("ValidateGrid() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGridGetIconBounds(t *testing.T) {
|
||||
grid := NewGrid(64.0, 0.08)
|
||||
|
||||
x, y, width, height := grid.GetIconBounds()
|
||||
|
||||
expectedX := float64(grid.X)
|
||||
expectedY := float64(grid.Y)
|
||||
expectedWidth := float64(grid.Cell * 4)
|
||||
expectedHeight := float64(grid.Cell * 4)
|
||||
|
||||
if x != expectedX {
|
||||
t.Errorf("GetIconBounds() x = %v, want %v", x, expectedX)
|
||||
}
|
||||
|
||||
if y != expectedY {
|
||||
t.Errorf("GetIconBounds() y = %v, want %v", y, expectedY)
|
||||
}
|
||||
|
||||
if width != expectedWidth {
|
||||
t.Errorf("GetIconBounds() width = %v, want %v", width, expectedWidth)
|
||||
}
|
||||
|
||||
if height != expectedHeight {
|
||||
t.Errorf("GetIconBounds() height = %v, want %v", height, expectedHeight)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGridGetCenterOffset(t *testing.T) {
|
||||
grid := NewGrid(64.0, 0.08)
|
||||
|
||||
dx, dy := grid.GetCenterOffset()
|
||||
|
||||
expected := float64(grid.Cell) / 2
|
||||
|
||||
if dx != expected {
|
||||
t.Errorf("GetCenterOffset() dx = %v, want %v", dx, expected)
|
||||
}
|
||||
|
||||
if dy != expected {
|
||||
t.Errorf("GetCenterOffset() dy = %v, want %v", dy, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewLayoutEngine(t *testing.T) {
|
||||
le := NewLayoutEngine(64.0, 0.08)
|
||||
|
||||
if le.grid == nil {
|
||||
t.Error("NewLayoutEngine() grid is nil")
|
||||
}
|
||||
|
||||
if le.Grid() != le.grid {
|
||||
t.Error("NewLayoutEngine() Grid() does not return internal grid")
|
||||
}
|
||||
|
||||
// Verify grid configuration
|
||||
if !le.grid.ValidateGrid() {
|
||||
t.Error("NewLayoutEngine() created invalid grid")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user