Skip to content

Commit e3d1e98

Browse files
committed
Refactor tests
1 parent 0e5c2c3 commit e3d1e98

6 files changed

Lines changed: 285 additions & 232 deletions

File tree

cell_test.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package grid
2+
3+
import (
4+
"testing"
5+
6+
"github.com/gravitton/assert"
7+
geom "github.com/gravitton/geometry"
8+
)
9+
10+
func TestCell_Valid(t *testing.T) {
11+
g := NewRectGrid[int](geom.Sz(4, 4), geom.Sz(32.0, 32.0))
12+
t.Run("in bounds", func(t *testing.T) {
13+
assert.True(t, g.Get(geom.Pt(0, 0)).Valid())
14+
assert.True(t, g.Get(geom.Pt(3, 3)).Valid())
15+
})
16+
t.Run("out of bounds", func(t *testing.T) {
17+
assert.False(t, g.Get(geom.Pt(10, 10)).Valid())
18+
})
19+
}
20+
21+
func TestCell_Index(t *testing.T) {
22+
g := NewRectGrid[int](geom.Sz(5, 5), geom.Sz(32.0, 32.0))
23+
assert.Equal(t, g.Get(geom.Pt(1, 3)).Index(), geom.Pt(1, 3))
24+
}
25+
26+
func TestCell_Center(t *testing.T) {
27+
g := NewRectGrid[int](geom.Sz(5, 5), geom.Sz(32.0, 32.0))
28+
// With AlignTopLeft, cell (0,0) center is at (16, 16) for 32×32 cells.
29+
geom.AssertPoint(t, g.Get(geom.Pt(0, 0)).Center(), 16.0, 16.0)
30+
}
31+
32+
func TestCell_DistanceTo(t *testing.T) {
33+
g := NewRectGrid[int](geom.Sz(10, 10), geom.Sz(32.0, 32.0))
34+
assert.Equal(t, g.Get(geom.Pt(0, 0)).DistanceTo(geom.Pt(3, 4)), 7)
35+
}
36+
37+
func TestCell_Range(t *testing.T) {
38+
g := NewRectGrid[int](geom.Sz(10, 10), geom.Sz(32.0, 32.0))
39+
all := func(c *Cell[int]) bool { return true }
40+
assert.Equal(t, len(g.Get(geom.Pt(5, 5)).Range(1, all)), 5)
41+
}
42+
43+
func TestCell_PathTo(t *testing.T) {
44+
g := NewRectGrid[int](geom.Sz(5, 5), geom.Sz(32.0, 32.0))
45+
assert.Equal(t, len(g.Get(geom.Pt(0, 0)).PathTo(geom.Pt(4, 0), nil, nil)), 5)
46+
}

direction_test.go

Lines changed: 76 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -8,41 +8,60 @@ import (
88
)
99

1010
func TestDirection_String(t *testing.T) {
11-
assert.Equal(t, E.String(), "E")
12-
assert.Equal(t, NE.String(), "NE")
13-
assert.Equal(t, N.String(), "N")
14-
assert.Equal(t, NW.String(), "NW")
15-
assert.Equal(t, W.String(), "W")
16-
assert.Equal(t, SW.String(), "SW")
17-
assert.Equal(t, S.String(), "S")
18-
assert.Equal(t, SE.String(), "SE")
19-
// values beyond 7 wrap via %8
20-
assert.Equal(t, Direction(8).String(), "E")
21-
assert.Equal(t, Direction(10).String(), "N")
11+
cases := []struct {
12+
name string
13+
dir Direction
14+
want string
15+
}{
16+
{"E", E, "E"},
17+
{"NE", NE, "NE"},
18+
{"N", N, "N"},
19+
{"NW", NW, "NW"},
20+
{"W", W, "W"},
21+
{"SW", SW, "SW"},
22+
{"S", S, "S"},
23+
{"SE", SE, "SE"},
24+
{"wrap_8_to_E", Direction(8), "E"},
25+
{"wrap_10_to_N", Direction(10), "N"},
26+
}
27+
for _, tc := range cases {
28+
t.Run(tc.name, func(t *testing.T) {
29+
assert.Equal(t, tc.dir.String(), tc.want)
30+
})
31+
}
2232
}
2333

