layout.test.ts 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import { renderHook } from '@testing-library/react-hooks';
  2. import { useLayout } from './layout';
  3. import { EdgeDatum, NodeDatum } from './types';
  4. let onmessage: jest.MockedFunction<any>;
  5. let postMessage: jest.MockedFunction<any>;
  6. let terminate: jest.MockedFunction<any>;
  7. jest.mock('./createLayoutWorker', () => {
  8. return {
  9. __esModule: true,
  10. createWorker: () => {
  11. onmessage = jest.fn();
  12. postMessage = jest.fn();
  13. terminate = jest.fn();
  14. return {
  15. onmessage: onmessage,
  16. postMessage: postMessage,
  17. terminate: terminate,
  18. };
  19. },
  20. };
  21. });
  22. describe('layout', () => {
  23. it('doesnt fail without any data', async () => {
  24. const nodes: NodeDatum[] = [];
  25. const edges: EdgeDatum[] = [];
  26. const { result } = renderHook(() => {
  27. return useLayout(nodes, edges, undefined, 100, 1000);
  28. });
  29. expect(result.current.nodes).toEqual([]);
  30. expect(result.current.edges).toEqual([]);
  31. expect(postMessage).toBeUndefined();
  32. });
  33. it('cancels worker', async () => {
  34. const { result, rerender } = renderHook(
  35. ({ nodes, edges }) => {
  36. return useLayout(nodes, edges, undefined, 100, 1000);
  37. },
  38. {
  39. initialProps: {
  40. nodes: [makeNode(0, 0), makeNode(1, 1)],
  41. edges: [makeEdge(0, 1)],
  42. },
  43. }
  44. );
  45. expect(postMessage).toBeCalledTimes(1);
  46. // Bit convoluted but we cannot easily access the worker instance as we only export constructor so the default
  47. // export is class and we only store latest instance of the methods as jest.fn here as module local variables.
  48. // So we capture the terminate function from current worker so that when we call rerender and new worker is created
  49. // we can still access and check the method from the old one that we assume should be canceled.
  50. const localTerminate = terminate;
  51. rerender({
  52. nodes: [],
  53. edges: [],
  54. });
  55. expect(result.current.nodes).toEqual([]);
  56. expect(result.current.edges).toEqual([]);
  57. expect(localTerminate).toBeCalledTimes(1);
  58. });
  59. });
  60. function makeNode(index: number, incoming: number): NodeDatum {
  61. return {
  62. id: `n${index}`,
  63. title: `n${index}`,
  64. subTitle: '',
  65. dataFrameRowIndex: 0,
  66. incoming,
  67. arcSections: [],
  68. };
  69. }
  70. function makeEdge(source: number, target: number): EdgeDatum {
  71. return {
  72. id: `${source}-${target}`,
  73. source: 'n' + source,
  74. target: 'n' + target,
  75. mainStat: '',
  76. secondaryStat: '',
  77. dataFrameRowIndex: 0,
  78. };
  79. }