// This program has been developed by students from the bachelor Computer Science at Utrecht // University within the Software Project course. // © Copyright Utrecht University (Department of Information and Computing Sciences) import '@testing-library/jest-dom'; import { cleanup } from '@testing-library/react'; import { type CompositeWarningKey, type SeverityIndex, } from "../src/pages/VisProgPage/visualProgrammingUI/components/EditorWarnings.tsx"; import useFlowStore from '../src/pages/VisProgPage/visualProgrammingUI/VisProgStores.tsx'; if (!globalThis.structuredClone) { globalThis.structuredClone = (obj: any) => { return JSON.parse(JSON.stringify(obj)); }; } // 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: 200, height: 200, }); }; beforeAll(() => { useFlowStore.setState({ nodes: [], edges: [], past: [], future: [], isBatchAction: false, edgeReconnectSuccessful: true, ruleRegistry: new Map(), editorWarningRegistry: new Map(), severityIndex: new Map([ ['INFO', new Set()], ['WARNING', new Set()], ['ERROR', new Set()], ]) as SeverityIndex, }); }); afterEach(() => { cleanup(); useFlowStore.setState({ nodes: [], edges: [], past: [], future: [], isBatchAction: false, edgeReconnectSuccessful: true, ruleRegistry: new Map(), editorWarningRegistry: new Map(), severityIndex: new Map([ ['INFO', new Set()], ['WARNING', new Set()], ['ERROR', new Set()], ]) as SeverityIndex, }); }); if (typeof HTMLDialogElement !== 'undefined') { if (!HTMLDialogElement.prototype.showModal) { HTMLDialogElement.prototype.showModal = function () { // basic behavior: mark as open this.setAttribute('open', ''); }; } if (!HTMLDialogElement.prototype.close) { HTMLDialogElement.prototype.close = function () { this.removeAttribute('open'); }; } }