mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
185 lines
4.7 KiB
TypeScript
185 lines
4.7 KiB
TypeScript
import { render } from '@testing-library/react';
|
|
import createMockRaf from 'mock-raf';
|
|
import React from 'react';
|
|
import uPlot from 'uplot';
|
|
|
|
import { FieldConfig, FieldType, MutableDataFrame } from '@grafana/data';
|
|
import { GraphFieldConfig, GraphDrawStyle } from '@grafana/schema';
|
|
|
|
import { UPlotChart } from './Plot';
|
|
import { UPlotConfigBuilder } from './config/UPlotConfigBuilder';
|
|
import { SeriesProps } from './config/UPlotSeriesBuilder';
|
|
import { preparePlotData2, getStackingGroups } from './utils';
|
|
|
|
const mockRaf = createMockRaf();
|
|
const setDataMock = jest.fn();
|
|
const setSizeMock = jest.fn();
|
|
const initializeMock = jest.fn();
|
|
const destroyMock = jest.fn();
|
|
|
|
jest.mock('uplot', () => {
|
|
return jest.fn().mockImplementation(() => {
|
|
return {
|
|
setData: setDataMock,
|
|
setSize: setSizeMock,
|
|
initialize: initializeMock,
|
|
destroy: destroyMock,
|
|
};
|
|
});
|
|
});
|
|
|
|
const mockData = () => {
|
|
const data = new MutableDataFrame();
|
|
|
|
data.addField({
|
|
type: FieldType.time,
|
|
name: 'Time',
|
|
values: [1602630000000, 1602633600000, 1602637200000],
|
|
config: {},
|
|
});
|
|
|
|
data.addField({
|
|
type: FieldType.number,
|
|
name: 'Value',
|
|
values: [10, 20, 5],
|
|
config: {
|
|
custom: {
|
|
drawStyle: GraphDrawStyle.Line,
|
|
},
|
|
} as FieldConfig<GraphFieldConfig>,
|
|
});
|
|
|
|
const config = new UPlotConfigBuilder();
|
|
config.addSeries({} as SeriesProps);
|
|
return { data: data, config };
|
|
};
|
|
|
|
describe('UPlotChart', () => {
|
|
beforeEach(() => {
|
|
// @ts-ignore
|
|
uPlot.mockClear();
|
|
setDataMock.mockClear();
|
|
setSizeMock.mockClear();
|
|
initializeMock.mockClear();
|
|
destroyMock.mockClear();
|
|
|
|
jest.spyOn(window, 'requestAnimationFrame').mockImplementation(mockRaf.raf);
|
|
});
|
|
|
|
it('destroys uPlot instance when component unmounts', () => {
|
|
const { data, config } = mockData();
|
|
|
|
const { unmount } = render(
|
|
<UPlotChart
|
|
data={preparePlotData2(data, getStackingGroups(data))} // mock
|
|
config={config}
|
|
width={100}
|
|
height={100}
|
|
/>
|
|
);
|
|
|
|
expect(uPlot).toBeCalledTimes(1);
|
|
unmount();
|
|
expect(destroyMock).toBeCalledTimes(1);
|
|
});
|
|
|
|
describe('data update', () => {
|
|
it('skips uPlot reinitialization when there are no field config changes', () => {
|
|
const { data, config } = mockData();
|
|
|
|
const { rerender } = render(
|
|
<UPlotChart
|
|
data={preparePlotData2(data, getStackingGroups(data))} // mock
|
|
config={config}
|
|
width={100}
|
|
height={100}
|
|
/>
|
|
);
|
|
|
|
expect(uPlot).toBeCalledTimes(1);
|
|
|
|
data.fields[1].values.set(0, 1);
|
|
|
|
rerender(
|
|
<UPlotChart
|
|
data={preparePlotData2(data, getStackingGroups(data))} // changed
|
|
config={config}
|
|
width={100}
|
|
height={100}
|
|
/>
|
|
);
|
|
|
|
expect(setDataMock).toBeCalledTimes(1);
|
|
});
|
|
});
|
|
|
|
describe('config update', () => {
|
|
it('skips uPlot intialization for width and height equal 0', async () => {
|
|
const { data, config } = mockData();
|
|
const { queryAllByTestId } = render(
|
|
<UPlotChart data={preparePlotData2(data, getStackingGroups(data))} config={config} width={0} height={0} />
|
|
);
|
|
|
|
expect(queryAllByTestId('uplot-main-div')).toHaveLength(1);
|
|
expect(uPlot).not.toBeCalled();
|
|
});
|
|
|
|
it('reinitializes uPlot when config changes', () => {
|
|
const { data, config } = mockData();
|
|
|
|
const { rerender } = render(
|
|
<UPlotChart
|
|
data={preparePlotData2(data, getStackingGroups(data))} // frame
|
|
config={config}
|
|
width={100}
|
|
height={100}
|
|
/>
|
|
);
|
|
|
|
expect(uPlot).toBeCalledTimes(1);
|
|
|
|
const nextConfig = new UPlotConfigBuilder();
|
|
nextConfig.addSeries({} as SeriesProps);
|
|
|
|
rerender(
|
|
<UPlotChart
|
|
data={preparePlotData2(data, getStackingGroups(data))}
|
|
config={nextConfig}
|
|
width={100}
|
|
height={100}
|
|
/>
|
|
);
|
|
|
|
expect(destroyMock).toBeCalledTimes(1);
|
|
expect(uPlot).toBeCalledTimes(2);
|
|
});
|
|
|
|
it('skips uPlot reinitialization when only dimensions change', () => {
|
|
const { data, config } = mockData();
|
|
|
|
const { rerender } = render(
|
|
<UPlotChart
|
|
data={preparePlotData2(data, getStackingGroups(data))} // frame
|
|
config={config}
|
|
width={100}
|
|
height={100}
|
|
/>
|
|
);
|
|
|
|
// we wait 1 frame for plugins initialisation logic to finish
|
|
rerender(
|
|
<UPlotChart
|
|
data={preparePlotData2(data, getStackingGroups(data))} // frame
|
|
config={config}
|
|
width={200}
|
|
height={200}
|
|
/>
|
|
);
|
|
|
|
expect(destroyMock).toBeCalledTimes(0);
|
|
expect(uPlot).toBeCalledTimes(1);
|
|
expect(setSizeMock).toBeCalledTimes(1);
|
|
});
|
|
});
|
|
});
|