2434
func TestDirection_Opposite(t *testing.T) {
25-
assert.Equal(t, E.Opposite(), W)
26-
assert.Equal(t, NE.Opposite(), SW)
27-
assert.Equal(t, N.Opposite(), S)
28-
assert.Equal(t, NW.Opposite(), SE)
29-
assert.Equal(t, W.Opposite(), E)
30-
assert.Equal(t, SW.Opposite(), NE)
31-
assert.Equal(t, S.Opposite(), N)
32-
assert.Equal(t, SE.Opposite(), NW)
33-
34-
// double opposite returns the original direction
35-
for _, d := range []Direction{E, NE, N, NW, W, SW, S, SE} {
36-
assert.Equal(t, d.Opposite().Opposite(), d)
37-
}
38-
39-
// neighbor vectors of opposite directions sum to zero
40-
for _, d := range []Direction{E, NE, N, NW} {
41-
v := Directions[d]
42-
opp := Directions[d.Opposite()]
43-
assert.Equal(t, v.X+opp.X, 0)
44-
assert.Equal(t, v.Y+opp.Y, 0)
45-
}
35+
t.Run("pairs", func(t *testing.T) {
36+
cases := []struct{ dir, want Direction }{
37+
{E, W},
38+
{NE, SW},
39+
{N, S},
40+
{NW, SE},
41+
{W, E},
42+
{SW, NE},
43+
{S, N},
44+
{SE, NW},
45+
}
46+
for _, tc := range cases {
47+
t.Run(tc.dir.String(), func(t *testing.T) {
48+
assert.Equal(t, tc.dir.Opposite(), tc.want)
49+
})
50+
}
51+
})
52+
t.Run("double opposite", func(t *testing.T) {
53+
for _, d := range []Direction{E, NE, N, NW, W, SW, S, SE} {
54+
assert.Equal(t, d.Opposite().Opposite(), d)
55+
}
56+
})
57+
t.Run("vectors sum to zero", func(t *testing.T) {
58+
for _, d := range []Direction{E, NE, N, NW} {
59+
v := Directions[d]
60+
opp := Directions[d.Opposite()]
61+
assert.Equal(t, v.X+opp.X, 0)
62+
assert.Equal(t, v.Y+opp.Y, 0)
63+
}
64+
})
4665
}
4766

