package world import ( "testing" "github.com/stretchr/testify/require" ) func TestPlanIncrementalPan_NoOp(t *testing.T) { t.Parallel() plan, err := PlanIncrementalPan(200, 100, 50, 30, 0, 0) require.NoError(t, err) require.Equal(t, IncrementalNoOp, plan.Mode) require.Empty(t, plan.Dirty) } func TestPlanIncrementalPan_FullRedrawOnInvalidCanvas(t *testing.T) { t.Parallel() _, err := PlanIncrementalPan(0, 100, 10, 10, 1, 0) require.ErrorIs(t, err, errInvalidCanvasSize) } func TestPlanIncrementalPan_FullRedrawOnTooLargeShift(t *testing.T) { t.Parallel() plan, err := PlanIncrementalPan(100, 80, 40, 40, 100, 0) require.NoError(t, err) require.Equal(t, IncrementalFullRedraw, plan.Mode) plan, err = PlanIncrementalPan(100, 80, 40, 40, 0, -80) require.NoError(t, err) require.Equal(t, IncrementalFullRedraw, plan.Mode) } func TestPlanIncrementalPan_FullRedrawWhenMarginIsZeroAndDeltaNonZero(t *testing.T) { t.Parallel() plan, err := PlanIncrementalPan(100, 80, 0, 20, 1, 0) require.NoError(t, err) require.Equal(t, IncrementalFullRedraw, plan.Mode) plan, err = PlanIncrementalPan(100, 80, 20, 0, 0, 1) require.NoError(t, err) require.Equal(t, IncrementalFullRedraw, plan.Mode) } func TestPlanIncrementalPan_FullRedrawWhenExceedsThresholdX(t *testing.T) { t.Parallel() // marginX=20 => threshold=10, dx=11 => full redraw plan, err := PlanIncrementalPan(200, 100, 20, 20, 11, 0) require.NoError(t, err) require.Equal(t, IncrementalFullRedraw, plan.Mode) } func TestPlanIncrementalPan_FullRedrawWhenExceedsThresholdY(t *testing.T) { t.Parallel() // marginY=20 => threshold=10, dy=-11 => full redraw plan, err := PlanIncrementalPan(200, 100, 20, 20, 0, -11) require.NoError(t, err) require.Equal(t, IncrementalFullRedraw, plan.Mode) } func TestPlanIncrementalPan_Shift_LeftStripWhenDxPositive(t *testing.T) { t.Parallel() // marginX=40 => threshold=20, dx=5 => shift ok plan, err := PlanIncrementalPan(200, 100, 40, 40, 5, 0) require.NoError(t, err) require.Equal(t, IncrementalShift, plan.Mode) require.Equal(t, 5, plan.DxPx) require.Equal(t, 0, plan.DyPx) require.Equal(t, []RectPx{ {X: 0, Y: 0, W: 6, H: 100}, }, plan.Dirty) } func TestPlanIncrementalPan_Shift_RightStripWhenDxNegative(t *testing.T) { t.Parallel() plan, err := PlanIncrementalPan(200, 100, 40, 40, -7, 0) require.NoError(t, err) require.Equal(t, IncrementalShift, plan.Mode) require.Equal(t, []RectPx{ {X: 200 - 8, Y: 0, W: 8, H: 100}, }, plan.Dirty) } func TestPlanIncrementalPan_Shift_TopStripWhenDyPositive(t *testing.T) { t.Parallel() plan, err := PlanIncrementalPan(200, 100, 40, 40, 0, 9) require.NoError(t, err) require.Equal(t, IncrementalShift, plan.Mode) require.Equal(t, []RectPx{ {X: 0, Y: 0, W: 200, H: 10}, }, plan.Dirty) } func TestPlanIncrementalPan_Shift_BottomStripWhenDyNegative(t *testing.T) { t.Parallel() plan, err := PlanIncrementalPan(200, 100, 40, 40, 0, -9) require.NoError(t, err) require.Equal(t, IncrementalShift, plan.Mode) require.Equal(t, []RectPx{ {X: 0, Y: 100 - 10, W: 200, H: 10}, }, plan.Dirty) } func TestPlanIncrementalPan_Shift_DiagonalReturnsTwoDirtyRects(t *testing.T) { t.Parallel() plan, err := PlanIncrementalPan(200, 100, 40, 40, -6, 8) require.NoError(t, err) require.Equal(t, IncrementalShift, plan.Mode) // Overlap is allowed; we just require both strips exist. require.Len(t, plan.Dirty, 2) require.ElementsMatch(t, []RectPx{ {X: 200 - 7, Y: 0, W: 7, H: 100}, // right strip {X: 0, Y: 0, W: 200, H: 9}, // top strip }, plan.Dirty) } func TestPlanIncrementalPan_OverdrawsDirtyStripsByOnePixel(t *testing.T) { t.Parallel() plan, err := PlanIncrementalPan(200, 100, 40, 40, -7, 0) require.NoError(t, err) require.Equal(t, IncrementalShift, plan.Mode) // Right strip width should be abs(dx)+1 = 8. require.Equal(t, []RectPx{ {X: 200 - 8, Y: 0, W: 8, H: 100}, }, plan.Dirty) }