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