Skip to content

Commit

Permalink
feat(bump): improve unit tests for the Bump component and remove enzyme
Browse files Browse the repository at this point in the history
  • Loading branch information
plouc committed May 1, 2024
1 parent 51eef71 commit e9a0a0a
Showing 1 changed file with 213 additions and 77 deletions.
290 changes: 213 additions & 77 deletions packages/bump/tests/Bump.test.tsx
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -81,45 +82,49 @@ const baseProps: BumpSvgProps<Datum, Record<string, unknown>> = {
}

it('should render a basic bump chart', () => {
const wrapper = mount(<Bump<Datum> {...baseProps} />)
const root = create(<Bump<Datum> {...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 (!node.props.hasOwnProperty('data-testid')) return false

Check failure on line 97 in packages/bump/tests/Bump.test.tsx

View workflow job for this annotation

GitHub Actions / build

Do not access Object.prototype method 'hasOwnProperty' from target object
return (node.props['data-testid'] as string) === `line.${seriesId}`
}

const seriesCircles = (seriesId: string) => (node: ReactTestInstance) => {
if (node.type !== 'circle') return false
if (!node.props.hasOwnProperty('data-testid')) return false

Check failure on line 103 in packages/bump/tests/Bump.test.tsx

View workflow job for this annotation

GitHub Actions / build

Do not access Object.prototype method 'hasOwnProperty' from target object
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(<Bump<Datum> {...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(<Bump<Datum> {...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(
<Bump<Datum, { color: string }>
{...baseProps}
data={sampleData.map((serie, i) => ({
Expand All @@ -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(<Bump<Datum> {...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(<Bump<Datum> {...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(
<Bump<Datum> {...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(
<Bump<Datum, { label: string }>
{...baseProps}
data={sampleData.map(serie => ({
Expand All @@ -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(<Bump<Datum> {...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(<Bump<Datum> {...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(
<Bump<Datum> {...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(
<Bump<Datum, { label: string }>
{...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(
<Bump<Datum> {...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(<Bump<Datum> {...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(
<Bump<Datum> {...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(<Bump<Datum> {...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(<Bump<Datum> {...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(<Bump<Datum> {...baseProps} useMesh={true} />).root

expect(root.findAllByProps({ 'data-testid': 'line.B.interactive' })).toHaveLength(0)
})
})
})

0 comments on commit e9a0a0a

Please sign in to comment.