/**
   * TODO: Make this work using a decent animation shadows / newer Robolectric
   *
   * @throws Exception
   */
  @Ignore
  @Test
  public void onTouchUpAction_eventWhenLeftOverscrolling_smoothScrollBackToRightEnd()
      throws Exception {

    // Arrange

    // Bring UUT to a left-overscroll state
    MotionEvent moveEvent = createShortLeftMoveEvent();

    when(mViewAdapter.isInAbsoluteStart()).thenReturn(false);
    when(mViewAdapter.isInAbsoluteEnd()).thenReturn(true);

    HorizontalOverScrollBounceEffectDecorator uut = getUUT();
    uut.onTouch(mView, moveEvent);
    reset(mView);

    // Make the view as though it's been moved by the move event
    float viewX = moveEvent.getX();
    when(mView.getTranslationX()).thenReturn(viewX);

    MotionEvent upEvent = createDefaultUpActionEvent();

    // Act

    boolean ret = uut.onTouch(mView, upEvent);

    // Assert

    assertTrue(ret);

    verify(mView, atLeastOnce()).setTranslationX(anyFloat());
  }
  @Test
  public void onTouchMoveAction_2ndLeftDragInRightEnd_overscrollLeftFurther() throws Exception {

    // Arrange

    // Bring UUT to a left-overscroll state
    MotionEvent event1 = createShortLeftMoveEvent();

    when(mViewAdapter.isInAbsoluteStart()).thenReturn(false);
    when(mViewAdapter.isInAbsoluteEnd()).thenReturn(true);

    HorizontalOverScrollBounceEffectDecorator uut = getUUT();
    uut.onTouch(mView, event1);
    reset(mView);

    // Create 2nd left-drag event
    MotionEvent event2 = createLongLeftMoveEvent();

    // Act

    boolean ret = uut.onTouch(mView, event2);

    // Assert

    float expectedTransX =
        (event2.getX() - event2.getHistoricalX(0)) / DEFAULT_TOUCH_DRAG_MOVE_RATIO_FWD;
    verify(mView).setTranslationX(expectedTransX);
    verify(mView, never()).setTranslationY(anyFloat());
    assertTrue(ret);
  }
  @Test
  public void onTouchMoveAction_notInViewEnds_ignoreTouchEvent() throws Exception {

    // Arrange

    MotionEvent event = createShortRightMoveEvent();

    when(mViewAdapter.isInAbsoluteStart()).thenReturn(false);
    when(mViewAdapter.isInAbsoluteEnd()).thenReturn(false);

    HorizontalOverScrollBounceEffectDecorator uut = getUUT();

    // Act

    boolean ret = uut.onTouch(mView, event);

    // Assert

    verify(mView, never()).setTranslationX(anyFloat());
    verify(mView, never()).setTranslationY(anyFloat());
    assertFalse(ret);
  }
  @Test
  public void onTouchUpAction_eventWhenNotOverscrolled_ignoreTouchEvent() throws Exception {

    // Arrange

    MotionEvent event = createDefaultUpActionEvent();

    when(mViewAdapter.isInAbsoluteStart()).thenReturn(true);
    when(mViewAdapter.isInAbsoluteEnd()).thenReturn(true);

    HorizontalOverScrollBounceEffectDecorator uut = getUUT();

    // Act

    boolean ret = uut.onTouch(mView, event);

    // Assert

    verify(mView, never()).setTranslationX(anyFloat());
    verify(mView, never()).setTranslationY(anyFloat());
    assertFalse(ret);
  }
  /**
   * When over-scroll has already started (to the left in this case) and suddenly the user changes
   * their mind and scrolls a bit in the other direction: <br>
   * We expect the <b>touch to still be intercepted</b> in that case, and the <b>overscroll to
   * remain in effect</b>.
   */
  @Test
  public void onTouchMoveAction_dragRightWhenLeftOverscolled_continueOverscrollingRight()
      throws Exception {

    // Arrange

    // In left & right tests we use equal ratios to avoid the effect's under-scroll handling
    final float touchDragRatioFwd = 3f;
    final float touchDragRatioBck = 3f;

    // Bring UUT to a left-overscroll state
    when(mViewAdapter.isInAbsoluteStart()).thenReturn(false);
    when(mViewAdapter.isInAbsoluteEnd()).thenReturn(true);

    HorizontalOverScrollBounceEffectDecorator uut = getUUT(touchDragRatioFwd, touchDragRatioBck);
    MotionEvent eventMoveLeft = createLongLeftMoveEvent();
    uut.onTouch(mView, eventMoveLeft);
    reset(mView);

    float startTransX =
        (eventMoveLeft.getX() - eventMoveLeft.getHistoricalX(0)) / touchDragRatioFwd;
    when(mView.getTranslationX()).thenReturn(startTransX);

    // Create the right-drag event
    MotionEvent eventMoveRight = createShortRightMoveEvent();

    // Act

    boolean ret = uut.onTouch(mView, eventMoveRight);

    // Assert

    float expectedTransX =
        startTransX
            + (eventMoveRight.getX() - eventMoveRight.getHistoricalX(0)) / touchDragRatioBck;
    verify(mView).setTranslationX(expectedTransX);
    verify(mView, never()).setTranslationY(anyFloat());
    assertTrue(ret);
  }
  @Test
  public void onTouchMoveAction_dragRightInLeftEnd_overscrollRight() throws Exception {

    // Arrange

    MotionEvent event = createShortRightMoveEvent();

    when(mViewAdapter.isInAbsoluteStart()).thenReturn(true);
    when(mViewAdapter.isInAbsoluteEnd()).thenReturn(false);

    HorizontalOverScrollBounceEffectDecorator uut = getUUT();

    // Act

    boolean ret = uut.onTouch(mView, event);

    // Assert

    float expectedTransX =
        (event.getX() - event.getHistoricalX(0)) / DEFAULT_TOUCH_DRAG_MOVE_RATIO_FWD;
    verify(mView).setTranslationX(expectedTransX);
    verify(mView, never()).setTranslationY(anyFloat());
    assertTrue(ret);
  }