software-mansion / react-native-gesture-handler

Declarative API exposing platform native touch and gesture system to React Native.
https://docs.swmansion.com/react-native-gesture-handler/
MIT License
6.13k stars 982 forks source link

fireGestureHandler should not trigger disabled gestures #3117

Closed Glazzes closed 1 month ago

Glazzes commented 2 months ago

Description

Hello, I've been trying to write some tests for my library, however I've noticed fireGestureHandler is capable of triggering events in gestures whose enabled method has been set to false, is this the expected behavior?

Steps to reproduce

Run the following code as a Jest test, expected behavior is the second gesture is not triggered and therefore the mock is not called, however the mock it's called regardless of whether the gesture is enabled or not.

import React from 'react';
import Animated from 'react-native-reanimated';
import {
  Gesture,
  GestureDetector,
  type TapGesture,
} from 'react-native-gesture-handler';
import {
  fireGestureHandler,
  getByGestureTestId,
} from 'react-native-gesture-handler/jest-utils';
import { render } from '@testing-library/react-native';

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

Snack or a link to a repository

code provided above

Gesture Handler version

2.19.0

React Native version

0.74.1

Platforms

Android, iOS

JavaScript runtime

None

Workflow

None

Architecture

None

Build type

None

Device

None

Device model

No response

Acknowledgements

Yes

github-actions[bot] commented 2 months ago

Hey! 👋

The issue doesn't seem to contain a minimal reproduction.

Could you provide a snack or a link to a GitHub repository under your username that reproduces the problem?

m-bert commented 1 month ago

Hi @Glazzes! Could you please check if #3119 solves this problem?

Glazzes commented 1 month ago

@m-bert Excuse me if it's an ignorant question, but how do I test these changes? I copied your changes pretty much to the T in my project but I do keep getting the same results.

m-bert commented 1 month ago

I've just run your test and it seems to work:

image

(...) how do I test these changes?

You can install Gesture Handler directly from my branch and then run tests. Doing so may vary depending on your package manager (and its version). Here you can find out how to do this:

Glazzes commented 1 month ago

I just tested by installing the main branch and it does indeed work, thank you for work!