diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index e483ed47f52..c2e30d8e249 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -1722,12 +1722,36 @@ importers: specifier: 18.2.0 version: 18.2.0(react@18.2.0) devDependencies: + '@babel/core': + specifier: ~7.27.1 + version: 7.27.7 + '@babel/preset-env': + specifier: ~7.27.2 + version: 7.27.2(@babel/core@7.27.7) + '@babel/preset-react': + specifier: ~7.27.1 + version: 7.27.1(@babel/core@7.27.7) + '@babel/preset-typescript': + specifier: ~7.27.1 + version: 7.27.1(@babel/core@7.27.7) '@storybook/react': specifier: ^6.3.7 version: 6.5.16(@babel/core@7.27.7)(@types/webpack@5.28.5)(encoding@0.1.13)(eslint@9.26.0(jiti@2.5.1))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(require-from-string@2.0.2)(type-fest@4.41.0)(typescript@5.8.3)(webpack-dev-server@5.2.2(webpack@5.101.0))(webpack-hot-middleware@2.26.1) + '@testing-library/dom': + specifier: ~10.4.0 + version: 10.4.1 + '@testing-library/jest-dom': + specifier: ~6.6.3 + version: 6.6.4 + '@testing-library/react': + specifier: ~16.3.0 + version: 16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@18.2.0)(@types/react@18.2.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@types/dagre': specifier: ~0.7.52 version: 0.7.53 + '@types/jest': + specifier: 29.5.14 + version: 29.5.14 '@types/lodash': specifier: ~4.17.16 version: 4.17.17 @@ -1737,9 +1761,15 @@ importers: '@types/react-dom': specifier: 18.2.0 version: 18.2.0 + '@types/react-test-renderer': + specifier: ~19.1.0 + version: 19.1.0 '@typescript-eslint/eslint-plugin': specifier: ~8.32.1 version: 8.32.1(@typescript-eslint/parser@8.33.1(eslint@9.26.0(jiti@2.5.1))(typescript@5.8.3))(eslint@9.26.0(jiti@2.5.1))(typescript@5.8.3) + babel-jest: + specifier: 29.7.0 + version: 29.7.0(@babel/core@7.27.7) copyfiles: specifier: ^2.4.1 version: 2.4.1 @@ -1752,9 +1782,27 @@ importers: eslint-plugin-unused-imports: specifier: ~4.1.4 version: 4.1.4(@typescript-eslint/eslint-plugin@8.32.1(@typescript-eslint/parser@8.33.1(eslint@9.26.0(jiti@2.5.1))(typescript@5.8.3))(eslint@9.26.0(jiti@2.5.1))(typescript@5.8.3))(eslint@9.26.0(jiti@2.5.1)) + identity-obj-proxy: + specifier: ~3.0.0 + version: 3.0.0 + jest: + specifier: 29.7.0 + version: 29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0) + jest-environment-jsdom: + specifier: 29.7.0 + version: 29.7.0 prettier: specifier: ~3.5.3 version: 3.5.3 + pretty-format: + specifier: ~29.7.0 + version: 29.7.0 + react-test-renderer: + specifier: ~19.1.0 + version: 19.1.1(react@18.2.0) + ts-jest: + specifier: 29.3.4 + version: 29.3.4(@babel/core@7.27.7)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.7))(jest@29.7.0(@types/node@22.15.35)(babel-plugin-macros@3.1.0))(typescript@5.8.3) typescript: specifier: 5.8.3 version: 5.8.3 @@ -24169,7 +24217,10 @@ snapshots: jest-runner: 25.5.4 jest-runtime: 25.5.4 transitivePeerDependencies: + - bufferutil + - canvas - supports-color + - utf-8-validate '@jest/test-sequencer@29.7.0': dependencies: diff --git a/workspaces/ballerina/sequence-diagram/babel.config.js b/workspaces/ballerina/sequence-diagram/babel.config.js new file mode 100644 index 00000000000..712a1a7819a --- /dev/null +++ b/workspaces/ballerina/sequence-diagram/babel.config.js @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +module.exports = { + presets: [ + ['@babel/preset-env', { targets: { node: 'current' } }], + '@babel/preset-typescript', + ['@babel/preset-react', { runtime: 'automatic' }], + ], +}; diff --git a/workspaces/ballerina/sequence-diagram/jest.config.js b/workspaces/ballerina/sequence-diagram/jest.config.js new file mode 100644 index 00000000000..846433a51c3 --- /dev/null +++ b/workspaces/ballerina/sequence-diagram/jest.config.js @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +module.exports = { + preset: 'ts-jest/presets/js-with-ts', + testEnvironment: 'jsdom', + transform: { + '^.+\\.(js|jsx)$': 'babel-jest', + '^.+\\.(ts|tsx)$': 'ts-jest', + }, + globals: { + 'ts-jest': { + isolatedModules: true, + tsconfig: { + jsx: 'react', + esModuleInterop: true, + allowSyntheticDefaultImports: true, + } + }, + }, + moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], + testMatch: ['**/?(*.)+(spec|test).ts?(x)'], + moduleNameMapper: { + '^@vscode/codicons/dist/codicon\\.css$': '/../../../node_modules/.pnpm/identity-obj-proxy@3.0.0/node_modules/identity-obj-proxy', + '\\.css$': '/../../../node_modules/.pnpm/identity-obj-proxy@3.0.0/node_modules/identity-obj-proxy', + '\\.(less|sass|scss)$': '/../../../node_modules/.pnpm/identity-obj-proxy@3.0.0/node_modules/identity-obj-proxy', + '\\.(svg|png|jpg|jpeg|gif)$': '/../../../node_modules/.pnpm/identity-obj-proxy@3.0.0/node_modules/identity-obj-proxy', + '^react$': '/../../../node_modules/.pnpm/react@18.2.0/node_modules/react/index.js', + '^react-dom$': '/../../../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/index.js', + '^@wso2/ui-toolkit$': '/../../common-libs/ui-toolkit/src/index.ts', + '^@wso2/ballerina-core$': '/../ballerina-core/src/index.ts', + '^@wso2/ballerina-rpc-client$': '/../ballerina-rpc-client/src/index.ts', + '^@wso2/syntax-tree$': '/../syntax-tree/src/index.ts', + }, + setupFilesAfterEnv: [ + '/src/test/jest.env.ts', + ], + setupFiles: ['/src/test/matchMedia.ts'], + transformIgnorePatterns: [ + '/node_modules/(?!(@wso2)/)' // Only transform @wso2 packages + ], + moduleDirectories: ['node_modules', '/../../../node_modules'], + collectCoverageFrom: [ + 'src/**/*.{ts,tsx}', + '!src/**/*.d.ts', + '!src/**/*.stories.{ts,tsx}', + '!src/test/**/*' + ] +}; diff --git a/workspaces/ballerina/sequence-diagram/package.json b/workspaces/ballerina/sequence-diagram/package.json index 7769bc056df..ec521ba1b1b 100644 --- a/workspaces/ballerina/sequence-diagram/package.json +++ b/workspaces/ballerina/sequence-diagram/package.json @@ -9,6 +9,9 @@ "types": "lib/index.d.ts", "scripts": { "start": "tsc && node dist/index.js", + "test": "jest --coverage", + "test:watch": "jest --watch", + "test:updateSnapshots": "jest --updateSnapshot", "build": "tsc --pretty && npm run copy:assets && pnpm run postbuild", "lint": "eslint src --ext .js,.jsx,.ts,.tsx", "lint:fix": "eslint src --ext .js,.jsx,.ts,.tsx --fix", @@ -51,6 +54,22 @@ "eslint": "~9.26.0", "@typescript-eslint/eslint-plugin": "~8.32.1", "eslint-plugin-react-hooks": "~5.2.0", - "eslint-plugin-unused-imports": "~4.1.4" + "eslint-plugin-unused-imports": "~4.1.4", + "jest": "29.7.0", + "ts-jest": "29.3.4", + "@types/jest": "29.5.14", + "@testing-library/jest-dom": "~6.6.3", + "@testing-library/react": "~16.3.0", + "@testing-library/dom": "~10.4.0", + "jest-environment-jsdom": "29.7.0", + "@babel/core": "~7.27.1", + "@babel/preset-env": "~7.27.2", + "@babel/preset-react": "~7.27.1", + "@babel/preset-typescript": "~7.27.1", + "babel-jest": "29.7.0", + "react-test-renderer": "~19.1.0", + "@types/react-test-renderer": "~19.1.0", + "pretty-format": "~29.7.0", + "identity-obj-proxy": "~3.0.0" } } diff --git a/workspaces/ballerina/sequence-diagram/src/stories/sample-with-return.json b/workspaces/ballerina/sequence-diagram/src/stories/sample-with-return.json new file mode 100644 index 00000000000..3857bf7afd0 --- /dev/null +++ b/workspaces/ballerina/sequence-diagram/src/stories/sample-with-return.json @@ -0,0 +1,197 @@ +{ + "participants": [ + { + "id": "33785", + "name": "httpClient", + "kind": "ENDPOINT", + "moduleName": "test_sample", + "location": { + "fileName": "connections.bal", + "startLine": { + "line": 2, + "offset": 0 + }, + "endLine": { + "line": 2, + "offset": 57 + } + }, + "viewState": { + "bBox": { + "x": 440, + "y": 0, + "h": 40, + "w": 160 + }, + "xIndex": 2, + "lifelineHeight": 99 + } + }, + { + "id": "37174", + "name": "get", + "kind": "FUNCTION", + "moduleName": "test_sample", + "nodes": [ + { + "interactionType": "ENDPOINT_CALL", + "targetId": "33785", + "kind": "INTERACTION", + "properties": { + "name": { + "type": "string", + "value": "get" + }, + "expr": { + "type": "http:Client", + "value": "httpClient" + }, + "params": [ + { + "type": "string", + "value": "\"path\"" + } + ], + "value": { + "type": "json|http:ClientError", + "value": "var1" + } + }, + "location": { + "fileName": "main.bal", + "startLine": { + "line": 7, + "offset": 30 + }, + "endLine": { + "line": 7, + "offset": 53 + } + }, + "viewStates": [ + { + "callNodeId": "participant-37174", + "bBox": { + "x": 0, + "y": 0, + "h": 0, + "w": 0 + }, + "points": { + "start": { + "bBox": { + "x": 220, + "y": 68, + "h": 20, + "w": 20 + }, + "participantId": "37174" + }, + "end": { + "bBox": { + "x": 440, + "y": 68, + "h": 20, + "w": 20 + }, + "participantId": "33785" + }, + "returnStart": { + "bBox": { + "x": 440, + "y": 96, + "h": 20, + "w": 20 + }, + "participantId": "33785" + }, + "returnEnd": { + "bBox": { + "x": 220, + "y": 96, + "h": 20, + "w": 20 + }, + "participantId": "37174" + } + } + } + ] + }, + { + "kind": "RETURN", + "branches": [], + "properties": { + "value": { + "type": "http:BadRequest" + } + }, + "location": { + "fileName": "main.bal", + "startLine": { + "line": 8, + "offset": 12 + }, + "endLine": { + "line": 11, + "offset": 14 + } + } + }, + { + "kind": "RETURN", + "branches": [], + "properties": { + "value": { + "type": "annotations:error" + } + }, + "location": { + "fileName": "main.bal", + "startLine": { + "line": 14, + "offset": 12 + }, + "endLine": { + "line": 14, + "offset": 49 + } + } + } + ], + "location": { + "fileName": "main.bal", + "startLine": { + "line": 5, + "offset": 4 + }, + "endLine": { + "line": 16, + "offset": 5 + } + }, + "viewState": { + "bBox": { + "x": 220, + "y": 0, + "h": 40, + "w": 160 + }, + "xIndex": 1, + "lifelineHeight": 99 + } + } + ], + "location": { + "fileName": "/Users/gayanka/dev/wso2/test/test_sample/main.bal", + "startLine": { + "line": 5, + "offset": 4 + }, + "endLine": { + "line": 16, + "offset": 5 + } + }, + "others": [] +} diff --git a/workspaces/ballerina/sequence-diagram/src/test/Diagram.test.tsx b/workspaces/ballerina/sequence-diagram/src/test/Diagram.test.tsx new file mode 100644 index 00000000000..1468f2a8dcc --- /dev/null +++ b/workspaces/ballerina/sequence-diagram/src/test/Diagram.test.tsx @@ -0,0 +1,126 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import React from "react"; +import { prettyDOM, waitFor } from "@testing-library/dom"; +import { render } from "@testing-library/react"; +import "@testing-library/jest-dom"; +import { Diagram } from "../components/Diagram"; +import { Flow } from "../utils/types"; + +// Import sample data +import model1 from "../stories/endpoint_call1.json"; +import model2 from "../stories/function_call1.json"; +import model3 from "../stories/function_call2.json"; +import model4 from "../stories/function_call3.json"; +import model5 from "../stories/if_node1.json"; +import model6 from "../stories/if_node4.json"; +import model7 from "../stories/if_node5.json"; +import model8 from "../stories/if_node8.json"; +import model9 from "../stories/while_node1.json"; +import model10 from "../stories/sample-with-return.json"; + +async function renderAndCheckSnapshot(model: Flow, testName: string) { + const mockProps = { + onClickParticipant: jest.fn(), + onAddParticipant: jest.fn(), + onReady: jest.fn(), + }; + + const dom = render(); + + // Wait for diagram to render + await waitFor( + () => { + const diagramElements = dom.container.querySelectorAll('[class*="diagram"], svg, canvas'); + expect(diagramElements.length).toBeGreaterThan(0); + }, + { timeout: 10000 } + ); + + // Wait for progress ring to be removed (indicates diagram is fully rendered) + await waitFor( + () => { + const progressRing = dom.container.querySelector('vscode-progress-ring'); + expect(progressRing).not.toBeInTheDocument(); + }, + { timeout: 5000 } + ); + + const prettyDom = prettyDOM(dom.container, 1000000, { + highlight: false, + filterNode(node) { + return true; + }, + }); + + expect(prettyDom).toBeTruthy(); + + // Sanitization: remove dynamic IDs and non-deterministic attributes + function sanitizeDom(domString: string): string { + return domString + .replace(/\s+(marker-end|id|data-linkid|data-nodeid)="[^"]*"/g, "") + .replace(/\s+(appearance|aria-label|current-value)="[^"]*"/g, "") + .replace(/href="#[^"]*"/g, 'href="#DYNAMIC_ID"') + .replace(//g, ""); + } + const sanitizedDom = sanitizeDom(prettyDom as string); + expect(sanitizedDom).toMatchSnapshot(testName); +} + +describe("Sequence Diagram - Snapshot Tests", () => { + test("renders endpoint call diagram correctly", async () => { + await renderAndCheckSnapshot(model1 as Flow, "endpoint-call"); + }, 15000); + + test("renders function call 1 diagram correctly", async () => { + await renderAndCheckSnapshot(model2 as Flow, "function-call-1"); + }, 15000); + + test("renders function call 2 diagram correctly", async () => { + await renderAndCheckSnapshot(model3 as Flow, "function-call-2"); + }, 15000); + + test("renders function call 3 diagram correctly", async () => { + await renderAndCheckSnapshot(model4 as Flow, "function-call-3"); + }, 15000); + + test("renders if node 1 diagram correctly", async () => { + await renderAndCheckSnapshot(model5 as Flow, "if-node-1"); + }, 15000); + + test("renders if node 4 diagram correctly", async () => { + await renderAndCheckSnapshot(model6 as Flow, "if-node-4"); + }, 15000); + + test("renders if node 5 diagram correctly", async () => { + await renderAndCheckSnapshot(model7 as Flow, "if-node-5"); + }, 15000); + + test("renders if node 8 diagram correctly", async () => { + await renderAndCheckSnapshot(model8 as Flow, "if-node-8"); + }, 15000); + + test("renders while node diagram correctly", async () => { + await renderAndCheckSnapshot(model9 as Flow, "while-node"); + }, 15000); + + test("renders sample with return diagram correctly", async () => { + await renderAndCheckSnapshot(model10 as Flow, "sample-with-return"); + }, 15000); +}); diff --git a/workspaces/ballerina/sequence-diagram/src/test/__snapshots__/Diagram.test.tsx.snap b/workspaces/ballerina/sequence-diagram/src/test/__snapshots__/Diagram.test.tsx.snap new file mode 100644 index 00000000000..63dbccb57b0 --- /dev/null +++ b/workspaces/ballerina/sequence-diagram/src/test/__snapshots__/Diagram.test.tsx.snap @@ -0,0 +1,7884 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Sequence Diagram - Snapshot Tests renders endpoint call diagram correctly: endpoint-call 1`] = ` +"
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + get + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + post + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+ + + +
+ getCall +
+
+
+ + + +
+
+
+
+
+
+
+ + + +
+
+ cl +
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
" +`; + +exports[`Sequence Diagram - Snapshot Tests renders function call 1 diagram correctly: function-call-1 1`] = ` +"
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + fn2 () + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fn3 (2) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fn3 (2) + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+ + + +
+ fn1 +
+
+
+ + + +
+
+
+
+
+
+
+ + + +
+ fn2 +
+
+
+ + + +
+
+
+
+
+
+
+ + + +
+ fn3 +
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
" +`; + +exports[`Sequence Diagram - Snapshot Tests renders function call 2 diagram correctly: function-call-2 1`] = ` +"
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + fn3 (2) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fn2 () + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fn3 (2) + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+ + + +
+ fn1 +
+
+
+ + + +
+
+
+
+
+
+
+ + + +
+ fn3 +
+
+
+ + + +
+
+
+
+
+
+
+ + + +
+ fn2 +
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
" +`; + +exports[`Sequence Diagram - Snapshot Tests renders function call 3 diagram correctly: function-call-3 1`] = ` +"
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + fn2 () + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fn3 (2) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fn2 () + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fn3 (2) + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+ + + +
+ fn1 +
+
+
+ + + +
+
+
+
+
+
+
+ + + +
+ fn2 +
+
+
+ + + +
+
+
+
+
+
+
+ + + +
+ fn3 +
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
" +`; + +exports[`Sequence Diagram - Snapshot Tests renders if node 1 diagram correctly: if-node-1 1`] = ` +"
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + fn2 () + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fn3 () + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fn4 () + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+ + + +
+ fn1 +
+
+
+ + + +
+
+
+
+
+
+
+ + + +
+ longfunctionname +
+
+
+ + + +
+
+
+
+
+
+
+ + + +
+ fn3 +
+
+
+ + + +
+
+
+
+
+
+
+ + + +
+ fn4 +
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
" +`; + +exports[`Sequence Diagram - Snapshot Tests renders if node 4 diagram correctly: if-node-4 1`] = ` +"
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + fn2 () + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+ + + +
+ fn1 +
+
+
+ + + +
+
+
+
+
+
+
+ + + +
+ fn2 +
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
" +`; + +exports[`Sequence Diagram - Snapshot Tests renders if node 5 diagram correctly: if-node-5 1`] = ` +"
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + fn2 () + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fn2 () + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+ + + +
+ fn1 +
+
+
+ + + +
+
+
+
+
+
+
+ + + +
+ fn2 +
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
" +`; + +exports[`Sequence Diagram - Snapshot Tests renders if node 8 diagram correctly: if-node-8 1`] = ` +"
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + fn1 (true) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fn2 () + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fn2 () + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fn3 () + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + fn4 () + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+ + + +
+ fn0 +
+
+
+ + + +
+
+
+
+
+
+
+ + + +
+ fn1 +
+
+
+ + + +
+
+
+
+
+
+
+ + + +
+ fn2 +
+
+
+ + + +
+
+
+
+
+
+
+ + + +
+ fn3 +
+
+
+ + + +
+
+
+
+
+
+
+ + + +
+ fn4 +
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
" +`; + +exports[`Sequence Diagram - Snapshot Tests renders sample with return diagram correctly: sample-with-return 1`] = ` +"
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + get + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+ + + +
+ get +
+
+
+ + + +
+
+
+
+
+
+
+ + + +
+
+ httpClient +
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
" +`; + +exports[`Sequence Diagram - Snapshot Tests renders while node diagram correctly: while-node 1`] = ` +"
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + fn2 (count) + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+ + + +
+ fn1 +
+
+
+ + + +
+
+
+
+
+
+
+ + + +
+ fn2 +
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+
+
" +`; diff --git a/workspaces/ballerina/sequence-diagram/src/test/jest.env.ts b/workspaces/ballerina/sequence-diagram/src/test/jest.env.ts new file mode 100644 index 00000000000..f2654e191e1 --- /dev/null +++ b/workspaces/ballerina/sequence-diagram/src/test/jest.env.ts @@ -0,0 +1,72 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import '@testing-library/jest-dom'; + +(globalThis as any).structuredClone = (val: any) => { + return JSON.parse(JSON.stringify(val)) +} + +(globalThis as any).setImmediate = (globalThis as any).setImmediate || ((fn: any, ...args: any) => globalThis.setTimeout(fn, 0, ...args)) as any; + +class MockResizeObserver { + observe = jest.fn(); + unobserve = jest.fn(); + disconnect = jest.fn(); +} + +(globalThis as any).ResizeObserver = MockResizeObserver; + +// Mock getBoundingClientRect for canvas elements +Element.prototype.getBoundingClientRect = jest.fn(() => ({ + width: 800, + height: 600, + top: 0, + left: 0, + bottom: 600, + right: 800, + x: 0, + y: 0, + toJSON: jest.fn() +})); + +// Mock canvas context +HTMLCanvasElement.prototype.getContext = jest.fn(() => ({ + fillRect: jest.fn(), + clearRect: jest.fn(), + getImageData: jest.fn(), + putImageData: jest.fn(), + createImageData: jest.fn(), + setTransform: jest.fn(), + drawImage: jest.fn(), + save: jest.fn(), + restore: jest.fn(), + beginPath: jest.fn(), + moveTo: jest.fn(), + lineTo: jest.fn(), + closePath: jest.fn(), + stroke: jest.fn(), + fill: jest.fn(), + scale: jest.fn(), + rotate: jest.fn(), + translate: jest.fn(), + measureText: jest.fn(() => ({ width: 10 })), + fillStyle: '', + strokeStyle: '', + globalAlpha: 1, +})) as any; diff --git a/workspaces/ballerina/sequence-diagram/src/test/matchMedia.ts b/workspaces/ballerina/sequence-diagram/src/test/matchMedia.ts new file mode 100644 index 00000000000..b2d279e0302 --- /dev/null +++ b/workspaces/ballerina/sequence-diagram/src/test/matchMedia.ts @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +Object.defineProperty(window, 'matchMedia', { + writable: true, + value: jest.fn().mockImplementation((query) => ({ + matches: false, + media: query, + onchange: null, + addListener: jest.fn(), + removeListener: jest.fn(), + addEventListener: jest.fn(), + removeEventListener: jest.fn(), + dispatchEvent: jest.fn(), + })), +}); + +window.HTMLElement.prototype.scrollIntoView = jest.fn()