diff --git a/src/handlers/createHandler.ts b/src/handlers/createHandler.ts index 6390f0824a..69bd01ebe8 100644 --- a/src/handlers/createHandler.ts +++ b/src/handlers/createHandler.ts @@ -11,7 +11,12 @@ import deepEqual from 'lodash/isEqual'; import RNGestureHandlerModule from '../RNGestureHandlerModule'; import type RNGestureHandlerModuleWeb from '../RNGestureHandlerModule.web'; import { State } from '../State'; -import { handlerIDToTag, getNextHandlerTag } from './handlersRegistry'; +import { + handlerIDToTag, + getNextHandlerTag, + unregisterJestHandler, + registerJestHandler, +} from './handlersRegistry'; import { BaseGestureHandlerProps, @@ -21,6 +26,7 @@ import { findNodeHandle, } from './gestureHandlerCommon'; import { ValueOf } from '../typeUtils'; +import { isJest } from '../utils'; const UIManagerAny = UIManager as any; @@ -152,7 +158,8 @@ export default function createHandler< constructor(props: T & InternalEventHandlers) { super(props); - this.handlerTag = getNextHandlerTag(); + this.handlerTag = + isJest() && props.testId ? props.testId : getNextHandlerTag(); this.config = {}; this.propsRef = React.createRef(); this.state = { allowTouches }; @@ -220,6 +227,10 @@ export default function createHandler< // eslint-disable-next-line @typescript-eslint/no-dynamic-delete delete handlerIDToTag[handlerID]; } + + if (isJest()) { + unregisterJestHandler(this.handlerTag); + } } private onGestureHandlerEvent = (event: GestureEvent) => { @@ -293,6 +304,10 @@ export default function createHandler< false ); } + + if (isJest()) { + registerJestHandler(this.handlerTag, this); + } }; private updateGestureHandler = ( @@ -301,6 +316,10 @@ export default function createHandler< this.config = newConfig; RNGestureHandlerModule.updateGestureHandler(this.handlerTag, newConfig); + + if (isJest()) { + registerJestHandler(this.handlerTag, this); + } }; private update() { diff --git a/src/handlers/gestureHandlerCommon.ts b/src/handlers/gestureHandlerCommon.ts index aaab3d09d7..ff9d5605ad 100644 --- a/src/handlers/gestureHandlerCommon.ts +++ b/src/handlers/gestureHandlerCommon.ts @@ -114,6 +114,7 @@ export type BaseGestureHandlerProps< id?: string; waitFor?: React.Ref | React.Ref[]; simultaneousHandlers?: React.Ref | React.Ref[]; + testId?: number; // TODO(TS) - fix event types onBegan?: (event: HandlerStateChangeEvent) => void; onFailed?: (event: HandlerStateChangeEvent) => void; diff --git a/src/handlers/gestures/GestureDetector.tsx b/src/handlers/gestures/GestureDetector.tsx index 4f16e92341..9d12ece58a 100644 --- a/src/handlers/gestures/GestureDetector.tsx +++ b/src/handlers/gestures/GestureDetector.tsx @@ -7,7 +7,12 @@ import { CALLBACK_TYPE, } from './gesture'; import { Reanimated, SharedValue } from './reanimatedWrapper'; -import { registerHandler, unregisterHandler } from '../handlersRegistry'; +import { + registerHandler, + registerJestHandler, + unregisterHandler, + unregisterJestHandler, +} from '../handlersRegistry'; import RNGestureHandlerModule from '../../RNGestureHandlerModule'; import { baseGestureHandlerWithMonitorProps, @@ -32,6 +37,7 @@ import { tapGestureHandlerProps } from '../TapGestureHandler'; import { State } from '../../State'; import { EventType } from '../../EventType'; import { ComposedGesture } from './gestureComposition'; +import { isJest } from '../../utils'; const ALLOWED_PROPS = [ ...baseGestureHandlerWithMonitorProps, @@ -76,6 +82,10 @@ function dropHandlers(preparedGesture: GestureConfigReference) { RNGestureHandlerModule.dropGestureHandler(handler.handlerTag); unregisterHandler(handler.handlerTag); + + if (isJest()) { + unregisterJestHandler(handler.handlerTag); + } } } @@ -147,6 +157,10 @@ function attachHandlers({ viewTag, !useAnimated // send direct events when using animatedGesture, device events otherwise ); + + if (isJest()) { + registerJestHandler(gesture.handlerTag, gesture); + } } if (preparedGesture.animatedHandlers) { @@ -198,6 +212,10 @@ function updateHandlers( ); registerHandler(handler.handlerTag, handler); + + if (isJest()) { + registerJestHandler(handler.handlerTag, handler); + } } if (preparedGesture.animatedHandlers) { diff --git a/src/handlers/gestures/gesture.ts b/src/handlers/gestures/gesture.ts index da4ab4f95b..1e8ff83631 100644 --- a/src/handlers/gestures/gesture.ts +++ b/src/handlers/gestures/gesture.ts @@ -15,6 +15,7 @@ import { PinchGestureHandlerEventPayload } from '../PinchGestureHandler'; import { RotationGestureHandlerEventPayload } from '../RotationGestureHandler'; import { TapGestureHandlerEventPayload } from '../TapGestureHandler'; import { NativeViewGestureHandlerPayload } from '../NativeViewGestureHandler'; +import { isJest } from '../../utils'; export type GestureType = | BaseGesture> @@ -41,6 +42,7 @@ export interface BaseGestureConfig simultaneousWith?: GestureRef[]; needsPointerData?: boolean; manualActivation?: boolean; + testId?: number; } type TouchEventHandlerType = ( @@ -246,8 +248,15 @@ export abstract class BaseGesture< return this; } + withTestId(id: number) { + this.config.testId = id; + return this; + } + initialize() { - this.handlerTag = getNextHandlerTag(); + this.handlerTag = + isJest() && this.config.testId ? this.config.testId : getNextHandlerTag(); + this.handlers = { ...this.handlers, handlerTag: this.handlerTag }; if (this.config.ref) { diff --git a/src/handlers/handlersRegistry.ts b/src/handlers/handlersRegistry.ts index eb165ceb76..e55f037ba2 100644 --- a/src/handlers/handlersRegistry.ts +++ b/src/handlers/handlersRegistry.ts @@ -20,3 +20,18 @@ export function unregisterHandler(handlerTag: number) { export function findHandler(handlerTag: number) { return handlers.get(handlerTag); } + +// store all gestures and handlers for Jest +const jestHandlers = new Map(); + +export function registerJestHandler(handlerTag: number, handler: any) { + jestHandlers.set(handlerTag, handler); +} + +export function unregisterJestHandler(handlerTag: number) { + jestHandlers.delete(handlerTag); +} + +export function findJestHandler(handlerTag: number) { + return jestHandlers.get(handlerTag); +} diff --git a/src/index.ts b/src/index.ts index fd4c8f3c1d..63b6b81d18 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,7 @@ import { initialize } from './init'; +export { findJestHandler } from './handlers/handlersRegistry'; + export { Directions } from './Directions'; export { State } from './State'; export { default as gestureHandlerRootHOC } from './gestureHandlerRootHOC'; diff --git a/src/utils.ts b/src/utils.ts index 3bc66c2306..4941e18f5f 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -5,3 +5,7 @@ export function toArray(object: T | T[]): T[] { return object; } + +export function isJest(): boolean { + return !!process.env.JEST_WORKER_ID; +} diff --git a/tsconfig.json b/tsconfig.json index ecfc118f30..4e9e5165f7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,7 @@ "esModuleInterop": true, "jsx": "react-native", "lib": ["esnext"], - "types": [], + "types": ["node"], "module": "esnext", "moduleResolution": "node", "resolveJsonModule": true,