mirror of
https://github.com/grafana/grafana.git
synced 2025-08-03 03:13:49 +08:00
![renovate[bot]](/assets/img/avatar_default.png)
* Update dependency @types/react-test-renderer to v19 * replace usage of react-test-renderer * use renderHook from @testing-library/react in most tests * update tests to work without @testing-library/react-hooks --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Ashley Harrison <ashley.harrison@grafana.com>
395 lines
9.5 KiB
TypeScript
395 lines
9.5 KiB
TypeScript
import { act, renderHook } from '@testing-library/react';
|
|
|
|
import { useLayout } from './layout';
|
|
import { EdgeDatum, NodeDatum } from './types';
|
|
|
|
let onmessage: jest.Mock;
|
|
let postMessage: jest.Mock;
|
|
let terminate: jest.Mock;
|
|
let worker: {
|
|
onmessage: (e: MessageEvent) => void;
|
|
postMessage: (d: unknown) => void;
|
|
terminate: () => void;
|
|
};
|
|
|
|
jest.mock('./createLayoutWorker', () => {
|
|
return {
|
|
__esModule: true,
|
|
createWorker: () => {
|
|
onmessage = jest.fn();
|
|
postMessage = jest.fn();
|
|
terminate = jest.fn();
|
|
worker = {
|
|
onmessage: onmessage,
|
|
postMessage: postMessage,
|
|
terminate: terminate,
|
|
};
|
|
return worker;
|
|
},
|
|
createMsaglWorker: () => {
|
|
onmessage = jest.fn();
|
|
postMessage = jest.fn();
|
|
terminate = jest.fn();
|
|
worker = {
|
|
onmessage: onmessage,
|
|
postMessage: postMessage,
|
|
terminate: terminate,
|
|
};
|
|
return worker;
|
|
},
|
|
};
|
|
});
|
|
|
|
describe('layout', () => {
|
|
it('doesnt fail without any data', async () => {
|
|
const nodes: NodeDatum[] = [];
|
|
const edges: EdgeDatum[] = [];
|
|
|
|
const { result } = renderHook(() => {
|
|
return useLayout(nodes, edges, undefined, 100, 1000);
|
|
});
|
|
expect(result.current.nodes).toEqual([]);
|
|
expect(result.current.edges).toEqual([]);
|
|
expect(postMessage).toBeUndefined();
|
|
});
|
|
|
|
it('cancels worker', async () => {
|
|
const { result, rerender } = renderHook(
|
|
({ nodes, edges }) => {
|
|
return useLayout(nodes, edges, undefined, 100, 1000);
|
|
},
|
|
{
|
|
initialProps: {
|
|
nodes: [makeNode(0, 0), makeNode(1, 1)],
|
|
edges: [makeEdge(0, 1)],
|
|
},
|
|
}
|
|
);
|
|
expect(postMessage).toBeCalledTimes(1);
|
|
// Bit convoluted but we cannot easily access the worker instance as we only export constructor so the default
|
|
// export is class and we only store latest instance of the methods as jest.fn here as module local variables.
|
|
// So we capture the terminate function from current worker so that when we call rerender and new worker is created
|
|
// we can still access and check the method from the old one that we assume should be canceled.
|
|
const localTerminate = terminate;
|
|
|
|
rerender({
|
|
nodes: [],
|
|
edges: [],
|
|
});
|
|
|
|
expect(result.current.nodes).toEqual([]);
|
|
expect(result.current.edges).toEqual([]);
|
|
expect(localTerminate).toBeCalledTimes(1);
|
|
});
|
|
|
|
it('correctly maps the layout data', async () => {
|
|
// This specifically tests whether the mapping of data from the layout code back to the original nodes is correct.
|
|
|
|
const { result, rerender } = renderHook(
|
|
({ nodes, edges }) => {
|
|
return useLayout(nodes, edges, undefined, 100, 1000);
|
|
},
|
|
{ initialProps: { nodes: rawNodes, edges: rawEdges } }
|
|
);
|
|
|
|
// Simulate response from the layout worker
|
|
act(() => {
|
|
worker.onmessage(new MessageEvent('message', { data: { nodes: testNodes, edges: testEdges } }));
|
|
});
|
|
|
|
rerender({ nodes: rawNodes, edges: rawEdges });
|
|
|
|
expect(result.current.nodes).toMatchObject([
|
|
{ id: 'otel-demo-alt/frontend', title: 'frontend' },
|
|
{ id: 'otel-demo-alt/cartservice', title: 'cartservice' },
|
|
{ id: 'otel-demo-alt/checkoutservice', title: 'checkoutservice' },
|
|
{ id: 'otel-demo-alt/frontend-proxy', title: 'frontend-proxy' },
|
|
{ id: 'otel-demo-alt/recommendationservice', title: 'recommendationservice' },
|
|
]);
|
|
});
|
|
});
|
|
|
|
function makeNode(index: number, incoming: number): NodeDatum {
|
|
return {
|
|
id: `n${index}`,
|
|
title: `n${index}`,
|
|
subTitle: '',
|
|
dataFrameRowIndex: 0,
|
|
incoming,
|
|
arcSections: [],
|
|
highlighted: false,
|
|
};
|
|
}
|
|
|
|
function makeEdge(source: number, target: number): EdgeDatum {
|
|
return {
|
|
id: `${source}-${target}`,
|
|
source: 'n' + source,
|
|
target: 'n' + target,
|
|
mainStat: '',
|
|
secondaryStat: '',
|
|
dataFrameRowIndex: 0,
|
|
sourceNodeRadius: 40,
|
|
targetNodeRadius: 40,
|
|
highlighted: false,
|
|
thickness: 1,
|
|
};
|
|
}
|
|
|
|
const rawNodes: NodeDatum[] = [
|
|
{
|
|
dataFrameRowIndex: 0,
|
|
id: 'otel-demo-alt/cartservice',
|
|
incoming: 1,
|
|
subTitle: 'otel-demo-alt',
|
|
title: 'cartservice',
|
|
highlighted: false,
|
|
arcSections: [],
|
|
},
|
|
{
|
|
dataFrameRowIndex: 1,
|
|
id: 'otel-demo-alt/frontend',
|
|
incoming: 1,
|
|
subTitle: 'otel-demo-alt',
|
|
title: 'frontend',
|
|
highlighted: false,
|
|
arcSections: [],
|
|
},
|
|
{
|
|
dataFrameRowIndex: 2,
|
|
id: 'otel-demo-alt/checkoutservice',
|
|
incoming: 1,
|
|
subTitle: 'otel-demo-alt',
|
|
title: 'checkoutservice',
|
|
highlighted: false,
|
|
arcSections: [],
|
|
},
|
|
{
|
|
dataFrameRowIndex: 3,
|
|
id: 'otel-demo-alt/frontend-proxy',
|
|
incoming: 1,
|
|
subTitle: 'otel-demo-alt',
|
|
title: 'frontend-proxy',
|
|
highlighted: false,
|
|
arcSections: [],
|
|
},
|
|
{
|
|
dataFrameRowIndex: 4,
|
|
id: 'otel-demo-alt/recommendationservice',
|
|
incoming: 1,
|
|
subTitle: 'otel-demo-alt',
|
|
title: 'recommendationservice',
|
|
highlighted: false,
|
|
arcSections: [],
|
|
},
|
|
];
|
|
|
|
const rawEdges = [
|
|
{
|
|
id: 'otel-demo-alt/frontend_otel-demo-alt/cartservice',
|
|
dataFrameRowIndex: 0,
|
|
source: 'otel-demo-alt/frontend',
|
|
target: 'otel-demo-alt/cartservice',
|
|
sourceNodeRadius: 40,
|
|
targetNodeRadius: 40,
|
|
mainStat: '1.08 ms/r',
|
|
secondaryStat: '0.93 r/sec',
|
|
highlighted: false,
|
|
thickness: 1,
|
|
},
|
|
{
|
|
id: 'otel-demo-alt/frontend_otel-demo-alt/checkoutservice',
|
|
dataFrameRowIndex: 1,
|
|
source: 'otel-demo-alt/frontend',
|
|
target: 'otel-demo-alt/checkoutservice',
|
|
sourceNodeRadius: 40,
|
|
targetNodeRadius: 40,
|
|
mainStat: '12.66 ms/r',
|
|
secondaryStat: '0.12 r/sec',
|
|
highlighted: false,
|
|
thickness: 1,
|
|
},
|
|
{
|
|
id: 'otel-demo-alt/frontend_otel-demo-alt/frontend-proxy',
|
|
dataFrameRowIndex: 2,
|
|
source: 'otel-demo-alt/frontend',
|
|
target: 'otel-demo-alt/frontend-proxy',
|
|
sourceNodeRadius: 40,
|
|
targetNodeRadius: 40,
|
|
mainStat: '7.45 ms/r',
|
|
secondaryStat: '0.99 r/sec',
|
|
highlighted: false,
|
|
thickness: 1,
|
|
},
|
|
{
|
|
id: 'otel-demo-alt/frontend_otel-demo-alt/recommendationservice',
|
|
dataFrameRowIndex: 3,
|
|
source: 'otel-demo-alt/frontend',
|
|
target: 'otel-demo-alt/recommendationservice',
|
|
sourceNodeRadius: 40,
|
|
targetNodeRadius: 40,
|
|
mainStat: '13.01 ms/r',
|
|
secondaryStat: '0.18 r/sec',
|
|
highlighted: false,
|
|
thickness: 1,
|
|
},
|
|
{
|
|
id: 'otel-demo-alt/frontend-proxy_otel-demo-alt/frontend',
|
|
dataFrameRowIndex: 4,
|
|
source: 'otel-demo-alt/frontend-proxy',
|
|
target: 'otel-demo-alt/frontend',
|
|
sourceNodeRadius: 40,
|
|
targetNodeRadius: 40,
|
|
mainStat: '7.50 ms/r',
|
|
secondaryStat: '6.06 r/sec',
|
|
highlighted: false,
|
|
thickness: 1,
|
|
},
|
|
];
|
|
|
|
const testNodes = [
|
|
{
|
|
id: 'otel-demo-alt/frontend',
|
|
incoming: 1,
|
|
x: -80.84375,
|
|
y: -70.49999999999997,
|
|
},
|
|
{
|
|
id: 'otel-demo-alt/cartservice',
|
|
incoming: 1,
|
|
x: 80.84375,
|
|
y: 211.5,
|
|
},
|
|
{
|
|
id: 'otel-demo-alt/checkoutservice',
|
|
incoming: 1,
|
|
x: 80.84375,
|
|
y: 70.5,
|
|
},
|
|
{
|
|
id: 'otel-demo-alt/frontend-proxy',
|
|
incoming: 1,
|
|
x: 80.84375,
|
|
y: -70.5,
|
|
},
|
|
{
|
|
id: 'otel-demo-alt/recommendationservice',
|
|
incoming: 1,
|
|
x: 80.84375,
|
|
y: -211.5,
|
|
},
|
|
];
|
|
|
|
const testEdges = [
|
|
{
|
|
id: 'otel-demo-alt/frontend_otel-demo-alt/cartservice',
|
|
dataFrameRowIndex: 0,
|
|
source: {
|
|
id: 'otel-demo-alt/frontend',
|
|
incoming: 1,
|
|
x: -80.84375,
|
|
y: -70.49999999999997,
|
|
},
|
|
target: {
|
|
id: 'otel-demo-alt/cartservice',
|
|
incoming: 1,
|
|
x: 80.84375,
|
|
y: 211.5,
|
|
},
|
|
sourceNodeRadius: 40,
|
|
targetNodeRadius: 40,
|
|
mainStat: '1.07 ms/r',
|
|
secondaryStat: '1.08 r/sec',
|
|
highlighted: false,
|
|
thickness: 1,
|
|
},
|
|
{
|
|
id: 'otel-demo-alt/frontend_otel-demo-alt/checkoutservice',
|
|
dataFrameRowIndex: 1,
|
|
source: {
|
|
id: 'otel-demo-alt/frontend',
|
|
incoming: 1,
|
|
x: -80.84375,
|
|
y: -70.49999999999997,
|
|
},
|
|
target: {
|
|
id: 'otel-demo-alt/checkoutservice',
|
|
incoming: 1,
|
|
x: 80.84375,
|
|
y: 70.5,
|
|
},
|
|
sourceNodeRadius: 40,
|
|
targetNodeRadius: 40,
|
|
mainStat: '8.18 ms/r',
|
|
secondaryStat: '0.14 r/sec',
|
|
highlighted: false,
|
|
thickness: 1,
|
|
},
|
|
{
|
|
id: 'otel-demo-alt/frontend_otel-demo-alt/frontend-proxy',
|
|
dataFrameRowIndex: 2,
|
|
source: {
|
|
id: 'otel-demo-alt/frontend',
|
|
incoming: 1,
|
|
x: -80.84375,
|
|
y: -70.49999999999997,
|
|
},
|
|
target: {
|
|
id: 'otel-demo-alt/frontend-proxy',
|
|
incoming: 1,
|
|
x: 80.84375,
|
|
y: -70.5,
|
|
},
|
|
sourceNodeRadius: 40,
|
|
targetNodeRadius: 40,
|
|
mainStat: '7.57 ms/r',
|
|
secondaryStat: '1.14 r/sec',
|
|
highlighted: false,
|
|
thickness: 1,
|
|
},
|
|
{
|
|
id: 'otel-demo-alt/frontend_otel-demo-alt/recommendationservice',
|
|
dataFrameRowIndex: 3,
|
|
source: {
|
|
id: 'otel-demo-alt/frontend',
|
|
incoming: 1,
|
|
x: -80.84375,
|
|
y: -70.49999999999997,
|
|
},
|
|
target: {
|
|
id: 'otel-demo-alt/recommendationservice',
|
|
incoming: 1,
|
|
x: 80.84375,
|
|
y: -211.5,
|
|
},
|
|
sourceNodeRadius: 40,
|
|
targetNodeRadius: 40,
|
|
mainStat: '8.60 ms/r',
|
|
secondaryStat: '0.22 r/sec',
|
|
highlighted: false,
|
|
thickness: 1,
|
|
},
|
|
{
|
|
id: 'otel-demo-alt/frontend-proxy_otel-demo-alt/frontend',
|
|
dataFrameRowIndex: 4,
|
|
source: {
|
|
id: 'otel-demo-alt/frontend-proxy',
|
|
incoming: 1,
|
|
x: 80.84375,
|
|
y: -70.5,
|
|
},
|
|
target: {
|
|
id: 'otel-demo-alt/frontend',
|
|
incoming: 1,
|
|
x: -80.84375,
|
|
y: -70.49999999999997,
|
|
},
|
|
sourceNodeRadius: 40,
|
|
targetNodeRadius: 40,
|
|
mainStat: '7.53 ms/r',
|
|
secondaryStat: '6.82 r/sec',
|
|
highlighted: false,
|
|
thickness: 1,
|
|
},
|
|
];
|