@@ -61,7 +61,7 @@ func TestFilter_CoalescesSameDirection(t *testing.T) {
61 require.Equal(t, float64(3), msg.DeltaY, "should accumulate 3 down events")
61 require.Equal(t, float64(3), msg.DeltaY, "should accumulate 3 down events")
64−func TestFilter_DirectionChangeResetsAccumulator(t *testing.T) {
64+func TestFilter_DirectionChangeWithinWindowAccumulatesNewDirection(t *testing.T) {
65 t.Parallel()
65 t.Parallel()
66 f, now := newTestFilter(t)
66 f, now := newTestFilter(t)
@@ -81,6 +81,31 @@ func TestFilter_DirectionChangeResetsAccumulator(t *testing.T) {
81 require.Equal(t, float64(-2), msg.DeltaY, "should have 2 accumulated up events")
81 require.Equal(t, float64(-2), msg.DeltaY, "should have 2 accumulated up events")
84+func TestFilter_DirectionChangeDropsStaleAccumulator(t *testing.T) {
86+ f, now := newTestFilter(t)
89+ f.Filter(nil, wheelUp())
92+ *now = now.Add(5 * time.Millisecond)
93+ result := f.Filter(nil, wheelUp())
94+ require.Nil(t, result)
96+ // Scroll down (accumulation should reset)
97+ *now = now.Add(5 * time.Millisecond)
98+ result = f.Filter(nil, wheelDown())
99+ require.Nil(t, result)
101+ // And scroll down again
102+ *now = now.Add(20 * time.Millisecond)
103+ result = f.Filter(nil, wheelDown())
104+ msg, ok := result.(common.CoalescedWheelMsg)
106+ require.Equal(t, float64(2), msg.DeltaY, "should drop stale opposite-direction events")
84func TestFilter_WindowExpiryEmitsAccumulated(t *testing.T) {
109func TestFilter_WindowExpiryEmitsAccumulated(t *testing.T) {
85 t.Parallel()
110 t.Parallel()
86 f, now := newTestFilter(t)
111 f, now := newTestFilter(t)