From 8641806f0e12b513e1865f9e1063710ec29c07e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Wed, 29 May 2019 16:21:43 +0200 Subject: [PATCH 1/2] feat: support 'disabled' prop --- src/__tests__/fireEvent.test.js | 25 +++++++++++++++++- src/fireEvent.js | 47 ++++++++++++++++++++++++++------- 2 files changed, 61 insertions(+), 11 deletions(-) diff --git a/src/__tests__/fireEvent.test.js b/src/__tests__/fireEvent.test.js index 845a1c2cd..44d882522 100644 --- a/src/__tests__/fireEvent.test.js +++ b/src/__tests__/fireEvent.test.js @@ -17,6 +17,18 @@ const OnPressComponent = ({ onPress }) => ( ); +const DisabledComponent = ({ onPress, disabled = false }) => ( + + + Press me + + +); + const WithoutEventComponent = () => ( Content @@ -60,7 +72,7 @@ describe('fireEvent', () => { const { getByTestId } = render(); expect(() => fireEvent(getByTestId('text'), 'press')).toThrow( - 'No handler function found for event: press' + 'No handler function found for event: "press"' ); }); @@ -90,6 +102,17 @@ describe('fireEvent', () => { expect(() => fireEvent.press(getByTestId('test'))).toThrow(); expect(onPressMock).not.toHaveBeenCalled(); }); + + test('should not stop bubbling when disabled element found', () => { + const onPressMock = jest.fn(); + + const { getByTestId } = render( + + ); + fireEvent.press(getByTestId('disabled-press-me')); + + expect(onPressMock).not.toHaveBeenCalled(); + }); }); test('fireEvent.press', () => { diff --git a/src/fireEvent.js b/src/fireEvent.js index 455966219..b5955c4d4 100644 --- a/src/fireEvent.js +++ b/src/fireEvent.js @@ -2,9 +2,31 @@ import act from './act'; import { ErrorWithStack } from './helpers/errors'; -const findEventHandler = (element: ReactTestInstance, eventName: string) => { +const isDisabled = element => { + const { disabled, accessibilityStates = [] } = element.props; + const hasA11yDisabledState = accessibilityStates.includes('disabled'); + // TODO: make this throw an error in v2, so user can get a more helpful message with a codeframe + if (disabled && !hasA11yDisabledState) { + // eslint-disable-next-line no-console + console.warn( + `Element disabled but not accessible. Please consider adding \`accessibilityStates: ["disabled"]\` prop next to "disabled".` + ); + } + + return disabled; +}; + +const findEventHandler = ( + element: ReactTestInstance, + eventName: string, + callsite?: any +) => { const eventHandler = toEventHandlerName(eventName); + if (isDisabled(element)) { + return null; + } + if (typeof element.props[eventHandler] === 'function') { return element.props[eventHandler]; } else if (typeof element.props[eventName] === 'function') { @@ -14,20 +36,25 @@ const findEventHandler = (element: ReactTestInstance, eventName: string) => { // Do not bubble event to the root element if (element.parent === null || element.parent.parent === null) { throw new ErrorWithStack( - `No handler function found for event: ${eventName}`, - invokeEvent + `No handler function found for event: "${eventName}"`, + callsite || invokeEvent ); } - return findEventHandler(element.parent, eventName); + return findEventHandler(element.parent, eventName, callsite); }; const invokeEvent = ( element: ReactTestInstance, eventName: string, - data?: * -): any => { - const handler = findEventHandler(element, eventName); + data?: any, + callsite?: any +) => { + const handler = findEventHandler(element, eventName, callsite); + + if (!handler) { + return null; + } let returnValue; @@ -42,11 +69,11 @@ const toEventHandlerName = (eventName: string) => `on${eventName.charAt(0).toUpperCase()}${eventName.slice(1)}`; const pressHandler = (element: ReactTestInstance) => - invokeEvent(element, 'press'); + invokeEvent(element, 'press', undefined, pressHandler); const changeTextHandler = (element: ReactTestInstance, data?: *) => - invokeEvent(element, 'changeText', data); + invokeEvent(element, 'changeText', data, changeTextHandler); const scrollHandler = (element: ReactTestInstance, data?: *) => - invokeEvent(element, 'scroll', data); + invokeEvent(element, 'scroll', data, scrollHandler); const fireEvent = invokeEvent; From 19353f01bea3000893cbe0728c06cdec282ecb26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Wed, 29 May 2019 16:35:53 +0200 Subject: [PATCH 2/2] revert disabled handling --- src/__tests__/fireEvent.test.js | 23 ----------------------- src/fireEvent.js | 18 ------------------ 2 files changed, 41 deletions(-) diff --git a/src/__tests__/fireEvent.test.js b/src/__tests__/fireEvent.test.js index 44d882522..c1914a0e9 100644 --- a/src/__tests__/fireEvent.test.js +++ b/src/__tests__/fireEvent.test.js @@ -17,18 +17,6 @@ const OnPressComponent = ({ onPress }) => ( ); -const DisabledComponent = ({ onPress, disabled = false }) => ( - - - Press me - - -); - const WithoutEventComponent = () => ( Content @@ -102,17 +90,6 @@ describe('fireEvent', () => { expect(() => fireEvent.press(getByTestId('test'))).toThrow(); expect(onPressMock).not.toHaveBeenCalled(); }); - - test('should not stop bubbling when disabled element found', () => { - const onPressMock = jest.fn(); - - const { getByTestId } = render( - - ); - fireEvent.press(getByTestId('disabled-press-me')); - - expect(onPressMock).not.toHaveBeenCalled(); - }); }); test('fireEvent.press', () => { diff --git a/src/fireEvent.js b/src/fireEvent.js index b5955c4d4..26fb7d2aa 100644 --- a/src/fireEvent.js +++ b/src/fireEvent.js @@ -2,20 +2,6 @@ import act from './act'; import { ErrorWithStack } from './helpers/errors'; -const isDisabled = element => { - const { disabled, accessibilityStates = [] } = element.props; - const hasA11yDisabledState = accessibilityStates.includes('disabled'); - // TODO: make this throw an error in v2, so user can get a more helpful message with a codeframe - if (disabled && !hasA11yDisabledState) { - // eslint-disable-next-line no-console - console.warn( - `Element disabled but not accessible. Please consider adding \`accessibilityStates: ["disabled"]\` prop next to "disabled".` - ); - } - - return disabled; -}; - const findEventHandler = ( element: ReactTestInstance, eventName: string, @@ -23,10 +9,6 @@ const findEventHandler = ( ) => { const eventHandler = toEventHandlerName(eventName); - if (isDisabled(element)) { - return null; - } - if (typeof element.props[eventHandler] === 'function') { return element.props[eventHandler]; } else if (typeof element.props[eventName] === 'function') {