Skip to content

Commit

Permalink
test(xychart): add PointerEvent tests (#952)
Browse files Browse the repository at this point in the history
* test(xychart): add tests for useEventEmitter sources, usePointerEventEmitters, usePointerEventHandlers

* test(xychart/useEventEmitter,usePointerEventHandlers): add more assertions
  • Loading branch information
williaster authored Dec 3, 2020
1 parent dd11a5c commit 4c82b1c
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 5 deletions.
5 changes: 4 additions & 1 deletion packages/visx-xychart/src/hooks/useEventEmitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ export default function useEventEmitter(
if (emitter && eventType && handler) {
// register handler, with source filtering as needed
const handlerWithSourceFilter: Handler = (params?: HandlerParams) => {
if (!params?.source || !sourcesRef.current || sourcesRef.current?.includes(params.source)) {
if (
!sourcesRef.current ||
(params?.source && sourcesRef.current?.includes(params.source))
) {
handler(params);
}
};
Expand Down
44 changes: 40 additions & 4 deletions packages/visx-xychart/test/hooks/useEventEmitter.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import { mount } from 'enzyme';
import useEventEmitter from '../../src/hooks/useEventEmitter';
import { EventEmitterProvider } from '../../src';

// avoids a lot of coercing of types
const getEvent = (eventType: string) =>
(new MouseEvent(eventType) as unknown) as React.PointerEvent;

describe('useEventEmitter', () => {
it('should be defined', () => {
expect(useEventEmitter).toBeDefined();
Expand All @@ -12,8 +16,8 @@ describe('useEventEmitter', () => {
expect.assertions(1);

const Component = () => {
const registry = useEventEmitter();
expect(registry).toEqual(expect.any(Function));
const emitter = useEventEmitter();
expect(emitter).toEqual(expect.any(Function));
return null;
};

Expand All @@ -33,9 +37,41 @@ describe('useEventEmitter', () => {

useEffect(() => {
if (emit) {
// @ts-ignore not a React.MouseEvent
emit('pointermove', new MouseEvent('pointermove'));
emit('pointermove', getEvent('pointermove'));
expect(listener).toHaveBeenCalledTimes(1);
}
});

return null;
};

mount(
<EventEmitterProvider>
<Component />
</EventEmitterProvider>,
);
});

it('should filter invalid sources if specified', () => {
expect.assertions(4);

const Component = () => {
const eventType = 'pointermove';
const sourceId = 'sourceId';
const listener = jest.fn();
const filteredListener = jest.fn();
const emit = useEventEmitter();
useEventEmitter('pointermove', listener);
useEventEmitter('pointermove', filteredListener, [sourceId]);

useEffect(() => {
if (emit) {
emit(eventType, getEvent(eventType));
expect(listener).toHaveBeenCalledTimes(1);
expect(filteredListener).toHaveBeenCalledTimes(0);
emit(eventType, getEvent(eventType), sourceId);
expect(listener).toHaveBeenCalledTimes(2);
expect(filteredListener).toHaveBeenCalledTimes(1);
}
});

Expand Down
55 changes: 55 additions & 0 deletions packages/visx-xychart/test/hooks/usePointerEventEmitters.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React, { useEffect } from 'react';
import { mount } from 'enzyme';
import { EventEmitterProvider, useEventEmitter } from '../../src';
import usePointerEventEmitters from '../../src/hooks/usePointerEventEmitters';

describe('usePointerEventEmitters', () => {
it('should be defined', () => {
expect(usePointerEventEmitters).toBeDefined();
});

it('should provide an emitter for each callback specified', () => {
expect.assertions(1);

const Component = () => {
const emitters = usePointerEventEmitters({ source: 'visx', onPointerOut: false });
expect(emitters).toEqual({
onPointerMove: expect.any(Function),
onPointerOut: undefined,
onPointerUp: expect.any(Function),
});
return null;
};

mount(
<EventEmitterProvider>
<Component />
</EventEmitterProvider>,
);
});
it('emitters should emit events', () => {
expect.assertions(1);

const Component = () => {
const source = 'sourceId';
const listener = jest.fn();
useEventEmitter('pointerup', listener, [source]);
const emitters = usePointerEventEmitters({ source });

useEffect(() => {
if (emitters.onPointerUp) {
emitters.onPointerUp((new MouseEvent('pointerup') as unknown) as React.PointerEvent);
expect(listener).toHaveBeenCalledTimes(1);
}
});

return null;
};

mount(
<EventEmitterProvider>
<Component />
</EventEmitterProvider>,
);
});
});
103 changes: 103 additions & 0 deletions packages/visx-xychart/test/hooks/usePointerEventHandlers.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import React, { useEffect } from 'react';
import { mount } from 'enzyme';
import { EventEmitterProvider, useEventEmitter, DataContext } from '../../src';
import usePointerEventHandlers, {
POINTER_EVENTS_ALL,
} from '../../src/hooks/usePointerEventHandlers';
import getDataContext from '../mocks/getDataContext';

const series1 = { key: 'series1', data: [{}], xAccessor: () => 4, yAccessor: () => 7 };
const series2 = { key: 'series2', data: [{}], xAccessor: () => 4, yAccessor: () => 7 };
// avoids a lot of coercing of types
const getEvent = (eventType: string) =>
(new MouseEvent(eventType) as unknown) as React.PointerEvent;

describe('usePointerEventHandlers', () => {
function setup(children: React.ReactNode) {
return mount(
<DataContext.Provider value={getDataContext([series1, series2])}>
<EventEmitterProvider>{children}</EventEmitterProvider>
</DataContext.Provider>,
);
}

it('should be defined', () => {
expect(usePointerEventHandlers).toBeDefined();
});
it('should invoke handlers for each pointer event handler specified', () => {
expect.assertions(3);

const Component = () => {
const sourceId = 'sourceId';
const pointerMoveListener = jest.fn();
const pointerOutListener = jest.fn();
const pointerUpListener = jest.fn();
const emit = useEventEmitter();

usePointerEventHandlers({
sources: [sourceId],
dataKey: series1.key,
onPointerMove: pointerMoveListener,
onPointerOut: pointerOutListener,
onPointerUp: pointerUpListener,
});

useEffect(() => {
if (emit) {
emit('pointermove', getEvent('pointermove'), sourceId);
emit('pointermove', getEvent('pointermove'), 'invalidSource');
expect(pointerMoveListener).toHaveBeenCalledTimes(1);

emit('pointerout', getEvent('pointerout'), sourceId);
emit('pointerout', getEvent('pointerout'), 'invalidSource');
expect(pointerOutListener).toHaveBeenCalledTimes(1);

emit('pointerup', getEvent('pointerup'), sourceId);
emit('pointerup', getEvent('pointerup'), 'invalidSource');
expect(pointerUpListener).toHaveBeenCalledTimes(1);
}
});

return null;
};

setup(<Component />);
});

it('should invoke handlers once for each dataKey specified', () => {
expect.assertions(4);

const Component = () => {
const sourceId = 'sourceId';
const pointerMoveListenerAll = jest.fn();
const pointerMoveListenerMultipleKeys = jest.fn();
const emit = useEventEmitter();

usePointerEventHandlers({
sources: [sourceId],
dataKey: POINTER_EVENTS_ALL,
onPointerMove: pointerMoveListenerAll,
});
usePointerEventHandlers({
sources: [sourceId],
dataKey: [series1.key, series2.key],
onPointerMove: pointerMoveListenerMultipleKeys,
});

useEffect(() => {
if (emit) {
emit('pointermove', getEvent('pointermove'), sourceId);
expect(pointerMoveListenerAll).toHaveBeenCalledTimes(2);
expect(pointerMoveListenerMultipleKeys).toHaveBeenCalledTimes(2);
emit('pointermove', getEvent('pointermove'), 'invalidSource');
expect(pointerMoveListenerAll).toHaveBeenCalledTimes(2);
expect(pointerMoveListenerMultipleKeys).toHaveBeenCalledTimes(2);
}
});

return null;
};

setup(<Component />);
});
});

0 comments on commit 4c82b1c

Please sign in to comment.