diff --git a/packages/bump/tests/Bump.test.tsx b/packages/bump/tests/Bump.test.tsx index c46fa0484..e609d4e9a 100644 --- a/packages/bump/tests/Bump.test.tsx +++ b/packages/bump/tests/Bump.test.tsx @@ -1,6 +1,7 @@ -import { mount } from 'enzyme' +import { create, act, ReactTestInstance } from 'react-test-renderer' // @ts-ignore -import { Bump, BumpSvgProps } from '../src' +import { Bump, BumpSvgProps, isComputedBumpSerie } from '../src' +import { Line } from '../src/bump/Line' interface Datum { x: number @@ -81,45 +82,49 @@ const baseProps: BumpSvgProps> = { } it('should render a basic bump chart', () => { - const wrapper = mount( {...baseProps} />) + const root = create( {...baseProps} />).root - const lineA = wrapper.find(`path[data-testid='line.A']`) - expect(lineA.exists()).toBeTruthy() + const lines = root.findAllByType(Line) + expect(lines).toHaveLength(3) - const lineB = wrapper.find(`path[data-testid='line.B']`) - expect(lineB.exists()).toBeTruthy() - - const lineC = wrapper.find(`path[data-testid='line.C']`) - expect(lineC.exists()).toBeTruthy() + expect(lines[0].props.serie.id).toEqual('A') + expect(lines[1].props.serie.id).toEqual('B') + expect(lines[2].props.serie.id).toEqual('C') }) +const seriesLine = (seriesId: string) => (node: ReactTestInstance) => { + if (node.type !== 'path') return false + if (!('data-testid' in node.props)) return false + return (node.props['data-testid'] as string) === `line.${seriesId}` +} + +const seriesCircles = (seriesId: string) => (node: ReactTestInstance) => { + if (node.type !== 'circle') return false + if (!('data-testid' in node.props)) return false + return (node.props['data-testid'] as string).startsWith(`point.${seriesId}.`) +} + describe('style', () => { it('custom colors array', () => { const colors = ['rgba(255, 0, 0, 1)', 'rgba(0, 255, 0, 1)', 'rgba(0, 0, 255, 1)'] - const wrapper = mount( {...baseProps} colors={colors} />) - - expect(wrapper.find(`path[data-testid='line.A']`).prop('stroke')).toEqual(colors[0]) - expect(wrapper.find(`circle[data-testid='point.A.2000']`).prop('fill')).toEqual(colors[0]) - expect(wrapper.find(`circle[data-testid='point.A.2001']`).prop('fill')).toEqual(colors[0]) - expect(wrapper.find(`circle[data-testid='point.A.2002']`).prop('fill')).toEqual(colors[0]) - expect(wrapper.find(`circle[data-testid='point.A.2003']`).prop('fill')).toEqual(colors[0]) - - expect(wrapper.find(`path[data-testid='line.B']`).prop('stroke')).toEqual(colors[1]) - expect(wrapper.find(`circle[data-testid='point.B.2000']`).prop('fill')).toEqual(colors[1]) - expect(wrapper.find(`circle[data-testid='point.B.2001']`).prop('fill')).toEqual(colors[1]) - expect(wrapper.find(`circle[data-testid='point.B.2002']`).prop('fill')).toEqual(colors[1]) - expect(wrapper.find(`circle[data-testid='point.B.2003']`).prop('fill')).toEqual(colors[1]) - - expect(wrapper.find(`path[data-testid='line.C']`).prop('stroke')).toEqual(colors[2]) - expect(wrapper.find(`circle[data-testid='point.C.2000']`).prop('fill')).toEqual(colors[2]) - expect(wrapper.find(`circle[data-testid='point.C.2001']`).prop('fill')).toEqual(colors[2]) - expect(wrapper.find(`circle[data-testid='point.C.2002']`).prop('fill')).toEqual(colors[2]) - expect(wrapper.find(`circle[data-testid='point.C.2003']`).prop('fill')).toEqual(colors[2]) + const root = create( {...baseProps} colors={colors} />).root + + expect(root.find(seriesLine('A')).props.stroke).toEqual(colors[0]) + const lineACircles = root.findAll(seriesCircles('A')) + expect(lineACircles.every(circle => circle.props.fill === colors[0])).toBeTruthy() + + expect(root.find(seriesLine('B')).props.stroke).toEqual(colors[1]) + const lineBCircles = root.findAll(seriesCircles('B')) + expect(lineBCircles.every(circle => circle.props.fill === colors[1])).toBeTruthy() + + expect(root.find(seriesLine('C')).props.stroke).toEqual(colors[2]) + const lineCCircles = root.findAll(seriesCircles('C')) + expect(lineCCircles.every(circle => circle.props.fill === colors[2])).toBeTruthy() }) it('colors from data', () => { const colors = ['rgba(255, 0, 0, 1)', 'rgba(0, 255, 0, 1)', 'rgba(0, 0, 255, 1)'] - const wrapper = mount( + const root = create( {...baseProps} data={sampleData.map((serie, i) => ({ @@ -128,46 +133,51 @@ describe('style', () => { }))} colors={serie => serie.color} /> - ) + ).root + + expect(root.find(seriesLine('A')).props.stroke).toEqual(colors[0]) + const lineACircles = root.findAll(seriesCircles('A')) + expect(lineACircles.every(circle => circle.props.fill === colors[0])).toBeTruthy() - expect(wrapper.find(`path[data-testid='line.A']`).prop('stroke')).toEqual(colors[0]) - expect(wrapper.find(`path[data-testid='line.B']`).prop('stroke')).toEqual(colors[1]) - expect(wrapper.find(`path[data-testid='line.C']`).prop('stroke')).toEqual(colors[2]) + expect(root.find(seriesLine('B')).props.stroke).toEqual(colors[1]) + const lineBCircles = root.findAll(seriesCircles('B')) + expect(lineBCircles.every(circle => circle.props.fill === colors[1])).toBeTruthy() + + expect(root.find(seriesLine('C')).props.stroke).toEqual(colors[2]) + const lineCCircles = root.findAll(seriesCircles('C')) + expect(lineCCircles.every(circle => circle.props.fill === colors[2])).toBeTruthy() }) }) describe('labels', () => { it('default end labels', () => { - const wrapper = mount( {...baseProps} />) - - const endLabelA = wrapper.find(`text[data-testid='label.end.A']`) - expect(endLabelA.exists()).toBeTruthy() - expect(endLabelA.text()).toEqual('A') - expect(endLabelA.prop('textAnchor')).toEqual('start') - - const endLabelB = wrapper.find(`text[data-testid='label.end.B']`) - expect(endLabelB.exists()).toBeTruthy() - expect(endLabelB.text()).toEqual('B') - expect(endLabelB.prop('textAnchor')).toEqual('start') - - const endLabelC = wrapper.find(`text[data-testid='label.end.C']`) - expect(endLabelC.exists()).toBeTruthy() - expect(endLabelC.text()).toEqual('C') - expect(endLabelC.prop('textAnchor')).toEqual('start') + const root = create( {...baseProps} />).root + + const labelA = root.findByProps({ 'data-testid': 'label.end.A' }) + expect(labelA.props.children).toEqual('A') + expect(labelA.props.textAnchor).toEqual('start') + + const labelB = root.findByProps({ 'data-testid': 'label.end.B' }) + expect(labelB.props.children).toEqual('B') + expect(labelB.props.textAnchor).toEqual('start') + + const labelC = root.findByProps({ 'data-testid': 'label.end.C' }) + expect(labelC.props.children).toEqual('C') + expect(labelC.props.textAnchor).toEqual('start') }) it('customize end labels', () => { - const wrapper = mount( + const root = create( {...baseProps} endLabel={serie => `Serie ${serie.id}`} /> - ) + ).root - expect(wrapper.find(`text[data-testid='label.end.A']`).text()).toEqual('Serie A') - expect(wrapper.find(`text[data-testid='label.end.B']`).text()).toEqual('Serie B') - expect(wrapper.find(`text[data-testid='label.end.C']`).text()).toEqual('Serie C') + expect(root.findByProps({ 'data-testid': 'label.end.A' }).props.children).toEqual('Serie A') + expect(root.findByProps({ 'data-testid': 'label.end.B' }).props.children).toEqual('Serie B') + expect(root.findByProps({ 'data-testid': 'label.end.C' }).props.children).toEqual('Serie C') }) - it('label from data', () => { - const wrapper = mount( + it('end labels from data', () => { + const root = create( {...baseProps} data={sampleData.map(serie => ({ @@ -176,29 +186,155 @@ describe('labels', () => { }))} endLabel={serie => serie.label} /> - ) + ).root - expect(wrapper.find(`text[data-testid='label.end.A']`).text()).toEqual('Serie A label') - expect(wrapper.find(`text[data-testid='label.end.B']`).text()).toEqual('Serie B label') - expect(wrapper.find(`text[data-testid='label.end.C']`).text()).toEqual('Serie C label') + expect(root.findByProps({ 'data-testid': 'label.end.A' }).props.children).toEqual( + 'Serie A label' + ) + expect(root.findByProps({ 'data-testid': 'label.end.B' }).props.children).toEqual( + 'Serie B label' + ) + expect(root.findByProps({ 'data-testid': 'label.end.C' }).props.children).toEqual( + 'Serie C label' + ) }) it('start labels', () => { - const wrapper = mount( {...baseProps} startLabel />) - - const startLabelA = wrapper.find(`text[data-testid='label.start.A']`) - expect(startLabelA.exists()).toBeTruthy() - expect(startLabelA.text()).toEqual('A') - expect(startLabelA.prop('textAnchor')).toEqual('end') - - const startLabelB = wrapper.find(`text[data-testid='label.start.B']`) - expect(startLabelB.exists()).toBeTruthy() - expect(startLabelB.text()).toEqual('B') - expect(startLabelB.prop('textAnchor')).toEqual('end') - - const startLabelC = wrapper.find(`text[data-testid='label.start.C']`) - expect(startLabelC.exists()).toBeTruthy() - expect(startLabelC.text()).toEqual('C') - expect(startLabelC.prop('textAnchor')).toEqual('end') + const root = create( {...baseProps} startLabel />).root + + const labelA = root.findByProps({ 'data-testid': 'label.start.A' }) + expect(labelA.props.children).toEqual('A') + expect(labelA.props.textAnchor).toEqual('end') + + const labelB = root.findByProps({ 'data-testid': 'label.start.B' }) + expect(labelB.props.children).toEqual('B') + expect(labelB.props.textAnchor).toEqual('end') + + const labelC = root.findByProps({ 'data-testid': 'label.start.C' }) + expect(labelC.props.children).toEqual('C') + expect(labelC.props.textAnchor).toEqual('end') + }) + + it('customize start labels', () => { + const root = create( + {...baseProps} startLabel={serie => `Serie ${serie.id}`} /> + ).root + + expect(root.findByProps({ 'data-testid': 'label.start.A' }).props.children).toEqual( + 'Serie A' + ) + expect(root.findByProps({ 'data-testid': 'label.start.B' }).props.children).toEqual( + 'Serie B' + ) + expect(root.findByProps({ 'data-testid': 'label.start.C' }).props.children).toEqual( + 'Serie C' + ) + }) + + it('start labels from data', () => { + const root = create( + + {...baseProps} + data={sampleData.map(serie => ({ + ...serie, + label: `Serie ${serie.id} label`, + }))} + startLabel={serie => serie.label} + /> + ).root + + expect(root.findByProps({ 'data-testid': 'label.start.A' }).props.children).toEqual( + 'Serie A label' + ) + expect(root.findByProps({ 'data-testid': 'label.start.B' }).props.children).toEqual( + 'Serie B label' + ) + expect(root.findByProps({ 'data-testid': 'label.start.C' }).props.children).toEqual( + 'Serie C label' + ) + }) +}) + +describe('interactivity', () => { + describe('lines', () => { + it('onMouseEnter', () => { + const mouseEnterHandler = jest.fn() + const root = create( + {...baseProps} onMouseEnter={mouseEnterHandler} /> + ).root + + const onMouseEnter = root.findByProps({ 'data-testid': 'line.B.interactive' }).props + .onMouseEnter + expect(onMouseEnter).toBeDefined() + // Skipped due to `getBoundingClientRect`. + // onMouseEnter() + + // expect(mouseEnterHandler).toHaveBeenCalledTimes(1) + // const [series] = mouseEnterHandler.mock.calls[0] + // expect(isComputedBumpSerie(series)).toBeTruthy() + // expect(series.id).toEqual('B') + }) + + it('onMouseMove', () => { + const mouseMoveHandler = jest.fn() + const root = create( {...baseProps} onMouseMove={mouseMoveHandler} />).root + + const onMouseMove = root.findByProps({ 'data-testid': 'line.C.interactive' }).props + .onMouseMove + expect(onMouseMove).toBeDefined() + // Skipped due to `getBoundingClientRect`. + // onMouseMove() + + // expect(mouseMoveHandler).toHaveBeenCalledTimes(1) + // const [series] = mouseMoveHandler.mock.calls[0] + // expect(isComputedBumpSerie(series)).toBeTruthy() + // expect(series.id).toEqual('C') + }) + + it('onMouseLeave', async () => { + const mouseLeaveHandler = jest.fn() + const root = create( + {...baseProps} onMouseLeave={mouseLeaveHandler} /> + ).root + + const onMouseLeave = root.findByProps({ 'data-testid': 'line.A.interactive' }).props + .onMouseLeave + expect(onMouseLeave).toBeDefined() + await act(() => onMouseLeave()) + + expect(mouseLeaveHandler).toHaveBeenCalledTimes(1) + const [series] = mouseLeaveHandler.mock.calls[0] + expect(isComputedBumpSerie(series)).toBeTruthy() + expect(series.id).toEqual('A') + }) + + it('onClick', async () => { + const clickHandler = jest.fn() + const root = create( {...baseProps} onClick={clickHandler} />).root + + const onClick = root.findByProps({ 'data-testid': 'line.B.interactive' }).props.onClick + expect(onClick).toBeDefined() + await act(() => onClick()) + + expect(clickHandler).toHaveBeenCalledTimes(1) + const [series] = clickHandler.mock.calls[0] + expect(isComputedBumpSerie(series)).toBeTruthy() + expect(series.id).toEqual('B') + }) + + it('non-interactive', () => { + const root = create( {...baseProps} isInteractive={false} />).root + + expect(root.findAllByProps({ 'data-testid': 'line.B.interactive' })).toHaveLength(0) + }) + }) + + describe('points', () => { + // Point event handlers cannot be tested as we need a DOM environment. + it('lines should not be interactive anymore when using a mesh', () => { + const root = create( {...baseProps} useMesh={true} />).root + + expect(root.findAllByProps({ 'data-testid': 'line.B.interactive' })).toHaveLength(0) + }) }) })