Skip to content

Commit 00a50a8

Browse files
fix: fire event should not throw for disabled handler (#470)
* updated tests * feat: implement behavior chage * code review changes * refactor: more strict test conditions
1 parent a766905 commit 00a50a8

File tree

2 files changed

+44
-24
lines changed

2 files changed

+44
-24
lines changed

src/__tests__/fireEvent.test.js

+12-12
Original file line numberDiff line numberDiff line change
@@ -168,28 +168,28 @@ test('event with multiple handler parameters', () => {
168168
test('should not fire on disabled TouchableOpacity', () => {
169169
const handlePress = jest.fn();
170170
const screen = render(
171-
<TouchableOpacity onPress={handlePress} disabled={true}>
172-
<Text>Trigger</Text>
173-
</TouchableOpacity>
171+
<View>
172+
<TouchableOpacity onPress={handlePress} disabled={true}>
173+
<Text>Trigger</Text>
174+
</TouchableOpacity>
175+
</View>
174176
);
175177

176-
expect(() => fireEvent.press(screen.getByText('Trigger'))).toThrow(
177-
'No handler function found for event: "press"'
178-
);
178+
fireEvent.press(screen.getByText('Trigger'));
179179
expect(handlePress).not.toHaveBeenCalled();
180180
});
181181

182182
test('should not fire on disabled Pressable', () => {
183183
const handlePress = jest.fn();
184184
const screen = render(
185-
<Pressable onPress={handlePress} disabled={true}>
186-
<Text>Trigger</Text>
187-
</Pressable>
185+
<View>
186+
<Pressable onPress={handlePress} disabled={true}>
187+
<Text>Trigger</Text>
188+
</Pressable>
189+
</View>
188190
);
189191

190-
expect(() => fireEvent.press(screen.getByText('Trigger'))).toThrow(
191-
'No handler function found for event: "press"'
192-
);
192+
fireEvent.press(screen.getByText('Trigger'));
193193
expect(handlePress).not.toHaveBeenCalled();
194194
});
195195

src/fireEvent.js

+32-12
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,50 @@ const findEventHandler = (
66
element: ReactTestInstance,
77
eventName: string,
88
callsite?: any,
9-
nearestHostDescendent?: ReactTestInstance
9+
nearestHostDescendent?: ReactTestInstance,
10+
hasDescendandHandler?: boolean
1011
) => {
12+
const handler = getEventHandler(element, eventName);
13+
const hasHandler = handler != null || hasDescendandHandler;
14+
1115
const isHostComponent = typeof element.type === 'string';
1216
const hostElement = isHostComponent ? element : nearestHostDescendent;
1317
const isEventEnabled =
1418
hostElement?.props.onStartShouldSetResponder?.() !== false;
19+
if (handler && isEventEnabled) return handler;
1520

16-
const eventHandlerName = toEventHandlerName(eventName);
21+
// Do not bubble event to the root element
22+
if (element.parent === null || element.parent.parent === null) {
23+
if (hasHandler) {
24+
return null;
25+
} else {
26+
throw new ErrorWithStack(
27+
`No handler function found for event: "${eventName}"`,
28+
callsite || invokeEvent
29+
);
30+
}
31+
}
32+
33+
return findEventHandler(
34+
element.parent,
35+
eventName,
36+
callsite,
37+
hostElement,
38+
hasHandler
39+
);
40+
};
1741

18-
if (typeof element.props[eventHandlerName] === 'function' && isEventEnabled) {
42+
const getEventHandler = (element: ReactTestInstance, eventName: string) => {
43+
const eventHandlerName = toEventHandlerName(eventName);
44+
if (typeof element.props[eventHandlerName] === 'function') {
1945
return element.props[eventHandlerName];
20-
} else if (typeof element.props[eventName] === 'function' && isEventEnabled) {
21-
return element.props[eventName];
2246
}
2347

24-
// Do not bubble event to the root element
25-
if (element.parent === null || element.parent.parent === null) {
26-
throw new ErrorWithStack(
27-
`No handler function found for event: "${eventName}"`,
28-
callsite || invokeEvent
29-
);
48+
if (typeof element.props[eventName] === 'function') {
49+
return element.props[eventName];
3050
}
3151

32-
return findEventHandler(element.parent, eventName, callsite, hostElement);
52+
return undefined;
3353
};
3454

3555
const invokeEvent = (

0 commit comments

Comments
 (0)