4867
func TestAllDirections_Order(t *testing.T) {
@@ -75,16 +94,19 @@ func TestNeighborOffsets_Panic(t *testing.T) {
7594
}
7695

7796
func TestNeighborOffset(t *testing.T) {
78-
// Cardinal: all four cardinal directions return the correct vector.
79-
assert.Equal(t, NeighborOffset(Cardinal, E), geom.Vec(1, 0))
80-
assert.Equal(t, NeighborOffset(Cardinal, N), geom.Vec(0, -1))
81-
assert.Equal(t, NeighborOffset(Cardinal, W), geom.Vec(-1, 0))
82-
assert.Equal(t, NeighborOffset(Cardinal, S), geom.Vec(0, 1))
83-
84-
// Diagonal: all eight directions return the correct vector.
85-
for _, d := range []Direction{E, NE, N, NW, W, SW, S, SE} {
86-
assert.Equal(t, NeighborOffset(Diagonal, d), Directions[d])
87-
}
97+
t.Run("cardinal", func(t *testing.T) {
98+
assert.Equal(t, NeighborOffset(Cardinal, E), geom.Vec(1, 0))
99+
assert.Equal(t, NeighborOffset(Cardinal, N), geom.Vec(0, -1))
100+
assert.Equal(t, NeighborOffset(Cardinal, W), geom.Vec(-1, 0))
101+
assert.Equal(t, NeighborOffset(Cardinal, S), geom.Vec(0, 1))
102+
})
103+
t.Run("diagonal", func(t *testing.T) {
104+
for _, d := range []Direction{E, NE, N, NW, W, SW, S, SE} {
105+
t.Run(d.String(), func(t *testing.T) {
106+
assert.Equal(t, NeighborOffset(Diagonal, d), Directions[d])
107+
})
108+
}
109+
})
88110
}
89111

90112
func TestNeighborOffset_Panic(t *testing.T) {
@@ -99,17 +121,18 @@ func TestDistanceTo(t *testing.T) {
99121
origin := geom.Pt(0, 0)
100122
target := geom.Pt(3, 4)
101123

102-
// Cardinal: Manhattan distance
103-
assert.Equal(t, DistanceTo(origin, target, Cardinal), 7)
104-
assert.Equal(t, DistanceTo(origin, geom.Pt(-2, 3), Cardinal), 5)
105-
106-
// Diagonal: Chebyshev distance
107-
assert.Equal(t, DistanceTo(origin, target, Diagonal), 4)
108-
assert.Equal(t, DistanceTo(origin, geom.Pt(2, 2), Diagonal), 2)
109-
110-
// symmetric
111-
assert.Equal(t, DistanceTo(origin, target, Cardinal), DistanceTo(target, origin, Cardinal))
112-
assert.Equal(t, DistanceTo(origin, target, Diagonal), DistanceTo(target, origin, Diagonal))
124+
t.Run("cardinal", func(t *testing.T) {
125+
assert.Equal(t, DistanceTo(origin, target, Cardinal), 7)
126+
assert.Equal(t, DistanceTo(origin, geom.Pt(-2, 3), Cardinal), 5)
127+
})
128+
t.Run("diagonal", func(t *testing.T) {
129+
assert.Equal(t, DistanceTo(origin, target, Diagonal), 4)
130+
assert.Equal(t, DistanceTo(origin, geom.Pt(2, 2), Diagonal), 2)
131+
})
132+
t.Run("symmetric", func(t *testing.T) {
133+
assert.Equal(t, DistanceTo(origin, target, Cardinal), DistanceTo(target, origin, Cardinal))
134+
assert.Equal(t, DistanceTo(origin, target, Diagonal), DistanceTo(target, origin, Diagonal))
135+
})
113136
}
114137

115138
func TestDistanceTo_Panic(t *testing.T) {

grid_hex_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package grid
2+
3+
import (
4+
"testing"
5+
6+
geom "github.com/gravitton/geometry"
7+
)
8+
9+
func TestHexFlatTopCellSize(t *testing.T) {
10+
// circumradius W = H = width/2; pixel bounding box: width × width·√3/2 ≈ 55.4256258
11+
size := HexFlatTopCellSize(64)
12+
geom.AssertSize(t, size, 32.0, 32.0)
13+
g := NewHexagonFlatTopGrid[int](geom.SzU(1), size)
14+
geom.AssertSize(t, g.CellBounds(), 64.0, 55.4256258)
15+
}
16+
17+
func TestHexPointyTopCellSize(t *testing.T) {
18+
// circumradius W = H = width/√3 ≈ 36.9504172; pixel bounding box: width × width·2/√3 ≈ 73.9008346
19+
size := HexPointyTopCellSize(64)
20+
geom.AssertSize(t, size, 36.9504172, 36.9504172)
21+
g := NewHexagonPointyTopGrid[int](geom.SzU(1), size)
22+
geom.AssertSize(t, g.CellBounds(), 64.0, 73.9008346)
23+
}
24+
25+
func TestHexFlatTopIsometricPixelPerfectCellSize(t *testing.T) {
26+
// 4:3 ratio — circumradius W = width/2, H = width·√3/4 ≈ 27.7128129; pixel bounding box: width × width·3/4
27+
size := HexFlatTopIsometricPixelPerfectCellSize(64)
28+
geom.AssertSize(t, size, 32.0, 27.7128129)
29+
g := NewHexagonFlatTopGrid[int](geom.SzU(1), size)
30+
geom.AssertSize(t, g.CellBounds(), 64.0, 48.0)
31+
}
32+
33+
func TestHexPointyTopIsometricPixelPerfectCellSize(t *testing.T) {
34+
// 1:1 ratio — circumradius W = width/√3 ≈ 36.9504172, H = width/2; pixel bounding box: width × width
35+
size := HexPointyTopIsometricPixelPerfectCellSize(64)
36+
geom.AssertSize(t, size, 36.9504172, 32.0)
37+
g := NewHexagonPointyTopGrid[int](geom.SzU(1), size)
38+
geom.AssertSize(t, g.CellBounds(), 64.0, 64.0)
39+
}

grid_rect_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package grid
2+
3+
import (
4+
"testing"
5+
6+
geom "github.com/gravitton/geometry"
7+
)
8+
9+
func TestRectCellSize(t *testing.T) {
10+
size := RectCellSize(64)
11+
geom.AssertSize(t, size, 64.0, 64.0)
12+
g := NewRectGrid[int](geom.SzU(1), size)
13+
geom.AssertSize(t, g.CellBounds(), 64.0, 64.0)
14+
}
15+
16+
func TestIsometricRectCellSize(t *testing.T) {
17+
// height = width·tan30° = width/√3 ≈ 36.9504172
18+
size := IsometricRectCellSize(64)
19+
geom.AssertSize(t, size, 64.0, 36.9504172)
20+
g := NewIsometricRectGrid[int](geom.SzU(1), size)
21+
geom.AssertSize(t, g.CellBounds(), 64.0, 36.9504172)
22+
}
23+
24+
func TestIsometricPixelPerfectRectCellSize(t *testing.T) {
25+
// 2:1 ratio
26+
size := IsometricPixelPerfectRectCellSize(64)
27+
geom.AssertSize(t, size, 64.0, 32.0)
28+
g := NewIsometricRectGrid[int](geom.SzU(1), size)
29+
geom.AssertSize(t, g.CellBounds(), 64.0, 32.0)
30+
}

0 commit comments

Comments
 (0)