diff --git a/jest.config.js b/jest.config.js index 7f582d1..ba73e36 100644 --- a/jest.config.js +++ b/jest.config.js @@ -2,7 +2,7 @@ export default { preset: 'ts-jest/presets/default-esm', testEnvironment: 'jsdom', extensionsToTreatAsEsm: ['.ts', '.tsx'], - setupFilesAfterEnv: ['/test/setupTests.ts'], + setupFilesAfterEnv: ['/test/setupTests.ts', '/test/setupFlowTests.ts' ], moduleNameMapper: { '^@/(.*)$': '/src/$1', '\\.(css|scss|sass)$': 'identity-obj-proxy' diff --git a/test/setupFlowTests.ts b/test/setupFlowTests.ts new file mode 100644 index 0000000..973460a --- /dev/null +++ b/test/setupFlowTests.ts @@ -0,0 +1,70 @@ +import '@testing-library/jest-dom'; +import { cleanup } from '@testing-library/react'; +import useFlowStore from '../src/pages/VisProgPage/visualProgrammingUI/VisProgStores.tsx'; + + +// To make sure that the tests are working, it's important that you are using +// this implementation of ResizeObserver and DOMMatrixReadOnly +class ResizeObserver { + callback: globalThis.ResizeObserverCallback; + + constructor(callback: globalThis.ResizeObserverCallback) { + this.callback = callback; + } + + observe(target: Element) { + this.callback([{ target } as globalThis.ResizeObserverEntry], this); + } + + unobserve() {} + + disconnect() {} +} + +class DOMMatrixReadOnly { + m22: number; + constructor(transform: string) { + const scale = transform?.match(/scale\(([1-9.])\)/)?.[1]; + this.m22 = scale !== undefined ? +scale : 1; + } +} + +// Only run the shim once when requested +let init = false; + +export const mockReactFlow = () => { + if (init) return; + init = true; + + globalThis.ResizeObserver = ResizeObserver; + + // @ts-expect-error included in advised setup code provided in ReactFlow documentation + global.DOMMatrixReadOnly = DOMMatrixReadOnly; + + Object.defineProperties(globalThis.HTMLElement.prototype, { + offsetHeight: { + get() { + return parseFloat(this.style.height) || 1; + }, + }, + offsetWidth: { + get() { + return parseFloat(this.style.width) || 1; + }, + }, + }); + + // @ts-expect-error included in advised setup code provided in ReactFlow documentation + (globalThis.SVGElement as never).prototype.getBBox = () => ({ + x: 0, + y: 0, + width: 0, + height: 0, + }); +}; + +afterEach(() => { + cleanup(); + useFlowStore.setState({ nodes: [], edges: [] }); +}); +