From 691d35b11a1f7a63b5d4e0eda102f9385bd9ae3a Mon Sep 17 00:00:00 2001 From: Koen Vlaswinkel <koesie10@github.com> Date: Thu, 24 Apr 2025 15:40:42 +0200 Subject: [PATCH] Use vitest browser mode for view tests --- extensions/ql-vscode/package-lock.json | 764 ++++++++++++++++-- extensions/ql-vscode/package.json | 7 +- .../SuggestBox/__tests__/SuggestBox.test.tsx | 4 +- .../__tests__/useEffectEvent.test.ts | 4 +- .../SuggestBox/__tests__/useOpenKey.test.ts | 6 +- .../src/view/jest-environment-jsdom.ts | 15 - extensions/ql-vscode/src/view/jest.config.ts | 203 ----- extensions/ql-vscode/src/view/jest.setup.ts | 41 - .../__tests__/MethodModeling.spec.tsx | 2 +- .../__tests__/MethodModelingInputs.spec.tsx | 2 +- .../MultipleModeledMethodsPanel.spec.tsx | 2 +- .../__tests__/LibraryRow.spec.tsx | 10 +- .../model-editor/__tests__/MethodRow.spec.tsx | 4 +- .../__tests__/ModelEvaluation.spec.tsx | 6 +- .../__tests__/ModelKindDropdown.spec.tsx | 2 +- .../__tests__/ModelTypeDropdown.spec.tsx | 2 +- .../__tests__/ModeledMethodDataGrid.spec.tsx | 4 +- .../__tests__/ModeledMethodsList.spec.tsx | 10 +- .../ModelingStatusIndicator.spec.tsx | 2 +- .../__tests__/AlertTablePathRow.spec.tsx | 4 +- .../__tests__/AlertTableResultRow.spec.tsx | 4 +- .../view/results/__tests__/results.spec.tsx | 7 +- .../results/__tests__/validSarif.sarif.json | 57 ++ extensions/ql-vscode/src/view/tsconfig.json | 3 +- .../ql-vscode/src/view/tsconfig.spec.json | 7 - .../__tests__/QueryDetails.spec.tsx | 10 +- .../__tests__/VariantAnalysisActions.spec.tsx | 6 +- .../VariantAnalysisOutcomePanels.spec.tsx | 2 +- .../__tests__/VariantAnalysisStats.spec.tsx | 2 +- .../ql-vscode/src/view/vitest.config.ts | 15 + extensions/ql-vscode/src/view/vitest.setup.ts | 7 + extensions/ql-vscode/vitest.workspace.ts | 3 + 32 files changed, 813 insertions(+), 404 deletions(-) delete mode 100644 extensions/ql-vscode/src/view/jest-environment-jsdom.ts delete mode 100644 extensions/ql-vscode/src/view/jest.config.ts delete mode 100644 extensions/ql-vscode/src/view/jest.setup.ts create mode 100644 extensions/ql-vscode/src/view/results/__tests__/validSarif.sarif.json delete mode 100644 extensions/ql-vscode/src/view/tsconfig.spec.json create mode 100644 extensions/ql-vscode/src/view/vitest.config.ts create mode 100644 extensions/ql-vscode/src/view/vitest.setup.ts create mode 100644 extensions/ql-vscode/vitest.workspace.ts diff --git a/extensions/ql-vscode/package-lock.json b/extensions/ql-vscode/package-lock.json index 28561888a8b..834d930999b 100644 --- a/extensions/ql-vscode/package-lock.json +++ b/extensions/ql-vscode/package-lock.json @@ -97,6 +97,8 @@ "@types/yauzl": "^2.10.3", "@typescript-eslint/eslint-plugin": "^8.30.1", "@typescript-eslint/parser": "^8.30.1", + "@vitejs/plugin-react": "^4.4.1", + "@vitest/browser": "^3.1.2", "@vscode/test-electron": "^2.3.9", "@vscode/vsce": "^3.2.1", "ansi-colors": "^4.1.1", @@ -142,7 +144,8 @@ "typescript": "^5.6.2", "typescript-plugin-css-modules": "^5.1.0", "vite": "^6.2.6", - "vite-node": "^3.0.7" + "vite-node": "^3.0.7", + "vitest": "^3.1.2" }, "engines": { "node": "^20.18.3", @@ -622,30 +625,32 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.6.tgz", - "integrity": "sha512-aC2DGhBq5eEdyXWqrDInSqQjO0k8xtPRf5YylULqx8MCd6jBtzqfta/3ETMRpuKIc5hyswfO80ObyA1MvkCcUQ==", + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz", + "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.6.tgz", - "integrity": "sha512-qAHSfAdVyFmIvl0VHELib8xar7ONuSHrE2hLnsaWkYNTI68dmi1x8GYDhJjMI/e7XWal9QBlZkwbOnkcw7Z8gQ==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz", + "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", "dev": true, + "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.6", - "@babel/generator": "^7.24.6", - "@babel/helper-compilation-targets": "^7.24.6", - "@babel/helper-module-transforms": "^7.24.6", - "@babel/helpers": "^7.24.6", - "@babel/parser": "^7.24.6", - "@babel/template": "^7.24.6", - "@babel/traverse": "^7.24.6", - "@babel/types": "^7.24.6", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.10", + "@babel/helper-compilation-targets": "^7.26.5", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.10", + "@babel/parser": "^7.26.10", + "@babel/template": "^7.26.9", + "@babel/traverse": "^7.26.10", + "@babel/types": "^7.26.10", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -670,13 +675,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", - "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.0.tgz", + "integrity": "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/parser": "^7.26.2", - "@babel/types": "^7.26.0", + "@babel/parser": "^7.27.0", + "@babel/types": "^7.27.0", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" @@ -710,14 +716,15 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.6.tgz", - "integrity": "sha512-VZQ57UsDGlX/5fFA7GkVPplZhHsVc+vuErWgdOiysI9Ksnw0Pbbd6pnPiR/mmJyKHgyIW0c7KT32gmhiF+cirg==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.0.tgz", + "integrity": "sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.24.6", - "@babel/helper-validator-option": "^7.24.6", - "browserslist": "^4.22.2", + "@babel/compat-data": "^7.26.8", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -1014,25 +1021,27 @@ } }, "node_modules/@babel/helpers": { - "version": "7.24.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.6.tgz", - "integrity": "sha512-V2PI+NqnyFu1i0GyTd/O/cTpxzQCYioSkUIRmgo7gFEHKKCg5w46+r/A6WeUR1+P3TeQ49dspGPNd/E3n9AnnA==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.0.tgz", + "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.24.6", - "@babel/types": "^7.24.6" + "@babel/template": "^7.27.0", + "@babel/types": "^7.27.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", - "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz", + "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.26.0" + "@babel/types": "^7.27.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -2045,6 +2054,38 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz", + "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz", + "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-transform-react-pure-annotations": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.25.9.tgz", @@ -2429,30 +2470,32 @@ } }, "node_modules/@babel/template": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", - "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz", + "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.25.9", - "@babel/parser": "^7.25.9", - "@babel/types": "^7.25.9" + "@babel/code-frame": "^7.26.2", + "@babel/parser": "^7.27.0", + "@babel/types": "^7.27.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", - "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.0.tgz", + "integrity": "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.25.9", - "@babel/generator": "^7.25.9", - "@babel/parser": "^7.25.9", - "@babel/template": "^7.25.9", - "@babel/types": "^7.25.9", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.27.0", + "@babel/parser": "^7.27.0", + "@babel/template": "^7.27.0", + "@babel/types": "^7.27.0", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -2461,10 +2504,11 @@ } }, "node_modules/@babel/types": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", - "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz", + "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9" @@ -5901,6 +5945,13 @@ "node": ">=18" } }, + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", + "dev": true, + "license": "MIT" + }, "node_modules/@rollup/pluginutils": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", @@ -8786,6 +8837,100 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true }, + "node_modules/@vitejs/plugin-react": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.4.1.tgz", + "integrity": "sha512-IpEm5ZmeXAP/osiBXVVP5KjFMzbWOonMs0NaQQl+xYnUAcq4oHUBsF2+p4MgKWG4YMmFYJU8A6sxRPuowllm6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.26.10", + "@babel/plugin-transform-react-jsx-self": "^7.25.9", + "@babel/plugin-transform-react-jsx-source": "^7.25.9", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" + } + }, + "node_modules/@vitest/browser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-3.1.2.tgz", + "integrity": "sha512-dwL6hQg3NSDP3Z4xzIZL0xHq/AkQAPQ4StFpWVlY2zbRJtK3Y2YqdFZ7YmZjszTETN1BDQZRn/QOrcP+c8ATgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@testing-library/dom": "^10.4.0", + "@testing-library/user-event": "^14.6.1", + "@vitest/mocker": "3.1.2", + "@vitest/utils": "3.1.2", + "magic-string": "^0.30.17", + "sirv": "^3.0.1", + "tinyrainbow": "^2.0.0", + "ws": "^8.18.1" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "playwright": "*", + "vitest": "3.1.2", + "webdriverio": "^7.0.0 || ^8.0.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "playwright": { + "optional": true + }, + "safaridriver": { + "optional": true + }, + "webdriverio": { + "optional": true + } + } + }, + "node_modules/@vitest/browser/node_modules/@vitest/pretty-format": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.1.2.tgz", + "integrity": "sha512-R0xAiHuWeDjTSB3kQ3OQpT8Rx3yhdOAIm/JM4axXxnG7Q/fS8XUwggv/A4xzbQA+drYRjzkMnpYnOGAc4oeq8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/browser/node_modules/@vitest/utils": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.1.2.tgz", + "integrity": "sha512-5GGd0ytZ7BH3H6JTj9Kw7Prn1Nbg0wZVrIvou+UWxm54d+WoXXgAgjFJ8wn3LdagWLFSEfpPeyYrByZaGEZHLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.1.2", + "loupe": "^3.1.3", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/browser/node_modules/tinyrainbow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@vitest/expect": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.5.tgz", @@ -8841,6 +8986,56 @@ "@types/estree": "^1.0.0" } }, + "node_modules/@vitest/mocker": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.1.2.tgz", + "integrity": "sha512-kOtd6K2lc7SQ0mBqYv/wdGedlqPdM/B38paPY+OwJ1XiNi44w3Fpog82UfOibmHaV9Wod18A09I9SCKLyDMqgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "3.1.2", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/mocker/node_modules/@vitest/spy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.1.2.tgz", + "integrity": "sha512-OEc5fSXMws6sHVe4kOFyDSj/+4MSwst0ib4un0DlcYgQvRuYQ0+M2HyqGaauUMnjq87tmUaMNDxKQx7wNfVqPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^3.0.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, "node_modules/@vitest/pretty-format": { "version": "2.1.9", "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.9.tgz", @@ -8854,6 +9049,96 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/@vitest/runner": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.1.2.tgz", + "integrity": "sha512-bhLib9l4xb4sUMPXnThbnhX2Yi8OutBMA8Yahxa7yavQsFDtwY/jrUZwpKp2XH9DhRFJIeytlyGpXCqZ65nR+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "3.1.2", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner/node_modules/@vitest/pretty-format": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.1.2.tgz", + "integrity": "sha512-R0xAiHuWeDjTSB3kQ3OQpT8Rx3yhdOAIm/JM4axXxnG7Q/fS8XUwggv/A4xzbQA+drYRjzkMnpYnOGAc4oeq8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner/node_modules/@vitest/utils": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.1.2.tgz", + "integrity": "sha512-5GGd0ytZ7BH3H6JTj9Kw7Prn1Nbg0wZVrIvou+UWxm54d+WoXXgAgjFJ8wn3LdagWLFSEfpPeyYrByZaGEZHLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.1.2", + "loupe": "^3.1.3", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner/node_modules/tinyrainbow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@vitest/snapshot": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.1.2.tgz", + "integrity": "sha512-Q1qkpazSF/p4ApZg1vfZSQ5Yw6OCQxVMVrLjslbLFA1hMDrT2uxtqMaw8Tc/jy5DLka1sNs1Y7rBcftMiaSH/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.1.2", + "magic-string": "^0.30.17", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot/node_modules/@vitest/pretty-format": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.1.2.tgz", + "integrity": "sha512-R0xAiHuWeDjTSB3kQ3OQpT8Rx3yhdOAIm/JM4axXxnG7Q/fS8XUwggv/A4xzbQA+drYRjzkMnpYnOGAc4oeq8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot/node_modules/tinyrainbow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@vitest/spy": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.5.tgz", @@ -10258,9 +10543,9 @@ "dev": true }, "node_modules/browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", "dev": true, "funding": [ { @@ -10276,11 +10561,12 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" @@ -10468,9 +10754,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001611", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001611.tgz", - "integrity": "sha512-19NuN1/3PjA3QI8Eki55N8my4LzfkMCRLgCVfrl/slbSAchQfV0+GwjPrK3rq37As4UCLlM/DHajbKkAqbv92Q==", + "version": "1.0.30001715", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001715.tgz", + "integrity": "sha512-7ptkFGMm2OAOgvZpwgA4yjQ5SQbrNVGdRjzH0pBdy1Fasvcr+KAeECmbCAECzTuDuoX0FCY8KzUxjf9+9kfZEw==", "dev": true, "funding": [ { @@ -10485,7 +10771,8 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/chai": { "version": "5.2.0", @@ -12391,10 +12678,11 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.742", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.742.tgz", - "integrity": "sha512-EhE+z1d5RNytAq/qnGAxPR+ie3UzKbv7qqQc0wnEbOh+KDUplgfzkGSCy9d78B+S+nVNTS42BabHXB6Ni+Ud4w==", - "dev": true + "version": "1.5.141", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.141.tgz", + "integrity": "sha512-qS+qH9oqVYc1ooubTiB9l904WVyM6qNYxtOEEGReoZXw3xlqeYdFr5GclNzbkAufWgwWLEPoDi3d9MoRwwIjGw==", + "dev": true, + "license": "ISC" }, "node_modules/emitter-listener": { "version": "1.1.2", @@ -12720,9 +13008,10 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", "engines": { "node": ">=6" } @@ -13857,6 +14146,16 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/expect-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.1.tgz", + "integrity": "sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -13971,6 +14270,21 @@ "pend": "~1.2.0" } }, + "node_modules/fdir": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", + "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -20856,10 +21170,11 @@ } }, "node_modules/magic-string": { - "version": "0.30.12", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", - "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } @@ -21808,6 +22123,16 @@ "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==", "dev": true }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -21973,10 +22298,11 @@ "dev": true }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, + "license": "MIT" }, "node_modules/normalize-package-data": { "version": "2.5.0", @@ -23579,6 +23905,16 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "dev": true }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/read": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", @@ -24506,6 +24842,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", @@ -24564,6 +24907,21 @@ "simple-concat": "^1.0.0" } }, + "node_modules/sirv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.1.tgz", + "integrity": "sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -24713,6 +25071,13 @@ "node": ">=8" } }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -24721,6 +25086,13 @@ "node": ">= 0.8" } }, + "node_modules/std-env": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz", + "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==", + "dev": true, + "license": "MIT" + }, "node_modules/stoppable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", @@ -25546,6 +25918,60 @@ "dev": true, "license": "MIT" }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz", + "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/tinypool": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz", + "integrity": "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, "node_modules/tinyrainbow": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", @@ -25667,6 +26093,16 @@ "xtend": "~4.0.1" } }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/tough-cookie": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", @@ -26474,9 +26910,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", "dev": true, "funding": [ { @@ -26492,9 +26928,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -26889,9 +27326,9 @@ } }, "node_modules/vite-node": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.7.tgz", - "integrity": "sha512-2fX0QwX4GkkkpULXdT1Pf4q0tC1i1lFOyseKoonavXUNlQ77KpW2XqBGGNIm/J4Ows4KxgGJzDguYVPKwG/n5A==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.1.2.tgz", + "integrity": "sha512-/8iMryv46J3aK13iUXsei5G/A3CUlW4665THCPS+K8xAaqrVWiGB4RfXMQXCLjpK9P2eK//BczrVkn5JLAk6DA==", "dev": true, "license": "MIT", "dependencies": { @@ -26911,6 +27348,144 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/vitest": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.1.2.tgz", + "integrity": "sha512-WaxpJe092ID1C0mr+LH9MmNrhfzi8I65EX/NRU/Ld016KqQNRgxSOlGNP1hHN+a/F8L15Mh8klwaF77zR3GeDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "3.1.2", + "@vitest/mocker": "3.1.2", + "@vitest/pretty-format": "^3.1.2", + "@vitest/runner": "3.1.2", + "@vitest/snapshot": "3.1.2", + "@vitest/spy": "3.1.2", + "@vitest/utils": "3.1.2", + "chai": "^5.2.0", + "debug": "^4.4.0", + "expect-type": "^1.2.1", + "magic-string": "^0.30.17", + "pathe": "^2.0.3", + "std-env": "^3.9.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.13", + "tinypool": "^1.0.2", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0", + "vite-node": "3.1.2", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/debug": "^4.1.12", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@vitest/browser": "3.1.2", + "@vitest/ui": "3.1.2", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/debug": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/@vitest/expect": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.1.2.tgz", + "integrity": "sha512-O8hJgr+zREopCAqWl3uCVaOdqJwZ9qaDwUP7vy3Xigad0phZe9APxKhPcDNqYYi0rX5oMvwJMSCAXY2afqeTSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "3.1.2", + "@vitest/utils": "3.1.2", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest/node_modules/@vitest/pretty-format": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.1.2.tgz", + "integrity": "sha512-R0xAiHuWeDjTSB3kQ3OQpT8Rx3yhdOAIm/JM4axXxnG7Q/fS8XUwggv/A4xzbQA+drYRjzkMnpYnOGAc4oeq8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest/node_modules/@vitest/spy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.1.2.tgz", + "integrity": "sha512-OEc5fSXMws6sHVe4kOFyDSj/+4MSwst0ib4un0DlcYgQvRuYQ0+M2HyqGaauUMnjq87tmUaMNDxKQx7wNfVqPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^3.0.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest/node_modules/@vitest/utils": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.1.2.tgz", + "integrity": "sha512-5GGd0ytZ7BH3H6JTj9Kw7Prn1Nbg0wZVrIvou+UWxm54d+WoXXgAgjFJ8wn3LdagWLFSEfpPeyYrByZaGEZHLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.1.2", + "loupe": "^3.1.3", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest/node_modules/tinyrainbow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/vscode-extension-telemetry": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.7.tgz", @@ -27187,6 +27762,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", diff --git a/extensions/ql-vscode/package.json b/extensions/ql-vscode/package.json index 19466ef2f5b..b55ba00f192 100644 --- a/extensions/ql-vscode/package.json +++ b/extensions/ql-vscode/package.json @@ -1943,7 +1943,7 @@ "watch": "gulp watch", "test": "npm-run-all test:*", "test:unit": "cross-env TZ=UTC LANG=en-US jest --projects test/unit-tests", - "test:view": "jest --projects src/view", + "test:view": "vitest run --dir src/view", "test:vscode-integration": "npm-run-all test:vscode-integration:*", "test:vscode-integration:activated-extension": "jest --projects test/vscode-tests/activated-extension", "test:vscode-integration:no-workspace": "jest --projects test/vscode-tests/no-workspace", @@ -2055,6 +2055,8 @@ "@types/yauzl": "^2.10.3", "@typescript-eslint/eslint-plugin": "^8.30.1", "@typescript-eslint/parser": "^8.30.1", + "@vitejs/plugin-react": "^4.4.1", + "@vitest/browser": "^3.1.2", "@vscode/test-electron": "^2.3.9", "@vscode/vsce": "^3.2.1", "ansi-colors": "^4.1.1", @@ -2100,7 +2102,8 @@ "typescript": "^5.6.2", "typescript-plugin-css-modules": "^5.1.0", "vite": "^6.2.6", - "vite-node": "^3.0.7" + "vite-node": "^3.0.7", + "vitest": "^3.1.2" }, "lint-staged": { "./**/*.{json,css,scss}": [ diff --git a/extensions/ql-vscode/src/view/common/SuggestBox/__tests__/SuggestBox.test.tsx b/extensions/ql-vscode/src/view/common/SuggestBox/__tests__/SuggestBox.test.tsx index e7db75d63ba..2e9d3f64928 100644 --- a/extensions/ql-vscode/src/view/common/SuggestBox/__tests__/SuggestBox.test.tsx +++ b/extensions/ql-vscode/src/view/common/SuggestBox/__tests__/SuggestBox.test.tsx @@ -77,8 +77,8 @@ const options: TestOption[] = [ ]; describe("SuggestBox", () => { - const onChange = jest.fn(); - const parseValueToTokens = jest.fn(); + const onChange = vi.fn(); + const parseValueToTokens = vi.fn(); const render = (props?: Partial<SuggestBoxProps<TestOption>>) => reactRender( <SuggestBox diff --git a/extensions/ql-vscode/src/view/common/SuggestBox/__tests__/useEffectEvent.test.ts b/extensions/ql-vscode/src/view/common/SuggestBox/__tests__/useEffectEvent.test.ts index 7f050d8b3ce..f7c82d3cb8e 100644 --- a/extensions/ql-vscode/src/view/common/SuggestBox/__tests__/useEffectEvent.test.ts +++ b/extensions/ql-vscode/src/view/common/SuggestBox/__tests__/useEffectEvent.test.ts @@ -3,8 +3,8 @@ import { useEffectEvent } from "../useEffectEvent"; describe("useEffectEvent", () => { it("does not change reference when changing the callback function", () => { - const callback1 = jest.fn(); - const callback2 = jest.fn(); + const callback1 = vi.fn(); + const callback2 = vi.fn(); const { result, rerender } = renderHook( (callback) => useEffectEvent(callback), diff --git a/extensions/ql-vscode/src/view/common/SuggestBox/__tests__/useOpenKey.test.ts b/extensions/ql-vscode/src/view/common/SuggestBox/__tests__/useOpenKey.test.ts index 93a581603a9..702078abf6b 100644 --- a/extensions/ql-vscode/src/view/common/SuggestBox/__tests__/useOpenKey.test.ts +++ b/extensions/ql-vscode/src/view/common/SuggestBox/__tests__/useOpenKey.test.ts @@ -5,7 +5,7 @@ import { mockedObject } from "../../../../../test/mocked-object"; import { useOpenKey } from "../useOpenKey"; describe("useOpenKey", () => { - const onOpenChange = jest.fn(); + const onOpenChange = vi.fn(); beforeEach(() => { onOpenChange.mockReset(); @@ -41,7 +41,7 @@ describe("useOpenKey", () => { ctrlKey = false, metaKey = false, shiftKey = false, - preventDefault = jest.fn(), + preventDefault = vi.fn(), }: Partial<KeyboardEvent>) => mockedObject<KeyboardEvent>({ key, @@ -183,7 +183,7 @@ describe("useOpenKey", () => { rerender( mockedObject<FloatingContext>({ open: true, - onOpenChange: jest.fn(), + onOpenChange: vi.fn(), }), ); diff --git a/extensions/ql-vscode/src/view/jest-environment-jsdom.ts b/extensions/ql-vscode/src/view/jest-environment-jsdom.ts deleted file mode 100644 index a43586ddbd3..00000000000 --- a/extensions/ql-vscode/src/view/jest-environment-jsdom.ts +++ /dev/null @@ -1,15 +0,0 @@ -// eslint-disable-next-line import/no-namespace -- We need a type of JSDOM so we can't use named imports. -import * as JSDOM from "jsdom"; -import type { - EnvironmentContext, - JestEnvironmentConfig, -} from "@jest/environment"; -import BaseEnv from "@jest/environment-jsdom-abstract"; - -export default class JSDOMEnvironment extends BaseEnv { - constructor(config: JestEnvironmentConfig, context: EnvironmentContext) { - super(config, context, JSDOM); - } -} - -export const TestEnvironment = JSDOMEnvironment; diff --git a/extensions/ql-vscode/src/view/jest.config.ts b/extensions/ql-vscode/src/view/jest.config.ts deleted file mode 100644 index c197b277e62..00000000000 --- a/extensions/ql-vscode/src/view/jest.config.ts +++ /dev/null @@ -1,203 +0,0 @@ -import type { Config } from "jest"; -import { transformIgnorePatterns } from "../../test/jest-config"; - -/* - * For a detailed explanation regarding each configuration property and type check, visit: - * https://jestjs.io/docs/configuration - */ - -const config: Config = { - // All imported modules in your tests should be mocked automatically - // automock: false, - - // Stop running tests after `n` failures - // bail: 0, - - // The directory where Jest should store its cached dependency information - // cacheDirectory: "/private/var/folders/6m/1394pht172qgd7dmw1fwjk100000gn/T/jest_dx", - - // Automatically clear mock calls, instances, contexts and results before every test - // clearMocks: true, - - // Indicates whether the coverage information should be collected while executing the test - // collectCoverage: false, - - // An array of glob patterns indicating a set of files for which coverage information should be collected - // collectCoverageFrom: undefined, - - // The directory where Jest should output its coverage files - // coverageDirectory: undefined, - - // An array of regexp pattern strings used to skip coverage collection - // coveragePathIgnorePatterns: [ - // "/node_modules/" - // ], - - // Indicates which provider should be used to instrument code for coverage - coverageProvider: "v8", - - // A list of reporter names that Jest uses when writing coverage reports - // coverageReporters: [ - // "json", - // "text", - // "lcov", - // "clover" - // ], - - // An object that configures minimum threshold enforcement for coverage results - // coverageThreshold: undefined, - - // A path to a custom dependency extractor - // dependencyExtractor: undefined, - - // Make calling deprecated APIs throw helpful error messages - // errorOnDeprecated: false, - - // The default configuration for fake timers - // fakeTimers: { - // "enableGlobally": false - // }, - - // Force coverage collection from ignored files using an array of glob patterns - // forceCoverageMatch: [], - - // A path to a module which exports an async function that is triggered once before all test suites - // globalSetup: undefined, - - // A path to a module which exports an async function that is triggered once after all test suites - // globalTeardown: undefined, - - // A set of global variables that need to be available in all test environments - // globals: {}, - - // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers. - // maxWorkers: "50%", - - // An array of directory names to be searched recursively up from the requiring module's location - // moduleDirectories: [ - // "node_modules" - // ], - - // An array of file extensions your modules use - moduleFileExtensions: ["js", "mjs", "cjs", "jsx", "ts", "tsx", "json"], - - // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module - moduleNameMapper: { - "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": - "<rootDir>/../../test/__mocks__/fileMock.ts", - "\\.(css|less)$": "<rootDir>/../../test/__mocks__/styleMock.ts", - }, - - // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader - // modulePathIgnorePatterns: [], - - // Activates notifications for test results - // notify: false, - - // An enum that specifies notification mode. Requires { notify: true } - // notifyMode: "failure-change", - - // A preset that is used as a base for Jest's configuration - preset: "ts-jest", - - // Run tests from one or more projects - // projects: undefined, - - // Use this configuration option to add custom reporters to Jest - // reporters: undefined, - - // Automatically reset mock state before every test - // resetMocks: false, - - // Reset the module registry before running each individual test - // resetModules: false, - - // A path to a custom resolver - // resolver: undefined, - - // Automatically restore mock state and implementation before every test - // restoreMocks: false, - - // The root directory that Jest should scan for tests and modules within - // rootDir: undefined, - - // A list of paths to directories that Jest should use to search for files in - // roots: [ - // "<rootDir>" - // ], - - // Allows you to use a custom runner instead of Jest's default test runner - // runner: "jest-runner", - - // The paths to modules that run some code to configure or set up the testing environment before each test - // setupFiles: [], - - // A list of paths to modules that run some code to configure or set up the testing framework before each test - setupFilesAfterEnv: ["<rootDir>/jest.setup.ts"], - - // The number of seconds after which a test is considered as slow and reported as such in the results. - // slowTestThreshold: 5, - - // A list of paths to snapshot serializer modules Jest should use for snapshot testing - // snapshotSerializers: [], - - // The test environment that will be used for testing - testEnvironment: "<rootDir>/jest-environment-jsdom.ts", - - // Options that will be passed to the testEnvironment - // testEnvironmentOptions: {}, - - // Adds a location field to test results - // testLocationInResults: false, - - // The glob patterns Jest uses to detect test files - testMatch: ["**/__tests__/**/*.[jt]s?(x)"], - - // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped - // testPathIgnorePatterns: [ - // "/node_modules/" - // ], - - // The regexp pattern or array of patterns that Jest uses to detect test files - // testRegex: [], - - // This option allows the use of a custom results processor - // testResultsProcessor: undefined, - - // This option allows use of a custom test runner - // testRunner: "jest-circus/runner", - - // A map from regular expressions to paths to transformers - transform: { - "^.+\\.tsx?$": [ - "ts-jest", - { - tsconfig: "<rootDir>/tsconfig.spec.json", - }, - ], - node_modules: [ - "babel-jest", - { - presets: ["@babel/preset-env"], - plugins: ["@babel/plugin-transform-modules-commonjs"], - }, - ], - }, - - // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation - transformIgnorePatterns, - - // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them - // unmockedModulePathPatterns: undefined, - - // Indicates whether each individual test should be reported during the run - // verbose: undefined, - - // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode - // watchPathIgnorePatterns: [], - - // Whether to use watchman for file crawling - // watchman: true, -}; - -export default config; diff --git a/extensions/ql-vscode/src/view/jest.setup.ts b/extensions/ql-vscode/src/view/jest.setup.ts deleted file mode 100644 index 31dc6657d40..00000000000 --- a/extensions/ql-vscode/src/view/jest.setup.ts +++ /dev/null @@ -1,41 +0,0 @@ -import "@testing-library/jest-dom"; - -// https://jestjs.io/docs/26.x/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom -Object.defineProperty(window, "matchMedia", { - writable: true, - value: jest.fn().mockImplementation((query) => ({ - matches: false, - media: query, - onchange: null, - addListener: jest.fn(), // deprecated - removeListener: jest.fn(), // deprecated - addEventListener: jest.fn(), - removeEventListener: jest.fn(), - dispatchEvent: jest.fn(), - })), -}); - -// Used by Primer React -window.CSS.supports = jest.fn().mockResolvedValue(false); - -// Functions that are not implemented in jsdom -window.CSSStyleSheet.prototype.replaceSync = jest - .fn() - .mockReturnValue(undefined); -window.ElementInternals.prototype.setFormValue = jest - .fn() - .mockReturnValue(undefined); -window.ElementInternals.prototype.setValidity = jest - .fn() - .mockReturnValue(undefined); -window.HTMLSlotElement.prototype.assignedElements = jest - .fn() - .mockReturnValue([]); - -// Store this on the window so we can mock it -window.vsCodeApi = { - postMessage: jest.fn(), - setState: jest.fn(), -}; - -window.acquireVsCodeApi = () => window.vsCodeApi; diff --git a/extensions/ql-vscode/src/view/method-modeling/__tests__/MethodModeling.spec.tsx b/extensions/ql-vscode/src/view/method-modeling/__tests__/MethodModeling.spec.tsx index 9a6496aea20..705c72796a8 100644 --- a/extensions/ql-vscode/src/view/method-modeling/__tests__/MethodModeling.spec.tsx +++ b/extensions/ql-vscode/src/view/method-modeling/__tests__/MethodModeling.spec.tsx @@ -13,7 +13,7 @@ describe(MethodModeling.name, () => { it("renders method modeling panel", () => { const method = createMethod(); const modeledMethod = createSinkModeledMethod(); - const onChange = jest.fn(); + const onChange = vi.fn(); render({ language: QueryLanguage.Java, diff --git a/extensions/ql-vscode/src/view/method-modeling/__tests__/MethodModelingInputs.spec.tsx b/extensions/ql-vscode/src/view/method-modeling/__tests__/MethodModelingInputs.spec.tsx index 0734a7064e3..4666583b247 100644 --- a/extensions/ql-vscode/src/view/method-modeling/__tests__/MethodModelingInputs.spec.tsx +++ b/extensions/ql-vscode/src/view/method-modeling/__tests__/MethodModelingInputs.spec.tsx @@ -19,7 +19,7 @@ describe(MethodModelingInputs.name, () => { const method = createMethod(); const modeledMethod = createSinkModeledMethod(); const modelConfig = defaultModelConfig; - const onChange = jest.fn(); + const onChange = vi.fn(); it("renders the method modeling inputs", () => { render({ diff --git a/extensions/ql-vscode/src/view/method-modeling/__tests__/MultipleModeledMethodsPanel.spec.tsx b/extensions/ql-vscode/src/view/method-modeling/__tests__/MultipleModeledMethodsPanel.spec.tsx index 27372287bfc..2c1846878c9 100644 --- a/extensions/ql-vscode/src/view/method-modeling/__tests__/MultipleModeledMethodsPanel.spec.tsx +++ b/extensions/ql-vscode/src/view/method-modeling/__tests__/MultipleModeledMethodsPanel.spec.tsx @@ -15,7 +15,7 @@ import { defaultModelConfig } from "../../../model-editor/languages"; describe(MultipleModeledMethodsPanel.name, () => { const language = QueryLanguage.Java; const method = createMethod(); - const onChange = jest.fn<void, [string, ModeledMethod[]]>(); + const onChange = vi.fn<void, [string, ModeledMethod[]]>(); const modelConfig = defaultModelConfig; const baseProps = { diff --git a/extensions/ql-vscode/src/view/model-editor/__tests__/LibraryRow.spec.tsx b/extensions/ql-vscode/src/view/model-editor/__tests__/LibraryRow.spec.tsx index 661c9f214c5..1d9fc1d36cc 100644 --- a/extensions/ql-vscode/src/view/model-editor/__tests__/LibraryRow.spec.tsx +++ b/extensions/ql-vscode/src/view/model-editor/__tests__/LibraryRow.spec.tsx @@ -7,10 +7,10 @@ import { createMockModelEditorViewState } from "../../../../test/factories/model describe(LibraryRow.name, () => { const method = createMethod(); - const onChange = jest.fn(); - const onMethodClick = jest.fn(); - const onSaveModelClick = jest.fn(); - const onModelDependencyClick = jest.fn(); + const onChange = vi.fn(); + const onMethodClick = vi.fn(); + const onSaveModelClick = vi.fn(); + const onModelDependencyClick = vi.fn(); const viewState = createMockModelEditorViewState(); @@ -40,7 +40,7 @@ describe(LibraryRow.name, () => { onChange={onChange} onMethodClick={onMethodClick} onSaveModelClick={onSaveModelClick} - onGenerateFromSourceClick={jest.fn()} + onGenerateFromSourceClick={vi.fn()} onModelDependencyClick={onModelDependencyClick} {...props} />, diff --git a/extensions/ql-vscode/src/view/model-editor/__tests__/MethodRow.spec.tsx b/extensions/ql-vscode/src/view/model-editor/__tests__/MethodRow.spec.tsx index 6ce364b4393..4025e5e2937 100644 --- a/extensions/ql-vscode/src/view/model-editor/__tests__/MethodRow.spec.tsx +++ b/extensions/ql-vscode/src/view/model-editor/__tests__/MethodRow.spec.tsx @@ -29,8 +29,8 @@ describe(MethodRow.name, () => { kind: "taint", provenance: "manual", }; - const onChange = jest.fn(); - const onMethodClick = jest.fn(); + const onChange = vi.fn(); + const onMethodClick = vi.fn(); const viewState = createMockModelEditorViewState(); diff --git a/extensions/ql-vscode/src/view/model-editor/__tests__/ModelEvaluation.spec.tsx b/extensions/ql-vscode/src/view/model-editor/__tests__/ModelEvaluation.spec.tsx index 150ace05b53..adb3808744b 100644 --- a/extensions/ql-vscode/src/view/model-editor/__tests__/ModelEvaluation.spec.tsx +++ b/extensions/ql-vscode/src/view/model-editor/__tests__/ModelEvaluation.spec.tsx @@ -19,9 +19,9 @@ describe(ModelEvaluation.name, () => { viewState={createMockModelEditorViewState({ showEvaluationUi: true })} modeledMethods={modeledMethodsMap} modifiedSignatures={new Set()} - onStartEvaluation={jest.fn()} - onStopEvaluation={jest.fn()} - openModelAlertsView={jest.fn()} + onStartEvaluation={vi.fn()} + onStopEvaluation={vi.fn()} + openModelAlertsView={vi.fn()} evaluationRun={undefined} {...props} />, diff --git a/extensions/ql-vscode/src/view/model-editor/__tests__/ModelKindDropdown.spec.tsx b/extensions/ql-vscode/src/view/model-editor/__tests__/ModelKindDropdown.spec.tsx index 22d4a3a65c7..7869f04bf38 100644 --- a/extensions/ql-vscode/src/view/model-editor/__tests__/ModelKindDropdown.spec.tsx +++ b/extensions/ql-vscode/src/view/model-editor/__tests__/ModelKindDropdown.spec.tsx @@ -9,7 +9,7 @@ import { import { QueryLanguage } from "../../../common/query-language"; describe(ModelKindDropdown.name, () => { - const onChange = jest.fn(); + const onChange = vi.fn(); beforeEach(() => { onChange.mockReset(); diff --git a/extensions/ql-vscode/src/view/model-editor/__tests__/ModelTypeDropdown.spec.tsx b/extensions/ql-vscode/src/view/model-editor/__tests__/ModelTypeDropdown.spec.tsx index f5ed858f3c1..7fe77bd6874 100644 --- a/extensions/ql-vscode/src/view/model-editor/__tests__/ModelTypeDropdown.spec.tsx +++ b/extensions/ql-vscode/src/view/model-editor/__tests__/ModelTypeDropdown.spec.tsx @@ -7,7 +7,7 @@ import { createMethod } from "../../../../test/factories/model-editor/method-fac import { defaultModelConfig } from "../../../model-editor/languages"; describe(ModelTypeDropdown.name, () => { - const onChange = jest.fn(); + const onChange = vi.fn(); beforeEach(() => { onChange.mockReset(); diff --git a/extensions/ql-vscode/src/view/model-editor/__tests__/ModeledMethodDataGrid.spec.tsx b/extensions/ql-vscode/src/view/model-editor/__tests__/ModeledMethodDataGrid.spec.tsx index 7a3645cca8f..9fdec40e2d9 100644 --- a/extensions/ql-vscode/src/view/model-editor/__tests__/ModeledMethodDataGrid.spec.tsx +++ b/extensions/ql-vscode/src/view/model-editor/__tests__/ModeledMethodDataGrid.spec.tsx @@ -35,8 +35,8 @@ describe(ModeledMethodDataGrid.name, () => { methodParameters: "()", supported: true, }); - const onChange = jest.fn(); - const onMethodClick = jest.fn(); + const onChange = vi.fn(); + const onMethodClick = vi.fn(); const viewState = createMockModelEditorViewState(); diff --git a/extensions/ql-vscode/src/view/model-editor/__tests__/ModeledMethodsList.spec.tsx b/extensions/ql-vscode/src/view/model-editor/__tests__/ModeledMethodsList.spec.tsx index 6bf0078a3b7..8a7ad236d1b 100644 --- a/extensions/ql-vscode/src/view/model-editor/__tests__/ModeledMethodsList.spec.tsx +++ b/extensions/ql-vscode/src/view/model-editor/__tests__/ModeledMethodsList.spec.tsx @@ -32,10 +32,10 @@ describe(ModeledMethodsList.name, () => { methodName: "println", methodParameters: "(String)", }); - const onChange = jest.fn(); - const onMethodClick = jest.fn(); - const onSaveModelClick = jest.fn(); - const onModelDependencyClick = jest.fn(); + const onChange = vi.fn(); + const onMethodClick = vi.fn(); + const onSaveModelClick = vi.fn(); + const onModelDependencyClick = vi.fn(); const viewState = createMockModelEditorViewState(); @@ -63,7 +63,7 @@ describe(ModeledMethodsList.name, () => { onChange={onChange} onMethodClick={onMethodClick} onSaveModelClick={onSaveModelClick} - onGenerateFromSourceClick={jest.fn()} + onGenerateFromSourceClick={vi.fn()} onModelDependencyClick={onModelDependencyClick} {...props} />, diff --git a/extensions/ql-vscode/src/view/model-editor/__tests__/ModelingStatusIndicator.spec.tsx b/extensions/ql-vscode/src/view/model-editor/__tests__/ModelingStatusIndicator.spec.tsx index 9b47af78072..910b62425e7 100644 --- a/extensions/ql-vscode/src/view/model-editor/__tests__/ModelingStatusIndicator.spec.tsx +++ b/extensions/ql-vscode/src/view/model-editor/__tests__/ModelingStatusIndicator.spec.tsx @@ -17,6 +17,6 @@ describe(ModelingStatusIndicator.name, () => { }, ] as const)("renders %s status indicator", ({ status, text }) => { render(<ModelingStatusIndicator status={status} />); - expect(screen.getByLabelText(text)).toBeVisible(); + expect(screen.getByLabelText(text)).toBeInTheDocument(); }); }); diff --git a/extensions/ql-vscode/src/view/results/__tests__/AlertTablePathRow.spec.tsx b/extensions/ql-vscode/src/view/results/__tests__/AlertTablePathRow.spec.tsx index ada710bee85..2e4add47eb4 100644 --- a/extensions/ql-vscode/src/view/results/__tests__/AlertTablePathRow.spec.tsx +++ b/extensions/ql-vscode/src/view/results/__tests__/AlertTablePathRow.spec.tsx @@ -23,8 +23,8 @@ describe(AlertTablePathRow.name, () => { databaseUri={"dbUri"} sourceLocationPrefix="src" userSettings={{ shouldShowProvenance: false }} - updateSelectionCallback={jest.fn()} - toggleExpanded={jest.fn()} + updateSelectionCallback={vi.fn()} + toggleExpanded={vi.fn()} {...props} />, ); diff --git a/extensions/ql-vscode/src/view/results/__tests__/AlertTableResultRow.spec.tsx b/extensions/ql-vscode/src/view/results/__tests__/AlertTableResultRow.spec.tsx index 0aa7279ae72..e2c0d75d4c2 100644 --- a/extensions/ql-vscode/src/view/results/__tests__/AlertTableResultRow.spec.tsx +++ b/extensions/ql-vscode/src/view/results/__tests__/AlertTableResultRow.spec.tsx @@ -18,8 +18,8 @@ describe(AlertTableResultRow.name, () => { databaseUri={"dbUri"} sourceLocationPrefix="src" userSettings={{ shouldShowProvenance: false }} - updateSelectionCallback={jest.fn()} - toggleExpanded={jest.fn()} + updateSelectionCallback={vi.fn()} + toggleExpanded={vi.fn()} {...props} />, ); diff --git a/extensions/ql-vscode/src/view/results/__tests__/results.spec.tsx b/extensions/ql-vscode/src/view/results/__tests__/results.spec.tsx index 0116368cbf7..12b09cd2c2d 100644 --- a/extensions/ql-vscode/src/view/results/__tests__/results.spec.tsx +++ b/extensions/ql-vscode/src/view/results/__tests__/results.spec.tsx @@ -5,14 +5,11 @@ import type { IntoResultsViewMsg, } from "../../../common/interface-types"; import { SortDirection } from "../../../common/interface-types"; -import { readJSONSync } from "fs-extra"; -import { resolve } from "path"; import { postMessage } from "../../common/post-message"; import { ColumnKind } from "../../../common/raw-result-types"; -const exampleSarif = readJSONSync( - resolve(__dirname, "../../../../test/data/sarif/validSarif.sarif"), -); +// eslint-disable-next-line import/no-namespace +import * as exampleSarif from "./validSarif.sarif.json"; describe(ResultsApp.name, () => { const render = () => reactRender(<ResultsApp />); diff --git a/extensions/ql-vscode/src/view/results/__tests__/validSarif.sarif.json b/extensions/ql-vscode/src/view/results/__tests__/validSarif.sarif.json new file mode 100644 index 00000000000..2d2fa5cacfa --- /dev/null +++ b/extensions/ql-vscode/src/view/results/__tests__/validSarif.sarif.json @@ -0,0 +1,57 @@ +{ + "version": "2.1.0", + "$schema": "http://json.schemastore.org/sarif-2.1.0-rtm.4", + "runs": [ + { + "tool": { + "driver": { + "name": "ESLint", + "informationUri": "https://eslint.org", + "rules": [ + { + "id": "no-unused-vars", + "shortDescription": { + "text": "disallow unused variables" + }, + "helpUri": "https://eslint.org/docs/rules/no-unused-vars", + "properties": { + "category": "Variables" + } + } + ] + } + }, + "artifacts": [ + { + "location": { + "uri": "file:///C:/dev/sarif/sarif-tutorials/samples/Introduction/simple-example.js" + } + } + ], + "results": [ + { + "level": "error", + "message": { + "text": "'x' is assigned a value but never used." + }, + "locations": [ + { + "physicalLocation": { + "artifactLocation": { + "uri": "file:///C:/dev/sarif/sarif-tutorials/samples/Introduction/simple-example.js", + "index": 0 + }, + "region": { + "startLine": 1, + "startColumn": 5 + } + } + } + ], + "ruleId": "no-unused-vars", + "ruleIndex": 0 + } + ] + } + ] +} \ No newline at end of file diff --git a/extensions/ql-vscode/src/view/tsconfig.json b/extensions/ql-vscode/src/view/tsconfig.json index d094c039d78..4551643a9c9 100644 --- a/extensions/ql-vscode/src/view/tsconfig.json +++ b/extensions/ql-vscode/src/view/tsconfig.json @@ -19,7 +19,8 @@ { "name": "typescript-plugin-css-modules" } - ] + ], + "types": ["vitest/globals"] }, "exclude": ["node_modules"] } diff --git a/extensions/ql-vscode/src/view/tsconfig.spec.json b/extensions/ql-vscode/src/view/tsconfig.spec.json deleted file mode 100644 index 96fce8c40fa..00000000000 --- a/extensions/ql-vscode/src/view/tsconfig.spec.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "module": "commonjs" - }, - "exclude": [] -} diff --git a/extensions/ql-vscode/src/view/variant-analysis/__tests__/QueryDetails.spec.tsx b/extensions/ql-vscode/src/view/variant-analysis/__tests__/QueryDetails.spec.tsx index e50ca9ef567..007cb5f1e3a 100644 --- a/extensions/ql-vscode/src/view/variant-analysis/__tests__/QueryDetails.spec.tsx +++ b/extensions/ql-vscode/src/view/variant-analysis/__tests__/QueryDetails.spec.tsx @@ -4,11 +4,11 @@ import type { QueryDetailsProps } from "../QueryDetails"; import { QueryDetails } from "../QueryDetails"; describe(QueryDetails.name, () => { - const onOpenQueryFileClick = jest.fn(); - const onViewQueryTextClick = jest.fn(); - const onStopQueryClick = jest.fn(); - const onCopyRepositoryListClick = jest.fn(); - const onExportResultsClick = jest.fn(); + const onOpenQueryFileClick = vi.fn(); + const onViewQueryTextClick = vi.fn(); + const onStopQueryClick = vi.fn(); + const onCopyRepositoryListClick = vi.fn(); + const onExportResultsClick = vi.fn(); afterEach(() => { onOpenQueryFileClick.mockReset(); diff --git a/extensions/ql-vscode/src/view/variant-analysis/__tests__/VariantAnalysisActions.spec.tsx b/extensions/ql-vscode/src/view/variant-analysis/__tests__/VariantAnalysisActions.spec.tsx index ff0a99099a3..1ddbbc7bab0 100644 --- a/extensions/ql-vscode/src/view/variant-analysis/__tests__/VariantAnalysisActions.spec.tsx +++ b/extensions/ql-vscode/src/view/variant-analysis/__tests__/VariantAnalysisActions.spec.tsx @@ -5,9 +5,9 @@ import type { VariantAnalysisActionsProps } from "../VariantAnalysisActions"; import { VariantAnalysisActions } from "../VariantAnalysisActions"; describe(VariantAnalysisActions.name, () => { - const onStopQueryClick = jest.fn(); - const onCopyRepositoryListClick = jest.fn(); - const onExportResultsClick = jest.fn(); + const onStopQueryClick = vi.fn(); + const onCopyRepositoryListClick = vi.fn(); + const onExportResultsClick = vi.fn(); afterEach(() => { onStopQueryClick.mockReset(); diff --git a/extensions/ql-vscode/src/view/variant-analysis/__tests__/VariantAnalysisOutcomePanels.spec.tsx b/extensions/ql-vscode/src/view/variant-analysis/__tests__/VariantAnalysisOutcomePanels.spec.tsx index 0ac4ab23df3..c3b3e9cb1d1 100644 --- a/extensions/ql-vscode/src/view/variant-analysis/__tests__/VariantAnalysisOutcomePanels.spec.tsx +++ b/extensions/ql-vscode/src/view/variant-analysis/__tests__/VariantAnalysisOutcomePanels.spec.tsx @@ -83,7 +83,7 @@ describe(VariantAnalysisOutcomePanels.name, () => { ...variantAnalysis, }} filterSortState={defaultFilterSortState} - setFilterSortState={jest.fn()} + setFilterSortState={vi.fn()} {...props} />, ); diff --git a/extensions/ql-vscode/src/view/variant-analysis/__tests__/VariantAnalysisStats.spec.tsx b/extensions/ql-vscode/src/view/variant-analysis/__tests__/VariantAnalysisStats.spec.tsx index e3a9f3a4abf..a6e5383231a 100644 --- a/extensions/ql-vscode/src/view/variant-analysis/__tests__/VariantAnalysisStats.spec.tsx +++ b/extensions/ql-vscode/src/view/variant-analysis/__tests__/VariantAnalysisStats.spec.tsx @@ -5,7 +5,7 @@ import { VariantAnalysisStats } from "../VariantAnalysisStats"; import { userEvent } from "@testing-library/user-event"; describe(VariantAnalysisStats.name, () => { - const onViewLogsClick = jest.fn(); + const onViewLogsClick = vi.fn(); afterEach(() => { onViewLogsClick.mockReset(); diff --git a/extensions/ql-vscode/src/view/vitest.config.ts b/extensions/ql-vscode/src/view/vitest.config.ts new file mode 100644 index 00000000000..99577384f0b --- /dev/null +++ b/extensions/ql-vscode/src/view/vitest.config.ts @@ -0,0 +1,15 @@ +import { defineConfig } from "vitest/config"; +import react from "@vitejs/plugin-react"; + +export default defineConfig({ + plugins: [react()], + test: { + globals: true, + browser: { + enabled: true, + provider: "playwright", + instances: [{ browser: "chromium" }], + }, + setupFiles: "./vitest.setup.ts", + }, +}); diff --git a/extensions/ql-vscode/src/view/vitest.setup.ts b/extensions/ql-vscode/src/view/vitest.setup.ts new file mode 100644 index 00000000000..60f5858bf81 --- /dev/null +++ b/extensions/ql-vscode/src/view/vitest.setup.ts @@ -0,0 +1,7 @@ +// Store this on the window so we can mock it +window.vsCodeApi = { + postMessage: vi.fn(), + setState: vi.fn(), +}; + +window.acquireVsCodeApi = () => window.vsCodeApi; diff --git a/extensions/ql-vscode/vitest.workspace.ts b/extensions/ql-vscode/vitest.workspace.ts new file mode 100644 index 00000000000..d429a40c5b4 --- /dev/null +++ b/extensions/ql-vscode/vitest.workspace.ts @@ -0,0 +1,3 @@ +import { defineWorkspace } from "vitest/config"; + +export default defineWorkspace(["src/view/vitest.config.ts"]);