Skip to content

Commit

Permalink
[Jest] Don't fire callbacks on disabled gestures (#3119)
Browse files Browse the repository at this point in the history
## Description

As pointed in #3117, `fireGestureHandler` runs callback function even if gesture has been marked as disabled with `enable(false)`. This PR removes this behavior. 

Closes #3117 

## Test plan

<details>
<summary>Run the following test:</summary>

```tsx
import React from 'react';
import { View } from 'react-native';
import Animated from 'react-native-reanimated';
import {
  Gesture,
  GestureDetector,
  GestureHandlerRootView,
  TapGestureHandler,
  type TapGesture,
} from '../';
import { fireGestureHandler, getByGestureTestId } from '../jestUtils';
import { render } from '@testing-library/react-native';
import Mocks from '../mocks';

type ComponentProps = {
  enabled: boolean;
  callback: () => void;
};

const Component = ({ enabled, callback }: ComponentProps) => {
  const tap = Gesture.Tap()
    .withTestId('tap')
    .enabled(enabled)
    .runOnJS(true)
    .onEnd(callback);

  return (
    <GestureDetector gesture={tap}>
      <Animated.View
        style={{ width: 200, height: 200, backgroundColor: 'orange' }}
      />
    </GestureDetector>
  );
};

describe('Some Random Tests', () => {
  type TestData = {
    title: string;
    enabled: boolean;
    timesCalled: number;
  };

  it.each<TestData>([
    { title: 'should trigger callback once', enabled: true, timesCalled: 1 },
    { title: 'should not trigger callback', enabled: false, timesCalled: 0 },
  ])('$title', ({ enabled, timesCalled }) => {
    const callback = jest.fn();
    render(<Component enabled={enabled} callback={callback} />);

    fireGestureHandler<TapGesture>(getByGestureTestId('tap'));

    expect(callback).toHaveBeenCalledTimes(timesCalled);
  });
});

describe('Button test', () => {
  const callback = jest.fn();
  const { getByTestId } = render(
    <Mocks.RectButton enabled={false} onPress={callback} testID="btn" />
  );

  fireGestureHandler(getByTestId('btn'));

  expect(callback).toHaveBeenCalledTimes(0);
});

describe('Old API test', () => {
  const callback = jest.fn();
  const { getByTestId } = render(
    <GestureHandlerRootView>
      <TapGestureHandler testID="tap" onActivated={callback} enabled={false}>
        <View />
      </TapGestureHandler>
    </GestureHandlerRootView>
  );

  fireGestureHandler(getByTestId('tap'));

  expect(callback).toHaveBeenCalledTimes(0);
});
```

</details>
  • Loading branch information
m-bert authored Sep 23, 2024
1 parent a92c219 commit 5b41fb1
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/handlers/createHandler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,7 @@ export default function createHandler<
? {
handlerType: name,
handlerTag: this.handlerTag,
enabled: this.props.enabled,
}
: {}),
testID: this.props.testID ?? child.props.testID,
Expand Down
9 changes: 8 additions & 1 deletion src/jestUtils/jestUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ interface HandlerData {
emitEvent: EventEmitter;
handlerType: HandlerNames;
handlerTag: number;
enabled: boolean | undefined;
}
function getHandlerData(
componentOrGesture: ReactTestInstance | GestureType
Expand All @@ -417,6 +418,7 @@ function getHandlerData(
},
handlerType: gesture.handlerName as HandlerNames,
handlerTag: gesture.handlerTag,
enabled: gesture.config.enabled,
};
}
const gestureHandlerComponent = componentOrGesture;
Expand All @@ -426,6 +428,7 @@ function getHandlerData(
},
handlerType: gestureHandlerComponent.props.handlerType as HandlerNames,
handlerTag: gestureHandlerComponent.props.handlerTag as number,
enabled: gestureHandlerComponent.props.enabled,
};
}
type AllGestures =
Expand Down Expand Up @@ -467,9 +470,13 @@ export function fireGestureHandler<THandler extends AllGestures | AllHandlers>(
componentOrGesture: ReactTestInstance | GestureType,
eventList: Partial<GestureHandlerTestEvent<ExtractConfig<THandler>>>[] = []
): void {
const { emitEvent, handlerType, handlerTag } =
const { emitEvent, handlerType, handlerTag, enabled } =
getHandlerData(componentOrGesture);

if (enabled === false) {
return;
}

let _ = fillMissingStatesTransitions(
eventList,
isDiscreteHandler(handlerType)
Expand Down

0 comments on commit 5b41fb1

Please sign in to comment.