diff --git a/src/__tests__/fireEvent.test.tsx b/src/__tests__/fireEvent.test.tsx index 184ba6067..0c34e8836 100644 --- a/src/__tests__/fireEvent.test.tsx +++ b/src/__tests__/fireEvent.test.tsx @@ -56,6 +56,28 @@ const CustomEventComponentWithCustomName = ({ ); describe('fireEvent', () => { + test('QUESTION: is there a kind of event that takes multiple arguments?', () => { + const handlerMock = jest.fn(); + + const { getByText } = render( + + + + ); + + fireEvent( + getByText('Custom event component'), + 'customEvent', + 'some_argument_1', + 'some_argument_2' + ); + + expect(handlerMock).toHaveBeenCalledWith( + 'some_argument_1', + 'some_argument_2' + ); + }); + test('should invoke specified event', () => { const onPressMock = jest.fn(); const { getByText } = render( @@ -67,6 +89,37 @@ describe('fireEvent', () => { expect(onPressMock).toHaveBeenCalled(); }); + test('should pass along provided event data', () => { + const onPressMock = jest.fn(); + const text = 'Fireevent press'; + const eventData = { + nativeEvent: { + pageX: 20, + pageY: 30, + }, + }; + const { getByText } = render( + + ); + + fireEvent(getByText(text), 'press', eventData); + + expect(onPressMock).toHaveBeenCalledWith(eventData); + }); + + test('should not pass a generated event object by default with the string syntax', () => { + const onPressMock = jest.fn(); + const text = 'Fireevent press'; + const { getByText } = render( + + ); + + fireEvent(getByText(text), 'press'); + + expect(onPressMock).toHaveBeenCalled(); + expect(onPressMock).not.toHaveBeenCalledWith({ eventName: 'press' }); + }); + test('should invoke specified event on parent element', () => { const onPressMock = jest.fn(); const text = 'New press text'; @@ -104,64 +157,113 @@ describe('fireEvent', () => { }); }); -test('fireEvent.press', () => { - const onPressMock = jest.fn(); - const text = 'Fireevent press'; - const eventData = { - nativeEvent: { - pageX: 20, - pageY: 30, - }, - }; - const { getByText } = render( - - ); +describe('fireEvent.press', () => { + test('should pass along provided event data', () => { + const onPressMock = jest.fn(); + const text = 'Fireevent press'; + const eventData = { + nativeEvent: { + pageX: 20, + pageY: 30, + }, + }; + const { getByText } = render( + + ); - fireEvent.press(getByText(text), eventData); + fireEvent.press(getByText(text), eventData); + + expect(onPressMock).toHaveBeenCalledWith(eventData); + }); - expect(onPressMock).toHaveBeenCalledWith(eventData); + test('should pass a generated event object by default with the function syntax', () => { + const onPressMock = jest.fn(); + const text = 'Fireevent press'; + const { getByText } = render( + + ); + + fireEvent.press(getByText(text)); + + expect(onPressMock).toHaveBeenCalledWith({ eventName: 'press' }); + }); }); -test('fireEvent.scroll', () => { - const onScrollMock = jest.fn(); - const eventData = { - nativeEvent: { - contentOffset: { - y: 200, +describe('fireEvent.scroll', () => { + test('should pass along provided event data', () => { + const onScrollMock = jest.fn(); + const eventData = { + nativeEvent: { + contentOffset: { + y: 200, + }, }, - }, - }; + }; - const { getByText } = render( - - XD - - ); + const { getByText } = render( + + XD + + ); + + fireEvent.scroll(getByText('XD'), eventData); + + expect(onScrollMock).toHaveBeenCalledWith(eventData); + }); + test('should pass a generated event object by default', () => { + const onScrollMock = jest.fn(); + const eventData = { eventName: 'scroll' }; + + const { getByText } = render( + + XD + + ); - fireEvent.scroll(getByText('XD'), eventData); + fireEvent.scroll(getByText('XD')); - expect(onScrollMock).toHaveBeenCalledWith(eventData); + expect(onScrollMock).toHaveBeenCalledWith(eventData); + }); }); -test('fireEvent.changeText', () => { - const onChangeTextMock = jest.fn(); - const CHANGE_TEXT = 'content'; +describe('fireEvent.changeText', () => { + test('should pass the provided text', () => { + const onChangeTextMock = jest.fn(); + const CHANGE_TEXT = 'content'; - const { getByPlaceholderText } = render( - - - - ); + const { getByPlaceholderText } = render( + + + + ); - fireEvent.changeText( - getByPlaceholderText('Customer placeholder'), - CHANGE_TEXT - ); + fireEvent.changeText( + getByPlaceholderText('Customer placeholder'), + CHANGE_TEXT + ); + + expect(onChangeTextMock).toHaveBeenCalledWith(CHANGE_TEXT); + }); + + test('what if no text is provided', () => { + const onChangeTextMock = jest.fn(); + + const { getByPlaceholderText } = render( + + + + ); - expect(onChangeTextMock).toHaveBeenCalledWith(CHANGE_TEXT); + fireEvent.changeText(getByPlaceholderText('Customer placeholder')); + + expect(onChangeTextMock).toHaveBeenCalledWith(); + }); }); test('custom component with custom event name', () => { diff --git a/src/fireEvent.ts b/src/fireEvent.ts index f5ec35f4f..00e1c3f76 100644 --- a/src/fireEvent.ts +++ b/src/fireEvent.ts @@ -107,7 +107,7 @@ const invokeEvent = ( element: ReactTestInstance, eventName: string, callsite?: any, - ...data: Array + ...callBackValues: Array ) => { const handler = findEventHandler(element, eventName, callsite); @@ -118,7 +118,7 @@ const invokeEvent = ( let returnValue; act(() => { - returnValue = handler(...data); + returnValue = handler(...callBackValues); }); return returnValue; @@ -127,23 +127,42 @@ const invokeEvent = ( const toEventHandlerName = (eventName: string) => `on${eventName.charAt(0).toUpperCase()}${eventName.slice(1)}`; -const pressHandler = (element: ReactTestInstance, ...data: Array): void => - invokeEvent(element, 'press', pressHandler, ...data); const changeTextHandler = ( element: ReactTestInstance, ...data: Array -): void => invokeEvent(element, 'changeText', changeTextHandler, ...data); -const scrollHandler = (element: ReactTestInstance, ...data: Array): void => - invokeEvent(element, 'scroll', scrollHandler, ...data); +): void => { + invokeEvent(element, 'changeText', changeTextHandler, ...data); +}; -const fireEvent = ( - element: ReactTestInstance, - eventName: string, - ...data: Array -): void => invokeEvent(element, eventName, fireEvent, ...data); +const generatedEventObject = (eventName: string) => { + // This should use the (as-yet nonexistent) event map to return a "real" object, just like + // https://github.com/testing-library/dom-testing-library/blob/29a17cb5f14b0f30f08a29172e35e55c3e8ba529/src/event-map.js#L0-L1 + return { eventName: eventName }; +}; + +const addHandler = (eventName: string) => { + return (element: ReactTestInstance, ...data: Array): void => { + const callBackValue = + data.length > 0 ? data : [generatedEventObject(eventName)]; + invokeEvent(element, eventName, addHandler, ...callBackValue); + }; +}; + +type FireEvent = { + (element: ReactTestInstance, eventName: string, ...data: Array): void; + [key: string]: (element: ReactTestInstance, ...data: Array) => void; +}; + +const fireEvent = ( + ((element: ReactTestInstance, eventName: string, ...data: Array) => + invokeEvent(element, eventName, fireEvent, ...data)) +); + +fireEvent['changeText'] = changeTextHandler; -fireEvent.press = pressHandler; -fireEvent.changeText = changeTextHandler; -fireEvent.scroll = scrollHandler; +// map.keys.forEach ... +['press', 'scroll'].forEach((eventName: string) => { + fireEvent[eventName] = addHandler(eventName); +}); export default fireEvent;