ui: basic map scroller
This commit is contained in:
@@ -0,0 +1,442 @@
|
||||
package world
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestWorldFixedToCameraZoom(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
zoomFp int
|
||||
want float64
|
||||
}{
|
||||
{name: "zero", zoomFp: 0, want: 0},
|
||||
{name: "neutral", zoomFp: SCALE, want: 1.0},
|
||||
{name: "fractional", zoomFp: 1250, want: 1.25},
|
||||
{name: "integer multiple", zoomFp: 3 * SCALE, want: 3.0},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := worldFixedToCameraZoom(tt.zoomFp)
|
||||
require.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRequiredZoomToFitWorld(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
viewportSpanPx int
|
||||
worldSpanFp int
|
||||
want int
|
||||
}{
|
||||
{
|
||||
name: "zero viewport span",
|
||||
viewportSpanPx: 0,
|
||||
worldSpanFp: 10 * SCALE,
|
||||
want: 0,
|
||||
},
|
||||
{
|
||||
name: "exact neutral fit",
|
||||
viewportSpanPx: 10,
|
||||
worldSpanFp: 10 * SCALE,
|
||||
want: SCALE,
|
||||
},
|
||||
{
|
||||
name: "exact 2x fit",
|
||||
viewportSpanPx: 20,
|
||||
worldSpanFp: 10 * SCALE,
|
||||
want: 2 * SCALE,
|
||||
},
|
||||
{
|
||||
name: "fractional fit rounded up",
|
||||
viewportSpanPx: 11,
|
||||
worldSpanFp: 10 * SCALE,
|
||||
want: 1100,
|
||||
},
|
||||
{
|
||||
name: "small world requires larger zoom",
|
||||
viewportSpanPx: 320,
|
||||
worldSpanFp: 80 * SCALE,
|
||||
want: 4 * SCALE,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := requiredZoomToFitWorld(tt.viewportSpanPx, tt.worldSpanFp)
|
||||
require.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRequiredZoomToFitWorldPanics(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
viewportSpanPx int
|
||||
worldSpanFp int
|
||||
}{
|
||||
{
|
||||
name: "negative viewport span",
|
||||
viewportSpanPx: -1,
|
||||
worldSpanFp: 10 * SCALE,
|
||||
},
|
||||
{
|
||||
name: "zero world span",
|
||||
viewportSpanPx: 10,
|
||||
worldSpanFp: 0,
|
||||
},
|
||||
{
|
||||
name: "negative world span",
|
||||
viewportSpanPx: 10,
|
||||
worldSpanFp: -1,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require.Panics(t, func() {
|
||||
_ = requiredZoomToFitWorld(tt.viewportSpanPx, tt.worldSpanFp)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCorrectCameraZoomFpReturnsCurrentWhenNoCorrectionNeeded(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
2*SCALE,
|
||||
40, 30,
|
||||
100*SCALE, 100*SCALE,
|
||||
MIN_ZOOM, MAX_ZOOM,
|
||||
)
|
||||
|
||||
require.Equal(t, 2*SCALE, got)
|
||||
}
|
||||
|
||||
func TestCorrectCameraZoomFpRaisesZoomToFitWorldWidth(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
SCALE,
|
||||
120, 20,
|
||||
100*SCALE, 100*SCALE,
|
||||
0, 0,
|
||||
)
|
||||
|
||||
require.Equal(t, 1200, got)
|
||||
}
|
||||
|
||||
func TestCorrectCameraZoomFpRaisesZoomToFitWorldHeight(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
SCALE,
|
||||
20, 150,
|
||||
100*SCALE, 100*SCALE,
|
||||
0, 0,
|
||||
)
|
||||
|
||||
require.Equal(t, 1500, got)
|
||||
}
|
||||
|
||||
func TestCorrectCameraZoomFpUsesMaxFitAcrossAxes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
SCALE,
|
||||
120, 150,
|
||||
100*SCALE, 100*SCALE,
|
||||
0, 0,
|
||||
)
|
||||
|
||||
require.Equal(t, 1500, got)
|
||||
}
|
||||
|
||||
func TestCorrectCameraZoomFpAppliesMinZoomWhenLargerThanCurrentAndFit(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
SCALE,
|
||||
20, 20,
|
||||
100*SCALE, 100*SCALE,
|
||||
1500, 0,
|
||||
)
|
||||
|
||||
require.Equal(t, 1500, got)
|
||||
}
|
||||
|
||||
func TestCorrectCameraZoomFpAppliesMaxZoomWhenNoFitConflict(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
4*SCALE,
|
||||
20, 20,
|
||||
100*SCALE, 100*SCALE,
|
||||
0, 3*SCALE,
|
||||
)
|
||||
|
||||
require.Equal(t, 3*SCALE, got)
|
||||
}
|
||||
|
||||
func TestCorrectCameraZoomFpIgnoresMaxZoomWhenFitNeedsMore(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
SCALE,
|
||||
200, 20,
|
||||
100*SCALE, 100*SCALE,
|
||||
0, 1500,
|
||||
)
|
||||
|
||||
require.Equal(t, 2*SCALE, got)
|
||||
}
|
||||
|
||||
func TestCorrectCameraZoomFpAppliesMinThenMaxWhenBothValid(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
SCALE,
|
||||
20, 20,
|
||||
100*SCALE, 100*SCALE,
|
||||
1500, 1600,
|
||||
)
|
||||
|
||||
require.Equal(t, 1500, got)
|
||||
}
|
||||
|
||||
func TestCorrectCameraZoomFpCurrentAboveMaxGetsClamped(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
5*SCALE,
|
||||
20, 20,
|
||||
100*SCALE, 100*SCALE,
|
||||
0, 3*SCALE,
|
||||
)
|
||||
|
||||
require.Equal(t, 3*SCALE, got)
|
||||
}
|
||||
|
||||
func TestCorrectCameraZoomFpZeroViewportUsesOnlyBounds(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
SCALE,
|
||||
0, 0,
|
||||
100*SCALE, 100*SCALE,
|
||||
1500, 0,
|
||||
)
|
||||
|
||||
require.Equal(t, 1500, got)
|
||||
}
|
||||
|
||||
func TestCorrectCameraZoomFpZeroBoundsAreIgnored(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
1250,
|
||||
20, 20,
|
||||
100*SCALE, 100*SCALE,
|
||||
0, 0,
|
||||
)
|
||||
|
||||
require.Equal(t, 1250, got)
|
||||
}
|
||||
|
||||
func TestCorrectCameraZoomFpPanics(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
fn func()
|
||||
}{
|
||||
{
|
||||
name: "non-positive current zoom",
|
||||
fn: func() {
|
||||
_ = correctCameraZoomFp(0, 10, 10, 100*SCALE, 100*SCALE, 0, 0)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "negative viewport width",
|
||||
fn: func() {
|
||||
_ = correctCameraZoomFp(SCALE, -1, 10, 100*SCALE, 100*SCALE, 0, 0)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "negative viewport height",
|
||||
fn: func() {
|
||||
_ = correctCameraZoomFp(SCALE, 10, -1, 100*SCALE, 100*SCALE, 0, 0)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "non-positive world width",
|
||||
fn: func() {
|
||||
_ = correctCameraZoomFp(SCALE, 10, 10, 0, 100*SCALE, 0, 0)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "non-positive world height",
|
||||
fn: func() {
|
||||
_ = correctCameraZoomFp(SCALE, 10, 10, 100*SCALE, 0, 0, 0)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "negative min zoom",
|
||||
fn: func() {
|
||||
_ = correctCameraZoomFp(SCALE, 10, 10, 100*SCALE, 100*SCALE, -1, 0)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "negative max zoom",
|
||||
fn: func() {
|
||||
_ = correctCameraZoomFp(SCALE, 10, 10, 100*SCALE, 100*SCALE, 0, -1)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "min greater than max",
|
||||
fn: func() {
|
||||
_ = correctCameraZoomFp(SCALE, 10, 10, 100*SCALE, 100*SCALE, 2000, 1500)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require.Panics(t, tt.fn)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestWorldCorrectCameraZoomReturnsFloatValue(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
w := NewWorld(100, 100)
|
||||
|
||||
got := w.CorrectCameraZoom(1.0, 120, 20)
|
||||
|
||||
require.Equal(t, 1.2, got)
|
||||
}
|
||||
|
||||
func TestWorldCorrectCameraZoomAppliesDefaultBounds(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
w := NewWorld(100, 100)
|
||||
|
||||
got := w.CorrectCameraZoom(100.0, 20, 20)
|
||||
|
||||
require.Equal(t, worldFixedToCameraZoom(MAX_ZOOM), got)
|
||||
}
|
||||
|
||||
func TestWorldCorrectCameraZoomFitBeatsDefaultMaxBound(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
w := NewWorld(1, 100)
|
||||
|
||||
got := w.CorrectCameraZoom(1.0, 40, 10)
|
||||
|
||||
require.Equal(t, 40.0, got)
|
||||
}
|
||||
|
||||
func TestCorrectCameraZoomFp_DoesNotLowerZoomWhenViewportIsSmallerThanWorld(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
SCALE, // currentZoomFp = 1.0x
|
||||
80, 80, // viewport px
|
||||
100*SCALE, 100*SCALE, // world fp
|
||||
0, 0,
|
||||
)
|
||||
|
||||
// No anti-wrap needed, and we do not auto-fit by lowering zoom.
|
||||
require.Equal(t, SCALE, got)
|
||||
}
|
||||
|
||||
func TestCorrectCameraZoomFp_RaisesZoomToPreventWrapWhenViewportIsLarger(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// World width = 100 units, viewport width = 120 px, at zoom=1 visible span = 120 units => too large.
|
||||
got := correctCameraZoomFp(
|
||||
SCALE,
|
||||
120, 20,
|
||||
100*SCALE, 100*SCALE,
|
||||
0, 0,
|
||||
)
|
||||
|
||||
require.Equal(t, 1200, got) // 1.2x
|
||||
}
|
||||
|
||||
func TestCorrectCameraZoomFp_AppliesMaxZoomWhenNoWrapConflict(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
4*SCALE, // user wants 4x
|
||||
20, 20,
|
||||
100*SCALE, 100*SCALE,
|
||||
0, 3*SCALE, // max 3x
|
||||
)
|
||||
|
||||
require.Equal(t, 3*SCALE, got)
|
||||
}
|
||||
|
||||
func TestCorrectCameraZoomFp_AntiWrapBeatsMaxZoom(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// requiredFit = 2x, but max is 1.5x => must return 2x.
|
||||
got := correctCameraZoomFp(
|
||||
SCALE,
|
||||
200, 20,
|
||||
100*SCALE, 100*SCALE,
|
||||
0, 1500,
|
||||
)
|
||||
|
||||
require.Equal(t, 2*SCALE, got)
|
||||
}
|
||||
|
||||
func TestCorrectCameraZoomFp_AppliesMinZoom(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
800, // 0.8x
|
||||
20, 20,
|
||||
100*SCALE, 100*SCALE,
|
||||
SCALE, 0, // min 1.0x
|
||||
)
|
||||
|
||||
require.Equal(t, SCALE, got)
|
||||
}
|
||||
|
||||
func TestCorrectCameraZoomFp_ZeroViewportUsesOnlyBounds(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := correctCameraZoomFp(
|
||||
SCALE,
|
||||
0, 0,
|
||||
100*SCALE, 100*SCALE,
|
||||
1500, 0,
|
||||
)
|
||||
|
||||
require.Equal(t, 1500, got)
|
||||
}
|
||||
Reference in New Issue
Block a user