From e467f6bd3bf42d82fbd66714c03564c516a1606a Mon Sep 17 00:00:00 2001 From: Tobias Ortmayr Date: Mon, 22 Jun 2026 17:25:27 +0200 Subject: [PATCH 1/3] GLSP-1635: Migrate test framework from Mocha to Vitest - Replace the Mocha/Chai/nyc/Sinon setup with Vitest: consume the @eclipse-glsp/dev next packages, drop .mocharc/.nycrc, and point all test scripts at `vitest run` - Drive the whole monorepo from a single flat Vitest config at the repo root instead of per-package configs, yielding one merged coverage report - Type-check specs separately via composite tsconfig.test.json projects, since Vitest only transpiles; wire them through a `compile:test` step so `pnpm test` type-checks specs before running them - Import the test API explicitly in every spec (no ambient globals) and load reflect-metadata once via root setup files for the DI specs - Replace the custom expectToThrowAsync helper with Vitest's native rejects.toThrow() / toThrow() matchers and drop the obsolete test-util module - Keep test-only code out of the published packages by excluding specs and test/ helper directories from both the build and the packed files - Switch CI and contributor docs to Vitest: run `pnpm test`, and remove the now-obsolete test-report step and the redundant per-package and :ci test scripts - Clean up leftover tooling artifacts: ignore *.tsbuildinfo so the new per-config build-info is covered, and drop the obsolete nyc/CTRF ignores and clean targets - Run the workflow-standalone example's TS scripts via Node's native type stripping instead of ts-node, which the Mocha toolchain used to provide transitively: convert the scripts to ESM (.mts), drop the ts-node dependency, and raise the Node engine floor to 22.18 where stripping is unflagged Also: - Fix indentation in the local /fix skill doc Part of: eclipse-glsp/glsp#1635 --- .claude/skills/fix/SKILL.md | 4 +- .github/workflows/ci.yml | 11 +- .gitignore | 4 +- .mocharc | 11 - .nycrc | 3 - .vscode/launch.json | 44 +- AGENTS.md | 2 +- CLAUDE.md | 2 +- examples/workflow-standalone/package.json | 16 +- ...download-server.ts => download-server.mts} | 7 +- ...t-node-server.ts => start-node-server.mts} | 2 +- .../scripts/{start.ts => start.mts} | 2 +- package.json | 14 +- packages/client/package.json | 10 +- .../client/src/base/action-dispatcher.spec.ts | 46 +- .../base/feedback/feedback-emitter.spec.ts | 34 +- .../src/base/model/glsp-model-source.ts | 2 +- .../model-initialization-constraint.spec.ts | 46 +- .../client/src/base/selection-service.spec.ts | 49 +- packages/client/src/default-modules.spec.ts | 20 +- .../features/bounds/freeform-layout.spec.ts | 42 +- .../src/features/bounds/hbox-layout.spec.ts | 93 +- .../src/features/bounds/vbox-layout.spec.ts | 93 +- .../point-position-updater.spec.ts | 44 +- .../src/features/grid/grid-snapper.spec.ts | 12 +- .../features/hints/type-hint-provider.spec.ts | 175 +- .../layout/layout-elements-action.spec.ts | 18 +- .../navigation-target-resolver.spec.ts | 23 +- .../sticky-manhattan-edge-router.spec.ts | 34 +- .../layouter-test-util.ts} | 5 +- .../marquee-behavior.spec.ts | 4 +- .../validation/marker-navigator.spec.ts | 49 +- packages/client/src/utils/gmodel-util.spec.ts | 16 +- packages/client/tsconfig.json | 4 +- packages/client/tsconfig.test.json | 10 + packages/protocol/package.json | 10 +- .../src/action-protocol/base-protocol.spec.ts | 84 +- .../client-notification.spec.ts | 52 +- .../src/action-protocol/clipboard.spec.ts | 38 +- .../src/action-protocol/contexts.spec.ts | 22 +- .../action-protocol/edge-modification.spec.ts | 22 +- .../action-protocol/element-creation.spec.ts | 36 +- .../src/action-protocol/element-hover.spec.ts | 22 +- .../element-navigation.spec.ts | 90 +- .../action-protocol/element-selection.spec.ts | 30 +- .../element-text-editing.spec.ts | 30 +- .../element-type-hints.spec.ts | 48 +- .../element-validation.spec.ts | 38 +- .../src/action-protocol/model-data.spec.ts | 50 +- .../action-protocol/model-edit-mode.spec.ts | 12 +- .../src/action-protocol/model-layout.spec.ts | 38 +- .../src/action-protocol/model-saving.spec.ts | 68 +- .../action-protocol/node-modification.spec.ts | 20 +- .../src/action-protocol/tool-palette.spec.ts | 22 +- .../src/action-protocol/undo-redo.spec.ts | 20 +- .../src/action-protocol/viewport.spec.ts | 40 +- .../base-glsp-client.spec.ts | 204 +- .../jsonrpc/base-jsonrpc-glsp-client.spec.ts | 230 +- .../src/di/container-configuration.spec.ts | 18 +- .../protocol/src/di/feature-module.spec.ts | 42 +- .../protocol/src/di/lazy-injector.spec.ts | 52 +- .../src/sprotty-geometry-bounds.spec.ts | 92 +- .../src/sprotty-geometry-dimension.spec.ts | 36 +- .../src/sprotty-geometry-point.spec.ts | 66 +- .../protocol/src/utils/array-util.spec.ts | 74 +- .../protocol/src/utils/disposable.spec.ts | 49 +- packages/protocol/src/utils/event.spec.ts | 25 +- .../protocol/src/utils/function-util.spec.ts | 69 +- .../src/utils/geometry-movement.spec.ts | 20 +- .../src/utils/geometry-vector.spec.ts | 46 +- packages/protocol/src/utils/test-util.ts | 52 - packages/protocol/src/utils/type-util.spec.ts | 110 +- packages/protocol/src/utils/uuid.spec.ts | 10 +- packages/protocol/tsconfig.json | 4 +- packages/protocol/tsconfig.test.json | 10 + pnpm-lock.yaml | 2230 +++++++---------- pnpm-workspace.yaml | 13 +- tsconfig.eslint.json | 2 +- tsconfig.json | 2 +- tsconfig.test.json | 13 + vite.config.ts | 29 + 81 files changed, 2407 insertions(+), 2834 deletions(-) delete mode 100644 .mocharc delete mode 100644 .nycrc rename examples/workflow-standalone/scripts/{download-server.ts => download-server.mts} (94%) rename examples/workflow-standalone/scripts/{start-node-server.ts => start-node-server.mts} (98%) rename examples/workflow-standalone/scripts/{start.ts => start.mts} (99%) rename packages/client/src/features/{bounds/layouter-test-util.spec.ts => test/layouter-test-util.ts} (96%) create mode 100644 packages/client/tsconfig.test.json delete mode 100644 packages/protocol/src/utils/test-util.ts create mode 100644 packages/protocol/tsconfig.test.json create mode 100644 tsconfig.test.json create mode 100644 vite.config.ts diff --git a/.claude/skills/fix/SKILL.md b/.claude/skills/fix/SKILL.md index 6ede9354..c3c487de 100644 --- a/.claude/skills/fix/SKILL.md +++ b/.claude/skills/fix/SKILL.md @@ -5,8 +5,8 @@ description: Run the fix-and-verify suite for the workspace (compile, auto-fix l Run the auto-fix and validation suite for the GLSP Client monorepo from the repository root. -1. Build first. This is a hard gate: if the build fails, stop immediately, report the build errors, and do not run any of the following steps. -The build must pass before anything else runs. +1. Build first. This is a hard gate: if the build fails, stop immediately, report the build errors, and do not run any of the following steps. + The build must pass before anything else runs. ```bash pnpm build diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9302c136..484c909f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,14 +44,7 @@ jobs: node-version: 22.x cache: pnpm - name: Test - run: pnpm test:ci - - name: Publish Test Report - uses: ctrf-io/github-test-reporter@0f299074936c32ccaab5be5230511f6b2b9080aa # v1.0.28 - with: - report-path: 'packages/*/ctrf/*.json' - summary-report: true - file-report: true - if: always() + run: pnpm test lint: name: Lint timeout-minutes: 60 @@ -83,7 +76,7 @@ jobs: node-version: 22.x cache: pnpm - name: Run Coverage Tests - run: pnpm test:coverage:ci + run: pnpm test:coverage - name: Upload Coverage Report uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: diff --git a/.gitignore b/.gitignore index e08ea5bc..9397acd6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ .idea/ -.nyc_output/ coverage node_modules/ @@ -16,10 +15,9 @@ examples/workflow-standalone/app/* *.jar !packages/client/src/lib -tsconfig.tsbuildinfo +*.tsbuildinfo eslint.xml report.xml -**/ctrf examples/workflow-standalone/server .claude/local.settings.json diff --git a/.mocharc b/.mocharc deleted file mode 100644 index 91f2321a..00000000 --- a/.mocharc +++ /dev/null @@ -1,11 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/mocharc", - "extends": "@eclipse-glsp/mocha-config", - "node-option": ["no-experimental-strip-types"], - "require": [ - "ts-node/register", - "tsconfig-paths/register", - "reflect-metadata/Reflect", - "ignore-styles" - ] -} diff --git a/.nycrc b/.nycrc deleted file mode 100644 index 98db690d..00000000 --- a/.nycrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "@eclipse-glsp/nyc-config" -} diff --git a/.vscode/launch.json b/.vscode/launch.json index 1fd46db8..6488c3ed 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,29 +5,23 @@ "type": "node", "request": "launch", "name": "Run current test", - "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", - "args": ["--config", "${workspaceRoot}/.mocharc", "--timeout", "0", "${file}"], + "autoAttachChildProcesses": true, + "skipFiles": ["/**", "**/node_modules/**"], + "program": "${workspaceFolder}/node_modules/vitest/vitest.mjs", + "args": ["run", "${relativeFile}"], + "smartStep": true, "console": "integratedTerminal", - "internalConsoleOptions": "neverOpen", - "env": { - "TS_NODE_PROJECT": "${workspaceFolder}/tsconfig.json" - } + "internalConsoleOptions": "neverOpen" }, { "type": "node", "request": "launch", "name": "Run tests", - "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", - "args": [ - "--config", - "${workspaceRoot}/.mocharc", - "--timeout", - "0", - "${workspaceFolder}/packages/client/src/**/*.spec.ts" - ], - "env": { - "TS_NODE_PROJECT": "${workspaceFolder}/tsconfig.json" - }, + "autoAttachChildProcesses": true, + "skipFiles": ["/**", "**/node_modules/**"], + "program": "${workspaceFolder}/node_modules/vitest/vitest.mjs", + "args": ["run", "packages/client/src"], + "smartStep": true, "console": "integratedTerminal", "internalConsoleOptions": "neverOpen" }, @@ -35,17 +29,11 @@ "type": "node", "request": "launch", "name": "Run tests (protocol)", - "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha", - "args": [ - "--config", - "${workspaceRoot}/.mocharc", - "--timeout", - "0", - "${workspaceFolder}/packages/protocol/src/**/*.spec.ts" - ], - "env": { - "TS_NODE_PROJECT": "${workspaceFolder}/tsconfig.json" - }, + "autoAttachChildProcesses": true, + "skipFiles": ["/**", "**/node_modules/**"], + "program": "${workspaceFolder}/node_modules/vitest/vitest.mjs", + "args": ["run", "packages/protocol/src"], + "smartStep": true, "console": "integratedTerminal", "internalConsoleOptions": "neverOpen" } diff --git a/AGENTS.md b/AGENTS.md index d76811bc..8e7aded1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -14,7 +14,7 @@ Eclipse GLSP Client monorepo. Provides the sprotty-based client framework for th ## Validation -- **Tests**: `pnpm test` (Mocha), single test: `pnpm test --grep 'test name'` +- **Tests**: `pnpm test` (Vitest), single test: `pnpm test -t 'test name'` ## Inter-Package Import Rules diff --git a/CLAUDE.md b/CLAUDE.md index ae32554b..e7bc36c2 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -12,7 +12,7 @@ Eclipse GLSP Client monorepo. Provides the sprotty-based client framework for th ## Validation -- **Tests**: `pnpm test` (Mocha), single test: `pnpm test --grep 'test name'` +- **Tests**: `pnpm test` (Vitest), single test: `pnpm test -t 'test name'` - After completing any code changes, always run the `/fix` skill before reporting completion. It auto-fixes lint/format/header issues and runs the tests; manually resolve anything it could not auto-fix (remaining lint errors, test failures) and re-run it. ## Commenting Style diff --git a/examples/workflow-standalone/package.json b/examples/workflow-standalone/package.json index a1a3448e..559bcdc5 100644 --- a/examples/workflow-standalone/package.json +++ b/examples/workflow-standalone/package.json @@ -25,17 +25,17 @@ "build": "pnpm compile && pnpm bundle", "build:browser": "pnpm compile && pnpm bundle:browser", "bundle": "node ./esbuild.js", - "bundle:browser": "ts-node ./scripts/download-server.ts --browser && node ./esbuild.js --browser", + "bundle:browser": "node ./scripts/download-server.mts --browser && node ./esbuild.js --browser", "clean": "rimraf lib *.tsbuildinfo app/bundle.js app/bundle.js.map app/bundle.css app/bundle.css.map app/wf-glsp-server-webworker.js app/wf-glsp-server-webworker.js.map app/*.ttf", "compile": "tsc -b", - "dev": "ts-node ./scripts/start.ts --dev", - "dev:browser": "ts-node ./scripts/start.ts --dev --browser", - "dev:mcp": "ts-node ./scripts/start.ts --dev --mcp", + "dev": "node ./scripts/start.mts --dev", + "dev:browser": "node ./scripts/start.mts --dev --browser", + "dev:mcp": "node ./scripts/start.mts --dev --mcp", "lint": "eslint ./src", - "start": "ts-node ./scripts/start.ts", - "start:browser": "ts-node ./scripts/start.ts --browser", - "start:mcp": "ts-node ./scripts/start.ts --mcp", - "start:server": "ts-node ./scripts/start-node-server.ts" + "start": "node ./scripts/start.mts", + "start:browser": "node ./scripts/start.mts --browser", + "start:mcp": "node ./scripts/start.mts --mcp", + "start:server": "node ./scripts/start-node-server.mts" }, "dependencies": { "@eclipse-glsp-examples/workflow-glsp": "workspace:*", diff --git a/examples/workflow-standalone/scripts/download-server.ts b/examples/workflow-standalone/scripts/download-server.mts similarity index 94% rename from examples/workflow-standalone/scripts/download-server.ts rename to examples/workflow-standalone/scripts/download-server.mts index a66316b4..ff40b948 100644 --- a/examples/workflow-standalone/scripts/download-server.ts +++ b/examples/workflow-standalone/scripts/download-server.mts @@ -17,9 +17,10 @@ import { execSync } from 'child_process'; import * as fs from 'fs'; import * as path from 'path'; import { extract } from 'tar'; -import * as packageJson from '../../../package.json'; +import { fileURLToPath } from 'url'; +import packageJson from '../../../package.json' with { type: 'json' }; -export const SERVER_DIR_PATH = path.resolve(__dirname, '..', 'server'); +export const SERVER_DIR_PATH = path.resolve(import.meta.dirname, '..', 'server'); const BUNDLES = { node: { npmPackage: '@eclipse-glsp-examples/workflow-server-bundled', stableName: 'wf-glsp-server-node.js' }, @@ -81,7 +82,7 @@ export function resolveVersion(): string { } // Direct invocation (e.g. prebundle:browser script) — skip when imported as a module by start.ts -if (require.main === module) { +if (process.argv[1] === fileURLToPath(import.meta.url)) { const bundle = process.argv.includes('--browser') ? BUNDLES.browser : BUNDLES.node; downloadServerBundle({ ...bundle, version: resolveVersion() }); } diff --git a/examples/workflow-standalone/scripts/start-node-server.ts b/examples/workflow-standalone/scripts/start-node-server.mts similarity index 98% rename from examples/workflow-standalone/scripts/start-node-server.ts rename to examples/workflow-standalone/scripts/start-node-server.mts index b9db0ce1..73d24209 100644 --- a/examples/workflow-standalone/scripts/start-node-server.ts +++ b/examples/workflow-standalone/scripts/start-node-server.mts @@ -15,7 +15,7 @@ ********************************************************************************/ import { execSync } from 'child_process'; import * as path from 'path'; -import { downloadServerBundle, resolveVersion, SERVER_DIR_PATH } from './download-server'; +import { downloadServerBundle, resolveVersion, SERVER_DIR_PATH } from './download-server.mts'; const NODE_SERVER_STABLE = 'wf-glsp-server-node.js'; diff --git a/examples/workflow-standalone/scripts/start.ts b/examples/workflow-standalone/scripts/start.mts similarity index 99% rename from examples/workflow-standalone/scripts/start.ts rename to examples/workflow-standalone/scripts/start.mts index 7794f93f..a1ce2db6 100644 --- a/examples/workflow-standalone/scripts/start.ts +++ b/examples/workflow-standalone/scripts/start.mts @@ -16,7 +16,7 @@ import concurrently from 'concurrently'; import * as fs from 'fs'; import * as path from 'path'; -import { downloadServerBundle, resolveVersion, SERVER_DIR_PATH } from './download-server'; +import { downloadServerBundle, resolveVersion, SERVER_DIR_PATH } from './download-server.mts'; const isBrowser = process.argv.includes('--browser'); const isDev = process.argv.includes('--dev'); diff --git a/package.json b/package.json index c065669c..5461fa61 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,9 @@ "bundle": "pnpm standalone bundle", "bundle:browser": "pnpm standalone bundle:browser", "check:all": "pnpm build && pnpm lint && pnpm format:check && pnpm headers:check && pnpm test", - "clean": "pnpm -r run clean && rimraf coverage .nyc_output", + "clean": "pnpm -r run clean && rimraf coverage *.tsbuildinfo", "compile": "tsc -b", + "compile:test": "pnpm compile && tsc -b tsconfig.test.json", "dev": "pnpm standalone dev", "dev:browser": "pnpm standalone dev:browser", "dev:mcp": "pnpm standalone dev:mcp", @@ -29,23 +30,20 @@ "start:browser": "pnpm standalone start:browser", "start:exampleServer": "pnpm standalone start:server", "start:mcp": "pnpm standalone start:mcp", - "test": "pnpm compile && pnpm -r --no-bail test", - "test:ci": "pnpm compile && pnpm -r --no-bail test:ci", - "test:coverage": "pnpm compile && pnpm -r test:coverage", - "test:coverage:ci": "glsp coverageReport", + "test": "pnpm compile:test && vitest run", + "test:coverage": "pnpm compile:test && vitest run --coverage", "upgrade:next": "glsp updateNext" }, "devDependencies": { "@eclipse-glsp/dev": "next", "@types/node": "22.x", "concurrently": "^9.2.1", - "mocha-ctrf-json-reporter": "^0.0.9", - "tsconfig-paths": "^4.2.0", + "reflect-metadata": "^0.2.2", "typescript": "^5.9.2" }, "packageManager": "pnpm@11.7.0", "engines": { - "node": ">=22", + "node": ">=22.18", "pnpm": ">=11" } } diff --git a/packages/client/package.json b/packages/client/package.json index 7bfc96bc..2ccdcc5b 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -33,17 +33,17 @@ "files": [ "lib", "src", - "css" + "css", + "!**/*.spec.ts", + "!**/*.spec.tsx", + "!**/test/**" ], "scripts": { "build": "tsc -b", - "clean": "rimraf lib *.tsbuildinfo coverage .nyc_output", + "clean": "rimraf lib *.tsbuildinfo coverage", "generate:index": "glsp generateIndex src -f -s", "lint": "eslint ./src", "prepublishOnly": "pnpm build", - "test": "mocha --config ../../.mocharc \"./src/**/*.spec.?(ts|tsx)\"", - "test:ci": "pnpm test --reporter mocha-ctrf-json-reporter", - "test:coverage": "nyc pnpm test", "watch": "tsc -w" }, "dependencies": { diff --git a/packages/client/src/base/action-dispatcher.spec.ts b/packages/client/src/base/action-dispatcher.spec.ts index a909db4e..acdef029 100644 --- a/packages/client/src/base/action-dispatcher.spec.ts +++ b/packages/client/src/base/action-dispatcher.spec.ts @@ -14,7 +14,7 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ import { ActionHandlerRegistry, Deferred, IActionHandler, RequestAction, ResponseAction, TYPES } from '@eclipse-glsp/sprotty'; -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { Container } from 'inversify'; /** Yields to the event loop long enough for pending microtasks (and already-queued timers) to run. */ @@ -59,13 +59,13 @@ describe('GLSPActionDispatcher', () => { testHandlerDelay = 15; const requestAction = { kind: 'request', requestId: '' }; const response = await actionDispatcher.requestUntil(requestAction, 150); - expect(response?.responseId).to.be.equal(requestAction.requestId); + expect(response?.responseId).toBe(requestAction.requestId); }); it('should resolve to `undefined` if no response dispatched within timeout & `rejectOnTimeout` flag is false', async () => { testHandlerDelay = 30; const requestAction = { kind: 'request', requestId: '' }; const response = await actionDispatcher.requestUntil(requestAction, 5); - expect(response).to.be.undefined; + expect(response).toBeUndefined(); }); it('should be rejected if no response dispatched within timeout & `rejectOnTimeout` flag is true', async () => { testHandlerDelay = 30; @@ -74,7 +74,7 @@ describe('GLSPActionDispatcher', () => { () => false, () => true ); - expect(gotRejected, 'Response promise should be rejected').to.be.true; + expect(gotRejected, 'Response promise should be rejected').toBe(true); }); it('should not leak timeout entries once the request settles', async () => { const timeouts = actionDispatcher['timeouts'] as Map; @@ -89,7 +89,7 @@ describe('GLSPActionDispatcher', () => { await actionDispatcher.requestUntil({ kind: 'noHandlerRequest', requestId: '' }, 50).catch(() => undefined); await flushMicrotasks(); - expect(timeouts.size, 'all timeout entries should be cleared after the requests settle').to.equal(0); + expect(timeouts.size, 'all timeout entries should be cleared after the requests settle').toBe(0); }); }); describe('request & re-dispatch', () => { @@ -100,7 +100,7 @@ describe('GLSPActionDispatcher', () => { () => true, err => false ); - expect(dispatchSuccessful, 'Promise of re-dispatch should resolve successfully').to.be.true; + expect(dispatchSuccessful, 'Promise of re-dispatch should resolve successfully').toBe(true); }); }); describe('async action handlers', () => { @@ -116,7 +116,7 @@ describe('GLSPActionDispatcher', () => { registry.register('asyncTest1', asyncHandler); await actionDispatcher.dispatch({ kind: 'asyncTest1' }); - expect(handlerExecuted).to.be.true; + expect(handlerExecuted).toBe(true); }); it('should invoke all handlers in one synchronous burst (parallel-start), without serializing on async ones', async () => { @@ -140,7 +140,7 @@ describe('GLSPActionDispatcher', () => { registry.register('multiAsyncTest', asyncHandler2); await actionDispatcher.dispatch({ kind: 'multiAsyncTest' }); - expect(executionOrder).to.deep.equal([2, 1]); + expect(executionOrder).toEqual([2, 1]); }); it('should not let a slow async handler starve a synchronous sibling registered after it', async () => { @@ -166,11 +166,11 @@ describe('GLSPActionDispatcher', () => { // Let the invocation burst run; the async handler is still gated. await flushMicrotasks(); - expect(executionOrder, 'sync sibling must run before the gated async handler resolves').to.deep.equal([2]); + expect(executionOrder, 'sync sibling must run before the gated async handler resolves').toEqual([2]); gate.resolve(); await dispatched; - expect(executionOrder).to.deep.equal([2, 1]); + expect(executionOrder).toEqual([2, 1]); }); it('should not let a never-resolving async handler starve a synchronous sibling', async () => { @@ -191,7 +191,7 @@ describe('GLSPActionDispatcher', () => { actionDispatcher.dispatch({ kind: 'stuckTest' }); await flushMicrotasks(); - expect(executionOrder).to.deep.equal([1]); + expect(executionOrder).toEqual([1]); }); it('should not deadlock when an async handler awaits a nested dispatch while a sibling is registered after it', async () => { @@ -220,7 +220,7 @@ describe('GLSPActionDispatcher', () => { registry.register('nestedTest', siblingHandler); await actionDispatcher.dispatch({ kind: 'nestedTest' }); - expect(executionOrder).to.deep.equal(['B', 'sub', 'A']); + expect(executionOrder).toEqual(['B', 'sub', 'A']); }); it('should handle mixed sync and async handlers correctly', async () => { @@ -241,7 +241,7 @@ describe('GLSPActionDispatcher', () => { registry.register('mixedTest', asyncHandler); await actionDispatcher.dispatch({ kind: 'mixedTest' }); - expect(executionOrder).to.deep.equal([1, 2]); + expect(executionOrder).toEqual([1, 2]); }); it('should propagate errors from async handlers', async () => { @@ -261,8 +261,8 @@ describe('GLSPActionDispatcher', () => { caughtError = error as Error; } - expect(caughtError).to.not.be.undefined; - expect(caughtError?.message).to.equal(errorMessage); + expect(caughtError).toBeDefined(); + expect(caughtError?.message).toBe(errorMessage); }); it('should handle errors in one handler without affecting others when multiple handlers are registered', async () => { @@ -291,10 +291,10 @@ describe('GLSPActionDispatcher', () => { } // First handler should have executed successfully - expect(executionOrder).to.deep.equal([1]); + expect(executionOrder).toEqual([1]); // Error should have been thrown - expect(caughtError).to.not.be.undefined; - expect(caughtError?.message).to.equal('Handler 2 error'); + expect(caughtError).toBeDefined(); + expect(caughtError?.message).toBe('Handler 2 error'); }); it('should handle synchronous errors in handlers', async () => { @@ -313,8 +313,8 @@ describe('GLSPActionDispatcher', () => { caughtError = error as Error; } - expect(caughtError).to.not.be.undefined; - expect(caughtError?.message).to.equal(errorMessage); + expect(caughtError).toBeDefined(); + expect(caughtError?.message).toBe(errorMessage); }); it('should handle async handlers that return actions', async () => { @@ -335,7 +335,7 @@ describe('GLSPActionDispatcher', () => { registry.register('returnedAction1', receivingHandler); await actionDispatcher.dispatch({ kind: 'asyncReturnTest' }); - expect(dispatchedActions).to.include('returnedAction1'); + expect(dispatchedActions).toContain('returnedAction1'); }); it('should wait for all async handlers to complete before resolving dispatch promise', async () => { @@ -359,8 +359,8 @@ describe('GLSPActionDispatcher', () => { await actionDispatcher.dispatch({ kind: 'completionTest' }); // Both handlers should be completed when dispatch resolves - expect(handler1Completed).to.be.true; - expect(handler2Completed).to.be.true; + expect(handler1Completed).toBe(true); + expect(handler2Completed).toBe(true); }); }); }); diff --git a/packages/client/src/base/feedback/feedback-emitter.spec.ts b/packages/client/src/base/feedback/feedback-emitter.spec.ts index b07e0c99..580a7b6b 100644 --- a/packages/client/src/base/feedback/feedback-emitter.spec.ts +++ b/packages/client/src/base/feedback/feedback-emitter.spec.ts @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2024 EclipseSource and others. + * Copyright (c) 2024-2026 EclipseSource and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -14,7 +14,7 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ import { Action, Command, CommandExecutionContext, Disposable } from '@eclipse-glsp/sprotty'; -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { IFeedbackActionDispatcher, IFeedbackEmitter } from './feedback-action-dispatcher'; import { FeedbackEmitter } from './feedback-emitter'; @@ -53,7 +53,7 @@ describe('FeedbackEmitter', () => { const feedbackActionDispatcher = new MockFeedbackActionDispatcher(); const feedback = feedbackActionDispatcher.createEmitter(); feedback.submit(); - expect(feedbackActionDispatcher['feedbackEmitters']).to.be.empty; + expect(feedbackActionDispatcher['feedbackEmitters'].size).toBe(0); }); }); @@ -63,7 +63,7 @@ describe('FeedbackEmitter', () => { const feedback = feedbackActionDispatcher.createEmitter(); const action: Action = { kind: 'action' }; feedback.add(action); - expect(feedback['feedbackActions']).to.deep.equal([action]); + expect(feedback['feedbackActions']).toEqual([action]); }); it('Should add an action and cleanup action as part of the emitter feedback.', () => { @@ -72,8 +72,8 @@ describe('FeedbackEmitter', () => { const action: Action = { kind: 'action' }; const cleanupAction: Action = { kind: 'cleanup' }; feedback.add(action, cleanupAction); - expect(feedback['feedbackActions']).to.deep.equal([action]); - expect(feedback['cleanupActions']).to.deep.equal([cleanupAction]); + expect(feedback['feedbackActions']).toEqual([action]); + expect(feedback['cleanupActions']).toEqual([cleanupAction]); }); }); @@ -87,7 +87,7 @@ describe('FeedbackEmitter', () => { feedback1.add(action1); feedback2.add(action2); feedback1.merge(feedback2); - expect(feedback1['feedbackActions']).to.deep.equal([action1, action2]); + expect(feedback1['feedbackActions']).toEqual([action1, action2]); }); }); @@ -98,7 +98,7 @@ describe('FeedbackEmitter', () => { const action: Action = { kind: 'action' }; feedback.add(action); feedback.remove(action); - expect(feedback['feedbackActions']).to.be.empty; + expect(feedback['feedbackActions']).toHaveLength(0); }); it('Should remove the action together with the cleanup action from the emitter feedback.', () => { @@ -108,8 +108,8 @@ describe('FeedbackEmitter', () => { const cleanupAction: Action = { kind: 'cleanup' }; feedback.add(action, cleanupAction); feedback.remove(action); - expect(feedback['feedbackActions']).to.be.empty; - expect(feedback['cleanupActions']).to.be.empty; + expect(feedback['feedbackActions']).toHaveLength(0); + expect(feedback['cleanupActions']).toHaveLength(0); }); }); @@ -121,8 +121,8 @@ describe('FeedbackEmitter', () => { const cleanupAction: Action = { kind: 'cleanup' }; feedback.add(action, cleanupAction); feedback.clear(); - expect(feedback['feedbackActions']).to.be.empty; - expect(feedback['cleanupActions']).to.be.empty; + expect(feedback['feedbackActions']).toHaveLength(0); + expect(feedback['cleanupActions']).toHaveLength(0); }); }); @@ -133,8 +133,8 @@ describe('FeedbackEmitter', () => { const action: Action = { kind: 'action' }; feedback.add(action); feedback.submit(); - expect(feedbackActionDispatcher['feedbackEmitters'].size).to.equal(1); - expect(feedbackActionDispatcher['feedbackEmitters'].get(feedback)).to.deep.equal([action]); + expect(feedbackActionDispatcher['feedbackEmitters'].size).toBe(1); + expect(feedbackActionDispatcher['feedbackEmitters'].get(feedback)).toEqual([action]); }); }); @@ -146,7 +146,7 @@ describe('FeedbackEmitter', () => { feedback.add(action); feedback.submit(); feedback.discard(); - expect(feedbackActionDispatcher['feedbackEmitters']).to.be.empty; + expect(feedbackActionDispatcher['feedbackEmitters'].size).toBe(0); }); }); @@ -159,7 +159,7 @@ describe('FeedbackEmitter', () => { feedback.add(action, cleanupAction); feedback.submit(); feedback.revert(); - expect(feedbackActionDispatcher['feedbackEmitters']).to.be.empty; + expect(feedbackActionDispatcher['feedbackEmitters'].size).toBe(0); }); }); @@ -170,7 +170,7 @@ describe('FeedbackEmitter', () => { const action: Action = { kind: 'action' }; feedback.add(action); feedback.dispose(); - expect(feedbackActionDispatcher['feedbackEmitters']).to.be.empty; + expect(feedbackActionDispatcher['feedbackEmitters'].size).toBe(0); }); }); }); diff --git a/packages/client/src/base/model/glsp-model-source.ts b/packages/client/src/base/model/glsp-model-source.ts index 4a2843fa..c06a3f16 100644 --- a/packages/client/src/base/model/glsp-model-source.ts +++ b/packages/client/src/base/model/glsp-model-source.ts @@ -34,7 +34,7 @@ import { } from '@eclipse-glsp/sprotty'; import { inject, injectable, preDestroy } from 'inversify'; import { GLSPActionHandlerRegistry } from '../action-handler-registry'; -import { IDiagramOptions } from './diagram-loader'; +import type { IDiagramOptions } from './diagram-loader'; /** * A helper interface that allows the client to mark actions that have been received from the server. diff --git a/packages/client/src/base/model/model-initialization-constraint.spec.ts b/packages/client/src/base/model/model-initialization-constraint.spec.ts index 1a56b9fd..17140b5a 100644 --- a/packages/client/src/base/model/model-initialization-constraint.spec.ts +++ b/packages/client/src/base/model/model-initialization-constraint.spec.ts @@ -13,83 +13,81 @@ * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; import { Container } from 'inversify'; import 'reflect-metadata'; -import * as sinon from 'sinon'; import { Deferred, EMPTY_ROOT, InitializeCanvasBoundsAction, SetModelAction, UpdateModelAction } from '@eclipse-glsp/sprotty'; import { DefaultModelInitializationConstraint, ModelInitializationConstraint } from './model-initialization-constraint'; -const sandbox = sinon.createSandbox(); const container = new Container(); let constraint: ModelInitializationConstraint; -const listener = sandbox.spy((): void => {}); +const listener = vi.fn((): void => {}); describe('DefaultModelInitializationConstraint', () => { beforeEach(() => { constraint = container.resolve(DefaultModelInitializationConstraint); - sandbox.reset(); + listener.mockClear(); }); it('should complete after dispatching non empty SetModelAction and `InitializeCanvasBoundsAction`', () => { - expect(constraint.isCompleted).to.be.false; + expect(constraint.isCompleted).toBe(false); constraint.notifyDispatched(SetModelAction.create({ id: 'model', type: 'graph' })); - expect(constraint.isCompleted).to.be.false; + expect(constraint.isCompleted).toBe(false); constraint.notifyDispatched({ kind: InitializeCanvasBoundsAction.KIND }); - expect(constraint.isCompleted).to.be.true; + expect(constraint.isCompleted).toBe(true); }); it('should complete after dispatching non empty UpdateModelAction and `InitializeCanvasBoundsAction`', () => { - expect(constraint.isCompleted).to.be.false; + expect(constraint.isCompleted).toBe(false); constraint.notifyDispatched(UpdateModelAction.create({ id: 'model', type: 'graph' })); - expect(constraint.isCompleted).to.be.false; + expect(constraint.isCompleted).toBe(false); constraint.notifyDispatched({ kind: InitializeCanvasBoundsAction.KIND }); - expect(constraint.isCompleted).to.be.true; + expect(constraint.isCompleted).toBe(true); }); it('should note complete after dispatching empty SetModelAction and `InitializeCanvasBoundsAction` ', () => { - expect(constraint.isCompleted).to.be.false; + expect(constraint.isCompleted).toBe(false); constraint.notifyDispatched(SetModelAction.create(EMPTY_ROOT)); - expect(constraint.isCompleted).to.be.false; + expect(constraint.isCompleted).toBe(false); constraint.notifyDispatched({ kind: InitializeCanvasBoundsAction.KIND }); - expect(constraint.isCompleted).to.be.false; + expect(constraint.isCompleted).toBe(false); }); it('should note complete after dispatching empty UpdateModelAction and `InitializeCanvasBoundsAction ', () => { - expect(constraint.isCompleted).to.be.false; + expect(constraint.isCompleted).toBe(false); constraint.notifyDispatched(UpdateModelAction.create(EMPTY_ROOT)); - expect(constraint.isCompleted).to.be.false; + expect(constraint.isCompleted).toBe(false); constraint.notifyDispatched({ kind: InitializeCanvasBoundsAction.KIND }); - expect(constraint.isCompleted).to.be.false; + expect(constraint.isCompleted).toBe(false); }); describe('onInitialized', () => { it('returned promise should resolve once the constraint is initialized', async () => { const initializeDeferred = new Deferred(); const initializePromise = constraint.onInitialized(); initializePromise.then(() => initializeDeferred.resolve()); - expect(initializeDeferred.state).to.be.equal('unresolved'); + expect(initializeDeferred.state).toBe('unresolved'); // Directly trigger the completion method simplify test logic constraint['setCompleted'](); // Short delay of test execution to ensure that the deferred state is updated. await new Promise(resolve => setTimeout(resolve, 5)); - expect(initializeDeferred.state).to.be.equal('resolved'); + expect(initializeDeferred.state).toBe('resolved'); }); it('registered listener should be invoked once the constraint is initialized', () => { constraint.onInitialized(listener); - expect(listener.called).to.be.false; + expect(listener).not.toHaveBeenCalled(); // Directly trigger the completion method simplify test logic constraint['setCompleted'](); - expect(listener.called).to.be.true; + expect(listener).toHaveBeenCalled(); }); it('registered listener should be invoked directly on registration if the constraint is already initialized', () => { // Directly trigger the completion method simplify test logic constraint['setCompleted'](); constraint.onInitialized(listener); - expect(listener.called).to.be.true; + expect(listener).toHaveBeenCalled(); }); it('Disposed listener should not be invoked once the constraint is initialized', () => { const toDispose = constraint.onInitialized(listener); - expect(listener.called).to.be.false; + expect(listener).not.toHaveBeenCalled(); toDispose.dispose(); // Directly trigger the completion method simplify test logic constraint['setCompleted'](); - expect(listener.called).to.be.false; + expect(listener).not.toHaveBeenCalled(); }); }); }); diff --git a/packages/client/src/base/selection-service.spec.ts b/packages/client/src/base/selection-service.spec.ts index 56acd173..5567e19c 100644 --- a/packages/client/src/base/selection-service.spec.ts +++ b/packages/client/src/base/selection-service.spec.ts @@ -14,9 +14,8 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ import { Action, Command, CommandExecutionContext, Disposable, GModelRoot, GNode, TYPES, initializeContainer } from '@eclipse-glsp/sprotty'; -import { AssertionError, expect } from 'chai'; +import { afterEach, beforeEach, describe, expect, it, vi, type Mock } from 'vitest'; import { Container, injectable } from 'inversify'; -import * as sinon from 'sinon'; import { defaultModule } from './default.module'; import { IFeedbackActionDispatcher, IFeedbackEmitter } from './feedback/feedback-action-dispatcher'; import { FeedbackEmitter } from './feedback/feedback-emitter'; @@ -127,7 +126,8 @@ describe('SelectionService', () => { it('Selecting multiple elements should have the selection order in the dispatched feedback.', () => { assertSelectionAndFeedback([], []); selectionService.updateSelection(root, ['node2', 'node1'], []); - expect(() => assertSelectionAndFeedback(['node1', 'node2'], [])).to.throw(AssertionError, 'ordered members'); + // assertion enforces order: expecting ['node1', 'node2'] must fail for the actual ['node2', 'node1'] + expect(() => assertSelectionAndFeedback(['node1', 'node2'], [])).toThrow(); }); it('Selecting the same elements twice in one operation should not make a difference.', () => { assertSelectionAndFeedback([], []); @@ -196,10 +196,10 @@ describe('SelectionService', () => { }); }); describe('Listeners', () => { - const sandbox = sinon.createSandbox(); - const listener = sandbox.createStubInstance(MockSelectionListener); + const listener = { selectionChanged: vi.fn() } as unknown as MockSelectionListener; beforeEach(() => { + (listener.selectionChanged as Mock).mockClear(); selectionService.onSelectionChanged(change => listener.selectionChanged(change.root, change.selectedElements, change.deselectedElements) ); @@ -207,7 +207,6 @@ describe('SelectionService', () => { afterEach(() => { selectionService.dispose(); - sandbox.reset(); }); it('A registered listener should be notified of a single selection change.', () => { selectionService.updateSelection(root, ['node1', 'node1'], []); @@ -249,7 +248,7 @@ describe('SelectionService', () => { }); it('Bindings of TYPES.ISelectionListener should be registered as listener in `preLoadDiagram`', () => { const container = createContainer(); - const selectionListener = sandbox.createStubInstance(MockSelectionListener); + const selectionListener = { selectionChanged: vi.fn() } as unknown as MockSelectionListener; container.bind(TYPES.ISelectionListener).toConstantValue(selectionListener); const testSelectionService = container.get(SelectionService); testSelectionService.preLoadDiagram(); @@ -277,12 +276,12 @@ describe('SelectionService', () => { } function assertSelectionService(expectedSelection: string[]): void { - expect(selectionService.isSingleSelection()).to.equal(expectedSelection.length === 1); - expect(selectionService.isMultiSelection()).to.equal(expectedSelection.length > 1); - expect(selectionService.hasSelectedElements()).to.equal(expectedSelection.length > 0); - expect(selectionService.getSelectedElementIDs()).to.have.lengthOf(expectedSelection.length); + expect(selectionService.isSingleSelection()).toBe(expectedSelection.length === 1); + expect(selectionService.isMultiSelection()).toBe(expectedSelection.length > 1); + expect(selectionService.hasSelectedElements()).toBe(expectedSelection.length > 0); + expect(selectionService.getSelectedElementIDs()).toHaveLength(expectedSelection.length); if (expectedSelection.length > 0) { - expect(selectionService.getSelectedElementIDs()).to.have.ordered.members(expectedSelection); + expect(selectionService.getSelectedElementIDs()).toEqual(expectedSelection); } } @@ -290,29 +289,31 @@ describe('SelectionService', () => { // a single feedback action reflects aggregated selection/deselection const hasFeedback = expectedSelection.length > 0 || expectedDeselection.length > 0; if (hasFeedback) { - expect(feedbackDispatcher.getRegisteredFeedback()).to.have.lengthOf(1); - expect(feedbackDispatcher.getSingleFeedbackAction()!.selectedElementsIDs).to.have.lengthOf(expectedSelection.length); - expect(feedbackDispatcher.getSingleFeedbackAction()!.selectedElementsIDs).to.have.ordered.members(expectedSelection); - expect(feedbackDispatcher.getSingleFeedbackAction()!.deselectedElementsIDs).to.have.lengthOf(expectedDeselection.length); - expect(feedbackDispatcher.getSingleFeedbackAction()!.deselectedElementsIDs).to.have.ordered.members(expectedDeselection); + expect(feedbackDispatcher.getRegisteredFeedback()).toHaveLength(1); + expect(feedbackDispatcher.getSingleFeedbackAction()!.selectedElementsIDs).toHaveLength(expectedSelection.length); + expect(feedbackDispatcher.getSingleFeedbackAction()!.selectedElementsIDs).toEqual(expectedSelection); + expect(feedbackDispatcher.getSingleFeedbackAction()!.deselectedElementsIDs).toHaveLength(expectedDeselection.length); + expect(feedbackDispatcher.getSingleFeedbackAction()!.deselectedElementsIDs).toEqual(expectedDeselection); } else { - expect(feedbackDispatcher.getRegisteredFeedback()).to.have.lengthOf(0); - expect(feedbackDispatcher.getSingleFeedbackAction()).to.be.undefined; + expect(feedbackDispatcher.getRegisteredFeedback()).toHaveLength(0); + expect(feedbackDispatcher.getSingleFeedbackAction()).toBeUndefined(); } } function assertListener( - listener: sinon.SinonStubbedInstance, + listener: MockSelectionListener, expectedRoot: GModelRoot | undefined, expectedSelection: string[], expectedDeselection: string[], expectedCalled: number ): void { - expect(listener.selectionChanged.callCount).to.be.equal(expectedCalled); + const selectionChanged = listener.selectionChanged as Mock; + expect(selectionChanged.mock.calls.length).toBe(expectedCalled); if (expectedCalled > 0) { - expect(listener.selectionChanged.lastCall.args[0]).to.be.deep.equals(expectedRoot); - expect(listener.selectionChanged.lastCall.args[1]).to.be.deep.equals(expectedSelection); - expect(listener.selectionChanged.lastCall.args[2]).to.be.deep.equals(expectedDeselection); + const lastCallArgs = selectionChanged.mock.calls[selectionChanged.mock.calls.length - 1]; + expect(lastCallArgs[0]).toEqual(expectedRoot); + expect(lastCallArgs[1]).toEqual(expectedSelection); + expect(lastCallArgs[2]).toEqual(expectedDeselection); } } }); diff --git a/packages/client/src/default-modules.spec.ts b/packages/client/src/default-modules.spec.ts index 1e0ef0ef..ced26c34 100644 --- a/packages/client/src/default-modules.spec.ts +++ b/packages/client/src/default-modules.spec.ts @@ -14,9 +14,8 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ import { FeatureModule } from '@eclipse-glsp/sprotty'; -import { expect } from 'chai'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; import { Container } from 'inversify'; -import * as sinon from 'sinon'; import { defaultModule } from './base/default.module'; import { DEFAULT_MODULES, initializeDiagramContainer } from './default-modules'; @@ -24,31 +23,30 @@ describe('default-modules', () => { // InitializeDiagramContainer internally uses `resolveContainerConfiguration` so we only test functionality // that is not covered by the tests of `resolveContainerConfiguration`. describe('initializeDiagramContainer', () => { - const sandbox = sinon.createSandbox(); const container = new Container(); - const loadSpy = sandbox.spy(container, 'load'); + let loadSpy: ReturnType; container.snapshot(); beforeEach(() => { - sandbox.reset(); container.restore(); container.snapshot(); + loadSpy = vi.spyOn(container, 'load'); }); it('should initialize the diagram container with the default modules in addition to the given config and load them first', () => { const extraModule = new FeatureModule(() => {}); initializeDiagramContainer(container, { add: extraModule }); - expect(loadSpy.calledOnce).to.be.true; - const callArgs = loadSpy.firstCall.args; + expect(loadSpy).toHaveBeenCalledOnce(); + const callArgs = [...loadSpy.mock.calls[0]]; const lastModule = callArgs.pop(); - expect(callArgs).to.be.deep.equal(DEFAULT_MODULES).ordered; - expect(lastModule).to.be.equal(extraModule); + expect(callArgs).toEqual(DEFAULT_MODULES); + expect(lastModule).toBe(extraModule); }); it('should throw an error if the base (default) module is removed via configuration', () => { - expect(() => initializeDiagramContainer(container, { remove: defaultModule })).to.throw(/Invalid module configuration/); + expect(() => initializeDiagramContainer(container, { remove: defaultModule })).toThrow(/Invalid module configuration/); }); it('should throw an error if the base (default) module is not the first module of the resolved configured (removed and added again)', () => { - expect(() => initializeDiagramContainer(container, { remove: defaultModule, add: defaultModule })).to.throw( + expect(() => initializeDiagramContainer(container, { remove: defaultModule, add: defaultModule })).toThrow( /Invalid module configuration/ ); }); diff --git a/packages/client/src/features/bounds/freeform-layout.spec.ts b/packages/client/src/features/bounds/freeform-layout.spec.ts index 5c37cd15..5f905ea1 100644 --- a/packages/client/src/features/bounds/freeform-layout.spec.ts +++ b/packages/client/src/features/bounds/freeform-layout.spec.ts @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2022-2023 STMicroelectronics and others. + * Copyright (c) 2022-2026 STMicroelectronics and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -13,11 +13,11 @@ * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; -import 'mocha'; + +import { describe, expect, it } from 'vitest'; import 'reflect-metadata'; import { BoundsData, ConsoleLogger, GModelElement } from '@eclipse-glsp/sprotty'; -import { createCompartment, createGraph, createLabel, createNode, layout, setupLayoutRegistry } from './layouter-test-util.spec'; +import { createCompartment, createGraph, createLabel, createNode, layout, setupLayoutRegistry } from '../test/layouter-test-util'; describe('FreeFormLayouter', () => { const layoutRegistry = setupLayoutRegistry(); @@ -60,13 +60,13 @@ describe('FreeFormLayouter', () => { model.add(category); layout(layoutRegistry, log, map, model); // check category - expect(map.get(category)!.bounds).to.deep.equal({ x: 0, y: 0, width: 410.0, height: 215.0 }); + expect(map.get(category)!.bounds).toEqual({ x: 0, y: 0, width: 410.0, height: 215.0 }); // check header compartment - expect(map.get(category.children[0])!.bounds).to.deep.equal({ x: 0, y: 0, width: -1, height: -1 }); + expect(map.get(category.children[0])!.bounds).toEqual({ x: 0, y: 0, width: -1, height: -1 }); // check child freeform compartment - expect(map.get(category.children[1])!.bounds).to.deep.equal({ x: 5, y: 5, width: 400.0, height: 205.0 }); + expect(map.get(category.children[1])!.bounds).toEqual({ x: 5, y: 5, width: 400.0, height: 205.0 }); // check label compartment - expect(map.get(category.children[2])!.bounds).to.deep.equal({ x: 0, y: 0, width: -1, height: -1 }); + expect(map.get(category.children[2])!.bounds).toEqual({ x: 0, y: 0, width: -1, height: -1 }); }); }); @@ -108,15 +108,15 @@ describe('FreeFormLayouter', () => { // layout graph layout(layoutRegistry, log, map, model); // check category - expect(map.get(category)!.bounds).to.deep.equal({ x: 0, y: 0, width: 500.0, height: 375.0 }); + expect(map.get(category)!.bounds).toEqual({ x: 0, y: 0, width: 500.0, height: 375.0 }); // check header compartment - expect(map.get(category.children[0])!.bounds).to.deep.equal({ x: 0, y: 0, width: -1, height: -1 }); + expect(map.get(category.children[0])!.bounds).toEqual({ x: 0, y: 0, width: -1, height: -1 }); // check child freeform compartment - expect(map.get(category.children[1])!.bounds).to.deep.equal({ x: 5.0, y: 5.0, width: 490.0, height: 365.0 }); + expect(map.get(category.children[1])!.bounds).toEqual({ x: 5.0, y: 5.0, width: 490.0, height: 365.0 }); // check child task node - expect(map.get(category.children[1].children[0])!.bounds).to.deep.equal({ x: 170.0, y: 190.0, width: 35.0, height: 30.0 }); + expect(map.get(category.children[1].children[0])!.bounds).toEqual({ x: 170.0, y: 190.0, width: 35.0, height: 30.0 }); // check label compartment - expect(map.get(category.children[2])!.bounds).to.deep.equal({ x: 0, y: 0, width: -1, height: -1 }); + expect(map.get(category.children[2])!.bounds).toEqual({ x: 0, y: 0, width: -1, height: -1 }); }); it('Structure compartment (hGrab=true, vGrab=true)', () => { @@ -152,13 +152,13 @@ describe('FreeFormLayouter', () => { // layout graph layout(layoutRegistry, log, map, model); // check category - expect(map.get(category)!.bounds).to.deep.equal({ x: 0, y: 0, width: 500.0, height: 375.0 }); + expect(map.get(category)!.bounds).toEqual({ x: 0, y: 0, width: 500.0, height: 375.0 }); // check header compartment - expect(map.get(category.children[0])!.bounds).to.deep.equal({ x: 0, y: 0, width: -1, height: -1 }); + expect(map.get(category.children[0])!.bounds).toEqual({ x: 0, y: 0, width: -1, height: -1 }); // check child freeform compartment - expect(map.get(category.children[1])!.bounds).to.deep.equal({ x: 5.0, y: 5.0, width: 490.0, height: 365.0 }); + expect(map.get(category.children[1])!.bounds).toEqual({ x: 5.0, y: 5.0, width: 490.0, height: 365.0 }); // check child task node - expect(map.get(category.children[1].children[0])!.bounds).to.deep.equal({ x: 55.0, y: 15.0, width: 60.0, height: 45.0 }); + expect(map.get(category.children[1].children[0])!.bounds).toEqual({ x: 55.0, y: 15.0, width: 60.0, height: 45.0 }); }); it('Structure compartment (hGrab=true, vGrab=true, padding*=10)', () => { @@ -204,13 +204,13 @@ describe('FreeFormLayouter', () => { // layout graph layout(layoutRegistry, log, map, model); // check category - expect(map.get(category)!.bounds).to.deep.equal({ x: 0, y: 0, width: 500.0, height: 375.0 }); + expect(map.get(category)!.bounds).toEqual({ x: 0, y: 0, width: 500.0, height: 375.0 }); // check header compartment - expect(map.get(category.children[0])!.bounds).to.deep.equal({ x: 0, y: 0, width: -1, height: -1 }); + expect(map.get(category.children[0])!.bounds).toEqual({ x: 0, y: 0, width: -1, height: -1 }); // check child freeform compartment - expect(map.get(category.children[1])!.bounds).to.deep.equal({ x: 10.0, y: 10.0, width: 480.0, height: 355.0 }); + expect(map.get(category.children[1])!.bounds).toEqual({ x: 10.0, y: 10.0, width: 480.0, height: 355.0 }); // check child task node - expect(map.get(category.children[1].children[0])!.bounds).to.deep.equal({ x: 55.0, y: 15.0, width: 70.0, height: 55.0 }); + expect(map.get(category.children[1].children[0])!.bounds).toEqual({ x: 55.0, y: 15.0, width: 70.0, height: 55.0 }); }); }); }); diff --git a/packages/client/src/features/bounds/hbox-layout.spec.ts b/packages/client/src/features/bounds/hbox-layout.spec.ts index fa56ca3c..78914b59 100644 --- a/packages/client/src/features/bounds/hbox-layout.spec.ts +++ b/packages/client/src/features/bounds/hbox-layout.spec.ts @@ -14,11 +14,10 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; -import 'mocha'; +import { describe, expect, it } from 'vitest'; import 'reflect-metadata'; import { BoundsData, ConsoleLogger, Dimension, GModelElement, GNode } from '@eclipse-glsp/sprotty'; -import { createLabel, createNode, layout, setupLayoutRegistry } from './layouter-test-util.spec'; +import { createLabel, createNode, layout, setupLayoutRegistry } from '../test/layouter-test-util'; describe('HBoxLayouter', () => { const layoutRegistry = setupLayoutRegistry(); @@ -39,10 +38,10 @@ describe('HBoxLayouter', () => { it('defaultParams', () => { const model = createModel(); layout(layoutRegistry, log, map, model); - expect(map.get(model)!.bounds).to.deep.equal({ x: 0, y: 0, width: 18, height: 13 }); - expect(map.get(model.children[0])!.bounds).to.deep.equal({ x: 5, y: 5.5, width: 1, height: 2 }); - expect(map.get(model.children[1])!.bounds).to.deep.equal({ x: 7, y: 6, width: 2, height: 1 }); - expect(map.get(model.children[2])!.bounds).to.deep.equal({ x: 10, y: 5, width: 3, height: 3 }); + expect(map.get(model)!.bounds).toEqual({ x: 0, y: 0, width: 18, height: 13 }); + expect(map.get(model.children[0])!.bounds).toEqual({ x: 5, y: 5.5, width: 1, height: 2 }); + expect(map.get(model.children[1])!.bounds).toEqual({ x: 7, y: 6, width: 2, height: 1 }); + expect(map.get(model.children[2])!.bounds).toEqual({ x: 10, y: 5, width: 3, height: 3 }); }); it('alignTop', () => { @@ -51,10 +50,10 @@ describe('HBoxLayouter', () => { vAlign: 'top' }; layout(layoutRegistry, log, map, model); - expect(map.get(model)!.bounds).to.deep.equal({ x: 0, y: 0, width: 18, height: 13 }); - expect(map.get(model.children[0])!.bounds).to.deep.equal({ x: 5, y: 5, width: 1, height: 2 }); - expect(map.get(model.children[1])!.bounds).to.deep.equal({ x: 7, y: 5, width: 2, height: 1 }); - expect(map.get(model.children[2])!.bounds).to.deep.equal({ x: 10, y: 5, width: 3, height: 3 }); + expect(map.get(model)!.bounds).toEqual({ x: 0, y: 0, width: 18, height: 13 }); + expect(map.get(model.children[0])!.bounds).toEqual({ x: 5, y: 5, width: 1, height: 2 }); + expect(map.get(model.children[1])!.bounds).toEqual({ x: 7, y: 5, width: 2, height: 1 }); + expect(map.get(model.children[2])!.bounds).toEqual({ x: 10, y: 5, width: 3, height: 3 }); }); it('alignCenter', () => { @@ -63,10 +62,10 @@ describe('HBoxLayouter', () => { vAlign: 'center' }; layout(layoutRegistry, log, map, model); - expect(map.get(model)!.bounds).to.deep.equal({ x: 0, y: 0, width: 18, height: 13 }); - expect(map.get(model.children[0])!.bounds).to.deep.equal({ x: 5, y: 5.5, width: 1, height: 2 }); - expect(map.get(model.children[1])!.bounds).to.deep.equal({ x: 7, y: 6, width: 2, height: 1 }); - expect(map.get(model.children[2])!.bounds).to.deep.equal({ x: 10, y: 5, width: 3, height: 3 }); + expect(map.get(model)!.bounds).toEqual({ x: 0, y: 0, width: 18, height: 13 }); + expect(map.get(model.children[0])!.bounds).toEqual({ x: 5, y: 5.5, width: 1, height: 2 }); + expect(map.get(model.children[1])!.bounds).toEqual({ x: 7, y: 6, width: 2, height: 1 }); + expect(map.get(model.children[2])!.bounds).toEqual({ x: 10, y: 5, width: 3, height: 3 }); }); it('alignBottom', () => { @@ -75,10 +74,10 @@ describe('HBoxLayouter', () => { vAlign: 'bottom' }; layout(layoutRegistry, log, map, model); - expect(map.get(model)!.bounds).to.deep.equal({ x: 0, y: 0, width: 18, height: 13 }); - expect(map.get(model.children[0])!.bounds).to.deep.equal({ x: 5, y: 6, width: 1, height: 2 }); - expect(map.get(model.children[1])!.bounds).to.deep.equal({ x: 7, y: 7, width: 2, height: 1 }); - expect(map.get(model.children[2])!.bounds).to.deep.equal({ x: 10, y: 5, width: 3, height: 3 }); + expect(map.get(model)!.bounds).toEqual({ x: 0, y: 0, width: 18, height: 13 }); + expect(map.get(model.children[0])!.bounds).toEqual({ x: 5, y: 6, width: 1, height: 2 }); + expect(map.get(model.children[1])!.bounds).toEqual({ x: 7, y: 7, width: 2, height: 1 }); + expect(map.get(model.children[2])!.bounds).toEqual({ x: 10, y: 5, width: 3, height: 3 }); }); it('padding', () => { @@ -90,10 +89,10 @@ describe('HBoxLayouter', () => { paddingRight: 10 }; layout(layoutRegistry, log, map, model); - expect(map.get(model)!.bounds).to.deep.equal({ x: 0, y: 0, width: 27, height: 18 }); - expect(map.get(model.children[0])!.bounds).to.deep.equal({ x: 9, y: 7.5, width: 1, height: 2 }); - expect(map.get(model.children[1])!.bounds).to.deep.equal({ x: 11, y: 8, width: 2, height: 1 }); - expect(map.get(model.children[2])!.bounds).to.deep.equal({ x: 14, y: 7, width: 3, height: 3 }); + expect(map.get(model)!.bounds).toEqual({ x: 0, y: 0, width: 27, height: 18 }); + expect(map.get(model.children[0])!.bounds).toEqual({ x: 9, y: 7.5, width: 1, height: 2 }); + expect(map.get(model.children[1])!.bounds).toEqual({ x: 11, y: 8, width: 2, height: 1 }); + expect(map.get(model.children[2])!.bounds).toEqual({ x: 14, y: 7, width: 3, height: 3 }); }); it('hGap', () => { @@ -102,10 +101,10 @@ describe('HBoxLayouter', () => { hGap: 4 }; layout(layoutRegistry, log, map, model); - expect(map.get(model)!.bounds).to.deep.equal({ x: 0, y: 0, width: 24, height: 13 }); - expect(map.get(model.children[0])!.bounds).to.deep.equal({ x: 5, y: 5.5, width: 1, height: 2 }); - expect(map.get(model.children[1])!.bounds).to.deep.equal({ x: 10, y: 6, width: 2, height: 1 }); - expect(map.get(model.children[2])!.bounds).to.deep.equal({ x: 16, y: 5, width: 3, height: 3 }); + expect(map.get(model)!.bounds).toEqual({ x: 0, y: 0, width: 24, height: 13 }); + expect(map.get(model.children[0])!.bounds).toEqual({ x: 5, y: 5.5, width: 1, height: 2 }); + expect(map.get(model.children[1])!.bounds).toEqual({ x: 10, y: 6, width: 2, height: 1 }); + expect(map.get(model.children[2])!.bounds).toEqual({ x: 16, y: 5, width: 3, height: 3 }); }); it('paddingFactor', () => { @@ -114,10 +113,10 @@ describe('HBoxLayouter', () => { paddingFactor: 2 }; layout(layoutRegistry, log, map, model); - expect(map.get(model)!.bounds).to.deep.equal({ x: 0, y: 0, width: 18, height: 13 }); - expect(map.get(model.children[0])!.bounds).to.deep.equal({ x: 9, y: 8.5, width: 1, height: 2 }); - expect(map.get(model.children[1])!.bounds).to.deep.equal({ x: 11, y: 9, width: 2, height: 1 }); - expect(map.get(model.children[2])!.bounds).to.deep.equal({ x: 14, y: 8, width: 3, height: 3 }); + expect(map.get(model)!.bounds).toEqual({ x: 0, y: 0, width: 18, height: 13 }); + expect(map.get(model.children[0])!.bounds).toEqual({ x: 9, y: 8.5, width: 1, height: 2 }); + expect(map.get(model.children[1])!.bounds).toEqual({ x: 11, y: 9, width: 2, height: 1 }); + expect(map.get(model.children[2])!.bounds).toEqual({ x: 14, y: 8, width: 3, height: 3 }); }); it('minWidth', () => { @@ -126,10 +125,10 @@ describe('HBoxLayouter', () => { minWidth: 25 }; layout(layoutRegistry, log, map, model); - expect(map.get(model)!.bounds).to.deep.equal({ x: 0, y: 0, width: 25, height: 13 }); - expect(map.get(model.children[0])!.bounds).to.deep.equal({ x: 5, y: 5.5, width: 1, height: 2 }); - expect(map.get(model.children[1])!.bounds).to.deep.equal({ x: 7, y: 6, width: 2, height: 1 }); - expect(map.get(model.children[2])!.bounds).to.deep.equal({ x: 10, y: 5, width: 3, height: 3 }); + expect(map.get(model)!.bounds).toEqual({ x: 0, y: 0, width: 25, height: 13 }); + expect(map.get(model.children[0])!.bounds).toEqual({ x: 5, y: 5.5, width: 1, height: 2 }); + expect(map.get(model.children[1])!.bounds).toEqual({ x: 7, y: 6, width: 2, height: 1 }); + expect(map.get(model.children[2])!.bounds).toEqual({ x: 10, y: 5, width: 3, height: 3 }); }); it('minHeight', () => { @@ -138,10 +137,10 @@ describe('HBoxLayouter', () => { minHeight: 25 }; layout(layoutRegistry, log, map, model); - expect(map.get(model)!.bounds).to.deep.equal({ x: 0, y: 0, width: 18, height: 25 }); - expect(map.get(model.children[0])!.bounds).to.deep.equal({ x: 5, y: 11.5, width: 1, height: 2 }); - expect(map.get(model.children[1])!.bounds).to.deep.equal({ x: 7, y: 12, width: 2, height: 1 }); - expect(map.get(model.children[2])!.bounds).to.deep.equal({ x: 10, y: 11, width: 3, height: 3 }); + expect(map.get(model)!.bounds).toEqual({ x: 0, y: 0, width: 18, height: 25 }); + expect(map.get(model.children[0])!.bounds).toEqual({ x: 5, y: 11.5, width: 1, height: 2 }); + expect(map.get(model.children[1])!.bounds).toEqual({ x: 7, y: 12, width: 2, height: 1 }); + expect(map.get(model.children[2])!.bounds).toEqual({ x: 10, y: 11, width: 3, height: 3 }); }); it('prefWidth', () => { @@ -150,10 +149,10 @@ describe('HBoxLayouter', () => { prefWidth: 20 }; layout(layoutRegistry, log, map, model); - expect(map.get(model)!.bounds).to.deep.equal({ x: 0, y: 0, width: 20, height: 13 }); - expect(map.get(model.children[0])!.bounds).to.deep.equal({ x: 5, y: 5.5, width: 1, height: 2 }); - expect(map.get(model.children[1])!.bounds).to.deep.equal({ x: 7, y: 6, width: 2, height: 1 }); - expect(map.get(model.children[2])!.bounds).to.deep.equal({ x: 10, y: 5, width: 3, height: 3 }); + expect(map.get(model)!.bounds).toEqual({ x: 0, y: 0, width: 20, height: 13 }); + expect(map.get(model.children[0])!.bounds).toEqual({ x: 5, y: 5.5, width: 1, height: 2 }); + expect(map.get(model.children[1])!.bounds).toEqual({ x: 7, y: 6, width: 2, height: 1 }); + expect(map.get(model.children[2])!.bounds).toEqual({ x: 10, y: 5, width: 3, height: 3 }); }); it('prefHeight', () => { @@ -162,9 +161,9 @@ describe('HBoxLayouter', () => { prefHeight: 20 }; layout(layoutRegistry, log, map, model); - expect(map.get(model)!.bounds).to.deep.equal({ x: 0, y: 0, width: 18, height: 20 }); - expect(map.get(model.children[0])!.bounds).to.deep.equal({ x: 5, y: 9, width: 1, height: 2 }); - expect(map.get(model.children[1])!.bounds).to.deep.equal({ x: 7, y: 9.5, width: 2, height: 1 }); - expect(map.get(model.children[2])!.bounds).to.deep.equal({ x: 10, y: 8.5, width: 3, height: 3 }); + expect(map.get(model)!.bounds).toEqual({ x: 0, y: 0, width: 18, height: 20 }); + expect(map.get(model.children[0])!.bounds).toEqual({ x: 5, y: 9, width: 1, height: 2 }); + expect(map.get(model.children[1])!.bounds).toEqual({ x: 7, y: 9.5, width: 2, height: 1 }); + expect(map.get(model.children[2])!.bounds).toEqual({ x: 10, y: 8.5, width: 3, height: 3 }); }); }); diff --git a/packages/client/src/features/bounds/vbox-layout.spec.ts b/packages/client/src/features/bounds/vbox-layout.spec.ts index 098ede32..d699a51b 100644 --- a/packages/client/src/features/bounds/vbox-layout.spec.ts +++ b/packages/client/src/features/bounds/vbox-layout.spec.ts @@ -14,11 +14,10 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; -import 'mocha'; +import { describe, expect, it } from 'vitest'; import 'reflect-metadata'; import { BoundsData, ConsoleLogger, Dimension, GModelElement, GNode } from '@eclipse-glsp/sprotty'; -import { createLabel, createNode, layout, setupLayoutRegistry } from './layouter-test-util.spec'; +import { createLabel, createNode, layout, setupLayoutRegistry } from '../test/layouter-test-util'; describe('VBoxLayouter', () => { const layoutRegistry = setupLayoutRegistry(); @@ -39,10 +38,10 @@ describe('VBoxLayouter', () => { it('defaultParams', () => { const model = createModel(); layout(layoutRegistry, log, map, model); - expect(map.get(model)!.bounds).to.deep.equal({ x: 0, y: 0, width: 13, height: 18 }); - expect(map.get(model.children[0])!.bounds).to.deep.equal({ x: 6, y: 5, width: 1, height: 2 }); - expect(map.get(model.children[1])!.bounds).to.deep.equal({ x: 5.5, y: 8, width: 2, height: 1 }); - expect(map.get(model.children[2])!.bounds).to.deep.equal({ x: 5, y: 10, width: 3, height: 3 }); + expect(map.get(model)!.bounds).toEqual({ x: 0, y: 0, width: 13, height: 18 }); + expect(map.get(model.children[0])!.bounds).toEqual({ x: 6, y: 5, width: 1, height: 2 }); + expect(map.get(model.children[1])!.bounds).toEqual({ x: 5.5, y: 8, width: 2, height: 1 }); + expect(map.get(model.children[2])!.bounds).toEqual({ x: 5, y: 10, width: 3, height: 3 }); }); it('alignLeft', () => { @@ -51,10 +50,10 @@ describe('VBoxLayouter', () => { hAlign: 'left' }; layout(layoutRegistry, log, map, model); - expect(map.get(model)!.bounds).to.deep.equal({ x: 0, y: 0, width: 13, height: 18 }); - expect(map.get(model.children[0])!.bounds).to.deep.equal({ x: 5, y: 5, width: 1, height: 2 }); - expect(map.get(model.children[1])!.bounds).to.deep.equal({ x: 5, y: 8, width: 2, height: 1 }); - expect(map.get(model.children[2])!.bounds).to.deep.equal({ x: 5, y: 10, width: 3, height: 3 }); + expect(map.get(model)!.bounds).toEqual({ x: 0, y: 0, width: 13, height: 18 }); + expect(map.get(model.children[0])!.bounds).toEqual({ x: 5, y: 5, width: 1, height: 2 }); + expect(map.get(model.children[1])!.bounds).toEqual({ x: 5, y: 8, width: 2, height: 1 }); + expect(map.get(model.children[2])!.bounds).toEqual({ x: 5, y: 10, width: 3, height: 3 }); }); it('alignCenter', () => { @@ -63,10 +62,10 @@ describe('VBoxLayouter', () => { hAlign: 'center' }; layout(layoutRegistry, log, map, model); - expect(map.get(model)!.bounds).to.deep.equal({ x: 0, y: 0, width: 13, height: 18 }); - expect(map.get(model.children[0])!.bounds).to.deep.equal({ x: 6, y: 5, width: 1, height: 2 }); - expect(map.get(model.children[1])!.bounds).to.deep.equal({ x: 5.5, y: 8, width: 2, height: 1 }); - expect(map.get(model.children[2])!.bounds).to.deep.equal({ x: 5, y: 10, width: 3, height: 3 }); + expect(map.get(model)!.bounds).toEqual({ x: 0, y: 0, width: 13, height: 18 }); + expect(map.get(model.children[0])!.bounds).toEqual({ x: 6, y: 5, width: 1, height: 2 }); + expect(map.get(model.children[1])!.bounds).toEqual({ x: 5.5, y: 8, width: 2, height: 1 }); + expect(map.get(model.children[2])!.bounds).toEqual({ x: 5, y: 10, width: 3, height: 3 }); }); it('alignRight', () => { @@ -75,10 +74,10 @@ describe('VBoxLayouter', () => { hAlign: 'right' }; layout(layoutRegistry, log, map, model); - expect(map.get(model)!.bounds).to.deep.equal({ x: 0, y: 0, width: 13, height: 18 }); - expect(map.get(model.children[0])!.bounds).to.deep.equal({ x: 7, y: 5, width: 1, height: 2 }); - expect(map.get(model.children[1])!.bounds).to.deep.equal({ x: 6, y: 8, width: 2, height: 1 }); - expect(map.get(model.children[2])!.bounds).to.deep.equal({ x: 5, y: 10, width: 3, height: 3 }); + expect(map.get(model)!.bounds).toEqual({ x: 0, y: 0, width: 13, height: 18 }); + expect(map.get(model.children[0])!.bounds).toEqual({ x: 7, y: 5, width: 1, height: 2 }); + expect(map.get(model.children[1])!.bounds).toEqual({ x: 6, y: 8, width: 2, height: 1 }); + expect(map.get(model.children[2])!.bounds).toEqual({ x: 5, y: 10, width: 3, height: 3 }); }); it('padding', () => { @@ -90,10 +89,10 @@ describe('VBoxLayouter', () => { paddingRight: 10 }; layout(layoutRegistry, log, map, model); - expect(map.get(model)!.bounds).to.deep.equal({ x: 0, y: 0, width: 22, height: 23 }); - expect(map.get(model.children[0])!.bounds).to.deep.equal({ x: 10, y: 7, width: 1, height: 2 }); - expect(map.get(model.children[1])!.bounds).to.deep.equal({ x: 9.5, y: 10, width: 2, height: 1 }); - expect(map.get(model.children[2])!.bounds).to.deep.equal({ x: 9, y: 12, width: 3, height: 3 }); + expect(map.get(model)!.bounds).toEqual({ x: 0, y: 0, width: 22, height: 23 }); + expect(map.get(model.children[0])!.bounds).toEqual({ x: 10, y: 7, width: 1, height: 2 }); + expect(map.get(model.children[1])!.bounds).toEqual({ x: 9.5, y: 10, width: 2, height: 1 }); + expect(map.get(model.children[2])!.bounds).toEqual({ x: 9, y: 12, width: 3, height: 3 }); }); it('vGap', () => { @@ -102,10 +101,10 @@ describe('VBoxLayouter', () => { vGap: 4 }; layout(layoutRegistry, log, map, model); - expect(map.get(model)!.bounds).to.deep.equal({ x: 0, y: 0, width: 13, height: 24 }); - expect(map.get(model.children[0])!.bounds).to.deep.equal({ x: 6, y: 5, width: 1, height: 2 }); - expect(map.get(model.children[1])!.bounds).to.deep.equal({ x: 5.5, y: 11, width: 2, height: 1 }); - expect(map.get(model.children[2])!.bounds).to.deep.equal({ x: 5, y: 16, width: 3, height: 3 }); + expect(map.get(model)!.bounds).toEqual({ x: 0, y: 0, width: 13, height: 24 }); + expect(map.get(model.children[0])!.bounds).toEqual({ x: 6, y: 5, width: 1, height: 2 }); + expect(map.get(model.children[1])!.bounds).toEqual({ x: 5.5, y: 11, width: 2, height: 1 }); + expect(map.get(model.children[2])!.bounds).toEqual({ x: 5, y: 16, width: 3, height: 3 }); }); it('paddingFactor', () => { @@ -114,10 +113,10 @@ describe('VBoxLayouter', () => { paddingFactor: 2 }; layout(layoutRegistry, log, map, model); - expect(map.get(model)!.bounds).to.deep.equal({ x: 0, y: 0, width: 13, height: 18 }); - expect(map.get(model.children[0])!.bounds).to.deep.equal({ x: 9, y: 9, width: 1, height: 2 }); - expect(map.get(model.children[1])!.bounds).to.deep.equal({ x: 8.5, y: 12, width: 2, height: 1 }); - expect(map.get(model.children[2])!.bounds).to.deep.equal({ x: 8, y: 14, width: 3, height: 3 }); + expect(map.get(model)!.bounds).toEqual({ x: 0, y: 0, width: 13, height: 18 }); + expect(map.get(model.children[0])!.bounds).toEqual({ x: 9, y: 9, width: 1, height: 2 }); + expect(map.get(model.children[1])!.bounds).toEqual({ x: 8.5, y: 12, width: 2, height: 1 }); + expect(map.get(model.children[2])!.bounds).toEqual({ x: 8, y: 14, width: 3, height: 3 }); }); it('minWidth', () => { @@ -126,10 +125,10 @@ describe('VBoxLayouter', () => { minWidth: 25 }; layout(layoutRegistry, log, map, model); - expect(map.get(model)!.bounds).to.deep.equal({ x: 0, y: 0, width: 25, height: 18 }); - expect(map.get(model.children[0])!.bounds).to.deep.equal({ x: 12, y: 5, width: 1, height: 2 }); - expect(map.get(model.children[1])!.bounds).to.deep.equal({ x: 11.5, y: 8, width: 2, height: 1 }); - expect(map.get(model.children[2])!.bounds).to.deep.equal({ x: 11, y: 10, width: 3, height: 3 }); + expect(map.get(model)!.bounds).toEqual({ x: 0, y: 0, width: 25, height: 18 }); + expect(map.get(model.children[0])!.bounds).toEqual({ x: 12, y: 5, width: 1, height: 2 }); + expect(map.get(model.children[1])!.bounds).toEqual({ x: 11.5, y: 8, width: 2, height: 1 }); + expect(map.get(model.children[2])!.bounds).toEqual({ x: 11, y: 10, width: 3, height: 3 }); }); it('minHeight', () => { @@ -138,10 +137,10 @@ describe('VBoxLayouter', () => { minHeight: 25 }; layout(layoutRegistry, log, map, model); - expect(map.get(model)!.bounds).to.deep.equal({ x: 0, y: 0, width: 13, height: 25 }); - expect(map.get(model.children[0])!.bounds).to.deep.equal({ x: 6, y: 5, width: 1, height: 2 }); - expect(map.get(model.children[1])!.bounds).to.deep.equal({ x: 5.5, y: 8, width: 2, height: 1 }); - expect(map.get(model.children[2])!.bounds).to.deep.equal({ x: 5, y: 10, width: 3, height: 3 }); + expect(map.get(model)!.bounds).toEqual({ x: 0, y: 0, width: 13, height: 25 }); + expect(map.get(model.children[0])!.bounds).toEqual({ x: 6, y: 5, width: 1, height: 2 }); + expect(map.get(model.children[1])!.bounds).toEqual({ x: 5.5, y: 8, width: 2, height: 1 }); + expect(map.get(model.children[2])!.bounds).toEqual({ x: 5, y: 10, width: 3, height: 3 }); }); it('prefWidth', () => { @@ -150,10 +149,10 @@ describe('VBoxLayouter', () => { prefWidth: 20 }; layout(layoutRegistry, log, map, model); - expect(map.get(model)!.bounds).to.deep.equal({ x: 0, y: 0, width: 20, height: 18 }); - expect(map.get(model.children[0])!.bounds).to.deep.equal({ x: 9.5, y: 5, width: 1, height: 2 }); - expect(map.get(model.children[1])!.bounds).to.deep.equal({ x: 9, y: 8, width: 2, height: 1 }); - expect(map.get(model.children[2])!.bounds).to.deep.equal({ x: 8.5, y: 10, width: 3, height: 3 }); + expect(map.get(model)!.bounds).toEqual({ x: 0, y: 0, width: 20, height: 18 }); + expect(map.get(model.children[0])!.bounds).toEqual({ x: 9.5, y: 5, width: 1, height: 2 }); + expect(map.get(model.children[1])!.bounds).toEqual({ x: 9, y: 8, width: 2, height: 1 }); + expect(map.get(model.children[2])!.bounds).toEqual({ x: 8.5, y: 10, width: 3, height: 3 }); }); it('prefHeight', () => { @@ -162,9 +161,9 @@ describe('VBoxLayouter', () => { prefHeight: 20 }; layout(layoutRegistry, log, map, model); - expect(map.get(model)!.bounds).to.deep.equal({ x: 0, y: 0, width: 13, height: 20 }); - expect(map.get(model.children[0])!.bounds).to.deep.equal({ x: 6, y: 5, width: 1, height: 2 }); - expect(map.get(model.children[1])!.bounds).to.deep.equal({ x: 5.5, y: 8, width: 2, height: 1 }); - expect(map.get(model.children[2])!.bounds).to.deep.equal({ x: 5, y: 10, width: 3, height: 3 }); + expect(map.get(model)!.bounds).toEqual({ x: 0, y: 0, width: 13, height: 20 }); + expect(map.get(model.children[0])!.bounds).toEqual({ x: 6, y: 5, width: 1, height: 2 }); + expect(map.get(model.children[1])!.bounds).toEqual({ x: 5.5, y: 8, width: 2, height: 1 }); + expect(map.get(model.children[2])!.bounds).toEqual({ x: 5, y: 10, width: 3, height: 3 }); }); }); diff --git a/packages/client/src/features/change-bounds/point-position-updater.spec.ts b/packages/client/src/features/change-bounds/point-position-updater.spec.ts index 7a768434..92d2f10b 100644 --- a/packages/client/src/features/change-bounds/point-position-updater.spec.ts +++ b/packages/client/src/features/change-bounds/point-position-updater.spec.ts @@ -17,7 +17,7 @@ /* eslint-disable @typescript-eslint/no-deprecated */ import { GModelElement } from '@eclipse-glsp/sprotty'; -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { GridSnapper } from './../grid/grid-snapper'; import { PointPositionUpdater } from './point-position-updater'; @@ -25,31 +25,31 @@ describe('PointPositionUpdater', () => { it('updatePosition with no last drag position', () => { const element = new GModelElement(); const updater = new PointPositionUpdater(); - expect(updater.updatePosition(element, { x: 0, y: 0 }, false)).to.be.undefined; - expect(updater.updatePosition(element, { x: 0, y: 0 }, true)).to.be.undefined; + expect(updater.updatePosition(element, { x: 0, y: 0 }, false)).toBeUndefined(); + expect(updater.updatePosition(element, { x: 0, y: 0 }, true)).toBeUndefined(); }); it('update last position and reset', () => { const updater = new PointPositionUpdater(); - expect(updater.isLastDragPositionUndefined()).to.be.true; + expect(updater.isLastDragPositionUndefined()).toBe(true); updater.updateLastDragPosition({ x: 0, y: 0 }); - expect(updater.isLastDragPositionUndefined()).to.be.false; + expect(updater.isLastDragPositionUndefined()).toBe(false); updater.resetPosition(); - expect(updater.isLastDragPositionUndefined()).to.be.true; + expect(updater.isLastDragPositionUndefined()).toBe(true); }); it('updatePosition with no snapper', () => { const element = new GModelElement(); const updater = new PointPositionUpdater(); resetUpdater(updater); - expect(updater.updatePosition(element, { x: 0, y: 0 }, false)).to.be.undefined; - expect(updater.updatePosition(element, { x: 0, y: 0 }, true)).to.be.undefined; + expect(updater.updatePosition(element, { x: 0, y: 0 }, false)).toBeUndefined(); + expect(updater.updatePosition(element, { x: 0, y: 0 }, true)).toBeUndefined(); resetUpdater(updater); - expect(updater.updatePosition(element, { x: 5, y: 3 }, false)).to.be.deep.equals({ x: 5, y: 3 }); - expect(updater.updatePosition(element, { x: 5, y: 3 }, true)).to.be.undefined; - expect(updater.updatePosition(element, { x: 11, y: 6 }, false)).to.be.deep.equals({ x: 6, y: 3 }); - expect(updater.updatePosition(element, { x: -3, y: 2 }, true)).to.be.deep.equals({ x: -14, y: -4 }); + expect(updater.updatePosition(element, { x: 5, y: 3 }, false)).toEqual({ x: 5, y: 3 }); + expect(updater.updatePosition(element, { x: 5, y: 3 }, true)).toBeUndefined(); + expect(updater.updatePosition(element, { x: 11, y: 6 }, false)).toEqual({ x: 6, y: 3 }); + expect(updater.updatePosition(element, { x: -3, y: 2 }, true)).toEqual({ x: -14, y: -4 }); }); it('updatePosition with snapper', () => { @@ -57,21 +57,21 @@ describe('PointPositionUpdater', () => { const snapper = new GridSnapper(); const updater = new PointPositionUpdater(snapper); resetUpdater(updater); - expect(updater.updatePosition(element, { x: 0, y: 0 }, false)).to.be.undefined; - expect(updater.updatePosition(element, { x: 0, y: 0 }, true)).to.be.undefined; + expect(updater.updatePosition(element, { x: 0, y: 0 }, false)).toBeUndefined(); + expect(updater.updatePosition(element, { x: 0, y: 0 }, true)).toBeUndefined(); resetUpdater(updater); - expect(updater.updatePosition(element, { x: 5, y: 3 }, true)).to.be.deep.equals({ x: 10, y: 0 }); - expect(updater.updatePosition(element, { x: 5, y: 3 }, true)).to.be.undefined; - expect(updater.updatePosition(element, { x: 11, y: 6 }, true)).to.be.deep.equals({ x: 0, y: 10 }); - expect(updater.updatePosition(element, { x: -3, y: 2 }, true)).to.be.deep.equals({ x: -10, y: -10 }); + expect(updater.updatePosition(element, { x: 5, y: 3 }, true)).toEqual({ x: 10, y: 0 }); + expect(updater.updatePosition(element, { x: 5, y: 3 }, true)).toBeUndefined(); + expect(updater.updatePosition(element, { x: 11, y: 6 }, true)).toEqual({ x: 0, y: 10 }); + expect(updater.updatePosition(element, { x: -3, y: 2 }, true)).toEqual({ x: -10, y: -10 }); // disable snapping (alt key) resetUpdater(updater); - expect(updater.updatePosition(element, { x: 5, y: 3 }, false)).to.be.deep.equals({ x: 5, y: 3 }); - expect(updater.updatePosition(element, { x: 5, y: 3 }, false)).to.be.undefined; - expect(updater.updatePosition(element, { x: 11, y: 6 }, false)).to.be.deep.equals({ x: 6, y: 3 }); - expect(updater.updatePosition(element, { x: -3, y: 2 }, false)).to.be.deep.equals({ x: -14, y: -4 }); + expect(updater.updatePosition(element, { x: 5, y: 3 }, false)).toEqual({ x: 5, y: 3 }); + expect(updater.updatePosition(element, { x: 5, y: 3 }, false)).toBeUndefined(); + expect(updater.updatePosition(element, { x: 11, y: 6 }, false)).toEqual({ x: 6, y: 3 }); + expect(updater.updatePosition(element, { x: -3, y: 2 }, false)).toEqual({ x: -14, y: -4 }); }); function resetUpdater(updater: PointPositionUpdater): void { diff --git a/packages/client/src/features/grid/grid-snapper.spec.ts b/packages/client/src/features/grid/grid-snapper.spec.ts index 737cd3de..779c65d2 100644 --- a/packages/client/src/features/grid/grid-snapper.spec.ts +++ b/packages/client/src/features/grid/grid-snapper.spec.ts @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2022-2024 EclipseSource and others. + * Copyright (c) 2022-2026 EclipseSource and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -15,16 +15,16 @@ ********************************************************************************/ import { GModelElement } from '@eclipse-glsp/sprotty'; -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { GridSnapper } from './grid-snapper'; describe('GridSnapper', () => { it('snap', () => { const element = new GModelElement(); const snapper = new GridSnapper(); - expect(snapper.snap({ x: 0, y: 0 }, element)).to.be.deep.equals({ x: 0, y: 0 }); - expect(snapper.snap({ x: 4, y: 5 }, element)).to.be.deep.equals({ x: 0, y: 10 }); - expect(snapper.snap({ x: 8, y: 11 }, element)).to.be.deep.equals({ x: 10, y: 10 }); - expect(snapper.snap({ x: -7, y: -4 }, element)).to.be.deep.equals({ x: -10, y: -0 }); + expect(snapper.snap({ x: 0, y: 0 }, element)).toEqual({ x: 0, y: 0 }); + expect(snapper.snap({ x: 4, y: 5 }, element)).toEqual({ x: 0, y: 10 }); + expect(snapper.snap({ x: 8, y: 11 }, element)).toEqual({ x: 10, y: 10 }); + expect(snapper.snap({ x: -7, y: -4 }, element)).toEqual({ x: -10, y: -0 }); }); }); diff --git a/packages/client/src/features/hints/type-hint-provider.spec.ts b/packages/client/src/features/hints/type-hint-provider.spec.ts index 38d25491..47d4ab1f 100644 --- a/packages/client/src/features/hints/type-hint-provider.spec.ts +++ b/packages/client/src/features/hints/type-hint-provider.spec.ts @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2023-2024 EclipseSource and others. + * Copyright (c) 2023-2026 EclipseSource and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -32,9 +32,8 @@ import { isDeletable, isMoveable } from '@eclipse-glsp/sprotty'; -import { expect } from 'chai'; +import { describe, expect, it, vi, type Mock } from 'vitest'; import { Container } from 'inversify'; -import * as sinon from 'sinon'; import { GLSPActionDispatcher } from '../../base/action-dispatcher'; import { FeedbackActionDispatcher } from '../../base/feedback/feedback-action-dispatcher'; import { FeedbackEmitter } from '../../base/feedback/feedback-emitter'; @@ -45,10 +44,13 @@ import { Containable, isContainable, isReparentable } from './model'; import { ApplyTypeHintsAction, ApplyTypeHintsCommand, ITypeHintProvider, TypeHintProvider } from './type-hint-provider'; describe('TypeHintProvider', () => { const container = new Container(); - container.bind(GLSPActionDispatcher).toConstantValue(sinon.createStubInstance(GLSPActionDispatcher)); + container.bind(GLSPActionDispatcher).toConstantValue({} as unknown as GLSPActionDispatcher); container.bind(TYPES.IActionDispatcher).toService(GLSPActionDispatcher); - const stub = sinon.createStubInstance(FeedbackActionDispatcher); - stub.createEmitter.returns(new FeedbackEmitter(stub)); + const stub = { + createEmitter: vi.fn(), + registerFeedback: vi.fn() + } as unknown as FeedbackActionDispatcher; + (stub.createEmitter as Mock).mockReturnValue(new FeedbackEmitter(stub)); container.bind(TYPES.IFeedbackActionDispatcher).toConstantValue(stub); const typeHintProvider = container.resolve(TypeHintProvider); @@ -69,23 +71,23 @@ describe('TypeHintProvider', () => { }; it('should return `undefined` if no `SetTypeHintsAction` has been handled yet', () => { - expect(typeHintProvider.getShapeTypeHint('some')).to.be.undefined; + expect(typeHintProvider.getShapeTypeHint('some')).toBeUndefined(); }); it('should return `undefined` if no hint is registered for the given type (exact type match)', () => { typeHintProvider.handle(SetTypeHintsAction.create({ shapeHints: [nodeHint], edgeHints: [] })); - expect(typeHintProvider.getShapeTypeHint('port')).to.be.undefined; + expect(typeHintProvider.getShapeTypeHint('port')).toBeUndefined(); }); it('should return the corresponding type hint for the given type (exact type match)', () => { typeHintProvider.handle(SetTypeHintsAction.create({ shapeHints: [nodeHint, taskHint], edgeHints: [] })); - expect(typeHintProvider.getShapeTypeHint('node')).to.equal(nodeHint); - expect(typeHintProvider.getShapeTypeHint('node:task')).to.equal(taskHint); + expect(typeHintProvider.getShapeTypeHint('node')).toBe(nodeHint); + expect(typeHintProvider.getShapeTypeHint('node:task')).toBe(taskHint); }); it('should return the corresponding type hint for the given type (sub type match)', () => { typeHintProvider.handle(SetTypeHintsAction.create({ shapeHints: [nodeHint, taskHint], edgeHints: [] })); - expect(typeHintProvider.getShapeTypeHint('node:task:manual')).to.equal(taskHint); - expect(typeHintProvider.getShapeTypeHint('node:task:manual:foo')).to.equal(taskHint); - expect(typeHintProvider.getShapeTypeHint('node:event')).to.equal(nodeHint); - expect(typeHintProvider.getShapeTypeHint('node:event:initial')).to.equal(nodeHint); + expect(typeHintProvider.getShapeTypeHint('node:task:manual')).toBe(taskHint); + expect(typeHintProvider.getShapeTypeHint('node:task:manual:foo')).toBe(taskHint); + expect(typeHintProvider.getShapeTypeHint('node:event')).toBe(nodeHint); + expect(typeHintProvider.getShapeTypeHint('node:event:initial')).toBe(nodeHint); }); }); describe('getEdgeTypeHint', () => { @@ -104,23 +106,23 @@ describe('TypeHintProvider', () => { dynamic: true }; it('should return `undefined` if no `SetTypeHintsAction` has been handled yet', () => { - expect(typeHintProvider.getEdgeTypeHint('some')).to.be.undefined; + expect(typeHintProvider.getEdgeTypeHint('some')).toBeUndefined(); }); it('should return `undefined` if no hint is registered for the given type (exact type match)', () => { typeHintProvider.handle(SetTypeHintsAction.create({ shapeHints: [], edgeHints: [edgeHint] })); - expect(typeHintProvider.getEdgeTypeHint('link')).to.be.undefined; + expect(typeHintProvider.getEdgeTypeHint('link')).toBeUndefined(); }); it('should return the corresponding type hint for the given type (exact type match)', () => { typeHintProvider.handle(SetTypeHintsAction.create({ shapeHints: [], edgeHints: [edgeHint, fooEdgeHint] })); - expect(typeHintProvider.getEdgeTypeHint('edge')).to.equal(edgeHint); - expect(typeHintProvider.getEdgeTypeHint('edge:foo')).to.equal(fooEdgeHint); + expect(typeHintProvider.getEdgeTypeHint('edge')).toBe(edgeHint); + expect(typeHintProvider.getEdgeTypeHint('edge:foo')).toBe(fooEdgeHint); }); it('should return the corresponding type hint for the given type (sub type match)', () => { typeHintProvider.handle(SetTypeHintsAction.create({ shapeHints: [], edgeHints: [edgeHint, fooEdgeHint] })); - expect(typeHintProvider.getEdgeTypeHint('edge:foo:bar')).to.equal(fooEdgeHint); - expect(typeHintProvider.getEdgeTypeHint('edge:foo:bar:baz')).to.equal(fooEdgeHint); - expect(typeHintProvider.getEdgeTypeHint('edge:some')).to.equal(edgeHint); - expect(typeHintProvider.getEdgeTypeHint('edge:some:other')).to.equal(edgeHint); + expect(typeHintProvider.getEdgeTypeHint('edge:foo:bar')).toBe(fooEdgeHint); + expect(typeHintProvider.getEdgeTypeHint('edge:foo:bar:baz')).toBe(fooEdgeHint); + expect(typeHintProvider.getEdgeTypeHint('edge:some')).toBe(edgeHint); + expect(typeHintProvider.getEdgeTypeHint('edge:some:other')).toBe(edgeHint); }); }); }); @@ -156,24 +158,19 @@ describe('ApplyTypeHintCommand', () => { return edge; } - const sandbox = sinon.createSandbox(); const container = new Container(); - const modelFactory = sinon.createStubInstance(GModelFactory); - const typeHintProviderMock = sandbox.stub({ - getEdgeTypeHint: () => undefined, - getShapeTypeHint: () => undefined - }); - container.bind(GLSPActionDispatcher).toConstantValue(sandbox.createStubInstance(GLSPActionDispatcher)); + const modelFactory = {} as unknown as GModelFactory; + const typeHintProviderMock = { + getEdgeTypeHint: vi.fn(), + getShapeTypeHint: vi.fn() + } as unknown as ITypeHintProvider; + container.bind(GLSPActionDispatcher).toConstantValue({} as unknown as GLSPActionDispatcher); container.bind(TYPES.IActionDispatcher).toService(GLSPActionDispatcher); - container.bind(TYPES.IFeedbackActionDispatcher).toConstantValue(sandbox.createStubInstance(FeedbackActionDispatcher)); + container.bind(TYPES.IFeedbackActionDispatcher).toConstantValue({} as unknown as FeedbackActionDispatcher); container.bind(TYPES.ITypeHintProvider).toConstantValue(typeHintProviderMock); bindOrRebind(container, TYPES.Action).toConstantValue(ApplyTypeHintsAction.create()); const command = container.resolve(ApplyTypeHintsCommand); - beforeEach(() => { - sandbox.reset(); - }); - describe('test hints to model feature translation (after command execution)`', () => { describe('ShapeTypeHint', () => { const allEnabledHint: ShapeTypeHint = { @@ -193,31 +190,31 @@ describe('ApplyTypeHintCommand', () => { containableElementTypeIds: [] }; it('should not modify feature set of model element with no applicable type hint', () => { - typeHintProviderMock.getShapeTypeHint.returns(undefined); + (typeHintProviderMock.getShapeTypeHint as Mock).mockReturnValue(undefined); const result = command.execute(createCommandExecutionContext(createNode())); const element = result.children[0]; - expect(GNode.DEFAULT_FEATURES, 'Element should have default feature set').to.have.same.members([ - ...(element.features as Set) - ]); + expect(new Set(GNode.DEFAULT_FEATURES), 'Element should have default feature set').toEqual( + new Set(element.features as Set) + ); }); it('should add all enabled (`true`) features, derived from the applied type hint, to the model', () => { - typeHintProviderMock.getShapeTypeHint.returns(allEnabledHint); + (typeHintProviderMock.getShapeTypeHint as Mock).mockReturnValue(allEnabledHint); const result = command.execute(createCommandExecutionContext(createNode())); const element = result.children[0]; - expect(isDeletable(element), 'Element should have deletable feature').to.be.true; - expect(isReparentable(element), 'Element should have reparentable feature').to.be.true; - expect(isMoveable(element), 'Element should have moveable feature').to.be.true; - expect(isContainable(element), 'Element should have containable feature').to.be.true; - expect(isResizable(element), 'Element should have resizeable feature').to.be.true; + expect(isDeletable(element), 'Element should have deletable feature').toBe(true); + expect(isReparentable(element), 'Element should have reparentable feature').toBe(true); + expect(isMoveable(element), 'Element should have moveable feature').toBe(true); + expect(isContainable(element), 'Element should have containable feature').toBe(true); + expect(isResizable(element), 'Element should have resizeable feature').toBe(true); }); it('should remove all disabled (`false`) features, derived from the applied type hint, from the model', () => { - typeHintProviderMock.getShapeTypeHint.returns(allDisabledHint); + (typeHintProviderMock.getShapeTypeHint as Mock).mockReturnValue(allDisabledHint); const result = command.execute(createCommandExecutionContext(createNode())); const element = result.children[0]; - expect(isDeletable(element), 'Element should not have deletable feature').to.be.false; - expect(isReparentable(element), 'Element should not have reparentable feature').to.be.false; - expect(isMoveable(element), 'Element should not have moveable feature').to.be.false; - expect(isResizable(element), 'Element should not have resizeable feature').to.be.false; + expect(isDeletable(element), 'Element should not have deletable feature').toBe(false); + expect(isReparentable(element), 'Element should not have reparentable feature').toBe(false); + expect(isMoveable(element), 'Element should not have moveable feature').toBe(false); + expect(isResizable(element), 'Element should not have resizeable feature').toBe(false); }); describe('`isConnectable` (after hint has been applied to element)', () => { const shapeHint: Writable = { @@ -234,58 +231,58 @@ describe('ApplyTypeHintCommand', () => { routable: false }; it('should return `true` if source/target elements are not defined in edge hint', () => { - typeHintProviderMock.getShapeTypeHint.returns(shapeHint); - typeHintProviderMock.getEdgeTypeHint.returns(edgeHint); + (typeHintProviderMock.getShapeTypeHint as Mock).mockReturnValue(shapeHint); + (typeHintProviderMock.getEdgeTypeHint as Mock).mockReturnValue(edgeHint); const result = command.execute(createCommandExecutionContext(createNode())); const element = result.children[0] as GNode; const edge = createEdge(); - expect(element.canConnect(edge, 'source')).to.be.true; - expect(element.canConnect(edge, 'target')).to.be.true; + expect(element.canConnect(edge, 'source')).toBe(true); + expect(element.canConnect(edge, 'target')).toBe(true); }); it('should return `false` if element type is not in source/target elements of edge hint', () => { - typeHintProviderMock.getShapeTypeHint.returns(shapeHint); - typeHintProviderMock.getEdgeTypeHint.returns(edgeHint); + (typeHintProviderMock.getShapeTypeHint as Mock).mockReturnValue(shapeHint); + (typeHintProviderMock.getEdgeTypeHint as Mock).mockReturnValue(edgeHint); edgeHint.sourceElementTypeIds = []; edgeHint.targetElementTypeIds = []; const result = command.execute(createCommandExecutionContext(createNode())); const element = result.children[0] as GNode; const edge = createEdge(); - expect(element.canConnect(edge, 'source')).to.be.false; - expect(element.canConnect(edge, 'target')).to.be.false; + expect(element.canConnect(edge, 'source')).toBe(false); + expect(element.canConnect(edge, 'target')).toBe(false); }); it('should return `true` if element type is in source/target elements of edge hint (exact type)', () => { - typeHintProviderMock.getShapeTypeHint.returns(shapeHint); - typeHintProviderMock.getEdgeTypeHint.returns(edgeHint); + (typeHintProviderMock.getShapeTypeHint as Mock).mockReturnValue(shapeHint); + (typeHintProviderMock.getEdgeTypeHint as Mock).mockReturnValue(edgeHint); edgeHint.sourceElementTypeIds = ['node']; edgeHint.targetElementTypeIds = ['node']; const result = command.execute(createCommandExecutionContext(createNode())); const element = result.children[0] as GNode; const edge = createEdge(); - expect(element.canConnect(edge, 'source')).to.be.true; - expect(element.canConnect(edge, 'target')).to.be.true; + expect(element.canConnect(edge, 'source')).toBe(true); + expect(element.canConnect(edge, 'target')).toBe(true); }); it('should return `true` if element super type is in source/target elements of edge hint (super type)', () => { - typeHintProviderMock.getShapeTypeHint.returns(shapeHint); - typeHintProviderMock.getEdgeTypeHint.returns(edgeHint); + (typeHintProviderMock.getShapeTypeHint as Mock).mockReturnValue(shapeHint); + (typeHintProviderMock.getEdgeTypeHint as Mock).mockReturnValue(edgeHint); edgeHint.sourceElementTypeIds = ['node']; edgeHint.targetElementTypeIds = ['node']; const result = command.execute(createCommandExecutionContext(createNode('node:task:automated'))); const element = result.children[0] as GNode; const edge = createEdge(); - expect(element.canConnect(edge, 'source')).to.be.true; - expect(element.canConnect(edge, 'target')).to.be.true; + expect(element.canConnect(edge, 'source')).toBe(true); + expect(element.canConnect(edge, 'target')).toBe(true); }); it('should fallback to class-level `canConnect` implementation if no edge hint is applicable to routable', () => { - typeHintProviderMock.getEdgeTypeHint.returns(undefined); - typeHintProviderMock.getShapeTypeHint.returns(shapeHint); + (typeHintProviderMock.getEdgeTypeHint as Mock).mockReturnValue(undefined); + (typeHintProviderMock.getShapeTypeHint as Mock).mockReturnValue(shapeHint); const node = createNode(); - const originalCanConnectSpy = sinon.spy(node, 'canConnect'); + const originalCanConnectSpy = vi.spyOn(node, 'canConnect'); const result = command.execute(createCommandExecutionContext(node)); const element = result.children[0] as GNode; const edge = createEdge(); - expect(element.canConnect(edge, 'source')).to.be.true; - expect(element.canConnect(edge, 'target')).to.be.true; - expect(originalCanConnectSpy.called).to.be.true; + expect(element.canConnect(edge, 'source')).toBe(true); + expect(element.canConnect(edge, 'target')).toBe(true); + expect(originalCanConnectSpy).toHaveBeenCalled(); }); }); describe('`isContainable` (after hint has been applied to element)', () => { @@ -297,24 +294,24 @@ describe('ApplyTypeHintCommand', () => { resizable: false }; it('should return `false` if corresponding hint has no containable elements defined', () => { - typeHintProviderMock.getShapeTypeHint.returns(shapeHint); + (typeHintProviderMock.getShapeTypeHint as Mock).mockReturnValue(shapeHint); const result = command.execute(createCommandExecutionContext(createNode('node'))); const element = result.children[0] as GNode & Containable; - expect(element.isContainableElement('other')).to.be.false; + expect(element.isContainableElement('other')).toBe(false); }); it('should return `true` if corresponding hint has containable element with matching type', () => { - typeHintProviderMock.getShapeTypeHint.returns(shapeHint); + (typeHintProviderMock.getShapeTypeHint as Mock).mockReturnValue(shapeHint); shapeHint.containableElementTypeIds = ['node']; const result = command.execute(createCommandExecutionContext(createNode('node'))); const element = result.children[0] as GNode & Containable; - expect(element.isContainableElement('node')).to.be.true; + expect(element.isContainableElement('node')).toBe(true); }); it('should return `true` if corresponding hint as has containable element with matching super type', () => { - typeHintProviderMock.getShapeTypeHint.returns(shapeHint); + (typeHintProviderMock.getShapeTypeHint as Mock).mockReturnValue(shapeHint); shapeHint.containableElementTypeIds = ['node']; const result = command.execute(createCommandExecutionContext(createNode('node'))); const element = result.children[0] as GNode & Containable; - expect(element.isContainableElement('node:task:automated')).to.be.true; + expect(element.isContainableElement('node:task:automated')).toBe(true); }); }); }); @@ -332,28 +329,28 @@ describe('ApplyTypeHintCommand', () => { routable: false }; it('should not modify feature set of model element with no applicable type hint', () => { - typeHintProviderMock.getEdgeTypeHint.returns(undefined); + (typeHintProviderMock.getEdgeTypeHint as Mock).mockReturnValue(undefined); const result = command.execute(createCommandExecutionContext(createEdge())); const element = result.children[0]; - expect(GEdge.DEFAULT_FEATURES, 'Element should have default feature set').to.have.same.members([ - ...(element.features as Set) - ]); + expect(new Set(GEdge.DEFAULT_FEATURES), 'Element should have default feature set').toEqual( + new Set(element.features as Set) + ); }); it('should add all enabled (`true`) features, derived from the applied type hint, to the model', () => { - typeHintProviderMock.getEdgeTypeHint.returns(allEnabledHint); + (typeHintProviderMock.getEdgeTypeHint as Mock).mockReturnValue(allEnabledHint); const result = command.execute(createCommandExecutionContext(createEdge())); const element = result.children[0]; - expect(isDeletable(element), 'Element should have deletable feature').to.be.true; - expect(element.hasFeature(editFeature), 'Element should have edit feature').to.be.true; - expect(isReconnectable(element), 'Element should have reconnectable feature').to.be.true; + expect(isDeletable(element), 'Element should have deletable feature').toBe(true); + expect(element.hasFeature(editFeature), 'Element should have edit feature').toBe(true); + expect(isReconnectable(element), 'Element should have reconnectable feature').toBe(true); }); it('should remove all disabled (`false`) features, derived from the applied type hint, from the model', () => { - typeHintProviderMock.getEdgeTypeHint.returns(allDisabledHint); + (typeHintProviderMock.getEdgeTypeHint as Mock).mockReturnValue(allDisabledHint); const result = command.execute(createCommandExecutionContext(createEdge())); const element = result.children[0]; - expect(isDeletable(element), 'Element should not have deletable feature').to.be.false; - expect(element.hasFeature(editFeature), 'Element should not have edit feature').to.be.false; - expect(isReconnectable(element), 'Element should not have reconnectable feature').to.be.false; + expect(isDeletable(element), 'Element should not have deletable feature').toBe(false); + expect(element.hasFeature(editFeature), 'Element should not have edit feature').toBe(false); + expect(isReconnectable(element), 'Element should not have reconnectable feature').toBe(false); }); }); }); diff --git a/packages/client/src/features/layout/layout-elements-action.spec.ts b/packages/client/src/features/layout/layout-elements-action.spec.ts index d533091f..185da8bf 100644 --- a/packages/client/src/features/layout/layout-elements-action.spec.ts +++ b/packages/client/src/features/layout/layout-elements-action.spec.ts @@ -37,11 +37,9 @@ import { SetBoundsAction, SetBoundsCommand } from '@eclipse-glsp/sprotty'; -import { expect } from 'chai'; +import { beforeEach, describe, expect, it } from 'vitest'; import { Container } from 'inversify'; -import 'mocha'; import 'reflect-metadata'; -import * as sinon from 'sinon'; import { defaultModule } from '../../base/default.module'; import { SelectionService } from '../../base/selection-service'; import { GGraph } from '../../model'; @@ -139,7 +137,7 @@ function applyFeature(element: GChildElement, feature: symbol): void { const context: CommandExecutionContext = { root: model, - modelFactory: sinon.createStubInstance(GModelFactory), + modelFactory: {} as unknown as GModelFactory, duration: 0, modelChanged: undefined!, logger: new ConsoleLogger(), @@ -382,17 +380,17 @@ function assertBounds(nodeId: string, bounds: Bounds): void { function assertBoundsInMoves(nodeId: string, bounds: Bounds): void { const moves = dispatchedElementMoves(); const move = getMoveById(nodeId, moves); - expect(move.toPosition.x).to.be.equal(bounds.x); - expect(move.toPosition.y).to.be.equal(bounds.y); + expect(move.toPosition.x).toBe(bounds.x); + expect(move.toPosition.y).toBe(bounds.y); } function assertBoundsInChangeBoundsActions(nodeId: string, bounds: Bounds): void { const allChangeBounds = dispatchedChangeBounds(); const changeBounds = getElementAndBoundsById(nodeId, allChangeBounds); - expect(changeBounds.newPosition!.x).to.be.equal(bounds.x); - expect(changeBounds.newPosition!.y).to.be.equal(bounds.y); - expect(changeBounds.newSize!.height).to.be.equal(bounds.height); - expect(changeBounds.newSize!.width).to.be.equal(bounds.width); + expect(changeBounds.newPosition!.x).toBe(bounds.x); + expect(changeBounds.newPosition!.y).toBe(bounds.y); + expect(changeBounds.newSize!.height).toBe(bounds.height); + expect(changeBounds.newSize!.width).toBe(bounds.width); } function getMoveById(id: string, moves: ElementMove[]): ElementMove { diff --git a/packages/client/src/features/navigation/navigation-target-resolver.spec.ts b/packages/client/src/features/navigation/navigation-target-resolver.spec.ts index 5c201000..044eb428 100644 --- a/packages/client/src/features/navigation/navigation-target-resolver.spec.ts +++ b/packages/client/src/features/navigation/navigation-target-resolver.spec.ts @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2020-2023 EclipseSource and others. + * Copyright (c) 2020-2026 EclipseSource and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -13,8 +13,7 @@ * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; -import 'mocha'; +import { describe, expect, it } from 'vitest'; import 'reflect-metadata'; import { NavigationTarget } from '@eclipse-glsp/sprotty'; @@ -22,35 +21,35 @@ describe('NavigationTarget', () => { it('should be able to set and get element IDs', () => { const navigationTarget: NavigationTarget = { uri: 'uri' }; NavigationTarget.setElementIds(navigationTarget, 'id1', 'id2'); - expect(NavigationTarget.getElementIds(navigationTarget)).to.be.eql(['id1', 'id2']); + expect(NavigationTarget.getElementIds(navigationTarget)).toEqual(['id1', 'id2']); }); it('should be able to set and get textual positions', () => { const navigationTarget: NavigationTarget = { uri: 'uri' }; NavigationTarget.setTextPosition(navigationTarget, { line: 1, character: 2 }); - expect(NavigationTarget.getTextPosition(navigationTarget)).to.be.eql({ line: 1, character: 2 }); + expect(NavigationTarget.getTextPosition(navigationTarget)).toEqual({ line: 1, character: 2 }); }); it('should be able to set and get custom query arguments', () => { const navigationTarget: NavigationTarget = { uri: 'uri' }; NavigationTarget.addArgument(navigationTarget, 'name', 'test'); - expect(navigationTarget.args!.name).to.be.eql('test'); + expect(navigationTarget.args!.name).toEqual('test'); }); it('should specify whether it has arguments', () => { let navigationTarget: NavigationTarget = { uri: 'uri' }; - expect(NavigationTarget.hasArguments(navigationTarget)).to.be.false; + expect(NavigationTarget.hasArguments(navigationTarget)).toBe(false); NavigationTarget.addArgument(navigationTarget, 'name', 'test'); - expect(NavigationTarget.hasArguments(navigationTarget)).to.be.true; + expect(NavigationTarget.hasArguments(navigationTarget)).toBe(true); navigationTarget = { uri: 'uri' }; - expect(NavigationTarget.hasArguments(navigationTarget)).to.be.false; + expect(NavigationTarget.hasArguments(navigationTarget)).toBe(false); NavigationTarget.setElementIds(navigationTarget, 'id1', 'id2'); - expect(NavigationTarget.hasArguments(navigationTarget)).to.be.true; + expect(NavigationTarget.hasArguments(navigationTarget)).toBe(true); navigationTarget = { uri: 'uri' }; - expect(NavigationTarget.hasArguments(navigationTarget)).to.be.false; + expect(NavigationTarget.hasArguments(navigationTarget)).toBe(false); NavigationTarget.setTextPosition(navigationTarget, { line: 1, character: 2 }); - expect(NavigationTarget.hasArguments(navigationTarget)).to.be.true; + expect(NavigationTarget.hasArguments(navigationTarget)).toBe(true); }); }); diff --git a/packages/client/src/features/routing/sticky-manhattan-edge-router.spec.ts b/packages/client/src/features/routing/sticky-manhattan-edge-router.spec.ts index dddccdf4..8413585f 100644 --- a/packages/client/src/features/routing/sticky-manhattan-edge-router.spec.ts +++ b/packages/client/src/features/routing/sticky-manhattan-edge-router.spec.ts @@ -14,7 +14,7 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ import { DefaultAnchors, EdgeRouterRegistry, GNode, GRoutableElement, Point, Side } from '@eclipse-glsp/sprotty'; -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { Container } from 'inversify'; import { GEdge, GGraph } from '../../model'; import { routingModule } from './routing-module'; @@ -91,15 +91,15 @@ describe('GLSPStickyManhattanEdgeRouter', () => { const router = container .get(EdgeRouterRegistry) .get(GLSPStickyManhattanEdgeRouter.KIND) as GLSPStickyManhattanEdgeRouter; - expect(router.route(edge)).to.deep.equal([]); + expect(router.route(edge)).toEqual([]); }); it('produces a source-first, target-last sequence with intermediate linear points', () => { const { edge, router } = setupEdge({}); const route = router.route(edge); - expect(route[0].kind).to.equal('source'); - expect(route[route.length - 1].kind).to.equal('target'); - expect(route.slice(1, -1).every(p => p.kind === 'linear')).to.equal(true); + expect(route[0].kind).toBe('source'); + expect(route[route.length - 1].kind).toBe('target'); + expect(route.slice(1, -1).every(p => p.kind === 'linear')).toBe(true); }); it('computes a two-corner default route for horizontally separated nodes', () => { @@ -107,9 +107,9 @@ describe('GLSPStickyManhattanEdgeRouter', () => { const route = router.route(edge); // source RIGHT -> target LEFT with different Y: two corners at midX. const interior = route.slice(1, -1); - expect(interior).to.have.lengthOf(2); - expect(interior[0].x).to.equal(interior[1].x); - expect(interior[0].y).to.not.equal(interior[1].y); + expect(interior).toHaveLength(2); + expect(interior[0].x).toBe(interior[1].x); + expect(interior[0].y).not.toBe(interior[1].y); }); }); @@ -133,9 +133,9 @@ describe('GLSPStickyManhattanEdgeRouter', () => { const interior = route.slice(1, -1); // The shared x=150 spine must stay put — no recomputed midX. - expect(interior.every(p => p.x === 150)).to.equal(true); + expect(interior.every(p => p.x === 150)).toBe(true); // The target-side bend must not have moved. - expect(interior[interior.length - 1].y).to.equal(215); + expect(interior[interior.length - 1].y).toBe(215); }); }); @@ -152,8 +152,8 @@ describe('GLSPStickyManhattanEdgeRouter', () => { }); const points = edge.routingPoints.slice(); router.cleanupRoutingPoints(edge, points, false, false); - expect(points).to.not.deep.include({ x: 10, y: 10 }); - expect(points[0]).to.deep.equal({ x: 150, y: 20 }); + expect(points).not.toContainEqual({ x: 10, y: 10 }); + expect(points[0]).toEqual({ x: 150, y: 20 }); }); it('collapses degenerate segments shorter than minimalPointDistance', () => { @@ -164,8 +164,8 @@ describe('GLSPStickyManhattanEdgeRouter', () => { { x: 250, y: 20 } ]; router.cleanupRoutingPoints(edge, points, false, false); - expect(points).to.have.lengthOf(1); - expect(points[0]).to.deep.equal({ x: 250, y: 20 }); + expect(points).toHaveLength(1); + expect(points[0]).toEqual({ x: 250, y: 20 }); }); }); @@ -178,7 +178,7 @@ describe('GLSPStickyManhattanEdgeRouter', () => { { x: 50, y: 50 } // diagonal ]; testable.manhattanify(points, edge); - expect(points).to.deep.equal([ + expect(points).toEqual([ { x: 0, y: 0 }, { x: 0, y: 50 }, { x: 50, y: 50 } @@ -195,7 +195,7 @@ describe('GLSPStickyManhattanEdgeRouter', () => { ]; const before = points.map(p => ({ ...p })); testable.manhattanify(points, edge); - expect(points).to.deep.equal(before); + expect(points).toEqual(before); }); }); @@ -206,7 +206,7 @@ describe('GLSPStickyManhattanEdgeRouter', () => { const sourceAnchors = new DefaultAnchors(edge.source!, edge.parent, 'source'); const targetAnchors = new DefaultAnchors(edge.target!, edge.parent, 'target'); const result = router.getBestConnectionAnchors(sourceAnchors, targetAnchors, router.getOptions(edge)); - expect(result).to.deep.equal({ source: Side.RIGHT, target: Side.LEFT }); + expect(result).toEqual({ source: Side.RIGHT, target: Side.LEFT }); }); }); }); diff --git a/packages/client/src/features/bounds/layouter-test-util.spec.ts b/packages/client/src/features/test/layouter-test-util.ts similarity index 96% rename from packages/client/src/features/bounds/layouter-test-util.spec.ts rename to packages/client/src/features/test/layouter-test-util.ts index 128c2f54..af4ad75a 100644 --- a/packages/client/src/features/bounds/layouter-test-util.spec.ts +++ b/packages/client/src/features/test/layouter-test-util.ts @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2022-2023 STMicroelectronics and others. + * Copyright (c) 2022-2026 STMicroelectronics and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -15,7 +15,6 @@ ********************************************************************************/ import { Container } from 'inversify'; -import 'mocha'; import { BoundsData, ConsoleLogger, @@ -32,7 +31,7 @@ import { layoutableChildFeature } from '@eclipse-glsp/sprotty'; import { initializeDiagramContainer } from '../../default-modules'; -import { StatefulLayouterExt } from './layouter'; +import { StatefulLayouterExt } from '../bounds/layouter'; import { GGraph } from '../../model'; export function createGraph(): GGraph { diff --git a/packages/client/src/features/tools/marquee-selection/marquee-behavior.spec.ts b/packages/client/src/features/tools/marquee-selection/marquee-behavior.spec.ts index 783211c5..2d2f03a3 100644 --- a/packages/client/src/features/tools/marquee-selection/marquee-behavior.spec.ts +++ b/packages/client/src/features/tools/marquee-selection/marquee-behavior.spec.ts @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2021-2024 EclipseSource and others. + * Copyright (c) 2021-2026 EclipseSource and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -15,7 +15,7 @@ ********************************************************************************/ import { DOMHelper } from '@eclipse-glsp/sprotty'; -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { IMarqueeBehavior, MarqueeUtil } from './marquee-behavior'; describe('MarqueeUtil', () => { diff --git a/packages/client/src/features/validation/marker-navigator.spec.ts b/packages/client/src/features/validation/marker-navigator.spec.ts index e08fb90c..01043281 100644 --- a/packages/client/src/features/validation/marker-navigator.spec.ts +++ b/packages/client/src/features/validation/marker-navigator.spec.ts @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2020-2023 EclipseSource and others. + * Copyright (c) 2020-2026 EclipseSource and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -14,9 +14,8 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ import { BoundsAware, GChildElement, GIssue, GModelElement, GModelRoot, GNode, GParentElement } from '@eclipse-glsp/sprotty'; -import { expect } from 'chai'; +import { beforeEach, describe, expect, it } from 'vitest'; import { Container } from 'inversify'; -import 'mocha'; import 'reflect-metadata'; import { defaultModule } from '../../base/default.module'; import { GGraph } from '../../model'; @@ -57,60 +56,60 @@ describe('MarkerNavigator', () => { const elementBottomRight = rootWithMarkers.children[0] as BoundsAware & GChildElement; elementBottomRight.bounds = { width: 10, height: 10, x: 200, y: 200 }; - beforeEach('clear issue marker', () => { + beforeEach(() => { [elementTopLeft, elementTopRight, elementBottomLeft, elementBottomRight].forEach(clearMarker); }); it('next(undefined) without any markers returns undefined', () => { - expect(markerNavigator.next(rootWithoutAnyMarkers)).to.be.undefined; + expect(markerNavigator.next(rootWithoutAnyMarkers)).toBeUndefined(); }); it('previous(undefined) without any markers returns undefined', () => { - expect(markerNavigator.previous(rootWithoutAnyMarkers)).to.be.undefined; + expect(markerNavigator.previous(rootWithoutAnyMarkers)).toBeUndefined(); }); it('next(undefined) with one marker returns the one marker', () => { const marker = setIssues(elementTopLeft, [{ message: 'msg', severity: 'error' }]); const next = markerNavigator.next(rootWithMarkers); - expect(next).to.eql(marker); + expect(next).toEqual(marker); }); it('next(firstMarker) with only one marker returns again the first marker', () => { const marker = setIssues(elementTopLeft, [{ message: 'msg', severity: 'error' }]); const next = markerNavigator.next(rootWithMarkers, marker); - expect(next).to.eql(marker); + expect(next).toEqual(marker); // and again and again const nextNext = markerNavigator.next(rootWithMarkers, next); - expect(nextNext).to.eql(marker); + expect(nextNext).toEqual(marker); }); it('previous(firstMarker) with only one marker returns again the first marker', () => { const marker = setIssues(elementTopLeft, [{ message: 'msg', severity: 'error' }]); const previous = markerNavigator.previous(rootWithMarkers, marker); - expect(previous).to.eql(marker); + expect(previous).toEqual(marker); // and again and again const previousPrevious = markerNavigator.previous(rootWithMarkers, previous); - expect(previousPrevious).to.eql(marker); + expect(previousPrevious).toEqual(marker); }); it('next(firstMarker) with two marker returns second marker then again first marker', () => { const marker1 = setIssues(elementTopLeft, [{ message: 'msg', severity: 'error' }]); const marker2 = setIssues(elementTopRight, [{ message: 'msg', severity: 'error' }]); const next = markerNavigator.next(rootWithMarkers, marker1); - expect(next).to.eql(marker2); + expect(next).toEqual(marker2); // and again and again const nextNext = markerNavigator.next(rootWithMarkers, next); - expect(nextNext).to.eql(marker1); + expect(nextNext).toEqual(marker1); }); it('previous(firstMarker) with two marker returns second marker then again first marker', () => { const marker1 = setIssues(elementTopLeft, [{ message: 'msg', severity: 'error' }]); const marker2 = setIssues(elementTopRight, [{ message: 'msg', severity: 'error' }]); const next = markerNavigator.previous(rootWithMarkers, marker1); - expect(next).to.eql(marker2); + expect(next).toEqual(marker2); // and again and again const nextNext = markerNavigator.previous(rootWithMarkers, next); - expect(nextNext).to.eql(marker1); + expect(nextNext).toEqual(marker1); }); it('returns markers in the order left-to-right, top-to-bottom with next()', () => { @@ -123,11 +122,11 @@ describe('MarkerNavigator', () => { const found3 = markerNavigator.next(rootWithMarkers, found2); const found4 = markerNavigator.next(rootWithMarkers, found3); const found5 = markerNavigator.next(rootWithMarkers, found4); - expect(found1).to.eql(marker1); - expect(found2).to.eql(marker2); - expect(found3).to.eql(marker3); - expect(found4).to.eql(marker4); - expect(found5).to.eql(marker1); + expect(found1).toEqual(marker1); + expect(found2).toEqual(marker2); + expect(found3).toEqual(marker3); + expect(found4).toEqual(marker4); + expect(found5).toEqual(marker1); }); it('returns markers in the order left-to-right, top-to-bottom with previous()', () => { @@ -140,11 +139,11 @@ describe('MarkerNavigator', () => { const found3 = markerNavigator.previous(rootWithMarkers, found2); const found4 = markerNavigator.previous(rootWithMarkers, found3); const found5 = markerNavigator.previous(rootWithMarkers, found4); - expect(found1).to.eql(marker1); - expect(found2).to.eql(marker4); - expect(found3).to.eql(marker3); - expect(found4).to.eql(marker2); - expect(found5).to.eql(marker1); + expect(found1).toEqual(marker1); + expect(found2).toEqual(marker4); + expect(found3).toEqual(marker3); + expect(found4).toEqual(marker2); + expect(found5).toEqual(marker1); }); }); diff --git a/packages/client/src/utils/gmodel-util.spec.ts b/packages/client/src/utils/gmodel-util.spec.ts index ea4c8159..501eeed6 100644 --- a/packages/client/src/utils/gmodel-util.spec.ts +++ b/packages/client/src/utils/gmodel-util.spec.ts @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2023 EclipseSource and others. + * Copyright (c) 2023-2026 EclipseSource and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -24,7 +24,7 @@ import { ResolvedHandleMove, RoutedPoint } from '@eclipse-glsp/sprotty'; -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { Container } from 'inversify'; import { routingModule } from '../features/routing/routing-module'; import { ALL_ROUTING_POINTS, ROUTE_KINDS, ROUTING_POINT_KINDS, calcRoute } from './gmodel-util'; @@ -110,7 +110,7 @@ describe('SModel Util', () => { { x: 40, y: 40 } ]; const route = calcRoute(edge, routerRegistry); - expect(route).to.deep.equal([ + expect(route).toEqual([ { x: 0, y: 0, kind: 'source' }, { x: 20, y: 20, kind: 'linear', pointIndex: 0 }, { x: 30, y: 30, kind: 'linear', pointIndex: 1 }, @@ -131,7 +131,7 @@ describe('SModel Util', () => { ]; const route = calcRoute(edge, routerRegistry); - expect(route).to.deep.equal([ + expect(route).toEqual([ { x: 0, y: 0, kind: 'source' }, { x: 20, y: 20, kind: 'linear', pointIndex: 0 }, { x: 30, y: 30, kind: 'linear', pointIndex: 2 }, @@ -151,7 +151,7 @@ describe('SModel Util', () => { ]; const route = calcRoute(edge, routerRegistry); - expect(route).to.deep.equal([ + expect(route).toEqual([ { x: 0, y: 0, kind: 'source' }, { x: 20, y: 20, kind: 'linear', pointIndex: 0 }, { x: 30, y: 30, kind: 'linear', pointIndex: 1 }, @@ -172,7 +172,7 @@ describe('SModel Util', () => { ]; const route = calcRoute(edge, routerRegistry, ALL_ROUTING_POINTS, 10); - expect(route).to.deep.equal([ + expect(route).toEqual([ { x: 0, y: 0, kind: 'source' }, { x: 20, y: 20, kind: 'linear', pointIndex: 0 }, { x: 30, y: 30, kind: 'linear', pointIndex: 2 }, @@ -192,7 +192,7 @@ describe('SModel Util', () => { ]; const route = calcRoute(edge, routerRegistry, ROUTE_KINDS); - expect(route).to.deep.equal([ + expect(route).toEqual([ { x: 0, y: 0, kind: 'source' }, { x: 20, y: 20, kind: 'linear', pointIndex: 0 }, { x: 30, y: 30, kind: 'linear', pointIndex: 1 }, @@ -211,7 +211,7 @@ describe('SModel Util', () => { ]; const route = calcRoute(edge, routerRegistry, ROUTING_POINT_KINDS); - expect(route).to.deep.equal([ + expect(route).toEqual([ { x: 20, y: 20, kind: 'linear', pointIndex: 0 }, { x: 30, y: 30, kind: 'linear', pointIndex: 1 }, { x: 40, y: 40, kind: 'linear', pointIndex: 2 } diff --git a/packages/client/tsconfig.json b/packages/client/tsconfig.json index 074058ae..35ad0555 100644 --- a/packages/client/tsconfig.json +++ b/packages/client/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@eclipse-glsp/ts-config/mocha", + "extends": "@eclipse-glsp/ts-config", "compilerOptions": { "composite": true, "rootDir": "src", @@ -8,7 +8,7 @@ "reactNamespace": "JSX" }, "include": ["src", "src/**/*.json"], - "exclude": ["**/*.spec.ts"], + "exclude": ["**/*.spec.ts", "**/test/**"], "references": [ { "path": "../glsp-sprotty" diff --git a/packages/client/tsconfig.test.json b/packages/client/tsconfig.test.json new file mode 100644 index 00000000..19a4102a --- /dev/null +++ b/packages/client/tsconfig.test.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "composite": true, + "noEmit": true + }, + "include": ["src/**/*.spec.ts", "src/**/*.spec.tsx", "src/**/test/**/*"], + "exclude": ["lib", "node_modules"], + "references": [{ "path": "./tsconfig.json" }] +} diff --git a/packages/protocol/package.json b/packages/protocol/package.json index 91ab70f2..ec429e69 100644 --- a/packages/protocol/package.json +++ b/packages/protocol/package.json @@ -32,17 +32,17 @@ "types": "lib/index", "files": [ "lib", - "src" + "src", + "!**/*.spec.ts", + "!**/*.spec.tsx", + "!**/test/**" ], "scripts": { "build": "tsc -b", - "clean": "rimraf lib *.tsbuildinfo coverage .nyc_output", + "clean": "rimraf lib *.tsbuildinfo coverage", "generate:index": "glsp generateIndex src/di src -f -s", "lint": "eslint ./src", "prepublishOnly": "pnpm build", - "test": "mocha --config ../../.mocharc \"./src/**/*.spec.?(ts|tsx)\"", - "test:ci": "pnpm test --reporter mocha-ctrf-json-reporter", - "test:coverage": "nyc pnpm test", "watch": "tsc -w" }, "dependencies": { diff --git a/packages/protocol/src/action-protocol/base-protocol.spec.ts b/packages/protocol/src/action-protocol/base-protocol.spec.ts index d4b0dd8f..7474e24f 100644 --- a/packages/protocol/src/action-protocol/base-protocol.spec.ts +++ b/packages/protocol/src/action-protocol/base-protocol.spec.ts @@ -14,7 +14,7 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { Action, ActionMessage, CompoundOperation, Operation, RejectAction, RequestAction, ResponseAction } from './base-protocol'; import { AnyObject } from '../utils/type-util'; @@ -29,30 +29,30 @@ describe('Base Protocol Actions', () => { describe('is', () => { it('should return true for an object having a `kind` property with string type', () => { const action = { kind: 'myAction' }; - expect(Action.is(action)).to.be.true; + expect(Action.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(Action.is(undefined)).to.be.false; + expect(Action.is(undefined)).toBe(false); }); it('should return false for an object having a `kind` property with incorrect type', () => { const notAnAction = { kind: 5 }; - expect(Action.is(notAnAction)).to.be.false; + expect(Action.is(notAnAction)).toBe(false); }); }); describe('hasKind', () => { it('should return true for an object having a `kind` property that matches the given value', () => { const action = { kind: 'myAction' }; - expect(Action.hasKind(action, 'myAction')).to.be.true; + expect(Action.hasKind(action, 'myAction')).toBe(true); }); it('should return false for undefined', () => { - expect(Action.hasKind(undefined, '')).to.be.false; + expect(Action.hasKind(undefined, '')).toBe(false); }); it('should return false for an object having a "kind" property that does not match the given value', () => { const action = { kind: 'myAction' }; - expect(Action.hasKind(action, 'someOtherKind')).to.be.false; + expect(Action.hasKind(action, 'someOtherKind')).toBe(false); }); it('should return false for an object not having a `kind` property', () => { - expect(Action.hasKind({ I: 'm not an action' }, '')).to.be.false; + expect(Action.hasKind({ I: 'm not an action' }, '')).toBe(false); }); }); }); @@ -61,22 +61,22 @@ describe('Base Protocol Actions', () => { describe('is', () => { it('should return true for an object having the correct type and a value for all required interface properties', () => { const message: ActionMessage = { action: { kind: 'myAction' }, clientId: 'someId' }; - expect(ActionMessage.is(message)).to.be.true; + expect(ActionMessage.is(message)).toBe(true); }); it('should return false for undefined', () => { - expect(ActionMessage.is(undefined)).to.be.false; + expect(ActionMessage.is(undefined)).toBe(false); }); it('should return false for an object that does have all required interface properties', () => { const notAnActionMessage = 'notAnActionMessage'; - expect(ActionMessage.is(notAnActionMessage)).to.be.false; + expect(ActionMessage.is(notAnActionMessage)).toBe(false); }); it('should return true for an object that has all required interface properties an `action` property that passes the typeguard check', () => { const message: ActionMessage = { action: customAction, clientId: 'someId' }; - expect(ActionMessage.is(message, isSomeCustomAction)).to.be.true; + expect(ActionMessage.is(message, isSomeCustomAction)).toBe(true); }); it('should return false for an object that has all required interface properties but does not have an `action` property that passes the typeguard check ', () => { const message: ActionMessage = { action: { kind: 'myAction' }, clientId: 'someId' }; - expect(ActionMessage.is(message, isSomeCustomAction)).to.be.false; + expect(ActionMessage.is(message, isSomeCustomAction)).toBe(false); }); }); }); @@ -86,28 +86,28 @@ describe('Base Protocol Actions', () => { describe('RequestAction', () => { describe('is', () => { it('should return true for an object having the correct type and a value for all required interface properties', () => { - expect(RequestAction.is(requestAction)).to.be.true; + expect(RequestAction.is(requestAction)).toBe(true); }); it('should return false for undefined', () => { - expect(RequestAction.is(undefined)).to.be.false; + expect(RequestAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(RequestAction.is(customAction)).to.be.false; + expect(RequestAction.is(customAction)).toBe(false); }); }); describe('hasKind', () => { it('should return true for an object having the correct type and a value for all required interface properties and a `kind` property that matches the given value', () => { - expect(RequestAction.hasKind(requestAction, 'someRequest')).to.be.true; + expect(RequestAction.hasKind(requestAction, 'someRequest')).toBe(true); }); it('should return false for `undefined`', () => { - expect(RequestAction.hasKind(undefined, '')).to.be.false; + expect(RequestAction.hasKind(undefined, '')).toBe(false); }); it('should return false for an object having the correct type and a value for all required interface properties but having a `kind` property that does not match the given value', () => { - expect(RequestAction.hasKind(requestAction, 'someOtherKind')).to.be.false; + expect(RequestAction.hasKind(requestAction, 'someOtherKind')).toBe(false); }); it('should return for an object not having the correct type and value for all required interface properties', () => { - expect(RequestAction.hasKind({ I: 'm not an action' }, '')).to.be.false; + expect(RequestAction.hasKind({ I: 'm not an action' }, '')).toBe(false); }); }); }); @@ -116,26 +116,26 @@ describe('Base Protocol Actions', () => { describe('ResponseAction', () => { describe('is', () => { it('should return true for an object having the correct type and a value for all required interface properties', () => { - expect(ResponseAction.is(responseAction)).to.be.true; + expect(ResponseAction.is(responseAction)).toBe(true); }); it('should return false for undefined', () => { - expect(ResponseAction.is(undefined)).to.be.false; + expect(ResponseAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(ResponseAction.is(customAction)).to.be.false; + expect(ResponseAction.is(customAction)).toBe(false); }); }); describe('hasValidResponseId', () => { it('should return true for an object having the correct type and a value for all required interface properties and a non-empty value for `requestId`', () => { const nonEmptyResponse = { ...responseAction, responseId: 'nonempty' }; - expect(ResponseAction.hasValidResponseId(nonEmptyResponse)).to.be.true; + expect(ResponseAction.hasValidResponseId(nonEmptyResponse)).toBe(true); }); it('should return false for an object having the correct type and a value for all required interface properties and an empty value for `requestId`', () => { - expect(ResponseAction.hasValidResponseId(responseAction)).to.be.false; + expect(ResponseAction.hasValidResponseId(responseAction)).toBe(false); }); it('should return false for `undefined`', () => { - expect(ResponseAction.hasValidResponseId(undefined)).to.be.false; + expect(ResponseAction.hasValidResponseId(undefined)).toBe(false); }); }); }); @@ -144,13 +144,13 @@ describe('Base Protocol Actions', () => { describe('RejectAction', () => { describe('is', () => { it('should return true for an object having the correct type and a value for all required interface properties', () => { - expect(RejectAction.is(rejectAction)).to.be.true; + expect(RejectAction.is(rejectAction)).toBe(true); }); it('should return false for undefined', () => { - expect(RejectAction.is(undefined)).to.be.false; + expect(RejectAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(RejectAction.is(customAction)).to.be.false; + expect(RejectAction.is(customAction)).toBe(false); }); }); @@ -158,12 +158,12 @@ describe('Base Protocol Actions', () => { it('should return an object conforming to the interface with matching properties for the given required arguments and default values for the optional arguments', () => { const expected = { kind: RejectAction.KIND, responseId: '', message: 'someMessage' }; const { message } = expected; - expect(RejectAction.create(message)).to.deep.equals(expected); + expect(RejectAction.create(message)).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected = { kind: RejectAction.KIND, responseId: 'someId', message: 'someMessage', detail: 'details' }; const { detail, responseId, message } = expected; - expect(RejectAction.create(message, { detail, responseId })).to.deep.equals(expected); + expect(RejectAction.create(message, { detail, responseId })).toEqual(expected); }); }); }); @@ -172,28 +172,28 @@ describe('Base Protocol Actions', () => { describe('Operation', () => { describe('is', () => { it('should return true for an object having the correct type and a value for all required interface properties', () => { - expect(Operation.is(operation)).to.be.true; + expect(Operation.is(operation)).toBe(true); }); it('should return false for undefined', () => { - expect(Operation.is(undefined)).to.be.false; + expect(Operation.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(Operation.is(customAction)).to.be.false; + expect(Operation.is(customAction)).toBe(false); }); }); describe('hasKind', () => { it('should return true for an object having the correct type and a value for all required interface properties and a `kind` property that matches the given value', () => { - expect(Operation.hasKind(operation, operation.kind)).to.be.true; + expect(Operation.hasKind(operation, operation.kind)).toBe(true); }); it('should return false for `undefined`', () => { - expect(Operation.hasKind(undefined, '')).to.be.false; + expect(Operation.hasKind(undefined, '')).toBe(false); }); it('should return false for an object having the correct type and a value for all required interface properties but having a `kind` property that does not match the given value', () => { - expect(Operation.hasKind(operation, 'someOtherKind')).to.be.false; + expect(Operation.hasKind(operation, 'someOtherKind')).toBe(false); }); it('should return false for an object not having the correct type and value for all required interface properties', () => { - expect(Operation.hasKind({ I: 'm not an action' }, '')).to.be.false; + expect(Operation.hasKind({ I: 'm not an action' }, '')).toBe(false); }); }); }); @@ -202,20 +202,20 @@ describe('Base Protocol Actions', () => { describe('CompoundOperation', () => { describe('is', () => { it('should return true for an object having the correct type and a value for all required interface properties', () => { - expect(CompoundOperation.is(compoundOperation)).to.be.true; + expect(CompoundOperation.is(compoundOperation)).toBe(true); }); it('should return false for undefined', () => { - expect(CompoundOperation.is(undefined)).to.be.false; + expect(CompoundOperation.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(CompoundOperation.is(customAction)).to.be.false; + expect(CompoundOperation.is(customAction)).toBe(false); }); }); describe('create', () => { it('should return an object conforming to the interface with matching properties for the given required arguments', () => { const operationList = [operation]; const expected = { kind: CompoundOperation.KIND, isOperation: true, operationList }; - expect(CompoundOperation.create(operationList)).to.deep.equals(expected); + expect(CompoundOperation.create(operationList)).toEqual(expected); }); }); }); diff --git a/packages/protocol/src/action-protocol/client-notification.spec.ts b/packages/protocol/src/action-protocol/client-notification.spec.ts index fbdea9ee..4c42ad4c 100644 --- a/packages/protocol/src/action-protocol/client-notification.spec.ts +++ b/packages/protocol/src/action-protocol/client-notification.spec.ts @@ -14,7 +14,7 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { EndProgressAction, MessageAction, StartProgressAction, StatusAction, UpdateProgressAction } from './client-notification'; /** * Tests for the utility functions declared in the namespaces of the protocol @@ -25,13 +25,13 @@ describe('Client notification actions', () => { describe('is', () => { it('should return true for an object having the correct type and a value for all required interface properties', () => { const statusAction: StatusAction = { kind: StatusAction.KIND, message: 'Some', severity: 'INFO' }; - expect(StatusAction.is(statusAction)).to.be.true; + expect(StatusAction.is(statusAction)).toBe(true); }); it('should return false for `undefined`', () => { - expect(StatusAction.is(undefined)).to.be.false; + expect(StatusAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(StatusAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(StatusAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -39,7 +39,7 @@ describe('Client notification actions', () => { it('should return an object conforming to the interface with matching properties for the given required arguments and default values for the optional arguments', () => { const message = 'someMessage'; const expected: StatusAction = { kind: StatusAction.KIND, message, severity: 'INFO' }; - expect(StatusAction.create(message)).to.deep.equals(expected); + expect(StatusAction.create(message)).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: StatusAction = { @@ -49,7 +49,7 @@ describe('Client notification actions', () => { timeout: 5 }; const { message, severity, timeout } = expected; - expect(StatusAction.create(message, { severity, timeout })).to.deep.equals(expected); + expect(StatusAction.create(message, { severity, timeout })).toEqual(expected); }); }); }); @@ -58,13 +58,13 @@ describe('Client notification actions', () => { describe('is', () => { it('should return true for an object having the correct type and a value for all required interface properties', () => { const messageAction: MessageAction = { kind: MessageAction.KIND, message: '', severity: 'INFO' }; - expect(MessageAction.is(messageAction)).to.be.true; + expect(MessageAction.is(messageAction)).toBe(true); }); it('should return false for `undefined`', () => { - expect(MessageAction.is(undefined)).to.be.false; + expect(MessageAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(MessageAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(MessageAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -72,7 +72,7 @@ describe('Client notification actions', () => { it('should return an object conforming to the interface with matching properties for the given required arguments and default values for the optional arguments', () => { const message = 'someMessage'; const expected: MessageAction = { kind: MessageAction.KIND, message, severity: 'INFO' }; - expect(MessageAction.create(message)).to.deep.equals(expected); + expect(MessageAction.create(message)).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: MessageAction = { @@ -82,7 +82,7 @@ describe('Client notification actions', () => { severity: 'ERROR' }; const { message, severity, details } = expected; - expect(MessageAction.create(message, { severity, details })).to.deep.equals(expected); + expect(MessageAction.create(message, { severity, details })).toEqual(expected); }); }); }); @@ -91,13 +91,13 @@ describe('Client notification actions', () => { describe('is', () => { it('should return true for an object having the correct type and a value for all required interface properties', () => { const messageAction: StartProgressAction = { kind: 'startProgress', progressId: '1', title: 'Progress title' }; - expect(StartProgressAction.is(messageAction)).to.be.true; + expect(StartProgressAction.is(messageAction)).toBe(true); }); it('should return false for `undefined`', () => { - expect(StartProgressAction.is(undefined)).to.be.false; + expect(StartProgressAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(StartProgressAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(StartProgressAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -106,7 +106,7 @@ describe('Client notification actions', () => { const progressId = '1'; const title = 'Progress title'; const expected: StartProgressAction = { kind: StartProgressAction.KIND, progressId, title }; - expect(StartProgressAction.create({ progressId, title })).to.deep.equals(expected); + expect(StartProgressAction.create({ progressId, title })).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: StartProgressAction = { @@ -117,7 +117,7 @@ describe('Client notification actions', () => { percentage: 10 }; const { progressId, title, message, percentage } = expected; - expect(StartProgressAction.create({ progressId, title, message, percentage })).to.deep.equals(expected); + expect(StartProgressAction.create({ progressId, title, message, percentage })).toEqual(expected); }); }); }); @@ -126,13 +126,13 @@ describe('Client notification actions', () => { describe('is', () => { it('should return true for an object having the correct type and a value for all required interface properties', () => { const messageAction: UpdateProgressAction = { kind: 'updateProgress', progressId: '1' }; - expect(UpdateProgressAction.is(messageAction)).to.be.true; + expect(UpdateProgressAction.is(messageAction)).toBe(true); }); it('should return false for `undefined`', () => { - expect(UpdateProgressAction.is(undefined)).to.be.false; + expect(UpdateProgressAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(UpdateProgressAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(UpdateProgressAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -140,7 +140,7 @@ describe('Client notification actions', () => { it('should return an object conforming to the interface with matching properties for the given required arguments and default values for the optional arguments', () => { const progressId = '1'; const expected: UpdateProgressAction = { kind: UpdateProgressAction.KIND, progressId }; - expect(UpdateProgressAction.create(progressId)).to.deep.equals(expected); + expect(UpdateProgressAction.create(progressId)).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: UpdateProgressAction = { @@ -150,7 +150,7 @@ describe('Client notification actions', () => { percentage: 10 }; const { progressId, message, percentage } = expected; - expect(UpdateProgressAction.create(progressId, { message, percentage })).to.deep.equals(expected); + expect(UpdateProgressAction.create(progressId, { message, percentage })).toEqual(expected); }); }); }); @@ -159,13 +159,13 @@ describe('Client notification actions', () => { describe('is', () => { it('should return true for an object having the correct type and a value for all required interface properties', () => { const messageAction: EndProgressAction = { kind: 'endProgress', progressId: '1' }; - expect(EndProgressAction.is(messageAction)).to.be.true; + expect(EndProgressAction.is(messageAction)).toBe(true); }); it('should return false for `undefined`', () => { - expect(EndProgressAction.is(undefined)).to.be.false; + expect(EndProgressAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(EndProgressAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(EndProgressAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -173,7 +173,7 @@ describe('Client notification actions', () => { it('should return an object conforming to the interface with matching properties for the given required arguments and default values for the optional arguments', () => { const progressId = '1'; const expected: EndProgressAction = { kind: EndProgressAction.KIND, progressId, message: undefined }; - expect(EndProgressAction.create(progressId)).to.deep.equals(expected); + expect(EndProgressAction.create(progressId)).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: EndProgressAction = { @@ -182,7 +182,7 @@ describe('Client notification actions', () => { message: 'Some message' }; const { progressId, message } = expected; - expect(EndProgressAction.create(progressId, message)).to.deep.equals(expected); + expect(EndProgressAction.create(progressId, message)).toEqual(expected); }); }); }); diff --git a/packages/protocol/src/action-protocol/clipboard.spec.ts b/packages/protocol/src/action-protocol/clipboard.spec.ts index 318c06e6..6fc8433b 100644 --- a/packages/protocol/src/action-protocol/clipboard.spec.ts +++ b/packages/protocol/src/action-protocol/clipboard.spec.ts @@ -14,7 +14,7 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { CutOperation, PasteOperation, RequestClipboardDataAction, SetClipboardDataAction } from './clipboard'; /** * Tests for the utility functions declared in the namespaces of the protocol @@ -30,13 +30,13 @@ describe('Clipboard actions', () => { describe('is', () => { it('should return true for an object having the correct type and a value for all required interface properties', () => { - expect(RequestClipboardDataAction.is(requestClipboardDataAction)).to.be.true; + expect(RequestClipboardDataAction.is(requestClipboardDataAction)).toBe(true); }); it('should return false for `undefined`', () => { - expect(RequestClipboardDataAction.is(undefined)).to.be.false; + expect(RequestClipboardDataAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(RequestClipboardDataAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(RequestClipboardDataAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -48,7 +48,7 @@ describe('Clipboard actions', () => { requestId: '' }; const { editorContext } = expected; - expect(RequestClipboardDataAction.create(editorContext)).to.deep.equals(expected); + expect(RequestClipboardDataAction.create(editorContext)).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: RequestClipboardDataAction = { @@ -57,7 +57,7 @@ describe('Clipboard actions', () => { requestId: '100' }; const { editorContext, requestId } = expected; - expect(RequestClipboardDataAction.create(editorContext, { requestId })).to.deep.equals(expected); + expect(RequestClipboardDataAction.create(editorContext, { requestId })).toEqual(expected); }); }); }); @@ -70,13 +70,13 @@ describe('Clipboard actions', () => { kind: 'setClipboardData', responseId: '' }; - expect(SetClipboardDataAction.is(action)).to.be.true; + expect(SetClipboardDataAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(SetClipboardDataAction.is(undefined)).to.be.false; + expect(SetClipboardDataAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(SetClipboardDataAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(SetClipboardDataAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -88,7 +88,7 @@ describe('Clipboard actions', () => { responseId: '' }; const { clipboardData } = expected; - expect(SetClipboardDataAction.create(clipboardData)).to.deep.equals(expected); + expect(SetClipboardDataAction.create(clipboardData)).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: SetClipboardDataAction = { @@ -97,7 +97,7 @@ describe('Clipboard actions', () => { responseId: '600' }; const { clipboardData, responseId } = expected; - expect(SetClipboardDataAction.create(clipboardData, { responseId })).to.deep.equals(expected); + expect(SetClipboardDataAction.create(clipboardData, { responseId })).toEqual(expected); }); }); }); @@ -110,13 +110,13 @@ describe('Clipboard actions', () => { isOperation: true, editorContext: { selectedElementIds: [] } }; - expect(CutOperation.is(operation)).to.be.true; + expect(CutOperation.is(operation)).toBe(true); }); it('should return false for `undefined`', () => { - expect(CutOperation.is(undefined)).to.be.false; + expect(CutOperation.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(CutOperation.is({ kind: 'notTheRightOne' })).to.be.false; + expect(CutOperation.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -128,7 +128,7 @@ describe('Clipboard actions', () => { editorContext: { selectedElementIds: ['element1'] } }; const { editorContext } = expected; - expect(CutOperation.create(editorContext)).to.deep.equals(expected); + expect(CutOperation.create(editorContext)).toEqual(expected); }); }); }); @@ -142,13 +142,13 @@ describe('Clipboard actions', () => { editorContext: { selectedElementIds: [] }, clipboardData: { format: '' } }; - expect(PasteOperation.is(operation)).to.be.true; + expect(PasteOperation.is(operation)).toBe(true); }); it('should return false for `undefined`', () => { - expect(PasteOperation.is(undefined)).to.be.false; + expect(PasteOperation.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(PasteOperation.is({ kind: 'notTheRightOne' })).to.be.false; + expect(PasteOperation.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -161,7 +161,7 @@ describe('Clipboard actions', () => { editorContext: { selectedElementIds: ['element1'] } }; const { editorContext, clipboardData } = expected; - expect(PasteOperation.create({ clipboardData, editorContext })).to.deep.equals(expected); + expect(PasteOperation.create({ clipboardData, editorContext })).toEqual(expected); }); }); }); diff --git a/packages/protocol/src/action-protocol/contexts.spec.ts b/packages/protocol/src/action-protocol/contexts.spec.ts index f8ddf9d2..52d210fa 100644 --- a/packages/protocol/src/action-protocol/contexts.spec.ts +++ b/packages/protocol/src/action-protocol/contexts.spec.ts @@ -14,7 +14,7 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { RequestContextActions, SetContextActions } from './contexts'; /** * Tests for the utility functions declared in the namespaces of the protocol @@ -30,13 +30,13 @@ describe('Context Actions', () => { kind: 'requestContextActions', requestId: '' }; - expect(RequestContextActions.is(action)).to.be.true; + expect(RequestContextActions.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(RequestContextActions.is(undefined)).to.be.false; + expect(RequestContextActions.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(RequestContextActions.is({ kind: 'notTheRightOne' })).to.be.false; + expect(RequestContextActions.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -49,7 +49,7 @@ describe('Context Actions', () => { requestId: '' }; const { contextId, editorContext } = expected; - expect(RequestContextActions.create({ contextId, editorContext })).to.deep.equals(expected); + expect(RequestContextActions.create({ contextId, editorContext })).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: RequestContextActions = { @@ -59,7 +59,7 @@ describe('Context Actions', () => { requestId: 'myRequest' }; const { contextId, editorContext, requestId } = expected; - expect(RequestContextActions.create({ contextId, editorContext, requestId })).to.deep.equals(expected); + expect(RequestContextActions.create({ contextId, editorContext, requestId })).toEqual(expected); }); }); }); @@ -72,13 +72,13 @@ describe('Context Actions', () => { actions: [], responseId: '' }; - expect(SetContextActions.is(action)).to.be.true; + expect(SetContextActions.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(SetContextActions.is(undefined)).to.be.false; + expect(SetContextActions.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(SetContextActions.is({ kind: 'notTheRightOne' })).to.be.false; + expect(SetContextActions.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -90,7 +90,7 @@ describe('Context Actions', () => { responseId: '' }; const { actions } = expected; - expect(SetContextActions.create(actions)).to.deep.equals(expected); + expect(SetContextActions.create(actions)).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: SetContextActions = { @@ -100,7 +100,7 @@ describe('Context Actions', () => { args: { some: 'args' } }; const { actions, args, responseId } = expected; - expect(SetContextActions.create(actions, { args, responseId })).to.deep.equals(expected); + expect(SetContextActions.create(actions, { args, responseId })).toEqual(expected); }); }); }); diff --git a/packages/protocol/src/action-protocol/edge-modification.spec.ts b/packages/protocol/src/action-protocol/edge-modification.spec.ts index 8e196021..e5df5e24 100644 --- a/packages/protocol/src/action-protocol/edge-modification.spec.ts +++ b/packages/protocol/src/action-protocol/edge-modification.spec.ts @@ -14,7 +14,7 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { Point } from 'sprotty-protocol'; import { ChangeRoutingPointsOperation, ReconnectEdgeOperation } from './edge-modification'; /** @@ -33,13 +33,13 @@ describe('Edge modification operations', () => { sourceElementId: '2', targetElementId: '3' }; - expect(ReconnectEdgeOperation.is(operation)).to.be.true; + expect(ReconnectEdgeOperation.is(operation)).toBe(true); }); it('should return false for `undefined`', () => { - expect(ReconnectEdgeOperation.is(undefined)).to.be.false; + expect(ReconnectEdgeOperation.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(ReconnectEdgeOperation.is({ kind: 'notTheRightOne' })).to.be.false; + expect(ReconnectEdgeOperation.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -53,7 +53,7 @@ describe('Edge modification operations', () => { targetElementId: 'target' }; const { edgeElementId, sourceElementId, targetElementId } = expected; - expect(ReconnectEdgeOperation.create({ edgeElementId, sourceElementId, targetElementId })).to.deep.equals(expected); + expect(ReconnectEdgeOperation.create({ edgeElementId, sourceElementId, targetElementId })).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: ReconnectEdgeOperation = { @@ -65,7 +65,7 @@ describe('Edge modification operations', () => { args: { some: 'args' } }; const { edgeElementId, sourceElementId, targetElementId, args } = expected; - expect(ReconnectEdgeOperation.create({ edgeElementId, sourceElementId, targetElementId, args })).to.deep.equals(expected); + expect(ReconnectEdgeOperation.create({ edgeElementId, sourceElementId, targetElementId, args })).toEqual(expected); }); }); }); @@ -78,13 +78,13 @@ describe('Edge modification operations', () => { isOperation: true, newRoutingPoints: [] }; - expect(ChangeRoutingPointsOperation.is(operation)).to.be.true; + expect(ChangeRoutingPointsOperation.is(operation)).toBe(true); }); it('should return false for `undefined`', () => { - expect(ChangeRoutingPointsOperation.is(undefined)).to.be.false; + expect(ChangeRoutingPointsOperation.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(ChangeRoutingPointsOperation.is({ kind: 'notTheRightOne' })).to.be.false; + expect(ChangeRoutingPointsOperation.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -98,7 +98,7 @@ describe('Edge modification operations', () => { targetElementId: 'target' }; const { edgeElementId, sourceElementId, targetElementId } = expected; - expect(ReconnectEdgeOperation.create({ edgeElementId, sourceElementId, targetElementId })).to.deep.equals(expected); + expect(ReconnectEdgeOperation.create({ edgeElementId, sourceElementId, targetElementId })).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required args', () => { const expected: ChangeRoutingPointsOperation = { @@ -107,7 +107,7 @@ describe('Edge modification operations', () => { newRoutingPoints: [{ elementId: 'element', newRoutingPoints: [Point.ORIGIN] }] }; const { newRoutingPoints } = expected; - expect(ChangeRoutingPointsOperation.create(newRoutingPoints)).to.deep.equals(expected); + expect(ChangeRoutingPointsOperation.create(newRoutingPoints)).toEqual(expected); }); }); }); diff --git a/packages/protocol/src/action-protocol/element-creation.spec.ts b/packages/protocol/src/action-protocol/element-creation.spec.ts index d4c1a8ad..e5db8310 100644 --- a/packages/protocol/src/action-protocol/element-creation.spec.ts +++ b/packages/protocol/src/action-protocol/element-creation.spec.ts @@ -14,7 +14,7 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { Point } from 'sprotty-protocol'; import { CreateEdgeOperation, CreateNodeOperation, CreateOperation, DeleteElementOperation } from './element-creation'; /** @@ -31,13 +31,13 @@ describe('Element creation operations', () => { isOperation: true, elementTypeId: 'someType' }; - expect(CreateOperation.is(operation)).to.be.true; + expect(CreateOperation.is(operation)).toBe(true); }); it('should return false for `undefined`', () => { - expect(CreateOperation.is(undefined)).to.be.false; + expect(CreateOperation.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(CreateOperation.is({ kind: 'notTheRightOne' })).to.be.false; + expect(CreateOperation.is({ kind: 'notTheRightOne' })).toBe(false); }); }); }); @@ -50,13 +50,13 @@ describe('Element creation operations', () => { isOperation: true, elementTypeId: '' }; - expect(CreateNodeOperation.is(operation)).to.be.true; + expect(CreateNodeOperation.is(operation)).toBe(true); }); it('should return false for `undefined`', () => { - expect(CreateNodeOperation.is(undefined)).to.be.false; + expect(CreateNodeOperation.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(CreateNodeOperation.is({ kind: 'notTheRightOne' })).to.be.false; + expect(CreateNodeOperation.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -68,7 +68,7 @@ describe('Element creation operations', () => { elementTypeId: 'someNode' }; const { elementTypeId } = expected; - expect(CreateNodeOperation.create(elementTypeId)).to.deep.equals(expected); + expect(CreateNodeOperation.create(elementTypeId)).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: CreateNodeOperation = { @@ -80,7 +80,7 @@ describe('Element creation operations', () => { args: { some: 'args' } }; const { elementTypeId, containerId, location, args } = expected; - expect(CreateNodeOperation.create(elementTypeId, { args, location, containerId })).to.deep.equals(expected); + expect(CreateNodeOperation.create(elementTypeId, { args, location, containerId })).toEqual(expected); }); }); }); @@ -95,13 +95,13 @@ describe('Element creation operations', () => { sourceElementId: '', targetElementId: '' }; - expect(CreateEdgeOperation.is(operation)).to.be.true; + expect(CreateEdgeOperation.is(operation)).toBe(true); }); it('should return false for `undefined`', () => { - expect(CreateEdgeOperation.is(undefined)).to.be.false; + expect(CreateEdgeOperation.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(CreateEdgeOperation.is({ kind: 'notTheRightOne' })).to.be.false; + expect(CreateEdgeOperation.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -115,7 +115,7 @@ describe('Element creation operations', () => { targetElementId: 'target' }; const { elementTypeId, sourceElementId, targetElementId } = expected; - expect(CreateEdgeOperation.create({ elementTypeId, sourceElementId, targetElementId })).to.deep.equals(expected); + expect(CreateEdgeOperation.create({ elementTypeId, sourceElementId, targetElementId })).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: CreateEdgeOperation = { @@ -127,7 +127,7 @@ describe('Element creation operations', () => { args: { some: 'args' } }; const { elementTypeId, sourceElementId, targetElementId, args } = expected; - expect(CreateEdgeOperation.create({ elementTypeId, sourceElementId, targetElementId, args })).to.deep.equals(expected); + expect(CreateEdgeOperation.create({ elementTypeId, sourceElementId, targetElementId, args })).toEqual(expected); }); }); }); @@ -140,13 +140,13 @@ describe('Element creation operations', () => { isOperation: true, elementIds: [] }; - expect(DeleteElementOperation.is(operation)).to.be.true; + expect(DeleteElementOperation.is(operation)).toBe(true); }); it('should return false for `undefined`', () => { - expect(DeleteElementOperation.is(undefined)).to.be.false; + expect(DeleteElementOperation.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(DeleteElementOperation.is({ kind: 'notTheRightOne' })).to.be.false; + expect(DeleteElementOperation.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -158,7 +158,7 @@ describe('Element creation operations', () => { elementIds: ['deleteMe'] }; const { elementIds } = expected; - expect(DeleteElementOperation.create(elementIds)).to.deep.equals(expected); + expect(DeleteElementOperation.create(elementIds)).toEqual(expected); }); }); }); diff --git a/packages/protocol/src/action-protocol/element-hover.spec.ts b/packages/protocol/src/action-protocol/element-hover.spec.ts index 9279eb0c..55ea5f32 100644 --- a/packages/protocol/src/action-protocol/element-hover.spec.ts +++ b/packages/protocol/src/action-protocol/element-hover.spec.ts @@ -14,7 +14,7 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { Bounds } from 'sprotty-protocol'; import { RequestPopupModelAction, SetPopupModelAction } from './element-hover'; /** @@ -32,13 +32,13 @@ describe('Element hover actions', () => { elementId: '', bounds: Bounds.EMPTY }; - expect(RequestPopupModelAction.is(action)).to.be.true; + expect(RequestPopupModelAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(RequestPopupModelAction.is(undefined)).to.be.false; + expect(RequestPopupModelAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(RequestPopupModelAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(RequestPopupModelAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -51,7 +51,7 @@ describe('Element hover actions', () => { bounds: Bounds.EMPTY }; const { elementId, bounds } = expected; - expect(RequestPopupModelAction.create({ bounds, elementId })).to.deep.equals(expected); + expect(RequestPopupModelAction.create({ bounds, elementId })).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: RequestPopupModelAction = { @@ -61,7 +61,7 @@ describe('Element hover actions', () => { bounds: Bounds.EMPTY }; const { elementId, bounds, requestId } = expected; - expect(RequestPopupModelAction.create({ bounds, elementId, requestId })).to.deep.equals(expected); + expect(RequestPopupModelAction.create({ bounds, elementId, requestId })).toEqual(expected); }); }); }); @@ -74,13 +74,13 @@ describe('Element hover actions', () => { responseId: '', newRoot: { id: '', type: '' } }; - expect(SetPopupModelAction.is(action)).to.be.true; + expect(SetPopupModelAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(SetPopupModelAction.is(undefined)).to.be.false; + expect(SetPopupModelAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(SetPopupModelAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(SetPopupModelAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -92,7 +92,7 @@ describe('Element hover actions', () => { newRoot: { id: '', type: '' } }; const { newRoot } = expected; - expect(SetPopupModelAction.create(newRoot)).to.deep.equals(expected); + expect(SetPopupModelAction.create(newRoot)).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: SetPopupModelAction = { @@ -101,7 +101,7 @@ describe('Element hover actions', () => { newRoot: { id: '', type: '' } }; const { newRoot, responseId } = expected; - expect(SetPopupModelAction.create(newRoot, { responseId })).to.deep.equals(expected); + expect(SetPopupModelAction.create(newRoot, { responseId })).toEqual(expected); }); }); }); diff --git a/packages/protocol/src/action-protocol/element-navigation.spec.ts b/packages/protocol/src/action-protocol/element-navigation.spec.ts index dd4b44e4..4789d30a 100644 --- a/packages/protocol/src/action-protocol/element-navigation.spec.ts +++ b/packages/protocol/src/action-protocol/element-navigation.spec.ts @@ -14,7 +14,7 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { NavigateToExternalTargetAction, NavigateToTargetAction, @@ -36,24 +36,24 @@ describe('Element navigation actions', () => { const target: NavigationTarget = { uri: '' }; - expect(NavigationTarget.is(target)).to.be.true; + expect(NavigationTarget.is(target)).toBe(true); }); it('should return false for `undefined`', () => { - expect(NavigationTarget.is(undefined)).to.be.false; + expect(NavigationTarget.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(NavigationTarget.is({ kind: 'notTheRightOne' })).to.be.false; + expect(NavigationTarget.is({ kind: 'notTheRightOne' })).toBe(false); }); }); describe('hasArguments', () => { it('should return true for an object having the correct type and a value for all required interface properties and a defined `args` property', () => { const target: NavigationTarget = { uri: 'myuri', args: { some: 'args' } }; - expect(NavigationTarget.hasArguments(target)).to.be.true; + expect(NavigationTarget.hasArguments(target)).toBe(true); }); it('should return false for an object having the correct type and a value for all required interface properties and an undefined `args property', () => { const target: NavigationTarget = { uri: 'myuri' }; - expect(NavigationTarget.hasArguments(target)).to.be.false; + expect(NavigationTarget.hasArguments(target)).toBe(false); }); }); @@ -61,7 +61,7 @@ describe('Element navigation actions', () => { it('should assign a new `args` property to the given target and add the given key-value pair to the args object', () => { const target: NavigationTarget = { uri: 'myuri' }; NavigationTarget.addArgument(target, 'some', 'argument'); - expect(target.args?.some).to.be.equal('argument'); + expect(target.args?.some).toBe('argument'); }); }); describe('getElementIds', () => { @@ -70,14 +70,14 @@ describe('Element navigation actions', () => { const id2 = 'anotherId'; const target: NavigationTarget = { uri: 'myuri', args: { [NavigationTarget.ELEMENT_IDS]: `${id1}&${id2}` } }; const elementIds = NavigationTarget.getElementIds(target); - expect(elementIds.length).to.be.equal(2); - expect(elementIds).to.include(id1); - expect(elementIds).to.include(id2); + expect(elementIds.length).toBe(2); + expect(elementIds).toContain(id1); + expect(elementIds).toContain(id2); }); it('should return an empty array for the given target with an undefined args property', () => { const target: NavigationTarget = { uri: 'myuri' }; const elementIds = NavigationTarget.getElementIds(target); - expect(elementIds.length).to.be.equal(0); + expect(elementIds.length).toBe(0); }); }); @@ -87,7 +87,7 @@ describe('Element navigation actions', () => { const id1 = 'someId'; const id2 = 'anotherId'; NavigationTarget.setElementIds(target, id1, id2); - expect(target.args?.[NavigationTarget.ELEMENT_IDS]).to.be.equal(`${id1}&${id2}`); + expect(target.args?.[NavigationTarget.ELEMENT_IDS]).toBe(`${id1}&${id2}`); }); }); @@ -97,8 +97,8 @@ describe('Element navigation actions', () => { const pos: NavigationTarget.TextPosition = { character: 5, line: 2 }; const { character: column, line } = pos; NavigationTarget.setTextPosition(target, pos); - expect(target.args?.[NavigationTarget.TEXT_COLUMN]).to.be.equal(column); - expect(target.args?.[NavigationTarget.TEXT_LINE]).to.be.equal(line); + expect(target.args?.[NavigationTarget.TEXT_COLUMN]).toBe(column); + expect(target.args?.[NavigationTarget.TEXT_LINE]).toBe(line); }); }); @@ -113,13 +113,13 @@ describe('Element navigation actions', () => { args: { [NavigationTarget.TEXT_COLUMN]: position.character, [NavigationTarget.TEXT_LINE]: position.line } }; const result = NavigationTarget.getTextPosition(target); - expect(result).to.be.not.undefined; - expect(result).to.be.deep.equal(position); + expect(result).toBeDefined(); + expect(result).toEqual(position); }); it('should return undefined for the given target with an undefined args property', () => { const target: NavigationTarget = { uri: 'myuri' }; const result = NavigationTarget.getTextPosition(target); - expect(result).to.be.undefined; + expect(result).toBeUndefined(); }); }); }); @@ -133,13 +133,13 @@ describe('Element navigation actions', () => { editorContext: { selectedElementIds: [] }, targetTypeId: '' }; - expect(RequestNavigationTargetsAction.is(action)).to.be.true; + expect(RequestNavigationTargetsAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(RequestNavigationTargetsAction.is(undefined)).to.be.false; + expect(RequestNavigationTargetsAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(RequestNavigationTargetsAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(RequestNavigationTargetsAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -152,7 +152,7 @@ describe('Element navigation actions', () => { targetTypeId: 'someId' }; const { editorContext, targetTypeId } = expected; - expect(RequestNavigationTargetsAction.create({ editorContext, targetTypeId })).to.deep.equals(expected); + expect(RequestNavigationTargetsAction.create({ editorContext, targetTypeId })).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: RequestNavigationTargetsAction = { @@ -162,7 +162,7 @@ describe('Element navigation actions', () => { targetTypeId: 'someId' }; const { editorContext, targetTypeId, requestId } = expected; - expect(RequestNavigationTargetsAction.create({ editorContext, targetTypeId, requestId })).to.deep.equals(expected); + expect(RequestNavigationTargetsAction.create({ editorContext, targetTypeId, requestId })).toEqual(expected); }); }); }); @@ -175,13 +175,13 @@ describe('Element navigation actions', () => { responseId: '', targets: [] }; - expect(SetNavigationTargetsAction.is(action)).to.be.true; + expect(SetNavigationTargetsAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(SetNavigationTargetsAction.is(undefined)).to.be.false; + expect(SetNavigationTargetsAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(SetNavigationTargetsAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(SetNavigationTargetsAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -193,7 +193,7 @@ describe('Element navigation actions', () => { targets: [{ uri: 'someUri' }] }; const { targets } = expected; - expect(SetNavigationTargetsAction.create(targets)).to.deep.equals(expected); + expect(SetNavigationTargetsAction.create(targets)).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: SetNavigationTargetsAction = { @@ -202,7 +202,7 @@ describe('Element navigation actions', () => { targets: [{ uri: 'someUri' }] }; const { targets, responseId } = expected; - expect(SetNavigationTargetsAction.create(targets, { responseId })).to.deep.equals(expected); + expect(SetNavigationTargetsAction.create(targets, { responseId })).toEqual(expected); }); }); }); @@ -214,14 +214,14 @@ describe('Element navigation actions', () => { kind: 'navigateToTarget', target: { uri: '' } }; - expect(NavigateToTargetAction.is(action)).to.be.true; + expect(NavigateToTargetAction.is(action)).toBe(true); }); }); it('should return false for `undefined`', () => { - expect(NavigateToTargetAction.is(undefined)).to.be.false; + expect(NavigateToTargetAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(NavigateToTargetAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(NavigateToTargetAction.is({ kind: 'notTheRightOne' })).toBe(false); }); describe('create', () => { @@ -231,7 +231,7 @@ describe('Element navigation actions', () => { target: { uri: 'myUri' } }; const { target } = expected; - expect(NavigateToTargetAction.create(target)).to.deep.equals(expected); + expect(NavigateToTargetAction.create(target)).toEqual(expected); }); }); }); @@ -244,13 +244,13 @@ describe('Element navigation actions', () => { requestId: '', navigationTarget: { uri: '' } }; - expect(ResolveNavigationTargetAction.is(action)).to.be.true; + expect(ResolveNavigationTargetAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(ResolveNavigationTargetAction.is(undefined)).to.be.false; + expect(ResolveNavigationTargetAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(ResolveNavigationTargetAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(ResolveNavigationTargetAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -262,7 +262,7 @@ describe('Element navigation actions', () => { navigationTarget: { uri: '' } }; const { navigationTarget } = expected; - expect(ResolveNavigationTargetAction.create(navigationTarget)).to.deep.equals(expected); + expect(ResolveNavigationTargetAction.create(navigationTarget)).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: ResolveNavigationTargetAction = { @@ -271,7 +271,7 @@ describe('Element navigation actions', () => { navigationTarget: { uri: '' } }; const { navigationTarget, requestId } = expected; - expect(ResolveNavigationTargetAction.create(navigationTarget, { requestId })).to.deep.equals(expected); + expect(ResolveNavigationTargetAction.create(navigationTarget, { requestId })).toEqual(expected); }); }); }); @@ -284,13 +284,13 @@ describe('Element navigation actions', () => { responseId: '', elementIds: [''] }; - expect(SetResolvedNavigationTargetAction.is(action)).to.be.true; + expect(SetResolvedNavigationTargetAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(SetResolvedNavigationTargetAction.is(undefined)).to.be.false; + expect(SetResolvedNavigationTargetAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(SetResolvedNavigationTargetAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(SetResolvedNavigationTargetAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -302,7 +302,7 @@ describe('Element navigation actions', () => { elementIds: [''] }; const { elementIds } = expected; - expect(SetResolvedNavigationTargetAction.create(elementIds)).to.deep.equals(expected); + expect(SetResolvedNavigationTargetAction.create(elementIds)).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: SetResolvedNavigationTargetAction = { @@ -311,7 +311,7 @@ describe('Element navigation actions', () => { elementIds: [''] }; const { elementIds, responseId } = expected; - expect(SetResolvedNavigationTargetAction.create(elementIds, { responseId })).to.deep.equals(expected); + expect(SetResolvedNavigationTargetAction.create(elementIds, { responseId })).toEqual(expected); }); }); }); @@ -323,13 +323,13 @@ describe('Element navigation actions', () => { kind: 'navigateToExternalTarget', target: { uri: '' } }; - expect(NavigateToExternalTargetAction.is(action)).to.be.true; + expect(NavigateToExternalTargetAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(NavigateToExternalTargetAction.is(undefined)).to.be.false; + expect(NavigateToExternalTargetAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(NavigateToExternalTargetAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(NavigateToExternalTargetAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -340,7 +340,7 @@ describe('Element navigation actions', () => { target: { uri: '' } }; const { target } = expected; - expect(NavigateToExternalTargetAction.create(target)).to.deep.equals(expected); + expect(NavigateToExternalTargetAction.create(target)).toEqual(expected); }); }); }); diff --git a/packages/protocol/src/action-protocol/element-selection.spec.ts b/packages/protocol/src/action-protocol/element-selection.spec.ts index 6d78b3fb..9bd642c1 100644 --- a/packages/protocol/src/action-protocol/element-selection.spec.ts +++ b/packages/protocol/src/action-protocol/element-selection.spec.ts @@ -14,7 +14,7 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { SelectAction, SelectAllAction } from './element-selection'; /** * Tests for the utility functions declared in the namespaces of the protocol @@ -30,13 +30,13 @@ describe('Element selection actions', () => { selectedElementsIDs: [], deselectedElementsIDs: [] }; - expect(SelectAction.is(action)).to.be.true; + expect(SelectAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(SelectAction.is(undefined)).to.be.false; + expect(SelectAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(SelectAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(SelectAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -48,7 +48,7 @@ describe('Element selection actions', () => { deselectedElementsIDs: [], deselectAll: false }; - expect(SelectAction.create()).to.deep.equals(expected); + expect(SelectAction.create()).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: SelectAction = { @@ -58,7 +58,7 @@ describe('Element selection actions', () => { deselectAll: false }; const { selectedElementsIDs, deselectedElementsIDs } = expected; - expect(SelectAction.create({ deselectedElementsIDs, selectedElementsIDs })).to.deep.equals(expected); + expect(SelectAction.create({ deselectedElementsIDs, selectedElementsIDs })).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments: deselectAll', () => { const expected: SelectAction = { @@ -68,7 +68,7 @@ describe('Element selection actions', () => { deselectAll: true }; const { selectedElementsIDs } = expected; - expect(SelectAction.create({ deselectedElementsIDs: true, selectedElementsIDs })).to.deep.equals(expected); + expect(SelectAction.create({ deselectedElementsIDs: true, selectedElementsIDs })).toEqual(expected); }); }); describe('addSelection', () => { @@ -80,7 +80,7 @@ describe('Element selection actions', () => { deselectAll: false }; const { selectedElementsIDs } = expected; - expect(SelectAction.addSelection(selectedElementsIDs)).to.deep.equals(expected); + expect(SelectAction.addSelection(selectedElementsIDs)).toEqual(expected); }); }); describe('removeSelection', () => { @@ -92,7 +92,7 @@ describe('Element selection actions', () => { deselectAll: false }; const { deselectedElementsIDs } = expected; - expect(SelectAction.removeSelection(deselectedElementsIDs)).to.deep.equals(expected); + expect(SelectAction.removeSelection(deselectedElementsIDs)).toEqual(expected); }); }); describe('setSelection', () => { @@ -104,7 +104,7 @@ describe('Element selection actions', () => { deselectAll: true }; const { selectedElementsIDs } = expected; - expect(SelectAction.setSelection(selectedElementsIDs)).to.deep.equals(expected); + expect(SelectAction.setSelection(selectedElementsIDs)).toEqual(expected); }); }); }); @@ -116,13 +116,13 @@ describe('Element selection actions', () => { kind: 'allSelected', select: true }; - expect(SelectAllAction.is(action)).to.be.true; + expect(SelectAllAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(SelectAllAction.is(undefined)).to.be.false; + expect(SelectAllAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(SelectAllAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(SelectAllAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -132,7 +132,7 @@ describe('Element selection actions', () => { kind: 'allSelected', select: true }; - expect(SelectAllAction.create()).to.deep.equals(expected); + expect(SelectAllAction.create()).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: SelectAllAction = { @@ -140,7 +140,7 @@ describe('Element selection actions', () => { select: false }; const { select } = expected; - expect(SelectAllAction.create(select)).to.deep.equals(expected); + expect(SelectAllAction.create(select)).toEqual(expected); }); }); }); diff --git a/packages/protocol/src/action-protocol/element-text-editing.spec.ts b/packages/protocol/src/action-protocol/element-text-editing.spec.ts index 4d734f67..6349f0bd 100644 --- a/packages/protocol/src/action-protocol/element-text-editing.spec.ts +++ b/packages/protocol/src/action-protocol/element-text-editing.spec.ts @@ -14,7 +14,7 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { ApplyLabelEditOperation, RequestEditValidationAction, @@ -37,13 +37,13 @@ describe('Element text editing actions', () => { modelElementId: '', text: '' }; - expect(RequestEditValidationAction.is(action)).to.be.true; + expect(RequestEditValidationAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(RequestEditValidationAction.is(undefined)).to.be.false; + expect(RequestEditValidationAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(RequestEditValidationAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(RequestEditValidationAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -57,7 +57,7 @@ describe('Element text editing actions', () => { text: 'someText' }; const { contextId, modelElementId, text } = expected; - expect(RequestEditValidationAction.create({ contextId, modelElementId, text })).to.deep.equals(expected); + expect(RequestEditValidationAction.create({ contextId, modelElementId, text })).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: RequestEditValidationAction = { @@ -68,7 +68,7 @@ describe('Element text editing actions', () => { text: 'someText' }; const { contextId, modelElementId, text, requestId } = expected; - expect(RequestEditValidationAction.create({ contextId, modelElementId, text, requestId })).to.deep.equals(expected); + expect(RequestEditValidationAction.create({ contextId, modelElementId, text, requestId })).toEqual(expected); }); }); }); @@ -81,13 +81,13 @@ describe('Element text editing actions', () => { responseId: '', status: { severity: ValidationStatus.Severity.OK } }; - expect(SetEditValidationResultAction.is(action)).to.be.true; + expect(SetEditValidationResultAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(SetEditValidationResultAction.is(undefined)).to.be.false; + expect(SetEditValidationResultAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(SetEditValidationResultAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(SetEditValidationResultAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -99,7 +99,7 @@ describe('Element text editing actions', () => { status: { severity: ValidationStatus.Severity.OK } }; const { status } = expected; - expect(SetEditValidationResultAction.create(status)).to.deep.equals(expected); + expect(SetEditValidationResultAction.create(status)).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: SetEditValidationResultAction = { @@ -109,7 +109,7 @@ describe('Element text editing actions', () => { status: { severity: ValidationStatus.Severity.OK } }; const { status, args, responseId } = expected; - expect(SetEditValidationResultAction.create(status, { args, responseId })).to.deep.equals(expected); + expect(SetEditValidationResultAction.create(status, { args, responseId })).toEqual(expected); }); }); }); @@ -123,13 +123,13 @@ describe('Element text editing actions', () => { labelId: '', text: '' }; - expect(ApplyLabelEditOperation.is(operation)).to.be.true; + expect(ApplyLabelEditOperation.is(operation)).toBe(true); }); it('should return false for `undefined`', () => { - expect(ApplyLabelEditOperation.is(undefined)).to.be.false; + expect(ApplyLabelEditOperation.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(ApplyLabelEditOperation.is({ kind: 'notTheRightOne' })).to.be.false; + expect(ApplyLabelEditOperation.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -142,7 +142,7 @@ describe('Element text editing actions', () => { text: 'myText' }; const { labelId, text } = expected; - expect(ApplyLabelEditOperation.create({ labelId, text })).to.deep.equals(expected); + expect(ApplyLabelEditOperation.create({ labelId, text })).toEqual(expected); }); }); }); diff --git a/packages/protocol/src/action-protocol/element-type-hints.spec.ts b/packages/protocol/src/action-protocol/element-type-hints.spec.ts index a61c75e2..6dc9b954 100644 --- a/packages/protocol/src/action-protocol/element-type-hints.spec.ts +++ b/packages/protocol/src/action-protocol/element-type-hints.spec.ts @@ -14,7 +14,7 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { CheckEdgeResultAction, RequestCheckEdgeAction, RequestTypeHintsAction, SetTypeHintsAction } from './element-type-hints'; /** * Tests for the utility functions declared in the namespaces of the protocol @@ -28,13 +28,13 @@ describe('Element type hints actions', () => { kind: 'requestTypeHints', requestId: '' }; - expect(RequestTypeHintsAction.is(action)).to.be.true; + expect(RequestTypeHintsAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(RequestTypeHintsAction.is(undefined)).to.be.false; + expect(RequestTypeHintsAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(RequestTypeHintsAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(RequestTypeHintsAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -45,7 +45,7 @@ describe('Element type hints actions', () => { requestId: '' }; - expect(RequestTypeHintsAction.create()).to.deep.equals(expected); + expect(RequestTypeHintsAction.create()).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: RequestTypeHintsAction = { @@ -53,7 +53,7 @@ describe('Element type hints actions', () => { requestId: 'myRequest' }; const { requestId } = expected; - expect(RequestTypeHintsAction.create({ requestId })).to.deep.equals(expected); + expect(RequestTypeHintsAction.create({ requestId })).toEqual(expected); }); }); }); @@ -67,13 +67,13 @@ describe('Element type hints actions', () => { edgeHints: [], shapeHints: [] }; - expect(SetTypeHintsAction.is(action)).to.be.true; + expect(SetTypeHintsAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(SetTypeHintsAction.is(undefined)).to.be.false; + expect(SetTypeHintsAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(SetTypeHintsAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(SetTypeHintsAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -104,7 +104,7 @@ describe('Element type hints actions', () => { ] }; const { edgeHints, shapeHints } = expected; - expect(SetTypeHintsAction.create({ edgeHints, shapeHints })).to.deep.equals(expected); + expect(SetTypeHintsAction.create({ edgeHints, shapeHints })).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: SetTypeHintsAction = { @@ -132,7 +132,7 @@ describe('Element type hints actions', () => { ] }; const { edgeHints, shapeHints, responseId } = expected; - expect(SetTypeHintsAction.create({ edgeHints, shapeHints, responseId })).to.deep.equals(expected); + expect(SetTypeHintsAction.create({ edgeHints, shapeHints, responseId })).toEqual(expected); }); }); }); @@ -145,7 +145,7 @@ describe('Element type hints actions', () => { sourceElementId: 'source', requestId: '' }; - expect(RequestCheckEdgeAction.is(action)).to.be.true; + expect(RequestCheckEdgeAction.is(action)).toBe(true); }); it('should return true for an object having the correct type and a value for all required interface & optional properties', () => { const action: RequestCheckEdgeAction = { @@ -155,13 +155,13 @@ describe('Element type hints actions', () => { targetElementId: 'target', requestId: '' }; - expect(RequestCheckEdgeAction.is(action)).to.be.true; + expect(RequestCheckEdgeAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(RequestCheckEdgeAction.is(undefined)).to.be.false; + expect(RequestCheckEdgeAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(RequestCheckEdgeAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(RequestCheckEdgeAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -175,7 +175,7 @@ describe('Element type hints actions', () => { targetElementId: undefined }; - expect(RequestCheckEdgeAction.create({ edgeType: 'edge', sourceElement: 'source' })).to.deep.equals(expected); + expect(RequestCheckEdgeAction.create({ edgeType: 'edge', sourceElement: 'source' })).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: RequestCheckEdgeAction = { @@ -193,7 +193,7 @@ describe('Element type hints actions', () => { targetElement: 'target', requestId: 'myRequest' }) - ).to.deep.equals(expected); + ).toEqual(expected); }); }); }); @@ -207,7 +207,7 @@ describe('Element type hints actions', () => { sourceElementId: 'source', responseId: '' }; - expect(CheckEdgeResultAction.is(action)).to.be.true; + expect(CheckEdgeResultAction.is(action)).toBe(true); }); it('should return true for an object having the correct type and a value for all required interface & optional properties', () => { const action: CheckEdgeResultAction = { @@ -218,13 +218,13 @@ describe('Element type hints actions', () => { targetElementId: 'target', responseId: 'myResponse' }; - expect(CheckEdgeResultAction.is(action)).to.be.true; + expect(CheckEdgeResultAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(CheckEdgeResultAction.is(undefined)).to.be.false; + expect(CheckEdgeResultAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(CheckEdgeResultAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(CheckEdgeResultAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -237,9 +237,7 @@ describe('Element type hints actions', () => { sourceElementId: 'source', responseId: '' }; - expect(CheckEdgeResultAction.create({ edgeType: 'edge', isValid: true, sourceElementId: 'source' })).to.deep.equals( - expected - ); + expect(CheckEdgeResultAction.create({ edgeType: 'edge', isValid: true, sourceElementId: 'source' })).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: CheckEdgeResultAction = { @@ -259,7 +257,7 @@ describe('Element type hints actions', () => { targetElementId: 'target', responseId: 'myResponse' }) - ).to.deep.equals(expected); + ).toEqual(expected); }); }); }); diff --git a/packages/protocol/src/action-protocol/element-validation.spec.ts b/packages/protocol/src/action-protocol/element-validation.spec.ts index f7760374..695377ed 100644 --- a/packages/protocol/src/action-protocol/element-validation.spec.ts +++ b/packages/protocol/src/action-protocol/element-validation.spec.ts @@ -14,7 +14,7 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { DeleteMarkersAction, RequestMarkersAction, SetMarkersAction } from './element-validation'; /** * Tests for the utility functions declared in the namespaces of the protocol @@ -30,13 +30,13 @@ describe('Element validation actions', () => { requestId: '', elementsIDs: [] }; - expect(RequestMarkersAction.is(action)).to.be.true; + expect(RequestMarkersAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(RequestMarkersAction.is(undefined)).to.be.false; + expect(RequestMarkersAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(RequestMarkersAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(RequestMarkersAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -49,7 +49,7 @@ describe('Element validation actions', () => { reason: 'batch' }; const { elementsIDs } = expected; - expect(RequestMarkersAction.create(elementsIDs)).to.deep.equals(expected); + expect(RequestMarkersAction.create(elementsIDs)).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: RequestMarkersAction = { @@ -59,7 +59,7 @@ describe('Element validation actions', () => { reason: 'batch' }; const { elementsIDs, requestId } = expected; - expect(RequestMarkersAction.create(elementsIDs, { requestId })).to.deep.equals(expected); + expect(RequestMarkersAction.create(elementsIDs, { requestId })).toEqual(expected); }); }); }); @@ -72,13 +72,13 @@ describe('Element validation actions', () => { responseId: '', markers: [] }; - expect(SetMarkersAction.is(action)).to.be.true; + expect(SetMarkersAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(SetMarkersAction.is(undefined)).to.be.false; + expect(SetMarkersAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(SetMarkersAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(SetMarkersAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -91,7 +91,7 @@ describe('Element validation actions', () => { markers: [{ description: 'desc', elementId: 'myId', kind: 'info', label: 'string' }] }; const { markers } = expected; - expect(SetMarkersAction.create(markers)).to.deep.equals(expected); + expect(SetMarkersAction.create(markers)).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: SetMarkersAction = { @@ -101,7 +101,7 @@ describe('Element validation actions', () => { markers: [{ description: 'desc', elementId: 'myId', kind: 'info', label: 'string' }] }; const { markers, responseId } = expected; - expect(SetMarkersAction.create(markers, { responseId })).to.deep.equals(expected); + expect(SetMarkersAction.create(markers, { responseId })).toEqual(expected); }); }); }); @@ -113,13 +113,13 @@ describe('Element validation actions', () => { kind: 'deleteMarkers', markers: [] }; - expect(DeleteMarkersAction.is(action)).to.be.true; - it('should return false for `undefined`', () => { - expect(DeleteMarkersAction.is(undefined)).to.be.false; - }); - it('should return false for an object that does not have all required interface properties', () => { - expect(DeleteMarkersAction.is({ kind: 'notTheRightOne' })).to.be.false; - }); + expect(DeleteMarkersAction.is(action)).toBe(true); + }); + it('should return false for `undefined`', () => { + expect(DeleteMarkersAction.is(undefined)).toBe(false); + }); + it('should return false for an object that does not have all required interface properties', () => { + expect(DeleteMarkersAction.is({ kind: 'notTheRightOne' })).toBe(false); }); describe('create', () => { @@ -129,7 +129,7 @@ describe('Element validation actions', () => { markers: [{ description: 'desc', elementId: 'myId', kind: 'info', label: 'string' }] }; const { markers } = expected; - expect(DeleteMarkersAction.create(markers)).to.deep.equals(expected); + expect(DeleteMarkersAction.create(markers)).toEqual(expected); }); }); }); diff --git a/packages/protocol/src/action-protocol/model-data.spec.ts b/packages/protocol/src/action-protocol/model-data.spec.ts index 9b10b961..578839ad 100644 --- a/packages/protocol/src/action-protocol/model-data.spec.ts +++ b/packages/protocol/src/action-protocol/model-data.spec.ts @@ -14,7 +14,7 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { RequestModelAction, SetModelAction, SourceModelChangedAction, UpdateModelAction } from './model-data'; /** * Tests for the utility functions declared in the namespaces of the protocol @@ -24,19 +24,17 @@ describe('Model data actions', () => { describe('RequestModelAction', () => { describe('is', () => { it('should return true for an object having the correct type and a value for all required interface properties', () => { - it('RequestModelAction.is with valid action type', () => { - const action: RequestModelAction = { - kind: 'requestModel', - requestId: '' - }; - expect(RequestModelAction.is(action)).to.be.true; - }); + const action: RequestModelAction = { + kind: 'requestModel', + requestId: '' + }; + expect(RequestModelAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(RequestModelAction.is(undefined)).to.be.false; + expect(RequestModelAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(RequestModelAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(RequestModelAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -47,7 +45,7 @@ describe('Model data actions', () => { requestId: '' }; - expect(RequestModelAction.create()).to.deep.equals(expected); + expect(RequestModelAction.create()).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: RequestModelAction = { @@ -56,7 +54,7 @@ describe('Model data actions', () => { options: { some: 'option' } }; const { requestId, options } = expected; - expect(RequestModelAction.create({ options, requestId })).to.deep.equals(expected); + expect(RequestModelAction.create({ options, requestId })).toEqual(expected); }); }); }); @@ -69,13 +67,13 @@ describe('Model data actions', () => { responseId: '', newRoot: { id: '', type: '' } }; - expect(SetModelAction.is(action)).to.be.true; + expect(SetModelAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(SetModelAction.is(undefined)).to.be.false; + expect(SetModelAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(SetModelAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(SetModelAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -87,7 +85,7 @@ describe('Model data actions', () => { newRoot: { id: 'myId', type: 'myType' } }; const { newRoot } = expected; - expect(SetModelAction.create(newRoot)).to.deep.equals(expected); + expect(SetModelAction.create(newRoot)).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: SetModelAction = { @@ -96,7 +94,7 @@ describe('Model data actions', () => { newRoot: { id: '', type: '' } }; const { newRoot, responseId } = expected; - expect(SetModelAction.create(newRoot, { responseId })).to.deep.equals(expected); + expect(SetModelAction.create(newRoot, { responseId })).toEqual(expected); }); }); }); @@ -108,13 +106,13 @@ describe('Model data actions', () => { kind: 'updateModel', newRoot: { id: '', type: '' } }; - expect(UpdateModelAction.is(action)).to.be.true; + expect(UpdateModelAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(UpdateModelAction.is(undefined)).to.be.false; + expect(UpdateModelAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(UpdateModelAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(UpdateModelAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -126,7 +124,7 @@ describe('Model data actions', () => { newRoot: { id: 'myId', type: 'myType' } }; const { newRoot } = expected; - expect(UpdateModelAction.create(newRoot)).to.deep.equals(expected); + expect(UpdateModelAction.create(newRoot)).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: UpdateModelAction = { @@ -135,7 +133,7 @@ describe('Model data actions', () => { animate: false }; const { newRoot, animate } = expected; - expect(UpdateModelAction.create(newRoot, { animate })).to.deep.equals(expected); + expect(UpdateModelAction.create(newRoot, { animate })).toEqual(expected); }); }); }); @@ -147,13 +145,13 @@ describe('Model data actions', () => { kind: 'sourceModelChanged', sourceModelName: '' }; - expect(SourceModelChangedAction.is(action)).to.be.true; + expect(SourceModelChangedAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(SourceModelChangedAction.is(undefined)).to.be.false; + expect(SourceModelChangedAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(SourceModelChangedAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(SourceModelChangedAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -164,7 +162,7 @@ describe('Model data actions', () => { sourceModelName: 'myModelSource' }; const { sourceModelName: sourceModelName } = expected; - expect(SourceModelChangedAction.create(sourceModelName)).to.deep.equals(expected); + expect(SourceModelChangedAction.create(sourceModelName)).toEqual(expected); }); }); }); diff --git a/packages/protocol/src/action-protocol/model-edit-mode.spec.ts b/packages/protocol/src/action-protocol/model-edit-mode.spec.ts index cc0c02e7..ae319a01 100644 --- a/packages/protocol/src/action-protocol/model-edit-mode.spec.ts +++ b/packages/protocol/src/action-protocol/model-edit-mode.spec.ts @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2022 STMicroelectronics and others. + * Copyright (c) 2022-2026 STMicroelectronics and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -13,7 +13,7 @@ * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { SetEditModeAction } from './model-edit-mode'; /** * Tests for the utility functions declared in the namespaces of the protocol @@ -26,13 +26,13 @@ describe('SetEditModeAction', () => { kind: 'setEditMode', editMode: '' }; - expect(SetEditModeAction.is(action)).to.be.true; + expect(SetEditModeAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(SetEditModeAction.is(undefined)).to.be.false; + expect(SetEditModeAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(SetEditModeAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(SetEditModeAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -43,7 +43,7 @@ describe('SetEditModeAction', () => { editMode: 'myMode' }; const { editMode } = expected; - expect(SetEditModeAction.create(editMode)).to.deep.equals(expected); + expect(SetEditModeAction.create(editMode)).toEqual(expected); }); }); }); diff --git a/packages/protocol/src/action-protocol/model-layout.spec.ts b/packages/protocol/src/action-protocol/model-layout.spec.ts index 3a05dc31..863f72f8 100644 --- a/packages/protocol/src/action-protocol/model-layout.spec.ts +++ b/packages/protocol/src/action-protocol/model-layout.spec.ts @@ -14,7 +14,7 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { Dimension, Point } from 'sprotty-protocol'; import { ComputedBoundsAction, LayoutOperation, RequestBoundsAction, TriggerLayoutAction } from './model-layout'; /** @@ -31,13 +31,13 @@ describe('Model layout actions', () => { requestId: '', newRoot: { id: '', type: '' } }; - expect(RequestBoundsAction.is(action)).to.be.true; + expect(RequestBoundsAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(RequestBoundsAction.is(undefined)).to.be.false; + expect(RequestBoundsAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(RequestBoundsAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(RequestBoundsAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -49,7 +49,7 @@ describe('Model layout actions', () => { newRoot: { id: 'myId', type: 'myType' } }; const { newRoot } = expected; - expect(RequestBoundsAction.create(newRoot)).to.deep.equals(expected); + expect(RequestBoundsAction.create(newRoot)).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: RequestBoundsAction = { @@ -58,7 +58,7 @@ describe('Model layout actions', () => { newRoot: { id: 'myId', type: 'myType' } }; const { newRoot, requestId } = expected; - expect(RequestBoundsAction.create(newRoot, { requestId })).to.deep.equals(expected); + expect(RequestBoundsAction.create(newRoot, { requestId })).toEqual(expected); }); }); }); @@ -71,13 +71,13 @@ describe('Model layout actions', () => { responseId: '', bounds: [] }; - expect(ComputedBoundsAction.is(action)).to.be.true; + expect(ComputedBoundsAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(ComputedBoundsAction.is(undefined)).to.be.false; + expect(ComputedBoundsAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(ComputedBoundsAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(ComputedBoundsAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -89,7 +89,7 @@ describe('Model layout actions', () => { bounds: [{ elementId: '', newSize: Dimension.EMPTY, newPosition: Point.ORIGIN }] }; const { bounds } = expected; - expect(ComputedBoundsAction.create(bounds)).to.deep.equals(expected); + expect(ComputedBoundsAction.create(bounds)).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: ComputedBoundsAction = { @@ -101,7 +101,7 @@ describe('Model layout actions', () => { routes: [{ elementId: 'myEdge', newRoutingPoints: [{ x: 42, y: 1337 }] }] }; const { bounds, responseId, alignments, revision, routes } = expected; - expect(ComputedBoundsAction.create(bounds, { responseId, alignments, revision, routes })).to.deep.equals(expected); + expect(ComputedBoundsAction.create(bounds, { responseId, alignments, revision, routes })).toEqual(expected); }); }); }); @@ -112,13 +112,13 @@ describe('Model layout actions', () => { const action: TriggerLayoutAction = { kind: 'triggerLayout' }; - expect(TriggerLayoutAction.is(action)).to.be.true; + expect(TriggerLayoutAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(TriggerLayoutAction.is(undefined)).to.be.false; + expect(TriggerLayoutAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(TriggerLayoutAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(TriggerLayoutAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -128,7 +128,7 @@ describe('Model layout actions', () => { kind: 'triggerLayout', args: { customArg: 'argValue' } }; - expect(TriggerLayoutAction.create({ args: { customArg: 'argValue' } })).to.deep.equals(expected); + expect(TriggerLayoutAction.create({ args: { customArg: 'argValue' } })).toEqual(expected); }); }); }); @@ -140,13 +140,13 @@ describe('Model layout actions', () => { kind: 'layout', isOperation: true }; - expect(LayoutOperation.is(action)).to.be.true; + expect(LayoutOperation.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(LayoutOperation.is(undefined)).to.be.false; + expect(LayoutOperation.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(LayoutOperation.is({ kind: 'notTheRightOne' })).to.be.false; + expect(LayoutOperation.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -158,7 +158,7 @@ describe('Model layout actions', () => { elementIds: ['myElements'] }; const { elementIds } = expected; - expect(LayoutOperation.create(elementIds)).to.deep.equals(expected); + expect(LayoutOperation.create(elementIds)).toEqual(expected); }); }); }); diff --git a/packages/protocol/src/action-protocol/model-saving.spec.ts b/packages/protocol/src/action-protocol/model-saving.spec.ts index cf7e47e0..41406ea2 100644 --- a/packages/protocol/src/action-protocol/model-saving.spec.ts +++ b/packages/protocol/src/action-protocol/model-saving.spec.ts @@ -15,7 +15,7 @@ ********************************************************************************/ /* eslint-disable @typescript-eslint/no-deprecated */ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { ExportResultAction, ExportSvgAction, @@ -36,13 +36,13 @@ describe('Model saving actions', () => { const action: SaveModelAction = { kind: 'saveModel' }; - expect(SaveModelAction.is(action)).to.be.true; + expect(SaveModelAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(SaveModelAction.is(undefined)).to.be.false; + expect(SaveModelAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(SaveModelAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(SaveModelAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -52,7 +52,7 @@ describe('Model saving actions', () => { kind: 'saveModel' }; - expect(SaveModelAction.create()).to.deep.equals(expected); + expect(SaveModelAction.create()).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: SaveModelAction = { @@ -60,7 +60,7 @@ describe('Model saving actions', () => { fileUri: 'myUri' }; const { fileUri } = expected; - expect(SaveModelAction.create({ fileUri })).to.deep.equals(expected); + expect(SaveModelAction.create({ fileUri })).toEqual(expected); }); }); }); @@ -72,13 +72,13 @@ describe('Model saving actions', () => { kind: 'setDirtyState', isDirty: true }; - expect(SetDirtyStateAction.is(action)).to.be.true; + expect(SetDirtyStateAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(SetDirtyStateAction.is(undefined)).to.be.false; + expect(SetDirtyStateAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(SetDirtyStateAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(SetDirtyStateAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -89,7 +89,7 @@ describe('Model saving actions', () => { isDirty: true }; const { isDirty } = expected; - expect(SetDirtyStateAction.create(isDirty)).to.deep.equals(expected); + expect(SetDirtyStateAction.create(isDirty)).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: SetDirtyStateAction = { @@ -98,7 +98,7 @@ describe('Model saving actions', () => { reason: 'save' }; const { isDirty, reason } = expected; - expect(SetDirtyStateAction.create(isDirty, { reason })).to.deep.equals(expected); + expect(SetDirtyStateAction.create(isDirty, { reason })).toEqual(expected); }); }); }); @@ -110,13 +110,13 @@ describe('Model saving actions', () => { kind: 'requestExportSvg', requestId: '' }; - expect(RequestExportSvgAction.is(action)).to.be.true; + expect(RequestExportSvgAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(RequestExportSvgAction.is(undefined)).to.be.false; + expect(RequestExportSvgAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(RequestExportSvgAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(RequestExportSvgAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -126,7 +126,7 @@ describe('Model saving actions', () => { kind: 'requestExportSvg', requestId: '' }; - expect(RequestExportSvgAction.create()).to.deep.equals(expected); + expect(RequestExportSvgAction.create()).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: RequestExportSvgAction = { @@ -134,7 +134,7 @@ describe('Model saving actions', () => { requestId: 'myRequest' }; const { requestId } = expected; - expect(RequestExportSvgAction.create({ requestId })).to.deep.equals(expected); + expect(RequestExportSvgAction.create({ requestId })).toEqual(expected); }); }); }); @@ -147,13 +147,13 @@ describe('Model saving actions', () => { responseId: '', svg: '' }; - expect(ExportSvgAction.is(action)).to.be.true; + expect(ExportSvgAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(ExportSvgAction.is(undefined)).to.be.false; + expect(ExportSvgAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(ExportSvgAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(ExportSvgAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -165,7 +165,7 @@ describe('Model saving actions', () => { svg: 'someSvg' }; const { svg } = expected; - expect(ExportSvgAction.create(svg)).to.deep.equals(expected); + expect(ExportSvgAction.create(svg)).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: ExportSvgAction = { @@ -174,7 +174,7 @@ describe('Model saving actions', () => { svg: 'someSvg' }; const { svg, responseId } = expected; - expect(ExportSvgAction.create(svg, { responseId })).to.deep.equals(expected); + expect(ExportSvgAction.create(svg, { responseId })).toEqual(expected); }); }); }); @@ -187,22 +187,22 @@ describe('Model saving actions', () => { requestId: '', format: 'png' }; - expect(RequestExportAction.is(action)).to.be.true; + expect(RequestExportAction.is(action)).toBe(true); }); it('should reject the legacy `requestExportSvg` kind to keep strict separation between the two protocols', () => { - expect(RequestExportAction.is({ kind: 'requestExportSvg', requestId: '' })).to.be.false; + expect(RequestExportAction.is({ kind: 'requestExportSvg', requestId: '' })).toBe(false); }); it('should return false for an action missing the `format` discriminator', () => { - expect(RequestExportAction.is({ kind: 'requestExport', requestId: '' })).to.be.false; + expect(RequestExportAction.is({ kind: 'requestExport', requestId: '' })).toBe(false); }); it('should return false for `undefined`', () => { - expect(RequestExportAction.is(undefined)).to.be.false; + expect(RequestExportAction.is(undefined)).toBe(false); }); }); describe('create', () => { it('should default `requestId` to empty when none is supplied', () => { - expect(RequestExportAction.create('svg')).to.deep.equals({ + expect(RequestExportAction.create('svg')).toEqual({ kind: 'requestExport', format: 'svg', requestId: '' @@ -210,7 +210,7 @@ describe('Model saving actions', () => { }); it('should propagate caller-supplied formatOptions and requestId', () => { const formatOptions = { width: 1024, skipCopyStyles: true }; - expect(RequestExportAction.create('png', { formatOptions, requestId: 'abc' })).to.deep.equals({ + expect(RequestExportAction.create('png', { formatOptions, requestId: 'abc' })).toEqual({ kind: 'requestExport', format: 'png', requestId: 'abc', @@ -219,7 +219,7 @@ describe('Model saving actions', () => { }); it('should accept an arbitrary string format (open registry)', () => { const action = RequestExportAction.create('pdf'); - expect(action.format).to.equal('pdf'); + expect(action.format).toBe('pdf'); }); }); }); @@ -235,7 +235,7 @@ describe('Model saving actions', () => { encoding: 'text', data: '' }; - expect(ExportResultAction.is(action)).to.be.true; + expect(ExportResultAction.is(action)).toBe(true); }); it('should return true for a well-formed base64-encoded result', () => { const action: ExportResultAction = { @@ -246,10 +246,10 @@ describe('Model saving actions', () => { encoding: 'base64', data: 'aGVsbG8=' }; - expect(ExportResultAction.is(action)).to.be.true; + expect(ExportResultAction.is(action)).toBe(true); }); it('should reject the legacy `exportSvg` kind to keep strict separation between the two protocols', () => { - expect(ExportResultAction.is({ kind: 'exportSvg', responseId: '', svg: '' })).to.be.false; + expect(ExportResultAction.is({ kind: 'exportSvg', responseId: '', svg: '' })).toBe(false); }); it('should return false when `data` is missing', () => { expect( @@ -260,14 +260,14 @@ describe('Model saving actions', () => { mimeType: 'image/svg+xml', encoding: 'text' }) - ).to.be.false; + ).toBe(false); }); }); describe('create', () => { it('should round-trip an SVG payload', () => { const created = ExportResultAction.create('svg', '', { mimeType: 'image/svg+xml', encoding: 'text' }); - expect(created).to.deep.equals({ + expect(created).toEqual({ kind: 'exportResult', responseId: '', format: 'svg', @@ -284,7 +284,7 @@ describe('Model saving actions', () => { responseId: 'r-1', formatOptions }); - expect(created).to.deep.equals({ + expect(created).toEqual({ kind: 'exportResult', responseId: 'r-1', format: 'png', diff --git a/packages/protocol/src/action-protocol/node-modification.spec.ts b/packages/protocol/src/action-protocol/node-modification.spec.ts index f19a0b06..b976b785 100644 --- a/packages/protocol/src/action-protocol/node-modification.spec.ts +++ b/packages/protocol/src/action-protocol/node-modification.spec.ts @@ -14,7 +14,7 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { Dimension, Point } from 'sprotty-protocol'; import { ChangeBoundsOperation, ChangeContainerOperation } from './node-modification'; @@ -32,13 +32,13 @@ describe('Node modification actions', () => { isOperation: true, newBounds: [] }; - expect(ChangeBoundsOperation.is(operation)).to.be.true; + expect(ChangeBoundsOperation.is(operation)).toBe(true); }); it('should return false for `undefined`', () => { - expect(ChangeBoundsOperation.is(undefined)).to.be.false; + expect(ChangeBoundsOperation.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(ChangeBoundsOperation.is({ kind: 'notTheRightOne' })).to.be.false; + expect(ChangeBoundsOperation.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -50,7 +50,7 @@ describe('Node modification actions', () => { newBounds: [{ elementId: 'someElement', newSize: Dimension.EMPTY, newPosition: Point.ORIGIN }] }; const { newBounds } = expected; - expect(ChangeBoundsOperation.create(newBounds)).to.deep.equals(expected); + expect(ChangeBoundsOperation.create(newBounds)).toEqual(expected); }); }); }); @@ -64,13 +64,13 @@ describe('ChangeContainerOperation', () => { elementId: '', targetContainerId: '' }; - expect(ChangeContainerOperation.is(action)).to.be.true; + expect(ChangeContainerOperation.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(ChangeContainerOperation.is(undefined)).to.be.false; + expect(ChangeContainerOperation.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(ChangeContainerOperation.is({ kind: 'notTheRightOne' })).to.be.false; + expect(ChangeContainerOperation.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -83,7 +83,7 @@ describe('ChangeContainerOperation', () => { targetContainerId: 'myContainer' }; const { elementId, targetContainerId } = expected; - expect(ChangeContainerOperation.create({ elementId, targetContainerId })).to.deep.equals(expected); + expect(ChangeContainerOperation.create({ elementId, targetContainerId })).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: ChangeContainerOperation = { @@ -94,7 +94,7 @@ describe('ChangeContainerOperation', () => { location: Point.ORIGIN }; const { elementId, targetContainerId, location } = expected; - expect(ChangeContainerOperation.create({ elementId, targetContainerId, location })).to.deep.equals(expected); + expect(ChangeContainerOperation.create({ elementId, targetContainerId, location })).toEqual(expected); }); }); }); diff --git a/packages/protocol/src/action-protocol/tool-palette.spec.ts b/packages/protocol/src/action-protocol/tool-palette.spec.ts index 248f19a3..859c9e65 100644 --- a/packages/protocol/src/action-protocol/tool-palette.spec.ts +++ b/packages/protocol/src/action-protocol/tool-palette.spec.ts @@ -14,7 +14,7 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { TriggerEdgeCreationAction, TriggerNodeCreationAction } from './tool-palette'; describe('Tool palette Actions', () => { @@ -25,13 +25,13 @@ describe('Tool palette Actions', () => { kind: 'triggerNodeCreation', elementTypeId: '' }; - expect(TriggerNodeCreationAction.is(action)).to.be.true; + expect(TriggerNodeCreationAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(TriggerNodeCreationAction.is(undefined)).to.be.false; + expect(TriggerNodeCreationAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(TriggerNodeCreationAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(TriggerNodeCreationAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -42,7 +42,7 @@ describe('Tool palette Actions', () => { elementTypeId: 'myElementType' }; const { elementTypeId } = expected; - expect(TriggerNodeCreationAction.create(elementTypeId)).to.deep.equals(expected); + expect(TriggerNodeCreationAction.create(elementTypeId)).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: TriggerNodeCreationAction = { @@ -51,7 +51,7 @@ describe('Tool palette Actions', () => { args: { some: 'args' } }; const { elementTypeId, args } = expected; - expect(TriggerNodeCreationAction.create(elementTypeId, { args })).to.deep.equals(expected); + expect(TriggerNodeCreationAction.create(elementTypeId, { args })).toEqual(expected); }); }); }); @@ -63,13 +63,13 @@ describe('Tool palette Actions', () => { kind: 'triggerEdgeCreation', elementTypeId: '' }; - expect(TriggerEdgeCreationAction.is(action)).to.be.true; + expect(TriggerEdgeCreationAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(TriggerEdgeCreationAction.is(undefined)).to.be.false; + expect(TriggerEdgeCreationAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(TriggerEdgeCreationAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(TriggerEdgeCreationAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -80,7 +80,7 @@ describe('Tool palette Actions', () => { elementTypeId: 'myEdge' }; const { elementTypeId } = expected; - expect(TriggerEdgeCreationAction.create(elementTypeId)).to.deep.equals(expected); + expect(TriggerEdgeCreationAction.create(elementTypeId)).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: TriggerEdgeCreationAction = { @@ -89,7 +89,7 @@ describe('Tool palette Actions', () => { args: { some: 'args' } }; const { elementTypeId, args } = expected; - expect(TriggerEdgeCreationAction.create(elementTypeId, { args })).to.deep.equals(expected); + expect(TriggerEdgeCreationAction.create(elementTypeId, { args })).toEqual(expected); }); }); }); diff --git a/packages/protocol/src/action-protocol/undo-redo.spec.ts b/packages/protocol/src/action-protocol/undo-redo.spec.ts index ffbb10fa..9f2599ed 100644 --- a/packages/protocol/src/action-protocol/undo-redo.spec.ts +++ b/packages/protocol/src/action-protocol/undo-redo.spec.ts @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2022 STMicroelectronics and others. + * Copyright (c) 2022-2026 STMicroelectronics and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -13,7 +13,7 @@ * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { RedoAction, UndoAction } from './undo-redo'; describe('Undo & Redo Actions', () => { @@ -23,13 +23,13 @@ describe('Undo & Redo Actions', () => { const action: UndoAction = { kind: 'glspUndo' }; - expect(UndoAction.is(action)).to.be.true; + expect(UndoAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(UndoAction.is(undefined)).to.be.false; + expect(UndoAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(UndoAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(UndoAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -38,7 +38,7 @@ describe('Undo & Redo Actions', () => { const expected: UndoAction = { kind: 'glspUndo' }; - expect(UndoAction.create()).to.deep.equals(expected); + expect(UndoAction.create()).toEqual(expected); }); }); }); @@ -49,13 +49,13 @@ describe('Undo & Redo Actions', () => { const action: RedoAction = { kind: 'glspRedo' }; - expect(RedoAction.is(action)).to.be.true; + expect(RedoAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(RedoAction.is(undefined)).to.be.false; + expect(RedoAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(RedoAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(RedoAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -64,7 +64,7 @@ describe('Undo & Redo Actions', () => { const expected: RedoAction = { kind: 'glspRedo' }; - expect(RedoAction.create()).to.deep.equals(expected); + expect(RedoAction.create()).toEqual(expected); }); }); }); diff --git a/packages/protocol/src/action-protocol/viewport.spec.ts b/packages/protocol/src/action-protocol/viewport.spec.ts index 9980c179..2a7ce113 100644 --- a/packages/protocol/src/action-protocol/viewport.spec.ts +++ b/packages/protocol/src/action-protocol/viewport.spec.ts @@ -14,7 +14,7 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { CenterAction, FitToScreenAction, MoveViewportAction, OriginViewportAction } from './viewport'; describe('Viewport Actions', () => { @@ -27,13 +27,13 @@ describe('Viewport Actions', () => { animate: true, retainZoom: true }; - expect(CenterAction.is(action)).to.be.true; + expect(CenterAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(CenterAction.is(undefined)).to.be.false; + expect(CenterAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(CenterAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(CenterAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -46,7 +46,7 @@ describe('Viewport Actions', () => { retainZoom: false }; const { elementIds } = expected; - expect(CenterAction.create(elementIds)).to.deep.equals(expected); + expect(CenterAction.create(elementIds)).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: CenterAction = { @@ -56,7 +56,7 @@ describe('Viewport Actions', () => { retainZoom: true }; const { elementIds, animate, retainZoom } = expected; - expect(CenterAction.create(elementIds, { animate, retainZoom })).to.deep.equals(expected); + expect(CenterAction.create(elementIds, { animate, retainZoom })).toEqual(expected); }); }); }); @@ -69,13 +69,13 @@ describe('Viewport Actions', () => { elementIds: [], animate: true }; - expect(FitToScreenAction.is(action)).to.be.true; + expect(FitToScreenAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(FitToScreenAction.is(undefined)).to.be.false; + expect(FitToScreenAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(FitToScreenAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(FitToScreenAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -87,7 +87,7 @@ describe('Viewport Actions', () => { animate: true }; const { elementIds } = expected; - expect(FitToScreenAction.create(elementIds)).to.deep.equals(expected); + expect(FitToScreenAction.create(elementIds)).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { const expected: FitToScreenAction = { @@ -98,7 +98,7 @@ describe('Viewport Actions', () => { padding: 12 }; const { elementIds, maxZoom, padding, animate } = expected; - expect(FitToScreenAction.create(elementIds, { maxZoom, padding, animate })).to.deep.equals(expected); + expect(FitToScreenAction.create(elementIds, { maxZoom, padding, animate })).toEqual(expected); }); }); }); @@ -111,13 +111,13 @@ describe('Viewport Actions', () => { moveX: 0, moveY: 0 }; - expect(MoveViewportAction.is(action)).to.be.true; + expect(MoveViewportAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(MoveViewportAction.is(undefined)).to.be.false; + expect(MoveViewportAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(MoveViewportAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(MoveViewportAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -129,7 +129,7 @@ describe('Viewport Actions', () => { moveY: 0 }; const { moveX, moveY } = expected; - expect(MoveViewportAction.create({ moveX, moveY })).to.deep.equals(expected); + expect(MoveViewportAction.create({ moveX, moveY })).toEqual(expected); }); }); }); @@ -141,13 +141,13 @@ describe('Viewport Actions', () => { kind: 'originViewport', animate: true }; - expect(OriginViewportAction.is(action)).to.be.true; + expect(OriginViewportAction.is(action)).toBe(true); }); it('should return false for `undefined`', () => { - expect(OriginViewportAction.is(undefined)).to.be.false; + expect(OriginViewportAction.is(undefined)).toBe(false); }); it('should return false for an object that does not have all required interface properties', () => { - expect(OriginViewportAction.is({ kind: 'notTheRightOne' })).to.be.false; + expect(OriginViewportAction.is({ kind: 'notTheRightOne' })).toBe(false); }); }); @@ -157,7 +157,7 @@ describe('Viewport Actions', () => { kind: 'originViewport', animate: true }; - expect(OriginViewportAction.create()).to.deep.equals(expected); + expect(OriginViewportAction.create()).toEqual(expected); }); it('should return an object conforming to the interface with matching properties for the given optional arguments', () => { const expected: OriginViewportAction = { @@ -165,7 +165,7 @@ describe('Viewport Actions', () => { animate: false }; const { animate } = expected; - expect(OriginViewportAction.create({ animate })).to.deep.equals(expected); + expect(OriginViewportAction.create({ animate })).toEqual(expected); }); }); }); diff --git a/packages/protocol/src/client-server-protocol/base-glsp-client.spec.ts b/packages/protocol/src/client-server-protocol/base-glsp-client.spec.ts index 091cc459..5d2541f1 100644 --- a/packages/protocol/src/client-server-protocol/base-glsp-client.spec.ts +++ b/packages/protocol/src/client-server-protocol/base-glsp-client.spec.ts @@ -14,11 +14,9 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; -import * as sinon from 'sinon'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; import * as util from 'util'; import { Action, ActionMessage } from '../action-protocol/base-protocol'; -import { expectToThrowAsync } from '../utils/test-util'; import { BaseGLSPClient, GLOBAL_HANDLER_ID } from './base-glsp-client'; import { ClientState } from './glsp-client'; import { GLSPServer, GLSPServerListener } from './glsp-server'; @@ -46,15 +44,43 @@ class StubGLSPServer implements GLSPServer { } } -describe('Node GLSP Client', () => { - const sandbox = sinon.createSandbox(); +/** + * Spies on every method of the given object with a `vi.spyOn` mock that keeps the original + * implementation, mirroring the former `sandbox.stub(obj)` behavior. The preset's + * `restoreMocks: true` detaches spies between tests, so `setup()` must be re-invoked in a + * `beforeEach`. Returns the typed object plus `setup`/`reset` helpers. + */ +function spyOnAllMethods(obj: T): { mock: { [K in keyof T]: T[K] }; setup: () => void; reset: () => void } { + const methodNames = new Set(); + let proto: any = obj; + while (proto && proto !== Object.prototype) { + for (const key of Object.getOwnPropertyNames(proto)) { + if (key !== 'constructor' && typeof (obj as any)[key] === 'function') { + methodNames.add(key); + } + } + proto = Object.getPrototypeOf(proto); + } + // `mockImplementation(() => undefined)` mirrors Sinon's default stub: the original method body + // is suppressed and the stub returns `undefined` unless a test configures explicit behavior. + const eachSpy = (fn: (spy: ReturnType) => void): void => + methodNames.forEach(name => fn(vi.spyOn(obj as any, name as any).mockImplementation(() => undefined as any))); + return { + mock: obj as any, + setup: () => eachSpy(() => {}), + reset: () => eachSpy(spy => spy.mockReset().mockImplementation(() => undefined as any)) + }; +} - const server = sandbox.stub(new StubGLSPServer()); +describe('Node GLSP Client', () => { + const serverStub = spyOnAllMethods(new StubGLSPServer()); + const server = serverStub.mock; + beforeEach(() => serverStub.setup()); // Shared test client instance that is already in running state let client = new BaseGLSPClient({ id: 'test' }); function resetClient(setRunning = true): void { - sandbox.reset(); + serverStub.reset(); client = new BaseGLSPClient({ id: 'test' }); if (setRunning) { client['_server'] = server; @@ -64,158 +90,159 @@ describe('Node GLSP Client', () => { it('Should be in initial state after construction', () => { resetClient(false); - expect(client.currentState).to.be.equal(ClientState.Initial); + expect(client.currentState).toBe(ClientState.Initial); }); describe('start', () => { it('should fail if no server is configured', async () => { resetClient(false); - const stateChangeHandler = sinon.spy(); + const stateChangeHandler = vi.fn(); client.onCurrentStateChanged(stateChangeHandler); client.setStartupTimeout(5); - await expectToThrowAsync(() => client.start()); - expect(client.currentState).to.be.equal(ClientState.StartFailed); - expect(stateChangeHandler.calledWith(ClientState.StartFailed)).to.be.true; + await expect(client.start()).rejects.toThrow(); + expect(client.currentState).toBe(ClientState.StartFailed); + expect(stateChangeHandler).toHaveBeenCalledWith(ClientState.StartFailed); }); it('Should resolve when server is configured', async () => { resetClient(false); - const stateChangeHandler = sinon.spy(); + const stateChangeHandler = vi.fn(); client.onCurrentStateChanged(stateChangeHandler); const started = client.start(); - expect(client.currentState).to.be.equal(ClientState.Starting); - expect(stateChangeHandler.calledWith(ClientState.Starting)).to.be.true; + expect(client.currentState).toBe(ClientState.Starting); + expect(stateChangeHandler).toHaveBeenCalledWith(ClientState.Starting); client.configureServer(server); await started; - expect(client.currentState).to.be.equal(ClientState.Running); - expect(stateChangeHandler.calledWith(ClientState.Running)).to.be.true; + expect(client.currentState).toBe(ClientState.Running); + expect(stateChangeHandler).toHaveBeenCalledWith(ClientState.Running); }); }); describe('stop & onStop', () => { it('onStop should not resolve if stop has not been called', () => { resetClient(); - expect(util.inspect(client.onStop())).to.include('pending'); + expect(util.inspect(client.onStop())).toContain('pending'); }); it('should be in stopped state and onStop should resolve', async () => { resetClient(); - expect(client.currentState).to.be.not.equal(ClientState.Stopped); - const stateChangeHandler = sinon.spy(); + expect(client.currentState).not.toBe(ClientState.Stopped); + const stateChangeHandler = vi.fn(); client.onCurrentStateChanged(stateChangeHandler); await client.stop(); - expect(client.currentState).to.be.equal(ClientState.Stopped); - expect(stateChangeHandler.calledWith(ClientState.Stopping)).to.be.true; - expect(stateChangeHandler.calledWith(ClientState.Stopped)).to.be.true; - expect(server.shutdown.calledOnce).to.be.true; + expect(client.currentState).toBe(ClientState.Stopped); + expect(stateChangeHandler).toHaveBeenCalledWith(ClientState.Stopping); + expect(stateChangeHandler).toHaveBeenCalledWith(ClientState.Stopped); + expect(server.shutdown).toHaveBeenCalledOnce(); }); it('should only stop a running client once, if stop is called multiple times ', async () => { resetClient(); client.stop(); await client.stop(); - expect(client.currentState).to.be.equal(ClientState.Stopped); - expect(server.shutdown.calledOnce).to.be.true; + expect(client.currentState).toBe(ClientState.Stopped); + expect(server.shutdown).toHaveBeenCalledOnce(); }); }); describe('initialize', () => { it('should fail if server is not configured', async () => { resetClient(false); - await expectToThrowAsync(() => client.initializeServer({ applicationId: '', protocolVersion: '' })); - expect(server.initialize.called).to.be.false; - expect(client.initializeResult).to.be.undefined; + await expect(client.initializeServer({ applicationId: '', protocolVersion: '' })).rejects.toThrow(); + expect(server.initialize).not.toHaveBeenCalled(); + expect(client.initializeResult).toBeUndefined(); }); it('should fail if client is not running', async () => { resetClient(false); client.configureServer(server); - await expectToThrowAsync(() => client.initializeServer({ applicationId: '', protocolVersion: '' })); - expect(server.initialize.called).to.be.false; - expect(client.initializeResult).to.be.undefined; + await expect(client.initializeServer({ applicationId: '', protocolVersion: '' })).rejects.toThrow(); + expect(server.initialize).not.toHaveBeenCalled(); + expect(client.initializeResult).toBeUndefined(); }); it('should invoke the corresponding server method', async () => { resetClient(); const expectedResult = { protocolVersion: '1.0.0', serverActions: {} }; - server.initialize.returns(Promise.resolve(expectedResult)); - expect(client.initializeResult).to.be.undefined; + vi.mocked(server.initialize).mockReturnValue(Promise.resolve(expectedResult)); + expect(client.initializeResult).toBeUndefined(); const result = await client.initializeServer({ applicationId: 'id', protocolVersion: '1.0.0' }); - expect(result).to.deep.equals(expectedResult); - expect(server.initialize.calledOnce).to.be.true; - expect(client.initializeResult).to.be.equal(result); + expect(result).toEqual(expectedResult); + expect(server.initialize).toHaveBeenCalledOnce(); + expect(client.initializeResult).toBe(result); }); it('should return cached result on consecutive invocation', async () => { resetClient(); const expectedResult = { protocolVersion: '1.0.0', serverActions: {} }; const params = { applicationId: 'id', protocolVersion: '1.0.0' }; - server.initialize.returns(Promise.resolve(expectedResult)); + vi.mocked(server.initialize).mockReturnValue(Promise.resolve(expectedResult)); client.initializeServer(params); const result = await client.initializeServer(params); - expect(result).to.be.deep.equal(client.initializeResult); - expect(server.initialize.calledOnce).to.be.true; + expect(result).toEqual(client.initializeResult); + expect(server.initialize).toHaveBeenCalledOnce(); }); it('should fire event on first invocation', async () => { resetClient(); const expectedResult = { protocolVersion: '1.0.0', serverActions: {} }; const params = { applicationId: 'id', protocolVersion: '1.0.0' }; - server.initialize.returns(Promise.resolve(expectedResult)); + vi.mocked(server.initialize).mockReturnValue(Promise.resolve(expectedResult)); - const eventHandler = (result: InitializeResult): void => {}; - const eventHandlerSpy = sinon.spy(eventHandler); + const eventHandlerSpy = vi.fn((result: InitializeResult): void => {}); client.onServerInitialized(eventHandlerSpy); await client.initializeServer(params); await client.initializeServer(params); - expect(eventHandlerSpy.calledOnceWith(expectedResult)).to.be.true; + expect(eventHandlerSpy).toHaveBeenCalledExactlyOnceWith(expectedResult); }); it('should not use cached result on consecutive invocation if previous invocation errored', async () => { resetClient(); const expectedResult = { protocolVersion: '1.0.0', serverActions: {} }; const params = { applicationId: 'id', protocolVersion: '1.0.0' }; - server.initialize.throws(new Error('error')); - expectToThrowAsync(() => client.initializeServer(params)); - expect(client.initializeResult).to.be.undefined; - server.initialize.returns(Promise.resolve(expectedResult)); + vi.mocked(server.initialize).mockImplementation(() => { + throw new Error('error'); + }); + await expect(client.initializeServer(params)).rejects.toThrow(); + expect(client.initializeResult).toBeUndefined(); + vi.mocked(server.initialize).mockReturnValue(Promise.resolve(expectedResult)); const result = await client.initializeServer(params); - expect(result).to.be.deep.equal(expectedResult); - expect(server.initialize.calledTwice).to.be.true; - expect(client.initializeResult).to.be.equal(result); + expect(result).toEqual(expectedResult); + expect(server.initialize).toHaveBeenCalledTimes(2); + expect(client.initializeResult).toBe(result); }); }); describe('initializeClientSession', () => { it('should fail if server is not configured', async () => { resetClient(false); - await expectToThrowAsync(() => client.initializeClientSession({ clientSessionId: '', diagramType: '', clientActionKinds: [] })); - expect(server.initializeClientSession.called).to.be.false; + expect(() => client.initializeClientSession({ clientSessionId: '', diagramType: '', clientActionKinds: [] })).toThrow(); + expect(server.initializeClientSession).not.toHaveBeenCalled(); }); it('should fail if client is not running', async () => { resetClient(false); client.configureServer(server); - await expectToThrowAsync(() => client.initializeClientSession({ clientSessionId: '', diagramType: '', clientActionKinds: [] })); - expect(server.initializeClientSession.called).to.be.false; + expect(() => client.initializeClientSession({ clientSessionId: '', diagramType: '', clientActionKinds: [] })).toThrow(); + expect(server.initializeClientSession).not.toHaveBeenCalled(); }); it('should invoke the corresponding server method', async () => { resetClient(); const result = await client.initializeClientSession({ clientSessionId: '', diagramType: '', clientActionKinds: [] }); - expect(result).to.be.undefined; - expect(server.initializeClientSession.calledOnce).to.be.true; + expect(result).toBeUndefined(); + expect(server.initializeClientSession).toHaveBeenCalledOnce(); }); }); describe('disposeClientSession', () => { it('should fail if server is not configured', async () => { resetClient(false); - await expectToThrowAsync(() => client.disposeClientSession({ clientSessionId: '' })); - expect(server.disposeClientSession.called).to.be.false; + expect(() => client.disposeClientSession({ clientSessionId: '' })).toThrow(); + expect(server.disposeClientSession).not.toHaveBeenCalled(); }); it('should fail if client is not running', async () => { resetClient(false); client.configureServer(server); - await expectToThrowAsync(() => client.disposeClientSession({ clientSessionId: '' })); - expect(server.disposeClientSession.called).to.be.false; + expect(() => client.disposeClientSession({ clientSessionId: '' })).toThrow(); + expect(server.disposeClientSession).not.toHaveBeenCalled(); }); it('should invoke the corresponding server method', async () => { resetClient(); const result = await client.disposeClientSession({ clientSessionId: '' }); - expect(result).to.be.undefined; - expect(server.disposeClientSession.calledOnce).to.be.true; + expect(result).toBeUndefined(); + expect(server.disposeClientSession).toHaveBeenCalledOnce(); }); }); @@ -229,9 +256,9 @@ describe('Node GLSP Client', () => { } catch (err) { rejection = err; } - expect(rejection).to.be.instanceOf(Error); - expect((rejection as Error).message).to.match(/not in 'Running' state/); - expect(server.shutdown.called).to.be.false; + expect(rejection).toBeInstanceOf(Error); + expect((rejection as Error).message).toMatch(/not in 'Running' state/); + expect(server.shutdown).not.toHaveBeenCalled(); }); it('should fail if client is not running', async () => { resetClient(false); @@ -242,75 +269,76 @@ describe('Node GLSP Client', () => { } catch (err) { rejection = err; } - expect(rejection).to.be.instanceOf(Error); - expect((rejection as Error).message).to.match(/not in 'Running' state/); - expect(server.shutdown.called).to.be.false; + expect(rejection).toBeInstanceOf(Error); + expect((rejection as Error).message).toMatch(/not in 'Running' state/); + expect(server.shutdown).not.toHaveBeenCalled(); }); it('should invoke the corresponding server method', async () => { resetClient(); await client.shutdownServer(); - expect(server.shutdown.calledOnce).to.be.true; + expect(server.shutdown).toHaveBeenCalledOnce(); }); }); describe('sendActionMessage', () => { it('should fail if server is not configured', () => { resetClient(false); - expect(() => client.sendActionMessage({ action: { kind: '' }, clientId: '' })).to.throw(); - expect(server.process.called).to.be.false; + expect(() => client.sendActionMessage({ action: { kind: '' }, clientId: '' })).toThrow(); + expect(server.process).not.toHaveBeenCalled(); }); it('should fail if client is not running', () => { resetClient(false); client.configureServer(server); - expect(() => client.sendActionMessage({ action: { kind: '' }, clientId: '' })).to.throw(); - expect(server.process.called).to.be.false; + expect(() => client.sendActionMessage({ action: { kind: '' }, clientId: '' })).toThrow(); + expect(server.process).not.toHaveBeenCalled(); }); it('should invoke the corresponding server method', () => { resetClient(); client.sendActionMessage({ action: { kind: '' }, clientId: '' }); - expect(server.process.calledOnce).to.be.true; + expect(server.process).toHaveBeenCalledOnce(); }); }); describe('onActionMessage', () => { - const handler = sandbox.spy((_message: ActionMessage): void => {}); + const handler = vi.fn((_message: ActionMessage): void => {}); + beforeEach(() => handler.mockClear()); it('should be properly registered if server is not configured', () => { resetClient(false); client.onActionMessage(handler); - expect(client['actionMessageHandlers'].get(GLOBAL_HANDLER_ID)?.length).to.be.equal(1); - expect(handler.called).to.be.false; + expect(client['actionMessageHandlers'].get(GLOBAL_HANDLER_ID)?.length).toBe(1); + expect(handler).not.toHaveBeenCalled(); }); it('should be properly registered if client is not running', () => { resetClient(false); client.configureServer(server); client.onActionMessage(handler); - expect(client['actionMessageHandlers'].get(GLOBAL_HANDLER_ID)?.length).to.be.equal(1); - expect(handler.called).to.be.false; + expect(client['actionMessageHandlers'].get(GLOBAL_HANDLER_ID)?.length).toBe(1); + expect(handler).not.toHaveBeenCalled(); }); it('should unregister global handler if dispose is invoked', () => { resetClient(false); const toDispose = client.onActionMessage(handler); - expect(client['actionMessageHandlers'].get(GLOBAL_HANDLER_ID)?.length).to.be.equal(1); + expect(client['actionMessageHandlers'].get(GLOBAL_HANDLER_ID)?.length).toBe(1); toDispose.dispose(); - expect(client['actionMessageHandlers'].get(GLOBAL_HANDLER_ID)?.length).to.be.equal(0); + expect(client['actionMessageHandlers'].get(GLOBAL_HANDLER_ID)?.length).toBe(0); }); it('should unregister client id handler if dispose is invoked', () => { resetClient(false); const clientId = 'clientId'; const toDispose = client.onActionMessage(handler, clientId); - expect(client['actionMessageHandlers'].size).to.be.equal(2); + expect(client['actionMessageHandlers'].size).toBe(2); toDispose.dispose(); - expect(client['actionMessageHandlers'].get(clientId)?.length).to.be.equal(0); + expect(client['actionMessageHandlers'].get(clientId)?.length).toBe(0); }); it('should invoke global handler when the an action message is sent via proxy', () => { resetClient(); client.onActionMessage(handler); const expectedMessage = { action: { kind: 'someAction' }, clientId: 'someClientId' }; client.proxy.process(expectedMessage); - expect(handler.calledOnce).to.be.true; - expect(handler.firstCall.args[0]).to.deep.equals(expectedMessage); + expect(handler).toHaveBeenCalledOnce(); + expect(handler.mock.calls[0][0]).toEqual(expectedMessage); }); it('should invoke client id handler when the an action message is sent via proxy', () => { resetClient(); @@ -319,8 +347,8 @@ describe('Node GLSP Client', () => { const expectedMessage = { action: { kind: 'someAction' }, clientId }; client.proxy.process(expectedMessage); client.proxy.process({ clientId: 'someOtherId', action: { kind: 'someAction' } }); - expect(handler.calledOnce).to.be.true; - expect(handler.firstCall.args[0]).to.deep.equals(expectedMessage); + expect(handler).toHaveBeenCalledOnce(); + expect(handler.mock.calls[0][0]).toEqual(expectedMessage); }); }); }); diff --git a/packages/protocol/src/client-server-protocol/jsonrpc/base-jsonrpc-glsp-client.spec.ts b/packages/protocol/src/client-server-protocol/jsonrpc/base-jsonrpc-glsp-client.spec.ts index 3e8dd61e..a2e9f0dc 100644 --- a/packages/protocol/src/client-server-protocol/jsonrpc/base-jsonrpc-glsp-client.spec.ts +++ b/packages/protocol/src/client-server-protocol/jsonrpc/base-jsonrpc-glsp-client.spec.ts @@ -14,13 +14,11 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; -import * as sinon from 'sinon'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; import { Disposable, Event, MessageConnection, NotificationHandler, ProgressType } from 'vscode-jsonrpc'; import { ActionMessage } from '../../action-protocol/base-protocol'; import { remove } from '../../utils/array-util'; import { Emitter } from '../../utils/event'; -import { expectToThrowAsync } from '../../utils/test-util'; import { ClientState } from '../glsp-client'; import { InitializeResult } from '../types'; import { BaseJsonrpcGLSPClient } from './base-jsonrpc-glsp-client'; @@ -79,12 +77,41 @@ class TestJsonRpcClient extends BaseJsonrpcGLSPClient { lastListenerRemoved: boolean; } +/** + * Spies on every method of the given object with a `vi.spyOn` mock that keeps the original + * implementation, mirroring the former `sandbox.stub(obj)` behavior. The preset's + * `restoreMocks: true` detaches spies between tests, so `setup()` must be re-invoked in a + * `beforeEach`. Returns the typed object plus `setup`/`reset` helpers. + */ +function spyOnAllMethods(obj: T): { mock: { [K in keyof T]: T[K] }; setup: () => void; reset: () => void } { + const methodNames = new Set(); + let proto: any = obj; + while (proto && proto !== Object.prototype) { + for (const key of Object.getOwnPropertyNames(proto)) { + if (key !== 'constructor' && typeof (obj as any)[key] === 'function') { + methodNames.add(key); + } + } + proto = Object.getPrototypeOf(proto); + } + // `mockImplementation(() => undefined)` mirrors Sinon's default stub: the original method body + // is suppressed and the stub returns `undefined` unless a test configures explicit behavior. + const eachSpy = (fn: (spy: ReturnType) => void): void => + methodNames.forEach(name => fn(vi.spyOn(obj as any, name as any).mockImplementation(() => undefined as any))); + return { + mock: obj as any, + setup: () => eachSpy(() => {}), + reset: () => eachSpy(spy => spy.mockReset().mockImplementation(() => undefined as any)) + }; +} + describe('Base JSON-RPC GLSP Client', () => { - const sandbox = sinon.createSandbox(); - const connection = sandbox.stub(new StubMessageConnection()); + const connectionStub = spyOnAllMethods(new StubMessageConnection()); + const connection = connectionStub.mock; + beforeEach(() => connectionStub.setup()); let client = new TestJsonRpcClient({ id: 'test', connectionProvider: connection }); async function resetClient(setRunning = true): Promise { - sandbox.reset(); + connectionStub.reset(); client = new TestJsonRpcClient({ id: 'test', connectionProvider: connection }); if (setRunning) { return client.start(); @@ -94,173 +121,171 @@ describe('Base JSON-RPC GLSP Client', () => { describe('start', () => { it('should successfully start & activate the connection', async () => { await resetClient(false); - const stateChangeHandler = sinon.spy(); + const stateChangeHandler = vi.fn(); client.onCurrentStateChanged(stateChangeHandler); - expect(client.currentState).to.be.equal(ClientState.Initial); + expect(client.currentState).toBe(ClientState.Initial); const startCompleted = client.start(); - expect(client.currentState).to.be.equal(ClientState.Starting); - expect(stateChangeHandler.calledWith(ClientState.Starting)).to.be.true; + expect(client.currentState).toBe(ClientState.Starting); + expect(stateChangeHandler).toHaveBeenCalledWith(ClientState.Starting); await startCompleted; - expect(client.currentState).to.be.equal(ClientState.Running); - expect(client.isConnectionActive()).to.be.true; - expect(stateChangeHandler.calledWith(ClientState.Running)).to.be.true; + expect(client.currentState).toBe(ClientState.Running); + expect(client.isConnectionActive()).toBe(true); + expect(stateChangeHandler).toHaveBeenCalledWith(ClientState.Running); }); it('should fail to start if connecting to the server fails', async () => { await resetClient(false); - const stateChangeHandler = sinon.spy(); + const stateChangeHandler = vi.fn(); client.onCurrentStateChanged(stateChangeHandler); - expect(client.currentState).to.be.equal(ClientState.Initial); - connection.listen.throws(new Error('Connection failed')); + expect(client.currentState).toBe(ClientState.Initial); + vi.mocked(connection.listen).mockImplementation(() => { + throw new Error('Connection failed'); + }); await client.start(); - expect(client.currentState).to.be.equal(ClientState.StartFailed); - expect(stateChangeHandler.calledWith(ClientState.StartFailed)).to.be.true; + expect(client.currentState).toBe(ClientState.StartFailed); + expect(stateChangeHandler).toHaveBeenCalledWith(ClientState.StartFailed); }); it('should not start another connection if another start is already in progress', async () => { await resetClient(false); client.start(); await client.start(); - expect(client.currentState).to.be.equal(ClientState.Running); - expect(client.isConnectionActive()).to.be.true; - expect(connection.listen.calledOnce).to.be.true; + expect(client.currentState).toBe(ClientState.Running); + expect(client.isConnectionActive()).toBe(true); + expect(connection.listen).toHaveBeenCalledOnce(); }); }); describe('stop', () => { it('should successfully stop if the client was not running', async () => { await resetClient(false); - const stateChangeHandler = sinon.spy(); + const stateChangeHandler = vi.fn(); client.onCurrentStateChanged(stateChangeHandler); - expect(client.currentState).to.be.equal(ClientState.Initial); + expect(client.currentState).toBe(ClientState.Initial); await client.stop(); - expect(client.currentState).to.be.equal(ClientState.Stopped); - expect(stateChangeHandler.calledWith(ClientState.Stopped)).to.be.true; - expect(connection.dispose.called).to.be.false; + expect(client.currentState).toBe(ClientState.Stopped); + expect(stateChangeHandler).toHaveBeenCalledWith(ClientState.Stopped); + expect(connection.dispose).not.toHaveBeenCalled(); }); it('should successfully stop if the client was running', async () => { await resetClient(); - const stateChangeHandler = sinon.spy(); + const stateChangeHandler = vi.fn(); client.onCurrentStateChanged(stateChangeHandler); const stopped = client.stop(); - expect(client.currentState).to.be.equal(ClientState.Stopping); - expect(stateChangeHandler.calledWith(ClientState.Stopping)).to.be.true; + expect(client.currentState).toBe(ClientState.Stopping); + expect(stateChangeHandler).toHaveBeenCalledWith(ClientState.Stopping); await stopped; - expect(client.currentState).to.be.equal(ClientState.Stopped); - expect(stateChangeHandler.calledWith(ClientState.Stopped)).to.be.true; - expect(connection.dispose.called).to.be.true; + expect(client.currentState).toBe(ClientState.Stopped); + expect(stateChangeHandler).toHaveBeenCalledWith(ClientState.Stopped); + expect(connection.dispose).toHaveBeenCalled(); }); it('should only stop a running client once, if stop is called multiple times', async () => { await resetClient(); client.stop(); - expect(client.currentState).to.be.equal(ClientState.Stopping); + expect(client.currentState).toBe(ClientState.Stopping); await client.stop(); - expect(client.currentState).to.be.equal(ClientState.Stopped); - expect(connection.dispose.calledOnce).to.be.true; + expect(client.currentState).toBe(ClientState.Stopped); + expect(connection.dispose).toHaveBeenCalledOnce(); }); }); describe('initialize', () => { it('should fail if client is not running', async () => { await resetClient(false); - const stateChangeHandler = sinon.spy(); + const stateChangeHandler = vi.fn(); client.onCurrentStateChanged(stateChangeHandler); - await expectToThrowAsync(() => client.initializeServer({ applicationId: '', protocolVersion: '' })); - expect(connection.sendRequest.called).to.be.false; - expect(stateChangeHandler.called).to.be.false; + await expect(client.initializeServer({ applicationId: '', protocolVersion: '' })).rejects.toThrow(); + expect(connection.sendRequest).not.toHaveBeenCalled(); + expect(stateChangeHandler).not.toHaveBeenCalled(); }); it('should forward the corresponding initialize request and cache result', async () => { await resetClient(); const expectedResult = { protocolVersion: '1.0.0', serverActions: {} }; const params = { applicationId: 'id', protocolVersion: '1.0.0' }; - const initializeMock = connection.sendRequest.withArgs(JsonrpcGLSPClient.InitializeRequest, params); - initializeMock.returns(expectedResult); - expect(client.initializeResult).to.be.undefined; + vi.mocked(connection.sendRequest).mockReturnValue(expectedResult as any); + expect(client.initializeResult).toBeUndefined(); const result = await client.initializeServer({ applicationId: 'id', protocolVersion: '1.0.0' }); - expect(result).to.deep.equals(expectedResult); - expect(initializeMock.calledOnce).to.be.true; - expect(client.initializeResult).to.be.equal(result); + expect(result).toEqual(expectedResult); + expect(connection.sendRequest).toHaveBeenCalledExactlyOnceWith(JsonrpcGLSPClient.InitializeRequest, params); + expect(client.initializeResult).toBe(result); }); it('should return cached result on consecutive invocation', async () => { await resetClient(); const expectedResult = { protocolVersion: '1.0.0', serverActions: {} }; const params = { applicationId: 'id', protocolVersion: '1.0.0' }; - const initializeMock = connection.sendRequest.withArgs(JsonrpcGLSPClient.InitializeRequest, params); - initializeMock.returns(expectedResult); + vi.mocked(connection.sendRequest).mockReturnValue(expectedResult as any); client.initializeServer({ applicationId: 'id', protocolVersion: '1.0.0' }); const result = await client.initializeServer({ applicationId: 'id', protocolVersion: '1.0.0' }); - expect(result).to.be.deep.equal(client.initializeResult); - expect(initializeMock.calledOnce).to.be.true; + expect(result).toEqual(client.initializeResult); + expect(connection.sendRequest).toHaveBeenCalledExactlyOnceWith(JsonrpcGLSPClient.InitializeRequest, params); }); it('should fire event on first invocation', async () => { await resetClient(); const expectedResult = { protocolVersion: '1.0.0', serverActions: {} }; const params = { applicationId: 'id', protocolVersion: '1.0.0' }; - const initializeMock = connection.sendRequest.withArgs(JsonrpcGLSPClient.InitializeRequest, params); - initializeMock.returns(expectedResult); - const eventHandler = (result: InitializeResult): void => {}; - const eventHandlerSpy = sinon.spy(eventHandler); + vi.mocked(connection.sendRequest).mockReturnValue(expectedResult as any); + const eventHandlerSpy = vi.fn((result: InitializeResult): void => {}); client.onServerInitialized(eventHandlerSpy); await client.initializeServer(params); await client.initializeServer(params); - expect(eventHandlerSpy.calledOnceWith(expectedResult)).to.be.true; + expect(eventHandlerSpy).toHaveBeenCalledExactlyOnceWith(expectedResult); }); it('should not use cached result on consecutive invocation if previous invocation errored', async () => { await resetClient(); const expectedResult = { protocolVersion: '1.0.0', serverActions: {} }; const params = { applicationId: 'id', protocolVersion: '1.0.0' }; - const initializeMock = connection.sendRequest.withArgs(JsonrpcGLSPClient.InitializeRequest, params); - initializeMock.throws(new Error('SomeError')); - expectToThrowAsync(() => client.initializeServer(params)); - expect(client.initializeResult).to.be.undefined; - initializeMock.returns(expectedResult); + vi.mocked(connection.sendRequest).mockImplementation(() => { + throw new Error('SomeError'); + }); + await expect(client.initializeServer(params)).rejects.toThrow(); + expect(client.initializeResult).toBeUndefined(); + vi.mocked(connection.sendRequest).mockReturnValue(expectedResult as any); const result = await client.initializeServer(params); - expect(result).to.be.deep.equal(expectedResult); - expect(initializeMock.calledTwice).to.be.true; - expect(client.initializeResult).to.be.equal(result); + expect(result).toEqual(expectedResult); + expect(connection.sendRequest).toHaveBeenCalledTimes(2); + expect(connection.sendRequest).toHaveBeenCalledWith(JsonrpcGLSPClient.InitializeRequest, params); + expect(client.initializeResult).toBe(result); }); }); describe('initializeClientSession', () => { it('should fail if client is not running', async () => { await resetClient(false); - const stateChangeHandler = sinon.spy(); + const stateChangeHandler = vi.fn(); client.onCurrentStateChanged(stateChangeHandler); - await expectToThrowAsync(() => client.initializeClientSession({ clientSessionId: '', diagramType: '', clientActionKinds: [] })); - expect(connection.sendRequest.called).to.be.false; - expect(stateChangeHandler.called).to.be.false; + expect(() => client.initializeClientSession({ clientSessionId: '', diagramType: '', clientActionKinds: [] })).toThrow(); + expect(connection.sendRequest).not.toHaveBeenCalled(); + expect(stateChangeHandler).not.toHaveBeenCalled(); }); it('should invoke the corresponding server method', async () => { await resetClient(); const params = { clientSessionId: '', diagramType: '', clientActionKinds: [] }; - const initializeSessionMock = connection.sendRequest.withArgs(JsonrpcGLSPClient.InitializeClientSessionRequest, params); const result = await client.initializeClientSession(params); - expect(result).to.be.undefined; - expect(initializeSessionMock.calledOnce).to.be.true; + expect(result).toBeUndefined(); + expect(connection.sendRequest).toHaveBeenCalledExactlyOnceWith(JsonrpcGLSPClient.InitializeClientSessionRequest, params); }); }); describe('disposeClientSession', () => { it('should fail if client is not running', async () => { await resetClient(false); - const stateChangeHandler = sinon.spy(); + const stateChangeHandler = vi.fn(); client.onCurrentStateChanged(stateChangeHandler); - await expectToThrowAsync(() => client.disposeClientSession({ clientSessionId: '' })); - expect(connection.sendRequest.called).to.be.false; - expect(stateChangeHandler.called).to.be.false; + expect(() => client.disposeClientSession({ clientSessionId: '' })).toThrow(); + expect(connection.sendRequest).not.toHaveBeenCalled(); + expect(stateChangeHandler).not.toHaveBeenCalled(); }); it('should invoke the corresponding server method', async () => { await resetClient(); const params = { clientSessionId: 'someClient' }; - const disposeSessionMock = connection.sendRequest.withArgs(JsonrpcGLSPClient.DisposeClientSessionRequest, params); const result = await client.disposeClientSession(params); - expect(result).to.be.undefined; - expect(disposeSessionMock.calledOnce).to.be.true; + expect(result).toBeUndefined(); + expect(connection.sendRequest).toHaveBeenCalledExactlyOnceWith(JsonrpcGLSPClient.DisposeClientSessionRequest, params); }); }); describe('shutdownServer', () => { it('should fail if client is not running', async () => { await resetClient(false); - const stateChangeHandler = sinon.spy(); + const stateChangeHandler = vi.fn(); client.onCurrentStateChanged(stateChangeHandler); // `shutdownServer` is now async; the connection-state guard rejects the returned // promise rather than throwing synchronously. @@ -270,59 +295,58 @@ describe('Base JSON-RPC GLSP Client', () => { } catch (err) { rejection = err; } - expect(rejection).to.be.instanceOf(Error); - expect((rejection as Error).message).to.equal(JsonrpcGLSPClient.ClientNotReadyMsg); - expect(connection.sendNotification.called).to.be.false; - expect(stateChangeHandler.called).to.be.false; + expect(rejection).toBeInstanceOf(Error); + expect((rejection as Error).message).toBe(JsonrpcGLSPClient.ClientNotReadyMsg); + expect(connection.sendNotification).not.toHaveBeenCalled(); + expect(stateChangeHandler).not.toHaveBeenCalled(); }); it('should invoke the corresponding server method', async () => { await resetClient(); - const shutdownMock = connection.sendNotification.withArgs(JsonrpcGLSPClient.ShutdownNotification); const result = await client.shutdownServer(); - expect(result).to.be.undefined; - expect(shutdownMock.calledOnce).to.be.true; + expect(result).toBeUndefined(); + expect(connection.sendNotification).toHaveBeenCalledExactlyOnceWith(JsonrpcGLSPClient.ShutdownNotification); }); }); describe('sendActionMessage', () => { it('should fail if client is not running', async () => { await resetClient(false); - const stateChangeHandler = sinon.spy(); + const stateChangeHandler = vi.fn(); client.onCurrentStateChanged(stateChangeHandler); - expect(() => client.sendActionMessage({ action: { kind: '' }, clientId: '' })).to.throw(); - expect(connection.sendNotification.called).to.be.false; - expect(stateChangeHandler.called).to.be.false; + expect(() => client.sendActionMessage({ action: { kind: '' }, clientId: '' })).toThrow(); + expect(connection.sendNotification).not.toHaveBeenCalled(); + expect(stateChangeHandler).not.toHaveBeenCalled(); }); it('should invoke the corresponding server method', async () => { await resetClient(); const message = { action: { kind: '' }, clientId: '' }; - const messageMock = connection.sendNotification.withArgs(JsonrpcGLSPClient.ActionMessageNotification, message); client.sendActionMessage({ action: { kind: '' }, clientId: '' }); - expect(messageMock.calledOnce).to.be.true; + expect(connection.sendNotification).toHaveBeenCalledExactlyOnceWith(JsonrpcGLSPClient.ActionMessageNotification, message); }); }); describe('onActionMessage', () => { - const handler = sandbox.spy((_message: ActionMessage): void => {}); + const handler = vi.fn((_message: ActionMessage): void => {}); + beforeEach(() => handler.mockClear()); it('should be registered to message emitter if client is not running', async () => { await resetClient(false); client.onActionMessage(handler); - expect(client.firstListenerAdded).to.be.true; + expect(client.firstListenerAdded).toBe(true); }); it('should be registered to message emitter if client is running', async () => { await resetClient(); client.onActionMessage(handler, 'someId'); - expect(client.firstListenerAdded).to.be.true; + expect(client.firstListenerAdded).toBe(true); }); it('should unregister lister if dispose is invoked', () => { resetClient(false); const clientId = 'clientId'; const toDispose = client.onActionMessage(handler, clientId); - expect(client.firstListenerAdded).to.be.true; + expect(client.firstListenerAdded).toBe(true); toDispose.dispose(); - expect(client.lastListenerRemoved).to.be.true; + expect(client.lastListenerRemoved).toBe(true); }); }); @@ -330,34 +354,34 @@ describe('Base JSON-RPC GLSP Client', () => { it('Should be in error state after connection error', async () => { // mock setup resetClient(false); - const stateChangeHandler = sinon.spy(); + const stateChangeHandler = vi.fn(); client.onCurrentStateChanged(stateChangeHandler); const listeners: ((e: unknown) => unknown)[] = []; - connection.onError.callsFake(listener => { + vi.mocked(connection.onError).mockImplementation((listener: any) => { listeners.push(listener); return Disposable.create(() => remove(listeners, listener)); }); await client.start(); listeners.forEach(listener => listener(new Error('SomeError'))); - expect(client.currentState).to.be.equal(ClientState.ServerError); - expect(stateChangeHandler.calledWith(ClientState.ServerError)).to.be.true; + expect(client.currentState).toBe(ClientState.ServerError); + expect(stateChangeHandler).toHaveBeenCalledWith(ClientState.ServerError); }); it('Should be in error state after connection close while running', async () => { // mock setup resetClient(false); - const stateChangeHandler = sinon.spy(); + const stateChangeHandler = vi.fn(); client.onCurrentStateChanged(stateChangeHandler); const listeners: ((e: unknown) => unknown)[] = []; - connection.onClose.callsFake(listener => { + vi.mocked(connection.onClose).mockImplementation((listener: any) => { listeners.push(listener); return Disposable.create(() => remove(listeners, listener)); }); await client.start(); listeners.forEach(listener => listener(undefined)); - expect(client.currentState).to.be.equal(ClientState.ServerError); - expect(stateChangeHandler.calledWith(ClientState.ServerError)).to.be.true; + expect(client.currentState).toBe(ClientState.ServerError); + expect(stateChangeHandler).toHaveBeenCalledWith(ClientState.ServerError); }); }); }); diff --git a/packages/protocol/src/di/container-configuration.spec.ts b/packages/protocol/src/di/container-configuration.spec.ts index 889ed167..8c9509f5 100644 --- a/packages/protocol/src/di/container-configuration.spec.ts +++ b/packages/protocol/src/di/container-configuration.spec.ts @@ -13,7 +13,7 @@ * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { Container } from 'inversify'; import { resolveContainerConfiguration } from './container-configuration'; import { FeatureModule } from './feature-module'; @@ -30,41 +30,41 @@ describe('Container configuration', () => { describe('resolveContainerConfiguration', () => { it('should resolve the given container modules in incoming order', () => { const result = resolveContainerConfiguration(moduleA, moduleB, moduleC); - expect(result).to.deep.equal([moduleA, moduleB, moduleC]); + expect(result).toEqual([moduleA, moduleB, moduleC]); }); it('should resolve the same container module only once', () => { const result = resolveContainerConfiguration(moduleA, moduleA); - expect(result).to.deep.equal([moduleA]); + expect(result).toEqual([moduleA]); }); it('should resolve the given container modules and add configurations', () => { const result = resolveContainerConfiguration(moduleA, { add: [moduleB, moduleC] }); - expect(result).to.deep.equal([moduleA, moduleB, moduleC]); + expect(result).toEqual([moduleA, moduleB, moduleC]); }); it('should resolve the given container modules/add configurations and not load modules from remove configurations', () => { const result = resolveContainerConfiguration(moduleA, { add: [moduleB, moduleC], remove: moduleA }); - expect(result).to.deep.equal([moduleB, moduleC]); + expect(result).toEqual([moduleB, moduleC]); }); it('should resolve a module from a remove configuration if it is re-added with a subsequent add configuration', () => { const result = resolveContainerConfiguration(moduleA, { remove: moduleA }, moduleA); - expect(result).to.deep.equal([moduleA]); + expect(result).toEqual([moduleA]); }); it('should resolve a module from a replace configuration instead of a prior added module with the same feature id', () => { const replaceModule = new FeatureModule(() => {}, { featureId: moduleA.featureId }); const result = resolveContainerConfiguration(moduleA, moduleB, { replace: replaceModule }); - expect(result).to.deep.equal([replaceModule, moduleB]); + expect(result).toEqual([replaceModule, moduleB]); }); it('should still resolve a module from a replace configuration if there is no prior added module with the same featureId to replace', () => { const replaceModule = new FeatureModule(() => {}, { featureId: Symbol('replaceModule') }); const result = resolveContainerConfiguration(moduleA, moduleB, { replace: replaceModule }); - expect(result).to.deep.equal([moduleA, moduleB, replaceModule]); + expect(result).toEqual([moduleA, moduleB, replaceModule]); }); it('should throw an error for a configuration that resolves to multiple feature modules with the same featureId', () => { const duplicateModule = new FeatureModule(() => {}, { featureId: moduleA.featureId }); - expect(() => resolveContainerConfiguration(moduleA, duplicateModule)).to.throw(); + expect(() => resolveContainerConfiguration(moduleA, duplicateModule)).toThrow(); }); }); }); diff --git a/packages/protocol/src/di/feature-module.spec.ts b/packages/protocol/src/di/feature-module.spec.ts index 8210fc1b..4d5bdf47 100644 --- a/packages/protocol/src/di/feature-module.spec.ts +++ b/packages/protocol/src/di/feature-module.spec.ts @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2023-2024 EclipseSource and others. + * Copyright (c) 2023-2026 EclipseSource and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -13,7 +13,7 @@ * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { afterEach, describe, expect, it } from 'vitest'; import { Container } from 'inversify'; import { FeatureModule } from './feature-module'; describe('FeatureModule', () => { @@ -32,8 +32,8 @@ describe('FeatureModule', () => { bind('Foo').toConstantValue('Foo'); }); container.load(moduleWithNoRequirements); - expect(container.isBound(moduleWithNoRequirements.featureId)).to.be.true; - expect(container.isBound('Foo')).to.be.true; + expect(container.isBound(moduleWithNoRequirements.featureId)).toBe(true); + expect(container.isBound('Foo')).toBe(true); }); it('Should load a feature module with met required module', () => { const moduleWithNoRequirements = new FeatureModule( @@ -43,9 +43,9 @@ describe('FeatureModule', () => { { requires: moduleA } ); container.load(moduleA, moduleWithNoRequirements); - expect(container.isBound(moduleA.featureId)).to.be.true; - expect(container.isBound(moduleWithNoRequirements.featureId)).to.be.true; - expect(container.isBound('Foo')).to.be.true; + expect(container.isBound(moduleA.featureId)).toBe(true); + expect(container.isBound(moduleWithNoRequirements.featureId)).toBe(true); + expect(container.isBound('Foo')).toBe(true); }); it('Should not load a feature module if required module is loaded afterwards', () => { const moduleWithNoRequirements = new FeatureModule( @@ -55,9 +55,9 @@ describe('FeatureModule', () => { { requires: moduleA } ); container.load(moduleWithNoRequirements, moduleA); - expect(container.isBound(moduleA.featureId)).to.be.true; - expect(container.isBound(moduleWithNoRequirements.featureId)).to.be.false; - expect(container.isBound('Foo')).to.be.false; + expect(container.isBound(moduleA.featureId)).toBe(true); + expect(container.isBound(moduleWithNoRequirements.featureId)).toBe(false); + expect(container.isBound('Foo')).toBe(false); }); it('Should not load a feature module with missing required module', () => { const moduleWithUnmetRequirements = new FeatureModule( @@ -67,13 +67,13 @@ describe('FeatureModule', () => { { requires: moduleA } ); container.load(moduleWithUnmetRequirements); - expect(container.isBound(moduleWithUnmetRequirements.featureId)).to.be.false; - expect(container.isBound('Foo')).to.be.false; + expect(container.isBound(moduleWithUnmetRequirements.featureId)).toBe(false); + expect(container.isBound('Foo')).toBe(false); }); it('Should throw an error if a feature module with the same featureId is already loaded', () => { const loadedModule = new FeatureModule(() => {}, { featureId: moduleA.featureId }); container.load(loadedModule); - expect(() => container.load(moduleA)).to.throw(); + expect(() => container.load(moduleA)).toThrow(); }); }); describe('Multiple required modules', () => { @@ -85,9 +85,9 @@ describe('FeatureModule', () => { { requires: [moduleA, moduleB] } ); container.load(moduleA, moduleWithUnmetRequirements); - expect(container.isBound(moduleA.featureId)).to.be.true; - expect(container.isBound(moduleWithUnmetRequirements.featureId)).to.be.false; - expect(container.isBound('Foo')).to.be.false; + expect(container.isBound(moduleA.featureId)).toBe(true); + expect(container.isBound(moduleWithUnmetRequirements.featureId)).toBe(false); + expect(container.isBound('Foo')).toBe(false); }); }); it('Should not load a feature module with missing required modules', () => { @@ -98,8 +98,8 @@ describe('FeatureModule', () => { { requires: [moduleA, moduleB] } ); container.load(moduleWithUnmetRequirements); - expect(container.isBound(moduleWithUnmetRequirements.featureId)).to.be.false; - expect(container.isBound('Foo')).to.be.false; + expect(container.isBound(moduleWithUnmetRequirements.featureId)).toBe(false); + expect(container.isBound('Foo')).toBe(false); }); it('Should not load a feature module with partially loaded required modules', () => { const moduleWithUnmetRequirements = new FeatureModule( @@ -109,8 +109,8 @@ describe('FeatureModule', () => { { requires: [moduleA, moduleB] } ); container.load(moduleA, moduleWithUnmetRequirements); - expect(container.isBound(moduleA.featureId)).to.be.true; - expect(container.isBound(moduleWithUnmetRequirements.featureId)).to.be.false; - expect(container.isBound('Foo')).to.be.false; + expect(container.isBound(moduleA.featureId)).toBe(true); + expect(container.isBound(moduleWithUnmetRequirements.featureId)).toBe(false); + expect(container.isBound('Foo')).toBe(false); }); }); diff --git a/packages/protocol/src/di/lazy-injector.spec.ts b/packages/protocol/src/di/lazy-injector.spec.ts index 08b8eddc..c89d00ef 100644 --- a/packages/protocol/src/di/lazy-injector.spec.ts +++ b/packages/protocol/src/di/lazy-injector.spec.ts @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2024 EclipseSource and others. + * Copyright (c) 2024-2026 EclipseSource and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -13,7 +13,7 @@ * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { beforeEach, describe, expect, it } from 'vitest'; import { Container } from 'inversify'; import { LazyInjector, bindLazyInjector } from './lazy-injector'; @@ -42,80 +42,80 @@ describe('LazyInjector', () => { describe('get', () => { it('should return the service for a bound id', () => { const service = lazyInjector.get(ServiceA); - expect(service).to.not.be.undefined; - expect(service instanceof ServiceA).to.be.true; + expect(service).toBeDefined(); + expect(service instanceof ServiceA).toBe(true); }); it('should throw an error if the service id is not bound', () => { - expect(() => lazyInjector.get('UnboundService')).to.throw(); + expect(() => lazyInjector.get('UnboundService')).toThrow(); }); it('should throw an error if multiple services are bound to the given id', () => { container.bind(ServiceA).toConstantValue('ServiceA'); - expect(() => lazyInjector.get(ServiceA)).to.throw(); + expect(() => lazyInjector.get(ServiceA)).toThrow(); }); it('should return the same service instance for a bound id on subsequent calls', () => { const serviceA1 = lazyInjector.get(ServiceA); const serviceA2 = lazyInjector.get(ServiceA); const serviceB1 = lazyInjector.get(ServiceB); const serviceB2 = lazyInjector.get(ServiceB); - expect(serviceA1).to.equal(serviceA2); - expect(serviceB1).to.equal(serviceB2); + expect(serviceA1).toBe(serviceA2); + expect(serviceB1).toBe(serviceB2); }); }); describe('getOptional', () => { it('should return the service for a bound id', () => { const service = lazyInjector.getOptional(ServiceA); - expect(service).to.not.be.undefined; - expect(service instanceof ServiceA).to.be.true; + expect(service).toBeDefined(); + expect(service instanceof ServiceA).toBe(true); }); it('should return undefined if the service id is not bound', () => { const service = lazyInjector.getOptional('UnboundService'); - expect(service).to.be.undefined; + expect(service).toBeUndefined(); }); it('should throw an error if multiple services are bound to the given id', () => { container.bind(ServiceA).toConstantValue('ServiceA'); - expect(() => lazyInjector.get(ServiceA)).to.throw(); + expect(() => lazyInjector.get(ServiceA)).toThrow(); }); it('should return the same service instance for a bound id on subsequent calls', () => { const serviceA1 = lazyInjector.getOptional(ServiceA); const serviceA2 = lazyInjector.getOptional(ServiceA); const serviceB1 = lazyInjector.getOptional(ServiceB); const serviceB2 = lazyInjector.getOptional(ServiceB); - expect(serviceA1).to.not.be.undefined; - expect(serviceA1).to.equal(serviceA2); - expect(serviceB1).to.not.be.undefined; - expect(serviceB1).to.equal(serviceB2); + expect(serviceA1).toBeDefined(); + expect(serviceA1).toBe(serviceA2); + expect(serviceB1).toBeDefined(); + expect(serviceB1).toBe(serviceB2); }); it('should return undefined if the service id was initially not bound but is bound on subsequent calls', () => { const serviceC1 = lazyInjector.getOptional('ServiceC'); container.bind('ServiceC').toConstantValue('ServiceC'); const serviceC2 = lazyInjector.getOptional('ServiceC'); - expect(serviceC1).to.be.undefined; - expect(serviceC2).to.be.undefined; + expect(serviceC1).toBeUndefined(); + expect(serviceC2).toBeUndefined(); }); }); describe('getAll', () => { it('should return all services for a multi bound id', () => { const services = lazyInjector.getAll(MultiService); - expect(services).to.have.lengthOf(2); - expect(services[0] instanceof MultiService).to.be.true; - expect(services[1] instanceof MultiService).to.be.true; + expect(services).toHaveLength(2); + expect(services[0] instanceof MultiService).toBe(true); + expect(services[1] instanceof MultiService).toBe(true); }); it('should return the service for a single bound id', () => { const services = lazyInjector.getAll(ServiceA); - expect(services).to.have.lengthOf(1); - expect(services[0] instanceof ServiceA).to.be.true; + expect(services).toHaveLength(1); + expect(services[0] instanceof ServiceA).toBe(true); }); it('should return an empty array if the service id is not bound', () => { const services = lazyInjector.getAll('UnboundService'); - expect(services).to.be.empty; + expect(services).toHaveLength(0); }); it('should return an empty array if the service id was initially not bound but is bound on subsequent calls', () => { const services1 = lazyInjector.getAll('ServiceC'); container.bind('ServiceC').toConstantValue('ServiceC'); const services2 = lazyInjector.getAll('ServiceC'); - expect(services1).to.be.empty; - expect(services2).to.be.empty; + expect(services1).toHaveLength(0); + expect(services2).toHaveLength(0); }); }); }); diff --git a/packages/protocol/src/sprotty-geometry-bounds.spec.ts b/packages/protocol/src/sprotty-geometry-bounds.spec.ts index c63bd4c7..b3048703 100644 --- a/packages/protocol/src/sprotty-geometry-bounds.spec.ts +++ b/packages/protocol/src/sprotty-geometry-bounds.spec.ts @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2024 EclipseSource and others. + * Copyright (c) 2024-2026 EclipseSource and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -13,7 +13,7 @@ * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { Dimension, Point } from 'sprotty-protocol'; import { Bounds } from './sprotty-geometry-bounds'; @@ -22,13 +22,13 @@ describe('Bounds', () => { it('should return true if the given object is a bounds', () => { const bounds: Bounds = { x: 0, y: 0, width: 100, height: 100 }; const result = Bounds.is(bounds); - expect(result).to.be.true; + expect(result).toBe(true); }); it('should return false if the given object is not a bounds', () => { const bounds = { y: 0, width: 100, height: 100 }; const result = Bounds.is(bounds); - expect(result).to.be.false; + expect(result).toBe(false); }); }); @@ -36,19 +36,19 @@ describe('Bounds', () => { it('should return true if the bounds are valid', () => { const bounds: Bounds = { x: 0, y: 0, width: 100, height: 100 }; const result = Bounds.isValid(bounds); - expect(result).to.be.true; + expect(result).toBe(true); }); it('should return false if a dimension is not valid', () => { const bounds = { x: 0, y: 0, width: 100, height: -1 }; const result = Bounds.isValid(bounds); - expect(result).to.be.false; + expect(result).toBe(false); }); it('should return false if a coordinate is not valid', () => { const bounds = { x: 0, y: NaN, width: 100, height: 0 }; const result = Bounds.isValid(bounds); - expect(result).to.be.false; + expect(result).toBe(false); }); }); @@ -57,14 +57,14 @@ describe('Bounds', () => { const outer: Bounds = { x: 0, y: 0, width: 100, height: 100 }; const inner: Bounds = { x: 10, y: 10, width: 50, height: 50 }; const result = Bounds.encompasses(outer, inner); - expect(result).to.be.true; + expect(result).toBe(true); }); it('should return false if the outer bounds do not completely encompass the inner bounds', () => { const outer: Bounds = { x: 0, y: 0, width: 100, height: 100 }; const inner: Bounds = { x: 110, y: 110, width: 50, height: 50 }; const result = Bounds.encompasses(outer, inner); - expect(result).to.be.false; + expect(result).toBe(false); }); }); @@ -73,21 +73,21 @@ describe('Bounds', () => { const bounds1: Bounds = { x: 0, y: 0, width: 100, height: 100 }; const bounds2: Bounds = { x: 50, y: 50, width: 100, height: 100 }; const result = Bounds.overlap(bounds1, bounds2); - expect(result).to.be.true; + expect(result).toBe(true); }); it('should return false if the two bounds touch at the right edge of the left bounds', () => { const bounds1: Bounds = { x: 0, y: 0, width: 100, height: 100 }; const bounds2: Bounds = { x: 100, y: 0, width: 100, height: 100 }; const result = Bounds.overlap(bounds1, bounds2); - expect(result).to.be.false; + expect(result).toBe(false); }); it('should return true if the two bounds touch at the right edge of the left bounds and the touch flag is set', () => { const bounds1: Bounds = { x: 0, y: 0, width: 100, height: 100 }; const bounds2: Bounds = { x: 100, y: 0, width: 100, height: 100 }; const result = Bounds.overlap(bounds1, bounds2, true); - expect(result).to.be.true; + expect(result).toBe(true); }); }); @@ -96,14 +96,14 @@ describe('Bounds', () => { const bounds1: Bounds = { x: 0, y: 0, width: 100, height: 100 }; const bounds2: Bounds = { x: 0, y: 0, width: 100, height: 100 }; const result = Bounds.equals(bounds1, bounds2); - expect(result).to.be.true; + expect(result).toBe(true); }); it('should return false if the two bounds are not equal', () => { const bounds1: Bounds = { x: 0, y: 0, width: 100, height: 100 }; const bounds2: Bounds = { x: 50, y: 50, width: 100, height: 100 }; const result = Bounds.equals(bounds1, bounds2); - expect(result).to.be.false; + expect(result).toBe(false); }); }); @@ -111,7 +111,7 @@ describe('Bounds', () => { it('should return the x-coordinate of the left edge of the bounds', () => { const bounds: Bounds = { x: 10, y: 20, width: 100, height: 200 }; const result = Bounds.left(bounds); - expect(result).to.equal(10); + expect(result).toBe(10); }); }); @@ -119,7 +119,7 @@ describe('Bounds', () => { it('should return the x-coordinate of the center of the bounds', () => { const bounds: Bounds = { x: 10, y: 20, width: 100, height: 200 }; const result = Bounds.centerX(bounds); - expect(result).to.equal(60); + expect(result).toBe(60); }); }); @@ -127,7 +127,7 @@ describe('Bounds', () => { it('should return the x-coordinate of the right edge of the bounds', () => { const bounds: Bounds = { x: 10, y: 20, width: 100, height: 200 }; const result = Bounds.right(bounds); - expect(result).to.equal(110); + expect(result).toBe(110); }); }); @@ -135,7 +135,7 @@ describe('Bounds', () => { it('should return the y-coordinate of the top edge of the bounds', () => { const bounds: Bounds = { x: 10, y: 20, width: 100, height: 200 }; const result = Bounds.top(bounds); - expect(result).to.equal(20); + expect(result).toBe(20); }); }); @@ -143,7 +143,7 @@ describe('Bounds', () => { it('should return the y-coordinate of the middle of the bounds', () => { const bounds: Bounds = { x: 10, y: 20, width: 100, height: 200 }; const result = Bounds.middle(bounds); - expect(result).to.equal(120); + expect(result).toBe(120); }); }); @@ -151,7 +151,7 @@ describe('Bounds', () => { it('should return the y-coordinate of the center of the bounds', () => { const bounds: Bounds = { x: 10, y: 20, width: 100, height: 200 }; const result = Bounds.centerY(bounds); - expect(result).to.equal(120); + expect(result).toBe(120); }); }); @@ -159,7 +159,7 @@ describe('Bounds', () => { it('should return the y-coordinate of the bottom edge of the bounds', () => { const bounds: Bounds = { x: 10, y: 20, width: 100, height: 200 }; const result = Bounds.bottom(bounds); - expect(result).to.equal(220); + expect(result).toBe(220); }); }); @@ -167,7 +167,7 @@ describe('Bounds', () => { it('should return the top left corner of the bounds', () => { const bounds: Bounds = { x: 10, y: 20, width: 100, height: 200 }; const result = Bounds.topLeft(bounds); - expect(result).to.deep.equal({ x: 10, y: 20 }); + expect(result).toEqual({ x: 10, y: 20 }); }); }); @@ -175,7 +175,7 @@ describe('Bounds', () => { it('should return the top center point of the bounds', () => { const bounds: Bounds = { x: 10, y: 20, width: 100, height: 200 }; const result = Bounds.topCenter(bounds); - expect(result).to.deep.equal({ x: 60, y: 20 }); + expect(result).toEqual({ x: 60, y: 20 }); }); }); @@ -183,7 +183,7 @@ describe('Bounds', () => { it('should return the top right corner of the bounds', () => { const bounds: Bounds = { x: 10, y: 20, width: 100, height: 200 }; const result = Bounds.topRight(bounds); - expect(result).to.deep.equal({ x: 110, y: 20 }); + expect(result).toEqual({ x: 110, y: 20 }); }); }); @@ -191,7 +191,7 @@ describe('Bounds', () => { it('should return the middle left point of the bounds', () => { const bounds: Bounds = { x: 10, y: 20, width: 100, height: 200 }; const result = Bounds.middleLeft(bounds); - expect(result).to.deep.equal({ x: 10, y: 120 }); + expect(result).toEqual({ x: 10, y: 120 }); }); }); @@ -199,7 +199,7 @@ describe('Bounds', () => { it('should return the middle center point of the bounds', () => { const bounds: Bounds = { x: 10, y: 20, width: 100, height: 200 }; const result = Bounds.middleCenter(bounds); - expect(result).to.deep.equal({ x: 60, y: 120 }); + expect(result).toEqual({ x: 60, y: 120 }); }); }); @@ -207,7 +207,7 @@ describe('Bounds', () => { it('should return the middle right point of the bounds', () => { const bounds: Bounds = { x: 10, y: 20, width: 100, height: 200 }; const result = Bounds.middleRight(bounds); - expect(result).to.deep.equal({ x: 110, y: 120 }); + expect(result).toEqual({ x: 110, y: 120 }); }); }); @@ -215,7 +215,7 @@ describe('Bounds', () => { it('should return the bottom left corner of the bounds', () => { const bounds: Bounds = { x: 10, y: 20, width: 100, height: 200 }; const result = Bounds.bottomLeft(bounds); - expect(result).to.deep.equal({ x: 10, y: 220 }); + expect(result).toEqual({ x: 10, y: 220 }); }); }); @@ -223,7 +223,7 @@ describe('Bounds', () => { it('should return the bottom center point of the bounds', () => { const bounds: Bounds = { x: 10, y: 20, width: 100, height: 200 }; const result = Bounds.bottomCenter(bounds); - expect(result).to.deep.equal({ x: 60, y: 220 }); + expect(result).toEqual({ x: 60, y: 220 }); }); }); @@ -231,7 +231,7 @@ describe('Bounds', () => { it('should return the bottom right corner of the bounds', () => { const bounds: Bounds = { x: 10, y: 20, width: 100, height: 200 }; const result = Bounds.bottomRight(bounds); - expect(result).to.deep.equal({ x: 110, y: 220 }); + expect(result).toEqual({ x: 110, y: 220 }); }); }); @@ -240,14 +240,14 @@ describe('Bounds', () => { const leftBounds: Bounds = { x: 0, y: 0, width: 100, height: 100 }; const rightBounds: Bounds = { x: 0, y: 200, width: 100, height: 100 }; const result = Bounds.isAbove(leftBounds, rightBounds); - expect(result).to.be.true; + expect(result).toBe(true); }); it('should return false if the left bounds are not above the right bounds', () => { const leftBounds: Bounds = { x: 0, y: 200, width: 100, height: 100 }; const rightBounds: Bounds = { x: 0, y: 0, width: 100, height: 100 }; const result = Bounds.isAbove(leftBounds, rightBounds); - expect(result).to.be.false; + expect(result).toBe(false); }); }); @@ -256,14 +256,14 @@ describe('Bounds', () => { const leftBounds: Bounds = { x: 0, y: 200, width: 100, height: 100 }; const rightBounds: Bounds = { x: 0, y: 0, width: 100, height: 100 }; const result = Bounds.isBelow(leftBounds, rightBounds); - expect(result).to.be.true; + expect(result).toBe(true); }); it('should return false if the left bounds are not below the right bounds', () => { const leftBounds: Bounds = { x: 0, y: 0, width: 100, height: 100 }; const rightBounds: Bounds = { x: 0, y: 200, width: 100, height: 100 }; const result = Bounds.isBelow(leftBounds, rightBounds); - expect(result).to.be.false; + expect(result).toBe(false); }); }); @@ -272,14 +272,14 @@ describe('Bounds', () => { const leftBounds: Bounds = { x: 0, y: 0, width: 100, height: 100 }; const rightBounds: Bounds = { x: 200, y: 0, width: 100, height: 100 }; const result = Bounds.isBefore(leftBounds, rightBounds); - expect(result).to.be.true; + expect(result).toBe(true); }); it('should return false if the left bounds are not before the right bounds', () => { const leftBounds: Bounds = { x: 200, y: 0, width: 100, height: 100 }; const rightBounds: Bounds = { x: 0, y: 0, width: 100, height: 100 }; const result = Bounds.isBefore(leftBounds, rightBounds); - expect(result).to.be.false; + expect(result).toBe(false); }); }); @@ -288,14 +288,14 @@ describe('Bounds', () => { const leftBounds: Bounds = { x: 200, y: 0, width: 100, height: 100 }; const rightBounds: Bounds = { x: 0, y: 0, width: 100, height: 100 }; const result = Bounds.isAfter(leftBounds, rightBounds); - expect(result).to.be.true; + expect(result).toBe(true); }); it('should return false if the left bounds are not after the right bounds', () => { const leftBounds: Bounds = { x: 0, y: 0, width: 100, height: 100 }; const rightBounds: Bounds = { x: 200, y: 0, width: 100, height: 100 }; const result = Bounds.isAfter(leftBounds, rightBounds); - expect(result).to.be.false; + expect(result).toBe(false); }); }); @@ -304,7 +304,7 @@ describe('Bounds', () => { const topLeft: Point = { x: 10, y: 20 }; const bottomRight: Point = { x: 110, y: 220 }; const result = Bounds.from(topLeft, bottomRight); - expect(result).to.deep.equal({ x: 10, y: 20, width: 100, height: 200 }); + expect(result).toEqual({ x: 10, y: 20, width: 100, height: 200 }); }); }); @@ -312,7 +312,7 @@ describe('Bounds', () => { it('should return the position of the bounds', () => { const bounds: Bounds = { x: 10, y: 20, width: 30, height: 40 }; const result = Bounds.position(bounds); - expect(result).to.deep.equal({ x: 10, y: 20 }); + expect(result).toEqual({ x: 10, y: 20 }); }); }); @@ -320,7 +320,7 @@ describe('Bounds', () => { it('should create a new dimension from the given bounds', () => { const bounds = { x: 10, y: 20, width: 30, height: 40 }; const dimension = Bounds.dimension(bounds); - expect(dimension).to.deep.equal({ width: 30, height: 40 }); + expect(dimension).toEqual({ width: 30, height: 40 }); }); }); @@ -331,7 +331,7 @@ describe('Bounds', () => { const bounds3: Bounds = { x: 200, y: 200, width: 100, height: 100 }; const rankFunc = (bounds: Bounds): number => bounds.x; const sortedBounds = Bounds.sortBy(rankFunc, bounds1, bounds2, bounds3); - expect(sortedBounds).to.deep.equal([bounds1, bounds2, bounds3]); + expect(sortedBounds).toEqual([bounds1, bounds2, bounds3]); }); }); @@ -340,14 +340,14 @@ describe('Bounds', () => { const bounds: Bounds = { x: 10, y: 20, width: 100, height: 200 }; const delta: Point = { x: 10, y: 20 }; const result = Bounds.move(bounds, delta); - expect(result).to.deep.equal({ x: 20, y: 40, width: 100, height: 200 }); + expect(result).toEqual({ x: 20, y: 40, width: 100, height: 200 }); }); it('should move the bounds by the given delta with negative values', () => { const bounds: Bounds = { x: 10, y: 20, width: 100, height: 200 }; const delta: Point = { x: -10, y: -20 }; const result = Bounds.move(bounds, delta); - expect(result).to.deep.equal({ x: 0, y: 0, width: 100, height: 200 }); + expect(result).toEqual({ x: 0, y: 0, width: 100, height: 200 }); }); }); @@ -356,14 +356,14 @@ describe('Bounds', () => { const bounds: Bounds = { x: 10, y: 20, width: 100, height: 200 }; const delta: Dimension = { width: 10, height: 20 }; const result = Bounds.resize(bounds, delta); - expect(result).to.deep.equal({ x: 10, y: 20, width: 110, height: 220 }); + expect(result).toEqual({ x: 10, y: 20, width: 110, height: 220 }); }); it('should resize the bounds by the given delta with negative values', () => { const bounds: Bounds = { x: 10, y: 20, width: 100, height: 200 }; const delta: Dimension = { width: -10, height: -20 }; const result = Bounds.resize(bounds, delta); - expect(result).to.deep.equal({ x: 10, y: 20, width: 90, height: 180 }); + expect(result).toEqual({ x: 10, y: 20, width: 90, height: 180 }); }); }); }); diff --git a/packages/protocol/src/sprotty-geometry-dimension.spec.ts b/packages/protocol/src/sprotty-geometry-dimension.spec.ts index 02fde1b7..fe305e5c 100644 --- a/packages/protocol/src/sprotty-geometry-dimension.spec.ts +++ b/packages/protocol/src/sprotty-geometry-dimension.spec.ts @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2024 EclipseSource and others. + * Copyright (c) 2024-2026 EclipseSource and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -13,25 +13,25 @@ * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { Dimension } from './sprotty-geometry-dimension'; describe('Dimension', () => { describe('ZERO', () => { it('should have width and height set to 0', () => { - expect(Dimension.ZERO).to.deep.equal({ width: 0, height: 0 }); + expect(Dimension.ZERO).toEqual({ width: 0, height: 0 }); }); }); describe('is', () => { it('should return true if the given object is a dimension', () => { const dimension: Dimension = { width: 10, height: 20 }; - expect(Dimension.is(dimension)).to.be.true; + expect(Dimension.is(dimension)).toBe(true); }); it('should return false if the given object is not a dimension', () => { const dimension = { height: 20 }; - expect(Dimension.is(dimension)).to.be.false; + expect(Dimension.is(dimension)).toBe(false); }); }); @@ -39,7 +39,7 @@ describe('Dimension', () => { it('should apply the given function to width and height', () => { const dimension: Dimension = { width: 10, height: 20 }; const mappedDimension = Dimension.map(dimension, value => value * 2); - expect(mappedDimension).to.deep.equal({ width: 20, height: 40 }); + expect(mappedDimension).toEqual({ width: 20, height: 40 }); }); }); @@ -47,7 +47,7 @@ describe('Dimension', () => { it('should return the center point of the dimension', () => { const dimension: Dimension = { width: 100, height: 200 }; const centerPoint = Dimension.center(dimension); - expect(centerPoint).to.deep.equal({ x: 50, y: 100 }); + expect(centerPoint).toEqual({ x: 50, y: 100 }); }); }); @@ -56,7 +56,7 @@ describe('Dimension', () => { const dimension1: Dimension = { width: 10, height: 20 }; const dimension2: Dimension = { width: 5, height: 10 }; const sum = Dimension.add(dimension1, dimension2); - expect(sum).to.deep.equal({ width: 15, height: 30 }); + expect(sum).toEqual({ width: 15, height: 30 }); }); }); @@ -65,7 +65,7 @@ describe('Dimension', () => { const dimension1: Dimension = { width: 10, height: 20 }; const dimension2: Dimension = { width: 5, height: 10 }; const difference = Dimension.subtract(dimension1, dimension2); - expect(difference).to.deep.equal({ width: 5, height: 10 }); + expect(difference).toEqual({ width: 5, height: 10 }); }); }); @@ -74,7 +74,7 @@ describe('Dimension', () => { const dimension: Dimension = { width: 10, height: 20 }; const measure = 2; const product = Dimension.multiplyMeasure(dimension, measure); - expect(product).to.deep.equal({ width: 20, height: 40 }); + expect(product).toEqual({ width: 20, height: 40 }); }); }); @@ -83,7 +83,7 @@ describe('Dimension', () => { const dimension: Dimension = { width: 10, height: 20 }; const measure = 2; const quotient = Dimension.divideMeasure(dimension, measure); - expect(quotient).to.deep.equal({ width: 5, height: 10 }); + expect(quotient).toEqual({ width: 5, height: 10 }); }); }); @@ -92,35 +92,35 @@ describe('Dimension', () => { const dimension1: Dimension = { width: 10, height: 20 }; const dimension2: Dimension = { width: 10, height: 20 }; const isEqual = Dimension.equals(dimension1, dimension2); - expect(isEqual).to.be.true; + expect(isEqual).toBe(true); }); it('should return false if two dimensions are not equal', () => { const dimension1: Dimension = { width: 10, height: 20 }; const dimension2: Dimension = { width: 5, height: 10 }; const isEqual = Dimension.equals(dimension1, dimension2); - expect(isEqual).to.be.false; + expect(isEqual).toBe(false); }); it('should return false if the dimensions have different width', () => { const dimension1: Dimension = { width: 10, height: 20 }; const dimension2: Dimension = { width: 5, height: 20 }; const isEqual = Dimension.equals(dimension1, dimension2); - expect(isEqual).to.be.false; + expect(isEqual).toBe(false); }); it('should return false if the dimensions have different height', () => { const dimension1: Dimension = { width: 10, height: 20 }; const dimension2: Dimension = { width: 10, height: 10 }; const isEqual = Dimension.equals(dimension1, dimension2); - expect(isEqual).to.be.false; + expect(isEqual).toBe(false); }); it('should consider epsilon', () => { const dimension1: Dimension = { width: 10, height: 20 }; const dimension2: Dimension = { width: 10.0001, height: 20.0001 }; const isEqual = Dimension.equals(dimension1, dimension2, 0.001); - expect(isEqual).to.be.true; + expect(isEqual).toBe(true); }); }); @@ -128,7 +128,7 @@ describe('Dimension', () => { it('should create a new dimension from the given point', () => { const point = { x: 10, y: 20 }; const dimension = Dimension.fromPoint(point); - expect(dimension).to.deep.equal({ width: 10, height: 20 }); + expect(dimension).toEqual({ width: 10, height: 20 }); }); }); @@ -136,7 +136,7 @@ describe('Dimension', () => { it('should compute the area of the dimension', () => { const dimension: Dimension = { width: 10, height: 20 }; const area = Dimension.area(dimension); - expect(area).to.equal(200); + expect(area).toBe(200); }); }); }); diff --git a/packages/protocol/src/sprotty-geometry-point.spec.ts b/packages/protocol/src/sprotty-geometry-point.spec.ts index aacccd79..5b2cd4fa 100644 --- a/packages/protocol/src/sprotty-geometry-point.spec.ts +++ b/packages/protocol/src/sprotty-geometry-point.spec.ts @@ -14,75 +14,75 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { Direction } from '../lib'; import { Point } from './sprotty-geometry-point'; describe('Point', () => { describe('is', () => { it('returns true for a valid point', () => { - expect(Point.is({ x: 1, y: 2 })).to.be.true; + expect(Point.is({ x: 1, y: 2 })).toBe(true); }); it('returns false for an invalid point', () => { - expect(Point.is({ x: 1 })).to.be.false; + expect(Point.is({ x: 1 })).toBe(false); }); }); describe('isOrigin', () => { it('returns true for the origin', () => { - expect(Point.isOrigin({ x: 0, y: 0 })).to.be.true; + expect(Point.isOrigin({ x: 0, y: 0 })).toBe(true); }); it('returns false for a non-origin point', () => { - expect(Point.isOrigin({ x: 1, y: 2 })).to.be.false; + expect(Point.isOrigin({ x: 1, y: 2 })).toBe(false); }); }); describe('isValid', () => { it('returns true for a valid point', () => { - expect(Point.isValid({ x: 1, y: 2 })).to.be.true; + expect(Point.isValid({ x: 1, y: 2 })).toBe(true); }); it('returns false for an invalid point', () => { - expect(Point.isValid({ x: 1, y: NaN })).to.be.false; + expect(Point.isValid({ x: 1, y: NaN })).toBe(false); }); }); describe('abs', () => { it('returns the absolute point', () => { - expect(Point.abs({ x: -1, y: -2 })).to.deep.equal({ x: 1, y: 2 }); + expect(Point.abs({ x: -1, y: -2 })).toEqual({ x: 1, y: 2 }); }); }); describe('divideScalar', () => { it('divides both coordinates by the scalar', () => { - expect(Point.divideScalar({ x: 4, y: 6 }, 2)).to.deep.equal({ x: 2, y: 3 }); + expect(Point.divideScalar({ x: 4, y: 6 }, 2)).toEqual({ x: 2, y: 3 }); }); }); describe('multiplyScalar', () => { it('multiplies both coordinates by the scalar', () => { - expect(Point.multiplyScalar({ x: 4, y: 6 }, 2)).to.deep.equal({ x: 8, y: 12 }); + expect(Point.multiplyScalar({ x: 4, y: 6 }, 2)).toEqual({ x: 8, y: 12 }); }); }); describe('map', () => { it('applies the function to the coordinates', () => { - expect(Point.map({ x: 1, y: 2 }, c => c * 2)).to.deep.equal({ x: 2, y: 4 }); + expect(Point.map({ x: 1, y: 2 }, c => c * 2)).toEqual({ x: 2, y: 4 }); }); }); describe('snapToGrid', () => { it('snaps the point to the grid', () => { - expect(Point.snapToGrid({ x: 3, y: 4 }, { x: 2, y: 2 })).to.deep.equal({ x: 4, y: 4 }); + expect(Point.snapToGrid({ x: 3, y: 4 }, { x: 2, y: 2 })).toEqual({ x: 4, y: 4 }); }); it('snaps the point to the grid with a given origin', () => { - expect(Point.snapToGrid({ x: 3, y: 4 }, { x: 2, y: 2 }, { x: 1, y: 1 })).to.deep.equal({ x: 3, y: 5 }); + expect(Point.snapToGrid({ x: 3, y: 4 }, { x: 2, y: 2 }, { x: 1, y: 1 })).toEqual({ x: 3, y: 5 }); }); }); describe('vector', () => { it('returns the vector from the origin to the point', () => { - expect(Point.vector({ x: 3, y: 4 }, { x: 5, y: 8 })).to.deep.equal({ x: 2, y: 4 }); + expect(Point.vector({ x: 3, y: 4 }, { x: 5, y: 8 })).toEqual({ x: 2, y: 4 }); }); }); @@ -96,7 +96,7 @@ describe('Point', () => { vector: { x: 3, y: 4 }, direction: [Direction.Right, Direction.Down] }; - expect(Point.move(from, to)).to.deep.equal(expectedMovement); + expect(Point.move(from, to)).toEqual(expectedMovement); }); }); @@ -110,68 +110,68 @@ describe('Point', () => { vector: { x: 3, y: 4 }, direction: [Direction.Right, Direction.Down] }; - expect(Point.moveTowards(from, vector)).to.deep.equal(expectedMovement); + expect(Point.moveTowards(from, vector)).toEqual(expectedMovement); }); }); describe('equals', () => { it('returns true for equal points', () => { - expect(Point.equals({ x: 1, y: 2 }, { x: 1, y: 2 })).to.be.true; + expect(Point.equals({ x: 1, y: 2 }, { x: 1, y: 2 })).toBe(true); }); it('returns false for different points', () => { - expect(Point.equals({ x: 1, y: 2 }, { x: 1, y: 3 })).to.be.false; + expect(Point.equals({ x: 1, y: 2 }, { x: 1, y: 3 })).toBe(false); }); it('returns true up to an epsilon', () => { - expect(Point.equals({ x: 1, y: 2 }, { x: 1.0001, y: 2.0001 }, 0.001)).to.be.true; + expect(Point.equals({ x: 1, y: 2 }, { x: 1.0001, y: 2.0001 }, 0.001)).toBe(true); }); }); describe('isVerticalAligned', () => { it('returns true when both points share the same x coordinate', () => { - expect(Point.isVerticalAligned({ x: 10, y: 0 }, { x: 10, y: 100 })).to.be.true; + expect(Point.isVerticalAligned({ x: 10, y: 0 }, { x: 10, y: 100 })).toBe(true); }); it('returns true within the default tolerance', () => { - expect(Point.isVerticalAligned({ x: 10, y: 0 }, { x: 10.0001, y: 100 })).to.be.true; + expect(Point.isVerticalAligned({ x: 10, y: 0 }, { x: 10.0001, y: 100 })).toBe(true); }); it('returns false when the x coordinates differ beyond the default tolerance', () => { - expect(Point.isVerticalAligned({ x: 10, y: 0 }, { x: 10.5, y: 100 })).to.be.false; + expect(Point.isVerticalAligned({ x: 10, y: 0 }, { x: 10.5, y: 100 })).toBe(false); }); it('honors an explicit epsilon', () => { - expect(Point.isVerticalAligned({ x: 10, y: 0 }, { x: 14, y: 100 }, 5)).to.be.true; - expect(Point.isVerticalAligned({ x: 10, y: 0 }, { x: 14, y: 100 }, 3)).to.be.false; + expect(Point.isVerticalAligned({ x: 10, y: 0 }, { x: 14, y: 100 }, 5)).toBe(true); + expect(Point.isVerticalAligned({ x: 10, y: 0 }, { x: 14, y: 100 }, 3)).toBe(false); }); }); describe('isHorizontalAligned', () => { it('returns true when both points share the same y coordinate', () => { - expect(Point.isHorizontalAligned({ x: 0, y: 50 }, { x: 200, y: 50 })).to.be.true; + expect(Point.isHorizontalAligned({ x: 0, y: 50 }, { x: 200, y: 50 })).toBe(true); }); it('returns true within the default tolerance', () => { - expect(Point.isHorizontalAligned({ x: 0, y: 50 }, { x: 200, y: 50.0001 })).to.be.true; + expect(Point.isHorizontalAligned({ x: 0, y: 50 }, { x: 200, y: 50.0001 })).toBe(true); }); it('returns false when the y coordinates differ beyond the default tolerance', () => { - expect(Point.isHorizontalAligned({ x: 0, y: 50 }, { x: 200, y: 50.5 })).to.be.false; + expect(Point.isHorizontalAligned({ x: 0, y: 50 }, { x: 200, y: 50.5 })).toBe(false); }); it('honors an explicit epsilon', () => { - expect(Point.isHorizontalAligned({ x: 0, y: 50 }, { x: 200, y: 53 }, 5)).to.be.true; + expect(Point.isHorizontalAligned({ x: 0, y: 50 }, { x: 200, y: 53 }, 5)).toBe(true); }); }); describe('isAxisAligned', () => { it('returns true for vertically aligned points', () => { - expect(Point.isAxisAligned({ x: 10, y: 0 }, { x: 10, y: 100 })).to.be.true; + expect(Point.isAxisAligned({ x: 10, y: 0 }, { x: 10, y: 100 })).toBe(true); }); it('returns true for horizontally aligned points', () => { - expect(Point.isAxisAligned({ x: 0, y: 50 }, { x: 200, y: 50 })).to.be.true; + expect(Point.isAxisAligned({ x: 0, y: 50 }, { x: 200, y: 50 })).toBe(true); }); it('returns false for points that are neither vertically nor horizontally aligned', () => { - expect(Point.isAxisAligned({ x: 0, y: 0 }, { x: 50, y: 50 })).to.be.false; + expect(Point.isAxisAligned({ x: 0, y: 0 }, { x: 50, y: 50 })).toBe(false); }); it('honors an explicit epsilon', () => { - expect(Point.isAxisAligned({ x: 10, y: 0 }, { x: 14, y: 100 }, 5)).to.be.true; - expect(Point.isAxisAligned({ x: 10, y: 0 }, { x: 14, y: 100 }, 3)).to.be.false; + expect(Point.isAxisAligned({ x: 10, y: 0 }, { x: 14, y: 100 }, 5)).toBe(true); + expect(Point.isAxisAligned({ x: 10, y: 0 }, { x: 14, y: 100 }, 3)).toBe(false); }); }); }); diff --git a/packages/protocol/src/utils/array-util.spec.ts b/packages/protocol/src/utils/array-util.spec.ts index df0d3cbe..83141bfb 100644 --- a/packages/protocol/src/utils/array-util.spec.ts +++ b/packages/protocol/src/utils/array-util.spec.ts @@ -14,7 +14,7 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { TypeGuard } from './type-util'; import { arrayOf, @@ -37,17 +37,17 @@ describe('ArrayUtil', () => { it('should remove a present value and leave others intact', () => { const arr = [1, 2, 3, 4]; remove(arr, 2, 4); - expect(arr).to.deep.equal([1, 3]); + expect(arr).toEqual([1, 3]); }); it('should only remove the first occurrence', () => { const arr = [1, 2, 2, 3]; remove(arr, 2); - expect(arr).to.deep.equal([1, 2, 3]); + expect(arr).toEqual([1, 2, 3]); }); it('should do nothing for absent values', () => { const arr = [1, 2]; remove(arr, 99); - expect(arr).to.deep.equal([1, 2]); + expect(arr).toEqual([1, 2]); }); }); @@ -55,7 +55,7 @@ describe('ArrayUtil', () => { it('should push single values and nested arrays', () => { const arr: number[] = [1]; flatPush(arr, [2, [3, 4], 5]); - expect(arr).to.deep.equal([1, 2, 3, 4, 5]); + expect(arr).toEqual([1, 2, 3, 4, 5]); }); }); @@ -63,25 +63,25 @@ describe('ArrayUtil', () => { it('should add only values not already present', () => { const arr = [1, 2]; distinctAdd(arr, 2, 3, 4, 1); - expect(arr).to.deep.equal([1, 2, 3, 4]); + expect(arr).toEqual([1, 2, 3, 4]); }); }); describe('first', () => { it('should return the first element without n', () => { - expect(first([10, 20, 30])).to.equal(10); + expect(first([10, 20, 30])).toBe(10); }); it('should return first n elements', () => { - expect(first([10, 20, 30], 2)).to.deep.equal([10, 20]); + expect(first([10, 20, 30], 2)).toEqual([10, 20]); }); }); describe('last', () => { it('should return the last element without n', () => { - expect(last([10, 20, 30])).to.equal(30); + expect(last([10, 20, 30])).toBe(30); }); it('should return last n elements', () => { - expect(last([10, 20, 30], 2)).to.deep.equal([20, 30]); + expect(last([10, 20, 30], 2)).toEqual([20, 30]); }); }); @@ -91,17 +91,17 @@ describe('ArrayUtil', () => { { id: 1, name: 'a' }, { id: 2, name: 'b' } ]; - expect(pluck(items, 'name')).to.deep.equal(['a', 'b']); + expect(pluck(items, 'name')).toEqual(['a', 'b']); }); }); describe('asArray', () => { it('should wrap a single value in an array', () => { - expect(asArray(5)).to.deep.equal([5]); + expect(asArray(5)).toEqual([5]); }); it('should return the array as-is', () => { const arr = [1, 2]; - expect(asArray(arr)).to.equal(arr); + expect(asArray(arr)).toBe(arr); }); }); @@ -109,34 +109,34 @@ describe('ArrayUtil', () => { const isNumber: TypeGuard = (v: unknown): v is number => typeof v === 'number'; it('should return true for a matching array', () => { - expect(isArrayOfType([1, 2, 3], isNumber)).to.be.true; + expect(isArrayOfType([1, 2, 3], isNumber)).toBe(true); }); it('should return false for an empty array by default', () => { - expect(isArrayOfType([], isNumber)).to.be.false; + expect(isArrayOfType([], isNumber)).toBe(false); }); it('should return true for an empty array with supportEmpty', () => { - expect(isArrayOfType([], isNumber, true)).to.be.true; + expect(isArrayOfType([], isNumber, true)).toBe(true); }); it('should return false for a mixed array', () => { - expect(isArrayOfType([1, 'two'], isNumber)).to.be.false; + expect(isArrayOfType([1, 'two'], isNumber)).toBe(false); }); }); describe('isArrayOfClass', () => { it('should return true when all elements are instances of the class', () => { - expect(isArrayOfClass([new Date(), new Date()], Date)).to.be.true; + expect(isArrayOfClass([new Date(), new Date()], Date)).toBe(true); }); it('should return false for non-instances', () => { - expect(isArrayOfClass([{}, new Date()], Date)).to.be.false; + expect(isArrayOfClass([{}, new Date()], Date)).toBe(false); }); }); describe('isStringArray', () => { it('should return true for a string array', () => { - expect(isStringArray(['a', 'b'])).to.be.true; + expect(isStringArray(['a', 'b'])).toBe(true); }); it('should return false for a mixed array', () => { - expect(isStringArray(['a', 1])).to.be.false; + expect(isStringArray(['a', 1])).toBe(false); }); }); @@ -145,27 +145,27 @@ describe('ArrayUtil', () => { it('should split elements by predicate', () => { const result = partition(['a', 1, 'b', 2] as (string | number)[], isString as TypeGuard); - expect(result.match).to.deep.equal(['a', 'b']); - expect(result.rest).to.deep.equal([1, 2]); + expect(result.match).toEqual(['a', 'b']); + expect(result.rest).toEqual([1, 2]); }); it('should handle all-match case', () => { const result = partition(['a', 'b'], isString as TypeGuard); - expect(result.match).to.deep.equal(['a', 'b']); - expect(result.rest).to.deep.equal([]); + expect(result.match).toEqual(['a', 'b']); + expect(result.rest).toEqual([]); }); it('should handle empty array', () => { const result = partition([], isString as TypeGuard); - expect(result.match).to.deep.equal([]); - expect(result.rest).to.deep.equal([]); + expect(result.match).toEqual([]); + expect(result.rest).toEqual([]); }); }); describe('arrayOf', () => { it('should filter out undefined values', () => { - expect(arrayOf(1, undefined, 2, undefined, 3)).to.deep.equal([1, 2, 3]); + expect(arrayOf(1, undefined, 2, undefined, 3)).toEqual([1, 2, 3]); }); it('should return empty array when all undefined', () => { - expect(arrayOf(undefined, undefined)).to.deep.equal([]); + expect(arrayOf(undefined, undefined)).toEqual([]); }); }); @@ -177,17 +177,17 @@ describe('ArrayUtil', () => { { type: 'fruit', name: 'banana' } ]; const result = groupBy(items, i => i.type); - expect(result.size).to.equal(2); - expect(result.get('fruit')!.map(i => i.name)).to.deep.equal(['apple', 'banana']); - expect(result.get('veggie')!.map(i => i.name)).to.deep.equal(['carrot']); + expect(result.size).toBe(2); + expect(result.get('fruit')!.map(i => i.name)).toEqual(['apple', 'banana']); + expect(result.get('veggie')!.map(i => i.name)).toEqual(['carrot']); }); it('should return an empty map for an empty array', () => { - expect(groupBy([], () => 'k').size).to.equal(0); + expect(groupBy([], () => 'k').size).toBe(0); }); it('should support numeric keys', () => { const result = groupBy([1, 2, 3, 4, 5], n => n % 2); - expect(result.get(0)).to.deep.equal([2, 4]); - expect(result.get(1)).to.deep.equal([1, 3, 5]); + expect(result.get(0)).toEqual([2, 4]); + expect(result.get(1)).toEqual([1, 3, 5]); }); it('should sort groups by key when sorted is true', () => { const items = [ @@ -198,8 +198,8 @@ describe('ArrayUtil', () => { ]; const result = groupBy(items, i => i.rank, true); const keys = [...result.keys()]; - expect(keys).to.deep.equal([1, 2, 3]); - expect(result.get(1)!.map(i => i.name)).to.deep.equal(['a', 'a2']); + expect(keys).toEqual([1, 2, 3]); + expect(result.get(1)!.map(i => i.name)).toEqual(['a', 'a2']); }); }); }); diff --git a/packages/protocol/src/utils/disposable.spec.ts b/packages/protocol/src/utils/disposable.spec.ts index 7de19b41..58fdf020 100644 --- a/packages/protocol/src/utils/disposable.spec.ts +++ b/packages/protocol/src/utils/disposable.spec.ts @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2023 EclipseSource and others. + * Copyright (c) 2023-2026 EclipseSource and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -14,31 +14,30 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; -import * as sinon from 'sinon'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; import { Disposable, DisposableCollection } from './disposable'; describe('Disposable', () => { describe('is', () => { it('should return false for a primitive', () => { - expect(Disposable.is('A')).to.be.false; + expect(Disposable.is('A')).toBe(false); }); it('should return false for unknown function', () => { - expect(Disposable.is('A'.toString)).to.be.false; + expect(Disposable.is('A'.toString)).toBe(false); }); it('should return true for the return value of Disposable.create()', () => { - expect(Disposable.is(Disposable.create(() => 'A'.toString()))).to.be.true; + expect(Disposable.is(Disposable.create(() => 'A'.toString()))).toBe(true); }); it('should return true for the return value of Disposable.empty()', () => { - expect(Disposable.is(Disposable.empty())).to.be.true; + expect(Disposable.is(Disposable.empty())).toBe(true); }); it('should return false for an object with conflicting `dispose` property', () => { const obj = { dispose: '' }; - expect(Disposable.is(obj)).to.be.false; + expect(Disposable.is(obj)).toBe(false); }); it('disposable object', () => { const obj: Disposable = { dispose: () => 'ok' }; - expect(Disposable.is(obj)).to.be.true; + expect(Disposable.is(obj)).toBe(true); }); }); describe('DisposableCollection', () => { @@ -48,10 +47,10 @@ describe('Disposable', () => { it('should add one disposable to the collection and remove it again', () => { const disposable = Disposable.empty(); const toRemove = disposableCollection.push(disposable); - expect(disposableCollection['disposables'].length).to.be.equal(1); - expect(disposableCollection['disposables'][0]).to.equal(disposable); + expect(disposableCollection['disposables'].length).toBe(1); + expect(disposableCollection['disposables'][0]).toBe(disposable); toRemove.dispose(); - expect(disposableCollection['disposables'].length).to.be.equal(0); + expect(disposableCollection['disposables'].length).toBe(0); }); it('should add multiple disposable to the collection and remove them again', () => { const disposable1 = Disposable.empty(); @@ -59,27 +58,27 @@ describe('Disposable', () => { const disposable3 = Disposable.empty(); const toRemove = disposableCollection.push(disposable1, disposable2, disposable3); - expect(disposableCollection['disposables'].length).to.be.equal(3); - expect(disposableCollection['disposables'][0]).to.equal(disposable1); - expect(disposableCollection['disposables'][1]).to.equal(disposable2); - expect(disposableCollection['disposables'][2]).to.equal(disposable3); + expect(disposableCollection['disposables'].length).toBe(3); + expect(disposableCollection['disposables'][0]).toBe(disposable1); + expect(disposableCollection['disposables'][1]).toBe(disposable2); + expect(disposableCollection['disposables'][2]).toBe(disposable3); toRemove.dispose(); - expect(disposableCollection['disposables'].length).to.be.equal(0); + expect(disposableCollection['disposables'].length).toBe(0); }); it('should add one disposable function to the collection and remove it again', () => { const disposable = (): void => {}; const toRemove = disposableCollection.push(disposable); - expect(disposableCollection['disposables'].length).to.be.equal(1); + expect(disposableCollection['disposables'].length).toBe(1); toRemove.dispose(); - expect(disposableCollection['disposables'].length).to.be.equal(0); + expect(disposableCollection['disposables'].length).toBe(0); }); }); describe('dispose', () => { - describe('should invoke dispose on all elements of the collection exactly once', () => { + it('should invoke dispose on all elements of the collection exactly once', () => { const disposable1 = Disposable.empty(); const disposable2 = Disposable.empty(); - const disposable1Spy = sinon.spy(disposable1); - const disposable2Spy = sinon.spy(disposable2); + const disposable1Spy = vi.spyOn(disposable1, 'dispose'); + const disposable2Spy = vi.spyOn(disposable2, 'dispose'); disposableCollection = new DisposableCollection(disposable1, disposable2); @@ -87,9 +86,9 @@ describe('Disposable', () => { disposableCollection.dispose(); disposableCollection.dispose(); - expect(disposable1Spy.dispose.calledOnce).to.be.true; - expect(disposable2Spy.dispose.calledOnce).to.be.true; - expect(disposableCollection['disposables'].length).to.be.equal(0); + expect(disposable1Spy).toHaveBeenCalledOnce(); + expect(disposable2Spy).toHaveBeenCalledOnce(); + expect(disposableCollection['disposables'].length).toBe(0); }); }); }); diff --git a/packages/protocol/src/utils/event.spec.ts b/packages/protocol/src/utils/event.spec.ts index 6d114fd3..4d80e147 100644 --- a/packages/protocol/src/utils/event.spec.ts +++ b/packages/protocol/src/utils/event.spec.ts @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2024 EclipseSource and others. + * Copyright (c) 2024-2026 EclipseSource and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -14,8 +14,7 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; -import * as sinon from 'sinon'; +import { beforeEach, describe, expect, it, vi } from 'vitest'; import { Emitter, Event } from './event'; describe('Event', () => { @@ -27,26 +26,26 @@ describe('Event', () => { describe('once', () => { it('should invoke the listener when the event is fired', () => { - const listener = sinon.spy((e: string) => {}); + const listener = vi.fn((e: string) => {}); Event.once(emitter.event, listener); emitter.fire('test'); - expect(listener.calledOnce).to.be.true; - expect(listener.calledWith('test')).to.be.true; + expect(listener).toHaveBeenCalledOnce(); + expect(listener).toHaveBeenCalledWith('test'); }); it('should invoke the listener only once when the event is fired multiple times', () => { - const listener = sinon.spy((e: string) => {}); + const listener = vi.fn((e: string) => {}); Event.once(emitter.event, listener); emitter.fire('test'); emitter.fire('test1'); - expect(listener.calledOnce).to.be.true; - expect(listener.calledWith('test')).to.be.true; + expect(listener).toHaveBeenCalledOnce(); + expect(listener).toHaveBeenCalledWith('test'); }); it('should not invoke the listener when its disposed before the event fired', () => { - const listener = sinon.spy((e: string) => {}); + const listener = vi.fn((e: string) => {}); const disposable = Event.once(emitter.event, listener); disposable.dispose(); emitter.fire('test'); - expect(listener.called).to.be.false; + expect(listener).not.toHaveBeenCalled(); }); }); @@ -55,7 +54,7 @@ describe('Event', () => { const promise = Event.waitUntil(emitter.event); emitter.fire('test'); const result = await promise; - expect(result).to.equal('test'); + expect(result).toBe('test'); }); it('should resolve the promise only when the predicate matches', async () => { @@ -64,7 +63,7 @@ describe('Event', () => { emitter.fire('no-match'); emitter.fire('match'); const result = await promise; - expect(result).to.equal('match'); + expect(result).toBe('match'); }); }); }); diff --git a/packages/protocol/src/utils/function-util.spec.ts b/packages/protocol/src/utils/function-util.spec.ts index 3c7d15c1..5f1a332f 100644 --- a/packages/protocol/src/utils/function-util.spec.ts +++ b/packages/protocol/src/utils/function-util.spec.ts @@ -14,95 +14,92 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; -import * as sinon from 'sinon'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { debounce } from './function-util'; describe('FunctionUtil', () => { - let clock: sinon.SinonFakeTimers; - beforeEach(() => { - clock = sinon.useFakeTimers(); + vi.useFakeTimers(); }); afterEach(() => { - clock.restore(); + vi.useRealTimers(); }); describe('debounce', () => { it('should invoke the function after the wait period (trailing by default)', () => { - const spy = sinon.spy(); + const spy = vi.fn(); const debounced = debounce(spy, 100); debounced(); - expect(spy.called).to.be.false; - clock.tick(100); - expect(spy.calledOnce).to.be.true; + expect(spy).not.toHaveBeenCalled(); + vi.advanceTimersByTime(100); + expect(spy).toHaveBeenCalledOnce(); }); it('should reset the timer on rapid calls and only invoke once', () => { - const spy = sinon.spy(); + const spy = vi.fn(); const debounced = debounce(spy, 100); debounced(); - clock.tick(50); + vi.advanceTimersByTime(50); debounced(); - clock.tick(50); - expect(spy.called).to.be.false; - clock.tick(50); - expect(spy.calledOnce).to.be.true; + vi.advanceTimersByTime(50); + expect(spy).not.toHaveBeenCalled(); + vi.advanceTimersByTime(50); + expect(spy).toHaveBeenCalledOnce(); }); it('should pass the latest arguments', () => { - const spy = sinon.spy(); + const spy = vi.fn(); const debounced = debounce(spy, 100); debounced('a'); debounced('b'); - clock.tick(100); - expect(spy.calledOnce).to.be.true; - expect(spy.firstCall.args).to.deep.equal(['b']); + vi.advanceTimersByTime(100); + expect(spy).toHaveBeenCalledOnce(); + expect(spy.mock.calls[0]).toEqual(['b']); }); it('should invoke immediately with leading: true', () => { - const spy = sinon.spy(); + const spy = vi.fn(); const debounced = debounce(spy, 100, { leading: true }); debounced(); - expect(spy.calledOnce).to.be.true; + expect(spy).toHaveBeenCalledOnce(); }); it('should not invoke trailing call when leading: true, trailing: false', () => { - const spy = sinon.spy(); + const spy = vi.fn(); const debounced = debounce(spy, 100, { leading: true, trailing: false }); debounced(); debounced(); - expect(spy.calledOnce).to.be.true; - clock.tick(100); - expect(spy.calledOnce).to.be.true; + expect(spy).toHaveBeenCalledOnce(); + vi.advanceTimersByTime(100); + expect(spy).toHaveBeenCalledOnce(); }); it('should invoke both leading and trailing when both are true', () => { - const spy = sinon.spy(); + const spy = vi.fn(); const debounced = debounce(spy, 100, { leading: true, trailing: true }); debounced('first'); - expect(spy.calledOnce).to.be.true; + expect(spy).toHaveBeenCalledOnce(); debounced('second'); - clock.tick(100); - expect(spy.calledTwice).to.be.true; - expect(spy.secondCall.args).to.deep.equal(['second']); + vi.advanceTimersByTime(100); + expect(spy).toHaveBeenCalledTimes(2); + expect(spy.mock.calls[1]).toEqual(['second']); }); describe('cancel', () => { it('should prevent a pending trailing invocation', () => { - const spy = sinon.spy(); + const spy = vi.fn(); const debounced = debounce(spy, 100); debounced(); debounced.cancel(); - clock.tick(100); - expect(spy.called).to.be.false; + vi.advanceTimersByTime(100); + expect(spy).not.toHaveBeenCalled(); }); it('should be safe to call when nothing is pending', () => { - const spy = sinon.spy(); + const spy = vi.fn(); const debounced = debounce(spy, 100); - expect(() => debounced.cancel()).to.not.throw(); + expect(() => debounced.cancel()).not.toThrow(); }); }); }); diff --git a/packages/protocol/src/utils/geometry-movement.spec.ts b/packages/protocol/src/utils/geometry-movement.spec.ts index 641c8341..c14401a3 100644 --- a/packages/protocol/src/utils/geometry-movement.spec.ts +++ b/packages/protocol/src/utils/geometry-movement.spec.ts @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2024 EclipseSource and others. + * Copyright (c) 2024-2026 EclipseSource and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -13,7 +13,7 @@ * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { Movement } from './geometry-movement'; import { Direction } from './geometry-util'; @@ -27,12 +27,12 @@ describe('Movement', () => { direction: [Direction.Right, Direction.Up] }; const result = Movement.is(movement); - expect(result).to.be.true; + expect(result).toBe(true); }); it('should check if the given object is not a movement', () => { const obj = { x: 1, y: 2 }; const result = Movement.is(obj); - expect(result).to.be.false; + expect(result).toBe(false); }); }); @@ -45,7 +45,7 @@ describe('Movement', () => { direction: [] }; const result = Movement.isStationary(movement); - expect(result).to.be.true; + expect(result).toBe(true); }); it('should check if the movement is not stationary', () => { const movement: Movement = { @@ -55,7 +55,7 @@ describe('Movement', () => { direction: [Direction.Right, Direction.Up] }; const result = Movement.isStationary(movement); - expect(result).to.be.false; + expect(result).toBe(false); }); }); @@ -68,7 +68,7 @@ describe('Movement', () => { direction: [] }; const result = Movement.isZero(movement); - expect(result).to.be.true; + expect(result).toBe(true); }); it('should check if the movement is not zero', () => { const movement: Movement = { @@ -78,7 +78,7 @@ describe('Movement', () => { direction: [Direction.Right, Direction.Up] }; const result = Movement.isZero(movement); - expect(result).to.be.false; + expect(result).toBe(false); }); }); @@ -97,7 +97,7 @@ describe('Movement', () => { direction: [Direction.Right, Direction.Up] }; const result = Movement.equals(movement1, movement2); - expect(result).to.be.true; + expect(result).toBe(true); }); it('should check if two movements are not equal', () => { const movement1: Movement = { @@ -113,7 +113,7 @@ describe('Movement', () => { direction: [Direction.Right, Direction.Up] }; const result = Movement.equals(movement1, movement2); - expect(result).to.be.false; + expect(result).toBe(false); }); }); }); diff --git a/packages/protocol/src/utils/geometry-vector.spec.ts b/packages/protocol/src/utils/geometry-vector.spec.ts index ebb83b35..1cd0bc67 100644 --- a/packages/protocol/src/utils/geometry-vector.spec.ts +++ b/packages/protocol/src/utils/geometry-vector.spec.ts @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (c) 2024 EclipseSource and others. + * Copyright (c) 2024-2026 EclipseSource and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -13,7 +13,7 @@ * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { Direction } from './geometry-util'; import { Vector } from './geometry-vector'; @@ -22,7 +22,7 @@ describe('Vector', () => { it('should compute the absolute value of the vector', () => { const vector: Vector = { x: -5, y: -10 }; const result = Vector.abs(vector); - expect(result).to.deep.equal({ x: 5, y: 10 }); + expect(result).toEqual({ x: 5, y: 10 }); }); }); @@ -31,7 +31,7 @@ describe('Vector', () => { const vector1: Vector = { x: 1, y: 2 }; const vector2: Vector = { x: 3, y: 4 }; const result = Vector.add(vector1, vector2); - expect(result).to.deep.equal({ x: 4, y: 6 }); + expect(result).toEqual({ x: 4, y: 6 }); }); }); @@ -40,7 +40,7 @@ describe('Vector', () => { const vector1: Vector = { x: 1, y: 2 }; const vector2: Vector = { x: 1, y: 2 }; const result = Vector.equals(vector1, vector2); - expect(result).to.be.true; + expect(result).toBe(true); }); }); @@ -48,7 +48,7 @@ describe('Vector', () => { it('should check if a vector is valid', () => { const vector: Vector = { x: 1, y: 2 }; const result = Vector.isValid(vector); - expect(result).to.be.true; + expect(result).toBe(true); }); }); @@ -56,7 +56,7 @@ describe('Vector', () => { it('should compute the magnitude of a vector', () => { const vector: Vector = { x: 3, y: 4 }; const result = Vector.magnitude(vector); - expect(result).to.equal(5); + expect(result).toBe(5); }); }); @@ -64,7 +64,7 @@ describe('Vector', () => { it('should map each component of the vector', () => { const vector: Vector = { x: 1, y: 2 }; const result = Vector.map(vector, (value, key) => value * 2); - expect(result).to.deep.equal({ x: 2, y: 4 }); + expect(result).toEqual({ x: 2, y: 4 }); }); }); @@ -72,12 +72,12 @@ describe('Vector', () => { it('should compute the normalized vector', () => { const vector: Vector = { x: 3, y: 4 }; const result = Vector.normalize(vector); - expect(result).to.deep.equal({ x: 0.6, y: 0.8 }); + expect(result).toEqual({ x: 0.6, y: 0.8 }); }); it('should return the zero vector if the vector is the zero vector', () => { const vector: Vector = { x: 0, y: 0 }; const result = Vector.normalize(vector); - expect(result).to.deep.equal(Vector.ZERO); + expect(result).toEqual(Vector.ZERO); }); }); @@ -85,7 +85,7 @@ describe('Vector', () => { it('should check if a vector is the zero vector', () => { const vector: Vector = { x: 0, y: 0 }; const result = Vector.isZero(vector); - expect(result).to.be.true; + expect(result).toBe(true); }); }); @@ -93,12 +93,12 @@ describe('Vector', () => { it('should check if the given object is a vector', () => { const vector: Vector = { x: 1, y: 2 }; const result = Vector.is(vector); - expect(result).to.be.true; + expect(result).toBe(true); }); it('should check if the given object is not a vector', () => { const vector = { x: 1, z: 2 }; const result = Vector.is(vector); - expect(result).to.be.false; + expect(result).toBe(false); }); }); @@ -107,7 +107,7 @@ describe('Vector', () => { const vector: Vector = { x: 4, y: 6 }; const scalar = 2; const result = Vector.divide(vector, scalar); - expect(result).to.deep.equal({ x: 2, y: 3 }); + expect(result).toEqual({ x: 2, y: 3 }); }); }); @@ -116,7 +116,7 @@ describe('Vector', () => { const vector: Vector = { x: 2, y: 3 }; const scalar = 2; const result = Vector.multiply(vector, scalar); - expect(result).to.deep.equal({ x: 4, y: 6 }); + expect(result).toEqual({ x: 4, y: 6 }); }); }); @@ -125,7 +125,7 @@ describe('Vector', () => { const vector: Vector = { x: 4, y: 6 }; const subtrahend: Vector = { x: 2, y: 3 }; const result = Vector.subtract(vector, subtrahend); - expect(result).to.deep.equal({ x: 2, y: 3 }); + expect(result).toEqual({ x: 2, y: 3 }); }); }); @@ -133,7 +133,7 @@ describe('Vector', () => { it('should reverse the direction of a vector', () => { const vector: Vector = { x: 2, y: 3 }; const result = Vector.reverse(vector); - expect(result).to.deep.equal({ x: -2, y: -3 }); + expect(result).toEqual({ x: -2, y: -3 }); }); }); @@ -141,12 +141,12 @@ describe('Vector', () => { it('should return right-up for a vector with positive x and negative y', () => { const vector: Vector = { x: 2, y: -3 }; const result = Vector.direction(vector); - expect(result).to.deep.equal([Direction.Right, Direction.Up]); + expect(result).toEqual([Direction.Right, Direction.Up]); }); it('should return left-down for a vector with negative x and positive y', () => { const vector: Vector = { x: -2, y: 3 }; const result = Vector.direction(vector); - expect(result).to.deep.equal([Direction.Left, Direction.Down]); + expect(result).toEqual([Direction.Left, Direction.Down]); }); }); @@ -155,7 +155,7 @@ describe('Vector', () => { const vector1: Vector = { x: 1, y: 2 }; const vector2: Vector = { x: 3, y: 4 }; const result = Vector.min(vector1, vector2); - expect(result).to.deep.equal({ x: 1, y: 2 }); + expect(result).toEqual({ x: 1, y: 2 }); }); }); @@ -164,7 +164,7 @@ describe('Vector', () => { const vector1: Vector = { x: 1, y: 2 }; const vector2: Vector = { x: 3, y: 4 }; const result = Vector.max(vector1, vector2); - expect(result).to.deep.equal({ x: 3, y: 4 }); + expect(result).toEqual({ x: 3, y: 4 }); }); }); @@ -173,11 +173,11 @@ describe('Vector', () => { const vector1: Vector = { x: 1, y: 2 }; const vector2: Vector = { x: 3, y: 4 }; const result = Vector.avg(vector1, vector2); - expect(result).to.deep.equal({ x: 2, y: 3 }); + expect(result).toEqual({ x: 2, y: 3 }); }); it('should return the zero vector if no vectors are given', () => { const result = Vector.avg(); - expect(result).to.deep.equal(Vector.ZERO); + expect(result).toEqual(Vector.ZERO); }); }); }); diff --git a/packages/protocol/src/utils/test-util.ts b/packages/protocol/src/utils/test-util.ts deleted file mode 100644 index 178bf20f..00000000 --- a/packages/protocol/src/utils/test-util.ts +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2023 EclipseSource and others. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0. - * - * This Source Code may also be made available under the following Secondary - * Licenses when the conditions for such availability set forth in the Eclipse - * Public License v. 2.0 are satisfied: GNU General Public License, version 2 - * with the GNU Classpath Exception which is available at - * https://www.gnu.org/software/classpath/license.html. - * - * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 - ********************************************************************************/ - -import { expect } from 'chai'; -import { MaybePromise } from './type-util'; - -/* - * Utility classes used for testing. - * Only available in the testing context. Should not be used in production code. - */ - -/** - * Creates a promise that resolves after the given timeout - * @param timeout the timeout in milliseconds - * @returns - */ -export async function delay(timeout: number): Promise { - return new Promise(resolve => setTimeout(resolve, timeout)); -} - -/** - * Consumes a maybe async function and checks for error - * @param method - The function to check - * @param message - Optional message to match with error message - */ -export async function expectToThrowAsync(toEvaluate: () => MaybePromise, message?: string): Promise { - let err: unknown | undefined = undefined; - try { - await toEvaluate(); - } catch (error) { - err = error; - } - if (message) { - expect(err instanceof Error, 'The error cause should be an instance of Error').to.be.true; - expect((err as Error)?.message).to.be.equal(message); - } else { - expect(err).to.be.an('Error'); - } -} diff --git a/packages/protocol/src/utils/type-util.spec.ts b/packages/protocol/src/utils/type-util.spec.ts index 5b08292d..6353609c 100644 --- a/packages/protocol/src/utils/type-util.spec.ts +++ b/packages/protocol/src/utils/type-util.spec.ts @@ -13,7 +13,7 @@ * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { Action } from '../action-protocol/base-protocol'; import { AnyObject, @@ -30,28 +30,28 @@ describe('TypeUtil', () => { describe('AnyObject', () => { describe('is', () => { it('should return true for an empty object', () => { - expect(AnyObject.is({})).to.be.true; + expect(AnyObject.is({})).toBe(true); }); it('should return true for an object with arbitrary properties', () => { - expect(AnyObject.is({ a: 'a', b: 5 })).to.be.true; + expect(AnyObject.is({ a: 'a', b: 5 })).toBe(true); }); it('should return false for `undefined`', () => { - expect(AnyObject.is(undefined)).to.be.false; + expect(AnyObject.is(undefined)).toBe(false); }); it('should return false for `null`', () => { // eslint-disable-next-line no-null/no-null - expect(AnyObject.is(null)).to.be.false; + expect(AnyObject.is(null)).toBe(false); }); it('should return false for unknown object of primitive type', () => { - expect(AnyObject.is('')).to.be.false; - expect(AnyObject.is(5)).to.be.false; - expect(AnyObject.is(true)).to.be.false; + expect(AnyObject.is('')).toBe(false); + expect(AnyObject.is(5)).toBe(false); + expect(AnyObject.is(true)).toBe(false); expect( AnyObject.is(() => { /**/ }) - ).to.be.false; + ).toBe(false); expect(AnyObject.is(Symbol('Symbol'))); }); }); @@ -59,165 +59,165 @@ describe('TypeUtil', () => { describe('hasStringProp', () => { it('should return true for an object that has a property that matches the given key and type', () => { - expect(hasStringProp({ someProp: 'someKey' }, 'someProp')).to.be.true; + expect(hasStringProp({ someProp: 'someKey' }, 'someProp')).toBe(true); }); it('should return false for an object that has a property that matches the given but not the given type', () => { - expect(hasStringProp({ someProp: 123 }, 'someProp')).to.be.false; + expect(hasStringProp({ someProp: 123 }, 'someProp')).toBe(false); }); it('should return false for an object that does not have a property that matches the given key', () => { - expect(hasStringProp({ anotherProp: 123 }, 'someProp')).to.be.false; + expect(hasStringProp({ anotherProp: 123 }, 'someProp')).toBe(false); }); it('should return true for an object that does not have a matching key when using the optional flag', () => { - expect(hasStringProp({ anotherProp: 123 }, 'someProp', true)).to.be.true; + expect(hasStringProp({ anotherProp: 123 }, 'someProp', true)).toBe(true); }); it('should return false for an object that has a property with matching name but invalid type when using the optional flag', () => { - expect(hasStringProp({ someProp: 123 }, 'someProp', true)).to.be.false; + expect(hasStringProp({ someProp: 123 }, 'someProp', true)).toBe(false); }); it('should return true for an object that has a property with matching name but without value when using the optional flag', () => { - expect(hasStringProp({ someProp: undefined }, 'someProp', true)).to.be.true; + expect(hasStringProp({ someProp: undefined }, 'someProp', true)).toBe(true); }); it('should return true for an object that has a property that matches the given key and type when using the optional flag', () => { - expect(hasStringProp({ someProp: 'someKey' }, 'someProp', true)).to.be.true; + expect(hasStringProp({ someProp: 'someKey' }, 'someProp', true)).toBe(true); }); }); describe('hasBooleanProp', () => { it('should return true for an object that has a property that matches the given key and type', () => { - expect(hasBooleanProp({ someProp: true }, 'someProp')).to.be.true; + expect(hasBooleanProp({ someProp: true }, 'someProp')).toBe(true); }); it('should return false for an object that has a property that matches the given but not the given type', () => { - expect(hasBooleanProp({ someProp: 123 }, 'someProp')).to.be.false; + expect(hasBooleanProp({ someProp: 123 }, 'someProp')).toBe(false); }); it('should return false for an object that does not have a property that matches the given key', () => { - expect(hasBooleanProp({ anotherProp: 123 }, 'someProp')).to.be.false; + expect(hasBooleanProp({ anotherProp: 123 }, 'someProp')).toBe(false); }); it('should return true for an object that does not have a matching key when using the optional flag', () => { - expect(hasBooleanProp({ anotherProp: 123 }, 'someProp', true)).to.be.true; + expect(hasBooleanProp({ anotherProp: 123 }, 'someProp', true)).toBe(true); }); it('should return false for an object that has a property with matching name but invalid type when using the optional flag', () => { - expect(hasBooleanProp({ someProp: 123 }, 'someProp', true)).to.be.false; + expect(hasBooleanProp({ someProp: 123 }, 'someProp', true)).toBe(false); }); it('should return true for an object that has a property with matching name but without value when using the optional flag', () => { - expect(hasBooleanProp({ someProp: undefined }, 'someProp', true)).to.be.true; + expect(hasBooleanProp({ someProp: undefined }, 'someProp', true)).toBe(true); }); it('should return true for an object that has a property that matches the given key and type when using the optional flag', () => { - expect(hasBooleanProp({ someProp: true }, 'someProp', true)).to.be.true; + expect(hasBooleanProp({ someProp: true }, 'someProp', true)).toBe(true); }); }); describe('hasNumberProp', () => { it('should return true for an object that has a property that matches the given key and type', () => { - expect(hasNumberProp({ someProp: 123 }, 'someProp')).to.be.true; + expect(hasNumberProp({ someProp: 123 }, 'someProp')).toBe(true); }); it('should return false for an object that has a property that matches the given but not the given type', () => { - expect(hasNumberProp({ someProp: '123' }, 'someProp')).to.be.false; + expect(hasNumberProp({ someProp: '123' }, 'someProp')).toBe(false); }); it('should return false for an object that does not have a property that matches the given key', () => { - expect(hasNumberProp({ anotherProp: 123 }, 'someProp')).to.be.false; + expect(hasNumberProp({ anotherProp: 123 }, 'someProp')).toBe(false); }); it('should return true for an object that does not have a matching key when using the optional flag', () => { - expect(hasNumberProp({ anotherProp: 123 }, 'someProp', true)).to.be.true; + expect(hasNumberProp({ anotherProp: 123 }, 'someProp', true)).toBe(true); }); it('should return false for an object that has a property with matching name but invalid type when using the optional flag', () => { - expect(hasNumberProp({ someProp: '123' }, 'someProp', true)).to.be.false; + expect(hasNumberProp({ someProp: '123' }, 'someProp', true)).toBe(false); }); it('should return true for an object that has a property with matching name but without value when using the optional flag', () => { - expect(hasNumberProp({ someProp: undefined }, 'someProp', true)).to.be.true; + expect(hasNumberProp({ someProp: undefined }, 'someProp', true)).toBe(true); }); it('should return true for an object that has a property that matches the given key and type when using the optional flag', () => { - expect(hasNumberProp({ someProp: 123 }, 'someProp', true)).to.be.true; + expect(hasNumberProp({ someProp: 123 }, 'someProp', true)).toBe(true); }); }); describe('hasObjectProp', () => { it('should return true for an object that has a property that matches the given key and type', () => { - expect(hasObjectProp({ someProp: { value: 'someKey' } }, 'someProp')).to.be.true; + expect(hasObjectProp({ someProp: { value: 'someKey' } }, 'someProp')).toBe(true); }); it('should return false for an object that has a property that matches the given but not the given type', () => { - expect(hasObjectProp({ someProp: '123' }, 'someProp')).to.be.false; + expect(hasObjectProp({ someProp: '123' }, 'someProp')).toBe(false); }); it('should return false for an object that does not have a property that matches the given key', () => { - expect(hasObjectProp({ anotherProp: 123 }, 'someProp')).to.be.false; + expect(hasObjectProp({ anotherProp: 123 }, 'someProp')).toBe(false); }); it('should return true for an object that does not have a matching key when using the optional flag', () => { - expect(hasObjectProp({ anotherProp: 123 }, 'someProp', true)).to.be.true; + expect(hasObjectProp({ anotherProp: 123 }, 'someProp', true)).toBe(true); }); it('should return false for an object that has a property with matching name but invalid type when using the optional flag', () => { - expect(hasObjectProp({ someProp: 123 }, 'someProp', true)).to.be.false; + expect(hasObjectProp({ someProp: 123 }, 'someProp', true)).toBe(false); }); it('should return true for an object that has a property with matching name but without value when using the optional flag', () => { - expect(hasObjectProp({ someProp: undefined }, 'someProp', true)).to.be.true; + expect(hasObjectProp({ someProp: undefined }, 'someProp', true)).toBe(true); }); it('should return true for an object that has a property that matches the given key and type when using the optional flag', () => { - expect(hasObjectProp({ someProp: { value: 'someKey' } }, 'someProp', true)).to.be.true; + expect(hasObjectProp({ someProp: { value: 'someKey' } }, 'someProp', true)).toBe(true); }); }); describe('hasFunctionProp', () => { it('should return true for an object that has a property that matches the given key and type', () => { - expect(hasFunctionProp({ someProp: () => {} }, 'someProp')).to.be.true; + expect(hasFunctionProp({ someProp: () => {} }, 'someProp')).toBe(true); }); it('should return false for an object that has a property that matches the given but not the given type', () => { - expect(hasFunctionProp({ someProp: '123' }, 'someProp')).to.be.false; + expect(hasFunctionProp({ someProp: '123' }, 'someProp')).toBe(false); }); it('should return false for an object that does not have a property that matches the given key', () => { - expect(hasFunctionProp({ anotherProp: 123 }, 'someProp')).to.be.false; + expect(hasFunctionProp({ anotherProp: 123 }, 'someProp')).toBe(false); }); it('should return true for an object that does not have a matching key when using the optional flag', () => { - expect(hasFunctionProp({ anotherProp: 123 }, 'someProp', true)).to.be.true; + expect(hasFunctionProp({ anotherProp: 123 }, 'someProp', true)).toBe(true); }); it('should return false for an object that has a property with matching name but invalid type when using the optional flag', () => { - expect(hasFunctionProp({ someProp: 123 }, 'someProp', true)).to.be.false; + expect(hasFunctionProp({ someProp: 123 }, 'someProp', true)).toBe(false); }); it('should return true for an object that has a property with matching name but without value when using the optional flag', () => { - expect(hasFunctionProp({ someProp: undefined }, 'someProp', true)).to.be.true; + expect(hasFunctionProp({ someProp: undefined }, 'someProp', true)).toBe(true); }); it('should return true for an object that has a property that matches the given key and type when using the optional flag', () => { - expect(hasFunctionProp({ someProp: () => {} }, 'someProp', true)).to.be.true; + expect(hasFunctionProp({ someProp: () => {} }, 'someProp', true)).toBe(true); }); }); describe('hasArrayProp', () => { it('should return true for an object that has a property that matches the given key and type', () => { - expect(hasArrayProp({ someProp: ['some', 'prop'] }, 'someProp')).to.be.true; + expect(hasArrayProp({ someProp: ['some', 'prop'] }, 'someProp')).toBe(true); }); it('should return false for an object that has a property that matches the given but not the given type', () => { - expect(hasArrayProp({ someProp: '123' }, 'someProp')).to.be.false; + expect(hasArrayProp({ someProp: '123' }, 'someProp')).toBe(false); }); it('should return false for an object that does not have a property that matches the given key', () => { - expect(hasArrayProp({ anotherProp: 123 }, 'someProp')).to.be.false; + expect(hasArrayProp({ anotherProp: 123 }, 'someProp')).toBe(false); }); it('should return true for an object that does not have a matching key when using the optional flag', () => { - expect(hasArrayProp({ anotherProp: 123 }, 'someProp', true)).to.be.true; + expect(hasArrayProp({ anotherProp: 123 }, 'someProp', true)).toBe(true); }); it('should return false for an object that has a property with matching name but invalid type when using the optional flag', () => { - expect(hasArrayProp({ someProp: 123 }, 'someProp', true)).to.be.false; + expect(hasArrayProp({ someProp: 123 }, 'someProp', true)).toBe(false); }); it('should return true for an object that has a property with matching name but without value when using the optional flag', () => { - expect(hasArrayProp({ someProp: undefined }, 'someProp', true)).to.be.true; + expect(hasArrayProp({ someProp: undefined }, 'someProp', true)).toBe(true); }); it('should return true for an object that has a property that matches the given key and type when using the optional flag', () => { - expect(hasArrayProp({ someProp: ['some', 'prop'] }, 'someProp', true)).to.be.true; + expect(hasArrayProp({ someProp: ['some', 'prop'] }, 'someProp', true)).toBe(true); }); }); describe('MaybeActions', () => { describe('asArray', () => { it('should return an empty array if undefined is provided', () => { - expect(MaybeActions.asArray(undefined)).to.deep.equal([]); + expect(MaybeActions.asArray(undefined)).toEqual([]); }); it('should return an array with a single action if a single action is provided', () => { const action = { kind: 'someAction' }; - expect(MaybeActions.asArray(action)).to.deep.equal([action]); + expect(MaybeActions.asArray(action)).toEqual([action]); }); it('should return the same array if an array of actions is provided', () => { const actions = [{ kind: 'action1' }, { kind: 'action2' }]; - expect(MaybeActions.asArray(actions)).to.deep.equal(actions); + expect(MaybeActions.asArray(actions)).toEqual(actions); }); it('should return the result of the function if a function returning actions is provided', () => { const actions = [{ kind: 'action1' }, { kind: 'action2' }]; const actionFunction = (): Action[] => actions; - expect(MaybeActions.asArray(actionFunction)).to.deep.equal(actions); + expect(MaybeActions.asArray(actionFunction)).toEqual(actions); }); }); }); diff --git a/packages/protocol/src/utils/uuid.spec.ts b/packages/protocol/src/utils/uuid.spec.ts index c2bb2fae..7d99ed16 100644 --- a/packages/protocol/src/utils/uuid.spec.ts +++ b/packages/protocol/src/utils/uuid.spec.ts @@ -13,20 +13,20 @@ * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { expect } from 'chai'; +import { describe, expect, it } from 'vitest'; import { generateUuid, isUuid } from './uuid'; describe('Uuid', () => { describe('isUuid', () => { it('should return true for a valid UUID', () => { - expect(isUuid('f47ac10b-58cc-4372-a567-0e02b2c3d479')).to.be.true; + expect(isUuid('f47ac10b-58cc-4372-a567-0e02b2c3d479')).toBe(true); }); it('should return true for a generated UUID', () => { - expect(isUuid(generateUuid())).to.be.true; + expect(isUuid(generateUuid())).toBe(true); }); it('should return false for a malformed UUID', () => { - expect(isUuid('not-a-uuid')).to.be.false; - expect(isUuid('')).to.be.false; + expect(isUuid('not-a-uuid')).toBe(false); + expect(isUuid('')).toBe(false); }); }); }); diff --git a/packages/protocol/tsconfig.json b/packages/protocol/tsconfig.json index 19cd3812..2a819eae 100644 --- a/packages/protocol/tsconfig.json +++ b/packages/protocol/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@eclipse-glsp/ts-config/mocha", + "extends": "@eclipse-glsp/ts-config", "compilerOptions": { "composite": true, "rootDir": "src", @@ -7,5 +7,5 @@ "reactNamespace": "JSX" }, "include": ["src"], - "exclude": ["**/*.spec.ts"] + "exclude": ["**/*.spec.ts", "**/test/**"] } diff --git a/packages/protocol/tsconfig.test.json b/packages/protocol/tsconfig.test.json new file mode 100644 index 00000000..19a4102a --- /dev/null +++ b/packages/protocol/tsconfig.test.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "composite": true, + "noEmit": true + }, + "include": ["src/**/*.spec.ts", "src/**/*.spec.tsx", "src/**/test/**/*"], + "exclude": ["lib", "node_modules"], + "references": [{ "path": "./tsconfig.json" }] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b84ea705..00005976 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16,19 +16,16 @@ importers: devDependencies: '@eclipse-glsp/dev': specifier: next - version: 2.8.0-next.9(@types/node@22.19.15)(@typescript-eslint/utils@8.61.0(eslint@10.5.0)(typescript@5.9.2))(typescript@5.9.2) + version: 2.8.0-next.16(@types/node@22.19.15)(@typescript-eslint/utils@8.61.0(eslint@10.5.0)(typescript@5.9.2))(@vitest/browser-playwright@4.1.9)(@vitest/browser@4.1.9)(happy-dom@20.10.5)(typescript@5.9.2)(vite@8.0.16(@types/node@22.19.15)(esbuild@0.28.1)) '@types/node': specifier: 22.x version: 22.19.15 concurrently: specifier: ^9.2.1 version: 9.2.1 - mocha-ctrf-json-reporter: - specifier: ^0.0.9 - version: 0.0.9 - tsconfig-paths: - specifier: ^4.2.0 - version: 4.2.0 + reflect-metadata: + specifier: ^0.2.2 + version: 0.2.2 typescript: specifier: ^5.9.2 version: 5.9.2 @@ -167,40 +164,6 @@ importers: packages: - '@babel/code-frame@7.29.7': - resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} - engines: {node: '>=6.9.0'} - - '@babel/compat-data@7.29.7': - resolution: {integrity: sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==} - engines: {node: '>=6.9.0'} - - '@babel/core@7.29.7': - resolution: {integrity: sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==} - engines: {node: '>=6.9.0'} - - '@babel/generator@7.29.7': - resolution: {integrity: sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==} - engines: {node: '>=6.9.0'} - - '@babel/helper-compilation-targets@7.29.7': - resolution: {integrity: sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==} - engines: {node: '>=6.9.0'} - - '@babel/helper-globals@7.29.7': - resolution: {integrity: sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-imports@7.29.7': - resolution: {integrity: sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-transforms@7.29.7': - resolution: {integrity: sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@babel/helper-string-parser@7.29.7': resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} engines: {node: '>=6.9.0'} @@ -209,50 +172,37 @@ packages: resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.29.7': - resolution: {integrity: sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==} - engines: {node: '>=6.9.0'} - - '@babel/helpers@7.29.7': - resolution: {integrity: sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==} - engines: {node: '>=6.9.0'} - '@babel/parser@7.29.7': resolution: {integrity: sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/template@7.29.7': - resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==} - engines: {node: '>=6.9.0'} - - '@babel/traverse@7.29.7': - resolution: {integrity: sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==} - engines: {node: '>=6.9.0'} - '@babel/types@7.29.7': resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==} engines: {node: '>=6.9.0'} - '@cspotcode/source-map-support@0.8.1': - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} + '@bcoe/v8-coverage@1.0.2': + resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} + engines: {node: '>=18'} - '@eclipse-glsp/cli@2.8.0-next.9': - resolution: {integrity: sha512-NPyJJCs7VAkGwtKdnTn9oTZ/fWA35bvfFKOcB3jxZvi2dkLaxlhb/kVH4KPUSmAJ/D00JXHnCnMts/as2fTrdw==} + '@blazediff/core@1.9.1': + resolution: {integrity: sha512-ehg3jIkYKulZh+8om/O25vkvSsXXwC+skXmyA87FFx6A/45eqOkZsBltMw/TVteb0mloiGT8oGRTcjRAz66zaA==} + + '@eclipse-glsp/cli@2.8.0-next.16': + resolution: {integrity: sha512-PyIDa2YaXzXCiYEGEfFoDy0U6suclx8dLcX0DCoDQr4mPpfgU6H63zk9k+4FKr+u475XV3ch5kUPHMQVRv/Fag==} hasBin: true - '@eclipse-glsp/config-test@2.8.0-next.9': - resolution: {integrity: sha512-zYl7zBHjCTSsetV6oJAQenY44StTyl9elriQebCioWCPhdKg+sLy6f8pl/X3CK3Vj/5RJqaBLRzEGeq1dbJnxw==} + '@eclipse-glsp/config-test@2.8.0-next.16': + resolution: {integrity: sha512-7ihYKqjTIbfv1mTvrFsGy43f3h0jHNX1RJprAV9bp9zth2hfFQN/Y4xB564EwquE+suRc9ZJJvzJj/HNBa7BRg==} - '@eclipse-glsp/config@2.8.0-next.9': - resolution: {integrity: sha512-yvobLNQ/RRjPM3WaMtCj2WMpIW29ARICBDYu9zTyecWaIzTl7XUyGgD8uP67Wu8626qiAZgFusx8y+Inmt0R4A==} + '@eclipse-glsp/config@2.8.0-next.16': + resolution: {integrity: sha512-qM1PeD9UxvwKAf3G3ImOYFee7IvAFfL4TzwxPmPLnIdB4dAj7wDCY6COBcifAQD+jDoSuXFniQPcaUnHZKjfig==} - '@eclipse-glsp/dev@2.8.0-next.9': - resolution: {integrity: sha512-ngT+PkOd5sdh4F/yad6r/OzzL8wceZ7PWpdferq/GenRmMPEGMpYk1SHB0BkYrmDUS+qSk4Yk+8gQDfeR/fnCw==} + '@eclipse-glsp/dev@2.8.0-next.16': + resolution: {integrity: sha512-WUNk3B6MLkM8HZND1FqyccwQZ7A/DfqUBDGAypjj3JYMiAOTZwseQXB8ea4Z/iCTfEmq3wnYapbnm25SwSoFSQ==} - '@eclipse-glsp/eslint-config@2.8.0-next.9': - resolution: {integrity: sha512-hLEHaewvQTG5KzcC2aFkCufT+GU0ljhoyBOd2TyyNkYH8iCy10d53q4+wqPD309yrBp0yQjDWMc8HxIiH6bXcA==} + '@eclipse-glsp/eslint-config@2.8.0-next.16': + resolution: {integrity: sha512-FDWiHnTj/vv1+tBg7kNoUbsBm8OMIUhEsQfTNw53lqaXeNdcHRfv5Aur6tArRWbu0EoeEsqe79te3evP/tzReQ==} peerDependencies: '@eslint/js': ^10.0.1 '@stylistic/eslint-plugin': ^5.10.0 @@ -266,26 +216,19 @@ packages: globals: ^17.6.0 typescript-eslint: ^8.0.0 - '@eclipse-glsp/mocha-config@2.8.0-next.9': - resolution: {integrity: sha512-axu6xNd1wWxIiQv2F+Nm458fXum5JcGYQ7NCJ4kcWwV2paXWY6eWk3H2hO9HG004seOR+TQcR4kRfjwo3/ZoAQ==} - peerDependencies: - ignore-styles: ^5.0.1 - mocha: ^11.7.6 - reflect-metadata: ^0.2.2 + '@eclipse-glsp/prettier-config@2.8.0-next.16': + resolution: {integrity: sha512-ZdYR+vVDBlbpiLwQhvPAFktPQMB5hvi15g4hsGBALwCWa7v5FYfzAahTgoH5imCf0zJNXt/VmbsonK7eWCBaEA==} - '@eclipse-glsp/nyc-config@2.8.0-next.9': - resolution: {integrity: sha512-nBrEfGSfZluWaWIKj+T//WplxgC3EGgrioBTSaH4hOtWqGPG0BujwPz8jb0jJaUmBkKg8Vn6r9DroXhtx7/jnQ==} + '@eclipse-glsp/ts-config@2.8.0-next.16': + resolution: {integrity: sha512-0iLQOrjar/75XDYJjeLlIMBeWStLwf78wqypi+oTAfHpSliGd6hWSR8mHIA9G9YQNHrOZWxPgXI5ISJ6sHT14Q==} peerDependencies: - '@istanbuljs/nyc-config-typescript': ^1.0.2 - nyc: ^18.0.0 - - '@eclipse-glsp/prettier-config@2.8.0-next.9': - resolution: {integrity: sha512-fpHLtKdhMZg2lwHWqOgnEEYQ30LrTcHaDMfLbu6rG43OVgZffNxi275s0IgWIbrzNZoLIEl8z5tMpTDr17i0Mg==} + typescript: '>=5.5' - '@eclipse-glsp/ts-config@2.8.0-next.9': - resolution: {integrity: sha512-6CqN1XcAIiHGSHvazlGCReEyzRGnQHhgk56NjAn2yNC1Vefi+IvhV70yz0V4p6ooGT51jvv5VdzibD6XGzggZg==} + '@eclipse-glsp/vitest-config@2.8.0-next.16': + resolution: {integrity: sha512-gK/Unmg+lq9OYTyBxkYsY8H56FxhVrEa1NogvruqLg5HKkJGdNLP4j5DFACCq/jdnVvcfdCHM4Dx+nr+WM69jw==} peerDependencies: - typescript: '>=5.5' + '@vitest/coverage-v8': '>=4.0.0' + vitest: '>=4.0.0' '@emnapi/core@1.10.0': resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} @@ -522,34 +465,10 @@ packages: peerDependencies: reflect-metadata: 0.2.2 - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} - '@isaacs/fs-minipass@4.0.1': resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} engines: {node: '>=18.0.0'} - '@istanbuljs/load-nyc-config@1.1.0': - resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} - engines: {node: '>=8'} - - '@istanbuljs/nyc-config-typescript@1.0.2': - resolution: {integrity: sha512-iKGIyMoyJuFnJRSVTZ78POIRvNnwZaWIf8vG4ZS3rQq58MMDrqEX2nnzx0R28V2X8JvmKYiqY9FP2hlJsm8A0w==} - engines: {node: '>=8'} - peerDependencies: - nyc: '>=15' - - '@istanbuljs/schema@0.1.6': - resolution: {integrity: sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==} - engines: {node: '>=8'} - - '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} - - '@jridgewell/remapping@2.3.5': - resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} - '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} @@ -560,30 +479,121 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - '@jridgewell/trace-mapping@0.3.9': - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - '@napi-rs/wasm-runtime@1.1.5': resolution: {integrity: sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==} peerDependencies: '@emnapi/core': ^1.7.1 '@emnapi/runtime': ^1.7.1 + '@oxc-project/types@0.133.0': + resolution: {integrity: sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==} + '@package-json/types@0.0.12': resolution: {integrity: sha512-uu43FGU34B5VM9mCNjXCwLaGHYjXdNincqKLaraaCW+7S2+SmiBg1Nv8bPnmschrIfZmfKNY9f3fC376MRrObw==} - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} + '@polka/url@1.0.0-next.29': + resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} + + '@rolldown/binding-android-arm64@1.0.3': + resolution: {integrity: sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.0.3': + resolution: {integrity: sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.0.3': + resolution: {integrity: sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.0.3': + resolution: {integrity: sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.0.3': + resolution: {integrity: sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] - '@sinonjs/commons@3.0.1': - resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + '@rolldown/binding-linux-arm64-gnu@1.0.3': + resolution: {integrity: sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.0.3': + resolution: {integrity: sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.0.3': + resolution: {integrity: sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.0.3': + resolution: {integrity: sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.0.3': + resolution: {integrity: sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.0.3': + resolution: {integrity: sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.0.3': + resolution: {integrity: sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-wasm32-wasi@1.0.3': + resolution: {integrity: sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.0.3': + resolution: {integrity: sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.0.3': + resolution: {integrity: sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] - '@sinonjs/fake-timers@15.4.0': - resolution: {integrity: sha512-DsG+8/LscQIQg68J6Ef3dv10u6nVyetYn923s3/sus5eaGfTo1of5WMZSLf0UJc9KDuKPilPH0UDJCjvNbDNCA==} + '@rolldown/pluginutils@1.0.1': + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} - '@sinonjs/samsam@10.0.2': - resolution: {integrity: sha512-8lVwD1Df1BmzoaOLhMcGGcz/Jyr5QY2KSB75/YK1QgKzoabTeLdIVyhXNZK9ojfSKSdirbXqdbsXXqP9/Ve8+A==} + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} '@stylistic/eslint-plugin@5.10.0': resolution: {integrity: sha512-nPK52ZHvot8Ju/0A4ucSX1dcPV2/1clx0kLcH5wDmrE4naKso7TUC/voUyU1O9OTKTrR6MYip6LP0ogEMQ9jPQ==} @@ -596,23 +606,14 @@ packages: peerDependencies: eslint: '>=7.7.0' - '@tsconfig/node10@1.0.12': - resolution: {integrity: sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==} - - '@tsconfig/node12@1.0.11': - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - - '@tsconfig/node14@1.0.3': - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} - - '@tsconfig/node16@1.0.4': - resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - '@tybys/wasm-util@0.10.2': resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==} - '@types/chai@4.3.20': - resolution: {integrity: sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==} + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} '@types/esrecurse@4.3.1': resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==} @@ -629,24 +630,21 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/mocha@10.0.10': - resolution: {integrity: sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==} - '@types/node@22.19.15': resolution: {integrity: sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==} - '@types/sinon@21.0.1': - resolution: {integrity: sha512-5yoJSqLbjH8T9V2bksgRayuhpZy+723/z6wBOR+Soe4ZlXC0eW8Na71TeaZPUWDQvM7LYKa9UGFc6LRqxiR5fQ==} - - '@types/sinonjs__fake-timers@15.0.1': - resolution: {integrity: sha512-Ko2tjWJq8oozHzHV+reuvS5KYIRAokHnGbDwGh/J64LntgpbuylF74ipEL24HCyRjf9FOlBiBHWBR1RlVKsI1w==} - '@types/tar@6.1.5': resolution: {integrity: sha512-qm2I/RlZij5RofuY7vohTpYNaYcrSQlN2MyjucQc7ZweDwaEWkdN/EeNh6e9zjK6uEm6PwjdMXkcj05BxZdX1Q==} '@types/tough-cookie@4.0.5': resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + '@types/whatwg-mimetype@3.0.2': + resolution: {integrity: sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==} + + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + '@typescript-eslint/eslint-plugin@8.61.0': resolution: {integrity: sha512-bFNvl9ZczlVb+wR2Akszf3gHfKVj/8WanXaGJ3UstTA7brNKg0cNdk6X1Psu5V7MZ2oQtzZKOEzIUehaoxbDGw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -826,6 +824,55 @@ packages: cpu: [x64] os: [win32] + '@vitest/browser-playwright@4.1.9': + resolution: {integrity: sha512-Bq1rOGf9waevzG3EOkO/dene6bvKTUsZMVg8S1i+WH3JcMjuXEjiahP9rAqZRELUqjBySOJsvvSWqK/B3wjKQw==} + peerDependencies: + playwright: '*' + vitest: 4.1.9 + + '@vitest/browser@4.1.9': + resolution: {integrity: sha512-j1BKtWmPcqpMhmx/L9EPLgAJpCb0zKfwoWLmqBbxaogCXHjOwHFSEoHCBfnGtx93xKQwilZ26m+UOsHqHMkRNg==} + peerDependencies: + vitest: 4.1.9 + + '@vitest/coverage-v8@4.1.9': + resolution: {integrity: sha512-G9/lgqibheLVBDRuya45EbsEXTYcWoSG+TLg7i2axuzx0Eq62eXn+aWXyaVdV5vKvFSWd6ywcX8hA7la9Pvu8g==} + peerDependencies: + '@vitest/browser': 4.1.9 + vitest: 4.1.9 + peerDependenciesMeta: + '@vitest/browser': + optional: true + + '@vitest/expect@4.1.9': + resolution: {integrity: sha512-vl/rYsUKcBr3SnQn166+XR5ZQcgMx3DQhFWdfli/cWpLnLUmbxZvyrJZotLFUryib+LtArYMSTJ5RbQ57ZqrlA==} + + '@vitest/mocker@4.1.9': + resolution: {integrity: sha512-EVkXzBjrPGM+cK8/ANWgBrkUCfJfb38/EfTSO8h7pWvKkyPkpWxvR7BkD2MyItMF62C97zAEoqdpUixwR/e+Rw==} + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@4.1.9': + resolution: {integrity: sha512-s0iufns3iIFitdgm+YR7g1whCAaGtXz459VS9/PqyKDEEFgYIhsHOQmXgIgDuYCt7DeQmiZT0Qe2OA2p4ZPu5A==} + + '@vitest/runner@4.1.9': + resolution: {integrity: sha512-KXLMDtc7oe70+3mJfGrPUWPesswH+3sTxAMAMl8DG7I8IUQT4XW718dY5ID3vPUcmlu27CcKfY4P3h3I29SLJg==} + + '@vitest/snapshot@4.1.9': + resolution: {integrity: sha512-Jc7RKGNBo8Z28WYIm0Niej4xdSPByRf6mU58VpHQkd6Zh05rlnA+twjbK5HyeIGHxrzsc3mJgS43uM0CZKzaIA==} + + '@vitest/spy@4.1.9': + resolution: {integrity: sha512-fHpsS6mIi+PiEW+vcRVOMkX1oSaPKne3VOclSFICPcGOmfKgXPU5iAah+wcNcj2xPrCCmfq99IDGf+EojhhvhA==} + + '@vitest/utils@4.1.9': + resolution: {integrity: sha512-A51o8ymO5PpqlWNnBP9ZHPXDIpuMtTLlGSjN7la4US+LJzoUMyhwjA5QXlm39JexgwHKW4Xjs8Z2d3dLCXOeuA==} + '@vscode/codicons@0.0.44': resolution: {integrity: sha512-F7qPRumUK3EHjNdopfICLGRf3iNPoZQt+McTHAn4AlOWPB3W2kL4H0S7uqEqbyZ6rCxaeDjpAn3MCUnwTu/VJQ==} @@ -834,19 +881,11 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn-walk@8.3.5: - resolution: {integrity: sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==} - engines: {node: '>=0.4.0'} - acorn@8.17.0: resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==} engines: {node: '>=0.4.0'} hasBin: true - aggregate-error@3.1.0: - resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} - engines: {node: '>=8'} - ajv@6.15.0: resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} @@ -854,40 +893,20 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.2.2: - resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} - engines: {node: '>=12'} - ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} - ansi-styles@6.2.3: - resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} - append-transform@2.0.0: - resolution: {integrity: sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==} - engines: {node: '>=8'} - - archy@1.0.0: - resolution: {integrity: sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==} - - arg@4.1.3: - resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - - assertion-error@1.1.0: - resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + ast-v8-to-istanbul@1.0.4: + resolution: {integrity: sha512-0bC0/4bTSrnwdhU3IsZDwEdojvuPrSg59OYZfKsLRtJZ0u8VBx9DebfqqG8bRdCC0I7vjgxmPi41P0lpkhJHtA==} autocompleter@9.2.1: resolution: {integrity: sha512-lZVD5JZxxg3o6hnh7oB3M4kVAJPp/xFKmrO9RYeMGpFIH1XokmwevMLzSYz0BHSAbXMX6H3hEMsDxAd2dMebag==} - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - balanced-match@4.0.4: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} @@ -895,14 +914,6 @@ packages: balloon-css@0.5.2: resolution: {integrity: sha512-zheJpzwyNrG4t39vusA67v3BYg1HTVXOF8cErPEHzWK88PEOFwgo6Ea9VHOgOWNMgeuOtFVtB73NE2NWl9uDyQ==} - baseline-browser-mapping@2.10.37: - resolution: {integrity: sha512-girxaJ7WZssDOFhzCGZTDKoTa1gk6A1TbflaYTpykLJ4UU9Fz9kx1aREM8JCuoVHbL8X8T/mJg7w2oYSq72Oig==} - engines: {node: '>=6.0.0'} - hasBin: true - - brace-expansion@2.1.1: - resolution: {integrity: sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==} - brace-expansion@5.0.6: resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} engines: {node: 18 || 20 || >=22} @@ -910,58 +921,22 @@ packages: browser-split@0.0.1: resolution: {integrity: sha512-JhvgRb2ihQhsljNda3BI8/UcRHVzrVwo3Q+P8vDtSiyobXuFpuZ9mq+MbRGMnC22CjW3RrfXdg6j6ITX8M+7Ow==} - browser-stdout@1.3.1: - resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} - - browserslist@4.28.2: - resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - - caching-transform@4.0.0: - resolution: {integrity: sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==} - engines: {node: '>=8'} - - camelcase@5.3.1: - resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} - engines: {node: '>=6'} - - camelcase@6.3.0: - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} - engines: {node: '>=10'} - - caniuse-lite@1.0.30001799: - resolution: {integrity: sha512-hG1bReV+OUU+MOqK4t/ZWI0tZOyz3rqS9XuhOUz1cIcbwBKjOyJEJuw9ER5JuNyqxNk8u/JUVbGibBOL1yrjFw==} + buffer-image-size@0.6.4: + resolution: {integrity: sha512-nEh+kZOPY1w+gcCMobZ6ETUp9WfibndnosbpwB1iJk/8Gt5ZF2bhS6+B6bPYz424KtwsR6Rflc3tCz1/ghX2dQ==} + engines: {node: '>=4.0'} - chai@4.5.0: - resolution: {integrity: sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==} - engines: {node: '>=4'} + chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} + engines: {node: '>=18'} chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} - charenc@0.0.2: - resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==} - - check-error@1.0.3: - resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} - - chokidar@4.0.3: - resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} - engines: {node: '>= 14.16.0'} - chownr@3.0.0: resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} engines: {node: '>=18'} - clean-stack@2.2.0: - resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} - engines: {node: '>=6'} - - cliui@6.0.0: - resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} - cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} @@ -977,30 +952,18 @@ packages: resolution: {integrity: sha512-0h+uSNtQGW3D98eQt3jJ8L06Fves8hncB4V/PKdw/Qb8Hnk19VaKuTr55UNRYiSoVa7WwrFls+rh3ux9agmkeQ==} engines: {node: '>= 12.0.0'} - commondir@1.0.1: - resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} - concurrently@9.2.1: resolution: {integrity: sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==} engines: {node: '>=18'} hasBin: true - convert-source-map@1.9.0: - resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} - convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - create-require@1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} - crypt@0.0.2: - resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} - debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} @@ -1010,55 +973,34 @@ packages: supports-color: optional: true - decamelize@1.2.0: - resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} - engines: {node: '>=0.10.0'} - - decamelize@4.0.0: - resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} - engines: {node: '>=10'} - - deep-eql@4.1.4: - resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} - engines: {node: '>=6'} - deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - default-require-extensions@3.0.1: - resolution: {integrity: sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==} - engines: {node: '>=8'} - detect-indent@7.0.2: resolution: {integrity: sha512-y+8xyqdGLL+6sh0tVeHcfP/QDd8gUgbasolJJpY7NgeQGSZ739bDtSiaiDgtoicy+mtYB81dKLxO9xRhCyIB3A==} engines: {node: '>=12.20'} + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + detect-newline@4.0.1: resolution: {integrity: sha512-qE3Veg1YXzGHQhlA6jzebZN2qVf6NX+A7m7qlhCGG30dJixrAQhYOsJjsnBjJkCSmuOPpCk30145fr8FV0bzog==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - diff@9.0.0: - resolution: {integrity: sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw==} - engines: {node: '>=0.3.1'} - - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - - electron-to-chromium@1.5.372: - resolution: {integrity: sha512-M3yhbAlilnwqC8D21t28UCDGHyitShTmmLRU/H+b74P6Ski16Nb9HONYEaVpMj/pwC7BEo5B95FpjODLCWbtfA==} - emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} - es6-error@4.1.1: - resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} + entities@7.0.1: + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} + engines: {node: '>=0.12'} + + es-module-lexer@2.1.0: + resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==} esbuild@0.28.1: resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==} @@ -1172,10 +1114,17 @@ packages: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + engines: {node: '>=12.0.0'} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -1201,14 +1150,6 @@ packages: file-saver@2.0.5: resolution: {integrity: sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==} - find-cache-dir@3.3.2: - resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} - engines: {node: '>=8'} - - find-up@4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} - find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} @@ -1217,39 +1158,23 @@ packages: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} - flat@5.0.2: - resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} - hasBin: true - flatted@3.4.2: resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} - foreground-child@2.0.0: - resolution: {integrity: sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==} - engines: {node: '>=8.0.0'} - - foreground-child@3.3.1: - resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} - engines: {node: '>=14'} - - fromentries@1.3.2: - resolution: {integrity: sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==} + fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] - gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-func-name@2.0.2: - resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} - - get-package-type@0.1.0: - resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} - engines: {node: '>=8.0.0'} - get-tsconfig@4.14.0: resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==} @@ -1260,11 +1185,6 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} - glob@10.5.0: - resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} - deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me - hasBin: true - glob@13.0.6: resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==} engines: {node: 18 || 20 || >=22} @@ -1273,27 +1193,17 @@ packages: resolution: {integrity: sha512-sepffkT8stwnIYbsMBpoCHJuJM5l98FUF2AnE07hfvE0m/qp3R586hw4jF4uadbhvg1ooIdzuu7CsfD2jzCaNA==} engines: {node: '>=18'} - graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + happy-dom@20.10.5: + resolution: {integrity: sha512-0aA6BQoMnpcRE/c1E8ZyF2jXnET7MJskereWOXher4CJuYjrI5esN0Az/1NPMD4KeWUbampBGw2MGqabMPFIbg==} + engines: {node: '>=20.0.0'} has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} - hasha@5.2.2: - resolution: {integrity: sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==} - engines: {node: '>=8'} - - he@1.2.0: - resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} - hasBin: true - html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - ignore-styles@5.0.1: - resolution: {integrity: sha512-gQQmIznCETPLEzfg1UH4Cs2oRq+HBPl8quroEUNXT8oybEG7/0lqI3dGgDSRry6B9HcCXw3PVkFFS0FF3CMddg==} - ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -1306,18 +1216,11 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} - indent-string@4.0.0: - resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} - engines: {node: '>=8'} - inversify@6.2.0: resolution: {integrity: sha512-wpiGpyIphFthWf18CBASJ1gClYwnW0mKjcSHwOuF7ToF/TBoarYSItX492WTGyK0VdJN1afwBIfaEpvp8IetPA==} peerDependencies: reflect-metadata: ~0.2.2 - is-buffer@1.1.6: - resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} - is-bun-module@2.0.0: resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==} @@ -1333,33 +1236,10 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} - is-path-inside@3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} - - is-plain-obj@2.1.0: - resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} - engines: {node: '>=8'} - is-plain-obj@4.1.0: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} - is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - - is-typedarray@1.0.0: - resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} - - is-unicode-supported@0.1.0: - resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} - engines: {node: '>=10'} - - is-windows@1.0.2: - resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} - engines: {node: '>=0.10.0'} - isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -1367,44 +1247,16 @@ packages: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} - istanbul-lib-hook@3.0.0: - resolution: {integrity: sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==} - engines: {node: '>=8'} - - istanbul-lib-instrument@6.0.3: - resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} - engines: {node: '>=10'} - - istanbul-lib-processinfo@3.0.1: - resolution: {integrity: sha512-s3mX05h5wGZeScG6XnOanygPh4SJu5ujMc9YbvpnLGXWy1cRiGbp0NdVcjHxgoZt3WfQppfBsa0y+gWdYJ2pGQ==} - engines: {node: 20 || >=22} - istanbul-lib-report@3.0.1: resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} engines: {node: '>=10'} - istanbul-lib-source-maps@4.0.1: - resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} - engines: {node: '>=10'} - istanbul-reports@3.2.0: resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} engines: {node: '>=8'} - jackspeak@3.4.3: - resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - - js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - - js-yaml@4.2.0: - resolution: {integrity: sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==} - hasBin: true - - jsesc@3.1.0: - resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} - engines: {node: '>=6'} - hasBin: true + js-tokens@10.0.0: + resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} @@ -1415,11 +1267,6 @@ packages: json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -1427,22 +1274,89 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} - locate-path@5.0.0: - resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} - engines: {node: '>=8'} + lightningcss-android-arm64@1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} + lightningcss-darwin-arm64@1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] - lodash.escape@4.0.1: - resolution: {integrity: sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw==} + lightningcss-darwin-x64@1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] - lodash.flattendeep@4.4.0: - resolution: {integrity: sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==} + lightningcss-freebsd-x64@1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] - lodash.forown@4.4.0: - resolution: {integrity: sha512-xcpca6BCshoe5SFSrQOoV8FBEbNzcBa6QQYmtv48eEFNzdwQLkHkcWSaBlecHhyHb1BUk1xqFdXoiSLJkt/w5w==} + lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-musl@1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-gnu@1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-musl@1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-win32-arm64-msvc@1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + engines: {node: '>= 12.0.0'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.escape@4.0.1: + resolution: {integrity: sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw==} + + lodash.forown@4.4.0: + resolution: {integrity: sha512-xcpca6BCshoe5SFSrQOoV8FBEbNzcBa6QQYmtv48eEFNzdwQLkHkcWSaBlecHhyHb1BUk1xqFdXoiSLJkt/w5w==} lodash.kebabcase@4.1.1: resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==} @@ -1453,48 +1367,24 @@ packages: lodash.uniq@4.5.0: resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} - log-symbols@4.1.0: - resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} - engines: {node: '>=10'} - - loupe@2.3.7: - resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} - - lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@11.5.1: resolution: {integrity: sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==} engines: {node: 20 || >=22} - lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - make-dir@3.1.0: - resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} - engines: {node: '>=8'} + magicast@0.5.3: + resolution: {integrity: sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==} make-dir@4.0.0: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} - make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - - md5@2.3.0: - resolution: {integrity: sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==} - minimatch@10.2.5: resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} engines: {node: 18 || 20 || >=22} - minimatch@9.0.9: - resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} - engines: {node: '>=16 || 14 >=14.17'} - - minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minipass@4.2.8: resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} engines: {node: '>=8'} @@ -1511,17 +1401,18 @@ packages: resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} engines: {node: '>= 18'} - mocha-ctrf-json-reporter@0.0.9: - resolution: {integrity: sha512-9xMtcT7LujnIj84i58JFjrtCk/dRvMkYBSPUL6HdLqgKx9hO19QI+56VSYaGttMuNoBtO4v2dk99UWd8fufpjw==} - - mocha@11.7.6: - resolution: {integrity: sha512-nS9xOGbw2I3cjCpxwZAEJ9xK9lmJ08vEkQvLtz4du9ZrF9UrjRpeJGiIgl2Z+Qs++pmB4ecDe48Fwsh+j+j7xA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - hasBin: true + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} + engines: {node: '>=10'} ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + nanoid@3.3.12: + resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + napi-postinstall@0.3.4: resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} @@ -1530,55 +1421,26 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - node-preload@0.2.1: - resolution: {integrity: sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==} - engines: {node: '>=8'} - - node-releases@2.0.47: - resolution: {integrity: sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==} - engines: {node: '>=18'} - - nyc@18.0.0: - resolution: {integrity: sha512-G5UyHinFkB1BxqGTrmZdB6uIYH0+v7ZnVssuflUDi+J+RhKWyAhRT1RCehBSI6jLFLuUUgFDyLt49mUtdO1XeQ==} - engines: {node: 20 || >=22} - hasBin: true - object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} + obug@2.1.3: + resolution: {integrity: sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==} + engines: {node: '>=12.20.0'} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} - p-limit@2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} - p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} - p-locate@4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} - engines: {node: '>=8'} - p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} - p-map@3.0.0: - resolution: {integrity: sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==} - engines: {node: '>=8'} - - p-try@2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} - - package-hash@4.0.0: - resolution: {integrity: sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==} - engines: {node: '>=8'} - package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} @@ -1596,16 +1458,12 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - path-scurry@1.11.1: - resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} - engines: {node: '>=16 || 14 >=14.18'} - path-scurry@2.0.2: resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} engines: {node: 18 || 20 || >=22} - pathval@1.1.1: - resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -1614,9 +1472,23 @@ packages: resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} engines: {node: '>=12'} - pkg-dir@4.2.0: - resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} - engines: {node: '>=8'} + playwright-core@1.61.0: + resolution: {integrity: sha512-caX7TrY3Ml6egyDX0WUcTHDxodl/b51y5wJOdCEA36QviK/s2g081hvmGs8eaE3DWb6NYZQ6BjO/QkNRPenoPA==} + engines: {node: '>=18'} + hasBin: true + + playwright@1.61.0: + resolution: {integrity: sha512-Z+7BeeqQPRRzklHsVFP4KTGIyMxKUmfeRA4WisM6G3/XW6nwGeX6fX9qYaDa+CiUqpOkb2f6X3nar05R3kSuJQ==} + engines: {node: '>=18'} + hasBin: true + + pngjs@7.0.0: + resolution: {integrity: sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==} + engines: {node: '>=14.19.0'} + + postcss@8.5.15: + resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} + engines: {node: ^10 || ^12 || >=14} prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} @@ -1635,36 +1507,17 @@ packages: engines: {node: '>=14'} hasBin: true - process-on-spawn@1.1.0: - resolution: {integrity: sha512-JOnOPQ/8TZgjs1JIH/m9ni7FfimjNa/PRx7y/Wb5qdItsnhO0jE4AT7fC0HjC28DUQWDr50dwSYZLdRMlqDq3Q==} - engines: {node: '>=8'} - punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - readdirp@4.1.2: - resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} - engines: {node: '>= 14.18.0'} - reflect-metadata@0.2.2: resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} - release-zalgo@1.0.0: - resolution: {integrity: sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==} - engines: {node: '>=4'} - require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} - require-main-filename@2.0.0: - resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} - - resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} - resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} @@ -1673,25 +1526,19 @@ packages: engines: {node: 20 || >=22} hasBin: true + rolldown@1.0.3: + resolution: {integrity: sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + rxjs@7.8.2: resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} - semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true - semver@7.8.4: resolution: {integrity: sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==} engines: {node: '>=10'} hasBin: true - serialize-javascript@7.0.5: - resolution: {integrity: sha512-F4LcB0UqUl1zErq+1nYEEzSHJnIwb3AF2XWB94b+afhrekOUijwooAYqFyRbjYkm2PAKBabx6oYv/xDxNi8IBw==} - engines: {node: '>=20.0.0'} - - set-blocking@2.0.0: - resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} - shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -1704,15 +1551,12 @@ packages: resolution: {integrity: sha512-VsC6n6vz1ihYYyZZwX7YZSF5l5x36ca17OC+a69h94YqB7X6XLwf+5MOgynYir2SLFUbl8gIYvBo8K8RoNQ6bQ==} engines: {node: '>= 0.4'} - signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - sinon@22.0.0: - resolution: {integrity: sha512-sq/6DpdXOrLyfbKlXLg/Usc7xu8YXPeLkOFZRvA3bNUSA2lhbrZ06yuXbH1fkzBPCbz9O10+7hznzUsjaYNm0Q==} + sirv@3.0.2: + resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} + engines: {node: '>=18'} snabbdom-to-html@7.1.0: resolution: {integrity: sha512-R/Rc/5duxWvV4w/B3JI/lt1jXb96pIVV9Xxwqvne259cNuDRXYppuBMtoUGdda0JGhMjNmvc1z+G9ch/PQx+kg==} @@ -1729,14 +1573,10 @@ packages: engines: {node: '>=20'} hasBin: true - source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} - spawn-wrap@3.0.0: - resolution: {integrity: sha512-z+s5vv4KzFPJVddGab0xX2n7kQPGMdNUX5l9T8EJqsXdKTWpcxmAqWHpsgHEXoC1taGBCc7b79bi62M5kdbrxQ==} - engines: {node: '>=8'} - sprotty-protocol@1.4.0: resolution: {integrity: sha512-+AAskW3Mzcq5UhMnummp4wwJ1dYdgT7/utmWoHtjfrK7JTJq9G/VWWlHnTnQGzHHyma03Loy2AozToXoArQuAQ==} @@ -1747,34 +1587,20 @@ packages: resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==} engines: {node: '>=12.0.0'} + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + std-env@4.1.0: + resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==} + string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-ansi@7.2.0: - resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} - engines: {node: '>=12'} - - strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} - - strip-bom@4.0.0: - resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} - engines: {node: '>=8'} - - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -1787,9 +1613,12 @@ packages: resolution: {integrity: sha512-56adEpPMouktRlBLXiaYFFzZ/3+JXa8P9n7WbR+ibIjtviN55mEaOkiysCnPnWm+7kkui1Dn8J9l+g6zV8731w==} engines: {node: '>=18'} - test-exclude@8.0.0: - resolution: {integrity: sha512-ZOffsNrXYggvU1mDGHk54I96r26P8SyMjO5slMKSc7+IWmtB/MQKnEC2fP51imB3/pT6YK5cT5E8f+Dd9KdyOQ==} - engines: {node: 20 || >=22} + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@1.2.4: + resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==} + engines: {node: '>=18'} tinyglobby@0.2.17: resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} @@ -1798,6 +1627,14 @@ packages: tinyqueue@2.0.3: resolution: {integrity: sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==} + tinyrainbow@3.1.0: + resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} + engines: {node: '>=14.0.0'} + + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true @@ -1808,24 +1645,6 @@ packages: peerDependencies: typescript: '>=4.8.4' - ts-node@10.9.2: - resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} - hasBin: true - peerDependencies: - '@swc/core': '>=1.2.50' - '@swc/wasm': '>=1.2.50' - '@types/node': '*' - typescript: '>=2.7' - peerDependenciesMeta: - '@swc/core': - optional: true - '@swc/wasm': - optional: true - - tsconfig-paths@4.2.0: - resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} - engines: {node: '>=6'} - tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -1833,21 +1652,6 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - type-detect@4.0.8: - resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} - engines: {node: '>=4'} - - type-detect@4.1.0: - resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} - engines: {node: '>=4'} - - type-fest@0.8.1: - resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} - engines: {node: '>=8'} - - typedarray-to-buffer@3.1.5: - resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} - typescript-eslint@8.61.0: resolution: {integrity: sha512-8y31Rd0eGTrDKqhy6vT0HtzhN+YLjQizwX3aA3hPXP/ynSfnrBXcQY5IzsP9/DM7+klX4IUncZZjkchP0z+rUw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1866,12 +1670,6 @@ packages: unrs-resolver@1.12.2: resolution: {integrity: sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==} - update-browserslist-db@1.2.3: - resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} @@ -1879,220 +1677,195 @@ packages: resolution: {integrity: sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==} hasBin: true - v8-compile-cache-lib@3.0.1: - resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + vite@8.0.16: + resolution: {integrity: sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.1.18 + esbuild: ^0.27.0 || ^0.28.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + '@vitejs/devtools': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitest@4.1.9: + resolution: {integrity: sha512-nE3/LEyc0z87uHYLZebqCUOaJr2hdtuPp7BQ4BosVFnfltxgAvMG08NyrSGlPpOUWvR27c5flSmYFTNr78L9GQ==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@opentelemetry/api': ^1.9.0 + '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 4.1.9 + '@vitest/browser-preview': 4.1.9 + '@vitest/browser-webdriverio': 4.1.9 + '@vitest/coverage-istanbul': 4.1.9 + '@vitest/coverage-v8': 4.1.9 + '@vitest/ui': 4.1.9 + happy-dom: '*' + jsdom: '*' + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@opentelemetry/api': + optional: true + '@types/node': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/coverage-istanbul': + optional: true + '@vitest/coverage-v8': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true vscode-jsonrpc@8.2.0: resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==} engines: {node: '>=14.0.0'} - which-module@2.0.1: - resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + whatwg-mimetype@3.0.0: + resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} + engines: {node: '>=12'} which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} hasBin: true + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + word-wrap@1.2.5: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} - workerpool@9.3.4: - resolution: {integrity: sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg==} - - wrap-ansi@6.2.0: - resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} - engines: {node: '>=8'} - wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - - write-file-atomic@3.0.3: - resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} - - y18n@4.0.3: - resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + ws@8.21.0: + resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} - yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yallist@5.0.0: resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} engines: {node: '>=18'} - yargs-parser@18.1.3: - resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} - engines: {node: '>=6'} - yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} - yargs-unparser@2.0.0: - resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} - engines: {node: '>=10'} - - yargs@15.4.1: - resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} - engines: {node: '>=8'} - yargs@17.7.2: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} - yn@3.1.1: - resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} - engines: {node: '>=6'} - yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} snapshots: - '@babel/code-frame@7.29.7': - dependencies: - '@babel/helper-validator-identifier': 7.29.7 - js-tokens: 4.0.0 - picocolors: 1.1.1 - - '@babel/compat-data@7.29.7': {} - - '@babel/core@7.29.7': - dependencies: - '@babel/code-frame': 7.29.7 - '@babel/generator': 7.29.7 - '@babel/helper-compilation-targets': 7.29.7 - '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) - '@babel/helpers': 7.29.7 - '@babel/parser': 7.29.7 - '@babel/template': 7.29.7 - '@babel/traverse': 7.29.7 - '@babel/types': 7.29.7 - '@jridgewell/remapping': 2.3.5 - convert-source-map: 2.0.0 - debug: 4.4.3(supports-color@8.1.1) - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - '@babel/generator@7.29.7': - dependencies: - '@babel/parser': 7.29.7 - '@babel/types': 7.29.7 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - jsesc: 3.1.0 - - '@babel/helper-compilation-targets@7.29.7': - dependencies: - '@babel/compat-data': 7.29.7 - '@babel/helper-validator-option': 7.29.7 - browserslist: 4.28.2 - lru-cache: 5.1.1 - semver: 6.3.1 - - '@babel/helper-globals@7.29.7': {} - - '@babel/helper-module-imports@7.29.7': - dependencies: - '@babel/traverse': 7.29.7 - '@babel/types': 7.29.7 - transitivePeerDependencies: - - supports-color - - '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7)': - dependencies: - '@babel/core': 7.29.7 - '@babel/helper-module-imports': 7.29.7 - '@babel/helper-validator-identifier': 7.29.7 - '@babel/traverse': 7.29.7 - transitivePeerDependencies: - - supports-color - '@babel/helper-string-parser@7.29.7': {} '@babel/helper-validator-identifier@7.29.7': {} - '@babel/helper-validator-option@7.29.7': {} - - '@babel/helpers@7.29.7': - dependencies: - '@babel/template': 7.29.7 - '@babel/types': 7.29.7 - '@babel/parser@7.29.7': dependencies: '@babel/types': 7.29.7 - '@babel/template@7.29.7': - dependencies: - '@babel/code-frame': 7.29.7 - '@babel/parser': 7.29.7 - '@babel/types': 7.29.7 - - '@babel/traverse@7.29.7': - dependencies: - '@babel/code-frame': 7.29.7 - '@babel/generator': 7.29.7 - '@babel/helper-globals': 7.29.7 - '@babel/parser': 7.29.7 - '@babel/template': 7.29.7 - '@babel/types': 7.29.7 - debug: 4.4.3(supports-color@8.1.1) - transitivePeerDependencies: - - supports-color - '@babel/types@7.29.7': dependencies: '@babel/helper-string-parser': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 - '@cspotcode/source-map-support@0.8.1': - dependencies: - '@jridgewell/trace-mapping': 0.3.9 + '@bcoe/v8-coverage@1.0.2': {} - '@eclipse-glsp/cli@2.8.0-next.9': {} + '@blazediff/core@1.9.1': + optional: true + + '@eclipse-glsp/cli@2.8.0-next.16': {} - '@eclipse-glsp/config-test@2.8.0-next.9(@types/node@22.19.15)(typescript@5.9.2)': + '@eclipse-glsp/config-test@2.8.0-next.16(@types/node@22.19.15)(@vitest/browser-playwright@4.1.9)(@vitest/browser@4.1.9)(happy-dom@20.10.5)(vite@8.0.16(@types/node@22.19.15)(esbuild@0.28.1))': dependencies: - '@eclipse-glsp/mocha-config': 2.8.0-next.9(ignore-styles@5.0.1)(mocha@11.7.6)(reflect-metadata@0.2.2) - '@eclipse-glsp/nyc-config': 2.8.0-next.9(@istanbuljs/nyc-config-typescript@1.0.2(nyc@18.0.0))(nyc@18.0.0) - '@istanbuljs/nyc-config-typescript': 1.0.2(nyc@18.0.0) - '@types/chai': 4.3.20 - '@types/mocha': 10.0.10 - '@types/sinon': 21.0.1 - chai: 4.5.0 - ignore-styles: 5.0.1 - mocha: 11.7.6 - nyc: 18.0.0 - reflect-metadata: 0.2.2 - sinon: 22.0.0 - ts-node: 10.9.2(@types/node@22.19.15)(typescript@5.9.2) + '@eclipse-glsp/vitest-config': 2.8.0-next.16(@vitest/coverage-v8@4.1.9)(vitest@4.1.9) + '@vitest/coverage-v8': 4.1.9(@vitest/browser@4.1.9)(vitest@4.1.9) + vitest: 4.1.9(@types/node@22.19.15)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(happy-dom@20.10.5)(vite@8.0.16(@types/node@22.19.15)(esbuild@0.28.1)) transitivePeerDependencies: - - '@swc/core' - - '@swc/wasm' + - '@edge-runtime/vm' + - '@opentelemetry/api' - '@types/node' - - supports-color - - typescript - - '@eclipse-glsp/config@2.8.0-next.9(@typescript-eslint/utils@8.61.0(eslint@10.5.0)(typescript@5.9.2))(typescript@5.9.2)': - dependencies: - '@eclipse-glsp/eslint-config': 2.8.0-next.9(@eslint/js@10.0.1(eslint@10.5.0))(@stylistic/eslint-plugin@5.10.0(eslint@10.5.0))(@tony.ganchev/eslint-plugin-header@3.4.4(eslint@10.5.0))(eslint-config-prettier@10.1.8(eslint@10.5.0))(eslint-import-resolver-typescript@4.4.5(eslint-plugin-import-x@4.16.2(@typescript-eslint/utils@8.61.0(eslint@10.5.0)(typescript@5.9.2))(eslint@10.5.0))(eslint@10.5.0))(eslint-plugin-chai-friendly@1.2.0(eslint@10.5.0))(eslint-plugin-import-x@4.16.2(@typescript-eslint/utils@8.61.0(eslint@10.5.0)(typescript@5.9.2))(eslint@10.5.0))(eslint-plugin-no-null@1.0.2(eslint@10.5.0))(eslint@10.5.0)(globals@17.6.0)(typescript-eslint@8.61.0(eslint@10.5.0)(typescript@5.9.2)) - '@eclipse-glsp/prettier-config': 2.8.0-next.9(prettier@3.8.4) - '@eclipse-glsp/ts-config': 2.8.0-next.9(typescript@5.9.2) + - '@vitest/browser' + - '@vitest/browser-playwright' + - '@vitest/browser-preview' + - '@vitest/browser-webdriverio' + - '@vitest/coverage-istanbul' + - '@vitest/ui' + - happy-dom + - jsdom + - msw + - vite + + '@eclipse-glsp/config@2.8.0-next.16(@typescript-eslint/utils@8.61.0(eslint@10.5.0)(typescript@5.9.2))(typescript@5.9.2)': + dependencies: + '@eclipse-glsp/eslint-config': 2.8.0-next.16(@eslint/js@10.0.1(eslint@10.5.0))(@stylistic/eslint-plugin@5.10.0(eslint@10.5.0))(@tony.ganchev/eslint-plugin-header@3.4.4(eslint@10.5.0))(eslint-config-prettier@10.1.8(eslint@10.5.0))(eslint-import-resolver-typescript@4.4.5(eslint-plugin-import-x@4.16.2(@typescript-eslint/utils@8.61.0(eslint@10.5.0)(typescript@5.9.2))(eslint@10.5.0))(eslint@10.5.0))(eslint-plugin-chai-friendly@1.2.0(eslint@10.5.0))(eslint-plugin-import-x@4.16.2(@typescript-eslint/utils@8.61.0(eslint@10.5.0)(typescript@5.9.2))(eslint@10.5.0))(eslint-plugin-no-null@1.0.2(eslint@10.5.0))(eslint@10.5.0)(globals@17.6.0)(typescript-eslint@8.61.0(eslint@10.5.0)(typescript@5.9.2)) + '@eclipse-glsp/prettier-config': 2.8.0-next.16(prettier@3.8.4) + '@eclipse-glsp/ts-config': 2.8.0-next.16(typescript@5.9.2) '@eslint/js': 10.0.1(eslint@10.5.0) '@stylistic/eslint-plugin': 5.10.0(eslint@10.5.0) '@tony.ganchev/eslint-plugin-header': 3.4.4(eslint@10.5.0) @@ -2104,7 +1877,6 @@ snapshots: eslint-plugin-no-null: 1.0.2(eslint@10.5.0) globals: 17.6.0 prettier: 3.8.4 - reflect-metadata: 0.2.2 rimraf: 6.1.3 typescript-eslint: 8.61.0(eslint@10.5.0)(typescript@5.9.2) transitivePeerDependencies: @@ -2115,23 +1887,33 @@ snapshots: - supports-color - typescript - '@eclipse-glsp/dev@2.8.0-next.9(@types/node@22.19.15)(@typescript-eslint/utils@8.61.0(eslint@10.5.0)(typescript@5.9.2))(typescript@5.9.2)': + '@eclipse-glsp/dev@2.8.0-next.16(@types/node@22.19.15)(@typescript-eslint/utils@8.61.0(eslint@10.5.0)(typescript@5.9.2))(@vitest/browser-playwright@4.1.9)(@vitest/browser@4.1.9)(happy-dom@20.10.5)(typescript@5.9.2)(vite@8.0.16(@types/node@22.19.15)(esbuild@0.28.1))': dependencies: - '@eclipse-glsp/cli': 2.8.0-next.9 - '@eclipse-glsp/config': 2.8.0-next.9(@typescript-eslint/utils@8.61.0(eslint@10.5.0)(typescript@5.9.2))(typescript@5.9.2) - '@eclipse-glsp/config-test': 2.8.0-next.9(@types/node@22.19.15)(typescript@5.9.2) + '@eclipse-glsp/cli': 2.8.0-next.16 + '@eclipse-glsp/config': 2.8.0-next.16(@typescript-eslint/utils@8.61.0(eslint@10.5.0)(typescript@5.9.2))(typescript@5.9.2) + '@eclipse-glsp/config-test': 2.8.0-next.16(@types/node@22.19.15)(@vitest/browser-playwright@4.1.9)(@vitest/browser@4.1.9)(happy-dom@20.10.5)(vite@8.0.16(@types/node@22.19.15)(esbuild@0.28.1)) transitivePeerDependencies: - - '@swc/core' - - '@swc/wasm' + - '@edge-runtime/vm' + - '@opentelemetry/api' - '@types/node' - '@typescript-eslint/utils' + - '@vitest/browser' + - '@vitest/browser-playwright' + - '@vitest/browser-preview' + - '@vitest/browser-webdriverio' + - '@vitest/coverage-istanbul' + - '@vitest/ui' - eslint-import-resolver-node - eslint-plugin-import + - happy-dom - jiti + - jsdom + - msw - supports-color - typescript + - vite - '@eclipse-glsp/eslint-config@2.8.0-next.9(@eslint/js@10.0.1(eslint@10.5.0))(@stylistic/eslint-plugin@5.10.0(eslint@10.5.0))(@tony.ganchev/eslint-plugin-header@3.4.4(eslint@10.5.0))(eslint-config-prettier@10.1.8(eslint@10.5.0))(eslint-import-resolver-typescript@4.4.5(eslint-plugin-import-x@4.16.2(@typescript-eslint/utils@8.61.0(eslint@10.5.0)(typescript@5.9.2))(eslint@10.5.0))(eslint@10.5.0))(eslint-plugin-chai-friendly@1.2.0(eslint@10.5.0))(eslint-plugin-import-x@4.16.2(@typescript-eslint/utils@8.61.0(eslint@10.5.0)(typescript@5.9.2))(eslint@10.5.0))(eslint-plugin-no-null@1.0.2(eslint@10.5.0))(eslint@10.5.0)(globals@17.6.0)(typescript-eslint@8.61.0(eslint@10.5.0)(typescript@5.9.2))': + '@eclipse-glsp/eslint-config@2.8.0-next.16(@eslint/js@10.0.1(eslint@10.5.0))(@stylistic/eslint-plugin@5.10.0(eslint@10.5.0))(@tony.ganchev/eslint-plugin-header@3.4.4(eslint@10.5.0))(eslint-config-prettier@10.1.8(eslint@10.5.0))(eslint-import-resolver-typescript@4.4.5(eslint-plugin-import-x@4.16.2(@typescript-eslint/utils@8.61.0(eslint@10.5.0)(typescript@5.9.2))(eslint@10.5.0))(eslint@10.5.0))(eslint-plugin-chai-friendly@1.2.0(eslint@10.5.0))(eslint-plugin-import-x@4.16.2(@typescript-eslint/utils@8.61.0(eslint@10.5.0)(typescript@5.9.2))(eslint@10.5.0))(eslint-plugin-no-null@1.0.2(eslint@10.5.0))(eslint@10.5.0)(globals@17.6.0)(typescript-eslint@8.61.0(eslint@10.5.0)(typescript@5.9.2))': dependencies: '@eslint/js': 10.0.1(eslint@10.5.0) '@stylistic/eslint-plugin': 5.10.0(eslint@10.5.0) @@ -2145,27 +1927,21 @@ snapshots: globals: 17.6.0 typescript-eslint: 8.61.0(eslint@10.5.0)(typescript@5.9.2) - '@eclipse-glsp/mocha-config@2.8.0-next.9(ignore-styles@5.0.1)(mocha@11.7.6)(reflect-metadata@0.2.2)': - dependencies: - ignore-styles: 5.0.1 - mocha: 11.7.6 - reflect-metadata: 0.2.2 - - '@eclipse-glsp/nyc-config@2.8.0-next.9(@istanbuljs/nyc-config-typescript@1.0.2(nyc@18.0.0))(nyc@18.0.0)': - dependencies: - '@istanbuljs/nyc-config-typescript': 1.0.2(nyc@18.0.0) - nyc: 18.0.0 - - '@eclipse-glsp/prettier-config@2.8.0-next.9(prettier@3.8.4)': + '@eclipse-glsp/prettier-config@2.8.0-next.16(prettier@3.8.4)': dependencies: prettier-plugin-packagejson: 3.0.2(prettier@3.8.4) transitivePeerDependencies: - prettier - '@eclipse-glsp/ts-config@2.8.0-next.9(typescript@5.9.2)': + '@eclipse-glsp/ts-config@2.8.0-next.16(typescript@5.9.2)': dependencies: typescript: 5.9.2 + '@eclipse-glsp/vitest-config@2.8.0-next.16(@vitest/coverage-v8@4.1.9)(vitest@4.1.9)': + dependencies: + '@vitest/coverage-v8': 4.1.9(@vitest/browser@4.1.9)(vitest@4.1.9) + vitest: 4.1.9(@types/node@22.19.15)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(happy-dom@20.10.5)(vite@8.0.16(@types/node@22.19.15)(esbuild@0.28.1)) + '@emnapi/core@1.10.0': dependencies: '@emnapi/wasi-threads': 1.2.1 @@ -2270,7 +2046,7 @@ snapshots: '@eslint/config-array@0.23.5': dependencies: '@eslint/object-schema': 3.0.5 - debug: 4.4.3(supports-color@8.1.1) + debug: 4.4.3 minimatch: 10.2.5 transitivePeerDependencies: - supports-color @@ -2323,44 +2099,10 @@ snapshots: dependencies: reflect-metadata: 0.2.2 - '@isaacs/cliui@8.0.2': - dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.2.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 - '@isaacs/fs-minipass@4.0.1': dependencies: minipass: 7.1.2 - '@istanbuljs/load-nyc-config@1.1.0': - dependencies: - camelcase: 5.3.1 - find-up: 4.1.0 - get-package-type: 0.1.0 - js-yaml: 4.2.0 - resolve-from: 5.0.0 - - '@istanbuljs/nyc-config-typescript@1.0.2(nyc@18.0.0)': - dependencies: - '@istanbuljs/schema': 0.1.6 - nyc: 18.0.0 - - '@istanbuljs/schema@0.1.6': {} - - '@jridgewell/gen-mapping@0.3.13': - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.31 - - '@jridgewell/remapping@2.3.5': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - '@jridgewell/resolve-uri@3.1.2': {} '@jridgewell/sourcemap-codec@1.5.5': {} @@ -2370,11 +2112,6 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping@0.3.9': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 - '@napi-rs/wasm-runtime@1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': dependencies: '@emnapi/core': 1.10.0 @@ -2382,23 +2119,65 @@ snapshots: '@tybys/wasm-util': 0.10.2 optional: true + '@oxc-project/types@0.133.0': {} + '@package-json/types@0.0.12': {} - '@pkgjs/parseargs@0.11.0': + '@polka/url@1.0.0-next.29': optional: true - '@sinonjs/commons@3.0.1': - dependencies: - type-detect: 4.0.8 + '@rolldown/binding-android-arm64@1.0.3': + optional: true - '@sinonjs/fake-timers@15.4.0': - dependencies: - '@sinonjs/commons': 3.0.1 + '@rolldown/binding-darwin-arm64@1.0.3': + optional: true + + '@rolldown/binding-darwin-x64@1.0.3': + optional: true + + '@rolldown/binding-freebsd-x64@1.0.3': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.0.3': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.0.3': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.0.3': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.0.3': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.0.3': + optional: true - '@sinonjs/samsam@10.0.2': + '@rolldown/binding-linux-x64-gnu@1.0.3': + optional: true + + '@rolldown/binding-linux-x64-musl@1.0.3': + optional: true + + '@rolldown/binding-openharmony-arm64@1.0.3': + optional: true + + '@rolldown/binding-wasm32-wasi@1.0.3': dependencies: - '@sinonjs/commons': 3.0.1 - type-detect: 4.1.0 + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.0.3': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.0.3': + optional: true + + '@rolldown/pluginutils@1.0.1': {} + + '@standard-schema/spec@1.1.0': {} '@stylistic/eslint-plugin@5.10.0(eslint@10.5.0)': dependencies: @@ -2414,20 +2193,17 @@ snapshots: dependencies: eslint: 10.5.0 - '@tsconfig/node10@1.0.12': {} - - '@tsconfig/node12@1.0.11': {} - - '@tsconfig/node14@1.0.3': {} - - '@tsconfig/node16@1.0.4': {} - '@tybys/wasm-util@0.10.2': dependencies: tslib: 2.8.1 optional: true - '@types/chai@4.3.20': {} + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + + '@types/deep-eql@4.0.2': {} '@types/esrecurse@4.3.1': {} @@ -2443,18 +2219,10 @@ snapshots: '@types/json-schema@7.0.15': {} - '@types/mocha@10.0.10': {} - '@types/node@22.19.15': dependencies: undici-types: 6.21.0 - '@types/sinon@21.0.1': - dependencies: - '@types/sinonjs__fake-timers': 15.0.1 - - '@types/sinonjs__fake-timers@15.0.1': {} - '@types/tar@6.1.5': dependencies: '@types/node': 22.19.15 @@ -2462,6 +2230,14 @@ snapshots: '@types/tough-cookie@4.0.5': {} + '@types/whatwg-mimetype@3.0.2': + optional: true + + '@types/ws@8.18.1': + dependencies: + '@types/node': 22.19.15 + optional: true + '@typescript-eslint/eslint-plugin@8.61.0(@typescript-eslint/parser@8.61.0(eslint@10.5.0)(typescript@5.9.2))(eslint@10.5.0)(typescript@5.9.2)': dependencies: '@eslint-community/regexpp': 4.12.2 @@ -2484,7 +2260,7 @@ snapshots: '@typescript-eslint/types': 8.61.0 '@typescript-eslint/typescript-estree': 8.61.0(typescript@5.9.2) '@typescript-eslint/visitor-keys': 8.61.0 - debug: 4.4.3(supports-color@8.1.1) + debug: 4.4.3 eslint: 10.5.0 typescript: 5.9.2 transitivePeerDependencies: @@ -2494,7 +2270,7 @@ snapshots: dependencies: '@typescript-eslint/tsconfig-utils': 8.61.0(typescript@5.9.2) '@typescript-eslint/types': 8.61.0 - debug: 4.4.3(supports-color@8.1.1) + debug: 4.4.3 typescript: 5.9.2 transitivePeerDependencies: - supports-color @@ -2513,7 +2289,7 @@ snapshots: '@typescript-eslint/types': 8.61.0 '@typescript-eslint/typescript-estree': 8.61.0(typescript@5.9.2) '@typescript-eslint/utils': 8.61.0(eslint@10.5.0)(typescript@5.9.2) - debug: 4.4.3(supports-color@8.1.1) + debug: 4.4.3 eslint: 10.5.0 ts-api-utils: 2.5.0(typescript@5.9.2) typescript: 5.9.2 @@ -2528,7 +2304,7 @@ snapshots: '@typescript-eslint/tsconfig-utils': 8.61.0(typescript@5.9.2) '@typescript-eslint/types': 8.61.0 '@typescript-eslint/visitor-keys': 8.61.0 - debug: 4.4.3(supports-color@8.1.1) + debug: 4.4.3 minimatch: 10.2.5 semver: 7.8.4 tinyglobby: 0.2.17 @@ -2623,22 +2399,102 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.12.2': optional: true - '@vscode/codicons@0.0.44': {} + '@vitest/browser-playwright@4.1.9(playwright@1.61.0)(vite@8.0.16(@types/node@22.19.15)(esbuild@0.28.1))(vitest@4.1.9)': + dependencies: + '@vitest/browser': 4.1.9(vite@8.0.16(@types/node@22.19.15)(esbuild@0.28.1))(vitest@4.1.9) + '@vitest/mocker': 4.1.9(vite@8.0.16(@types/node@22.19.15)(esbuild@0.28.1)) + playwright: 1.61.0 + tinyrainbow: 3.1.0 + vitest: 4.1.9(@types/node@22.19.15)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(happy-dom@20.10.5)(vite@8.0.16(@types/node@22.19.15)(esbuild@0.28.1)) + transitivePeerDependencies: + - bufferutil + - msw + - utf-8-validate + - vite + optional: true - acorn-jsx@5.3.2(acorn@8.17.0): + '@vitest/browser@4.1.9(vite@8.0.16(@types/node@22.19.15)(esbuild@0.28.1))(vitest@4.1.9)': + dependencies: + '@blazediff/core': 1.9.1 + '@vitest/mocker': 4.1.9(vite@8.0.16(@types/node@22.19.15)(esbuild@0.28.1)) + '@vitest/utils': 4.1.9 + magic-string: 0.30.21 + pngjs: 7.0.0 + sirv: 3.0.2 + tinyrainbow: 3.1.0 + vitest: 4.1.9(@types/node@22.19.15)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(happy-dom@20.10.5)(vite@8.0.16(@types/node@22.19.15)(esbuild@0.28.1)) + ws: 8.21.0 + transitivePeerDependencies: + - bufferutil + - msw + - utf-8-validate + - vite + optional: true + + '@vitest/coverage-v8@4.1.9(@vitest/browser@4.1.9)(vitest@4.1.9)': dependencies: - acorn: 8.17.0 + '@bcoe/v8-coverage': 1.0.2 + '@vitest/utils': 4.1.9 + ast-v8-to-istanbul: 1.0.4 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-reports: 3.2.0 + magicast: 0.5.3 + obug: 2.1.3 + std-env: 4.1.0 + tinyrainbow: 3.1.0 + vitest: 4.1.9(@types/node@22.19.15)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(happy-dom@20.10.5)(vite@8.0.16(@types/node@22.19.15)(esbuild@0.28.1)) + optionalDependencies: + '@vitest/browser': 4.1.9(vite@8.0.16(@types/node@22.19.15)(esbuild@0.28.1))(vitest@4.1.9) - acorn-walk@8.3.5: + '@vitest/expect@4.1.9': dependencies: - acorn: 8.17.0 + '@standard-schema/spec': 1.1.0 + '@types/chai': 5.2.3 + '@vitest/spy': 4.1.9 + '@vitest/utils': 4.1.9 + chai: 6.2.2 + tinyrainbow: 3.1.0 - acorn@8.17.0: {} + '@vitest/mocker@4.1.9(vite@8.0.16(@types/node@22.19.15)(esbuild@0.28.1))': + dependencies: + '@vitest/spy': 4.1.9 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 8.0.16(@types/node@22.19.15)(esbuild@0.28.1) - aggregate-error@3.1.0: + '@vitest/pretty-format@4.1.9': dependencies: - clean-stack: 2.2.0 - indent-string: 4.0.0 + tinyrainbow: 3.1.0 + + '@vitest/runner@4.1.9': + dependencies: + '@vitest/utils': 4.1.9 + pathe: 2.0.3 + + '@vitest/snapshot@4.1.9': + dependencies: + '@vitest/pretty-format': 4.1.9 + '@vitest/utils': 4.1.9 + magic-string: 0.30.21 + pathe: 2.0.3 + + '@vitest/spy@4.1.9': {} + + '@vitest/utils@4.1.9': + dependencies: + '@vitest/pretty-format': 4.1.9 + convert-source-map: 2.0.0 + tinyrainbow: 3.1.0 + + '@vscode/codicons@0.0.44': {} + + acorn-jsx@5.3.2(acorn@8.17.0): + dependencies: + acorn: 8.17.0 + + acorn@8.17.0: {} ajv@6.15.0: dependencies: @@ -2649,104 +2505,44 @@ snapshots: ansi-regex@5.0.1: {} - ansi-regex@6.2.2: {} - ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 - ansi-styles@6.2.3: {} + assertion-error@2.0.1: {} - append-transform@2.0.0: + ast-v8-to-istanbul@1.0.4: dependencies: - default-require-extensions: 3.0.1 - - archy@1.0.0: {} - - arg@4.1.3: {} - - argparse@2.0.1: {} - - assertion-error@1.1.0: {} + '@jridgewell/trace-mapping': 0.3.31 + estree-walker: 3.0.3 + js-tokens: 10.0.0 autocompleter@9.2.1: {} - balanced-match@1.0.2: {} - balanced-match@4.0.4: {} balloon-css@0.5.2: {} - baseline-browser-mapping@2.10.37: {} - - brace-expansion@2.1.1: - dependencies: - balanced-match: 1.0.2 - brace-expansion@5.0.6: dependencies: balanced-match: 4.0.4 browser-split@0.0.1: {} - browser-stdout@1.3.1: {} - - browserslist@4.28.2: + buffer-image-size@0.6.4: dependencies: - baseline-browser-mapping: 2.10.37 - caniuse-lite: 1.0.30001799 - electron-to-chromium: 1.5.372 - node-releases: 2.0.47 - update-browserslist-db: 1.2.3(browserslist@4.28.2) - - caching-transform@4.0.0: - dependencies: - hasha: 5.2.2 - make-dir: 3.1.0 - package-hash: 4.0.0 - write-file-atomic: 3.0.3 - - camelcase@5.3.1: {} - - camelcase@6.3.0: {} - - caniuse-lite@1.0.30001799: {} + '@types/node': 22.19.15 + optional: true - chai@4.5.0: - dependencies: - assertion-error: 1.1.0 - check-error: 1.0.3 - deep-eql: 4.1.4 - get-func-name: 2.0.2 - loupe: 2.3.7 - pathval: 1.1.1 - type-detect: 4.1.0 + chai@6.2.2: {} chalk@4.1.2: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 - charenc@0.0.2: {} - - check-error@1.0.3: - dependencies: - get-func-name: 2.0.2 - - chokidar@4.0.3: - dependencies: - readdirp: 4.1.2 - chownr@3.0.0: {} - clean-stack@2.2.0: {} - - cliui@6.0.0: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 6.2.0 - cliui@8.0.1: dependencies: string-width: 4.2.3 @@ -2761,8 +2557,6 @@ snapshots: comment-parser@1.4.7: {} - commondir@1.0.1: {} - concurrently@9.2.1: dependencies: chalk: 4.1.2 @@ -2772,57 +2566,34 @@ snapshots: tree-kill: 1.2.2 yargs: 17.7.2 - convert-source-map@1.9.0: {} - convert-source-map@2.0.0: {} - create-require@1.1.1: {} - cross-spawn@7.0.6: dependencies: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 - crypt@0.0.2: {} - - debug@4.4.3(supports-color@8.1.1): + debug@4.4.3: dependencies: ms: 2.1.3 - optionalDependencies: - supports-color: 8.1.1 - - decamelize@1.2.0: {} - - decamelize@4.0.0: {} - - deep-eql@4.1.4: - dependencies: - type-detect: 4.1.0 deep-is@0.1.4: {} - default-require-extensions@3.0.1: - dependencies: - strip-bom: 4.0.0 - detect-indent@7.0.2: {} - detect-newline@4.0.1: {} - - diff@9.0.0: {} + detect-libc@2.1.2: {} - eastasianwidth@0.2.0: {} - - electron-to-chromium@1.5.372: {} + detect-newline@4.0.1: {} emoji-regex@8.0.0: {} - emoji-regex@9.2.2: {} - entities@4.5.0: {} - es6-error@4.1.1: {} + entities@7.0.1: + optional: true + + es-module-lexer@2.1.0: {} esbuild@0.28.1: optionalDependencies: @@ -2870,7 +2641,7 @@ snapshots: eslint-import-resolver-typescript@4.4.5(eslint-plugin-import-x@4.16.2(@typescript-eslint/utils@8.61.0(eslint@10.5.0)(typescript@5.9.2))(eslint@10.5.0))(eslint@10.5.0): dependencies: - debug: 4.4.3(supports-color@8.1.1) + debug: 4.4.3 eslint: 10.5.0 eslint-import-context: 0.1.9(unrs-resolver@1.12.2) get-tsconfig: 4.14.0 @@ -2892,7 +2663,7 @@ snapshots: '@package-json/types': 0.0.12 '@typescript-eslint/types': 8.61.0 comment-parser: 1.4.7 - debug: 4.4.3(supports-color@8.1.1) + debug: 4.4.3 eslint: 10.5.0 eslint-import-context: 0.1.9(unrs-resolver@1.12.2) is-glob: 4.0.3 @@ -2936,7 +2707,7 @@ snapshots: '@types/estree': 1.0.9 ajv: 6.15.0 cross-spawn: 7.0.6 - debug: 4.4.3(supports-color@8.1.1) + debug: 4.4.3 escape-string-regexp: 4.0.0 eslint-scope: 9.1.2 eslint-visitor-keys: 5.0.1 @@ -2979,8 +2750,14 @@ snapshots: estraverse@5.3.0: {} + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.9 + esutils@2.0.3: {} + expect-type@1.3.0: {} + fast-deep-equal@3.1.3: {} fast-json-stable-stringify@2.1.0: {} @@ -2997,17 +2774,6 @@ snapshots: file-saver@2.0.5: {} - find-cache-dir@3.3.2: - dependencies: - commondir: 1.0.1 - make-dir: 3.1.0 - pkg-dir: 4.2.0 - - find-up@4.1.0: - dependencies: - locate-path: 5.0.0 - path-exists: 4.0.0 - find-up@5.0.0: dependencies: locate-path: 6.0.0 @@ -3018,30 +2784,16 @@ snapshots: flatted: 3.4.2 keyv: 4.5.4 - flat@5.0.2: {} - flatted@3.4.2: {} - foreground-child@2.0.0: - dependencies: - cross-spawn: 7.0.6 - signal-exit: 3.0.7 - - foreground-child@3.3.1: - dependencies: - cross-spawn: 7.0.6 - signal-exit: 4.1.0 - - fromentries@1.3.2: {} + fsevents@2.3.2: + optional: true - gensync@1.0.0-beta.2: {} + fsevents@2.3.3: + optional: true get-caller-file@2.0.5: {} - get-func-name@2.0.2: {} - - get-package-type@0.1.0: {} - get-tsconfig@4.14.0: dependencies: resolve-pkg-maps: 1.0.0 @@ -3052,15 +2804,6 @@ snapshots: dependencies: is-glob: 4.0.3 - glob@10.5.0: - dependencies: - foreground-child: 3.3.1 - jackspeak: 3.4.3 - minimatch: 9.0.9 - minipass: 7.1.3 - package-json-from-dist: 1.0.1 - path-scurry: 1.11.1 - glob@13.0.6: dependencies: minimatch: 10.2.5 @@ -3069,37 +2812,36 @@ snapshots: globals@17.6.0: {} - graceful-fs@4.2.11: {} - - has-flag@4.0.0: {} - - hasha@5.2.2: + happy-dom@20.10.5: dependencies: - is-stream: 2.0.1 - type-fest: 0.8.1 + '@types/node': 22.19.15 + '@types/whatwg-mimetype': 3.0.2 + '@types/ws': 8.18.1 + buffer-image-size: 0.6.4 + entities: 7.0.1 + whatwg-mimetype: 3.0.0 + ws: 8.21.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + optional: true - he@1.2.0: {} + has-flag@4.0.0: {} html-escaper@2.0.2: {} - ignore-styles@5.0.1: {} - ignore@5.3.2: {} ignore@7.0.5: {} imurmurhash@0.1.4: {} - indent-string@4.0.0: {} - inversify@6.2.0(reflect-metadata@0.2.2): dependencies: '@inversifyjs/common': 1.4.0 '@inversifyjs/core': 1.3.5(reflect-metadata@0.2.2) reflect-metadata: 0.2.2 - is-buffer@1.1.6: {} - is-bun-module@2.0.0: dependencies: semver: 7.8.4 @@ -3112,78 +2854,24 @@ snapshots: dependencies: is-extglob: 2.1.1 - is-path-inside@3.0.3: {} - - is-plain-obj@2.1.0: {} - is-plain-obj@4.1.0: {} - is-stream@2.0.1: {} - - is-typedarray@1.0.0: {} - - is-unicode-supported@0.1.0: {} - - is-windows@1.0.2: {} - isexe@2.0.0: {} istanbul-lib-coverage@3.2.2: {} - istanbul-lib-hook@3.0.0: - dependencies: - append-transform: 2.0.0 - - istanbul-lib-instrument@6.0.3: - dependencies: - '@babel/core': 7.29.7 - '@babel/parser': 7.29.7 - '@istanbuljs/schema': 0.1.6 - istanbul-lib-coverage: 3.2.2 - semver: 7.8.4 - transitivePeerDependencies: - - supports-color - - istanbul-lib-processinfo@3.0.1: - dependencies: - archy: 1.0.0 - cross-spawn: 7.0.6 - istanbul-lib-coverage: 3.2.2 - p-map: 3.0.0 - rimraf: 6.1.3 - istanbul-lib-report@3.0.1: dependencies: istanbul-lib-coverage: 3.2.2 make-dir: 4.0.0 supports-color: 7.2.0 - istanbul-lib-source-maps@4.0.1: - dependencies: - debug: 4.4.3(supports-color@8.1.1) - istanbul-lib-coverage: 3.2.2 - source-map: 0.6.1 - transitivePeerDependencies: - - supports-color - istanbul-reports@3.2.0: dependencies: html-escaper: 2.0.2 istanbul-lib-report: 3.0.1 - jackspeak@3.4.3: - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - - js-tokens@4.0.0: {} - - js-yaml@4.2.0: - dependencies: - argparse: 2.0.1 - - jsesc@3.1.0: {} + js-tokens@10.0.0: {} json-buffer@3.0.1: {} @@ -3191,8 +2879,6 @@ snapshots: json-stable-stringify-without-jsonify@1.0.1: {} - json5@2.2.3: {} - keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -3202,9 +2888,54 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - locate-path@5.0.0: + lightningcss-android-arm64@1.32.0: + optional: true + + lightningcss-darwin-arm64@1.32.0: + optional: true + + lightningcss-darwin-x64@1.32.0: + optional: true + + lightningcss-freebsd-x64@1.32.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.32.0: + optional: true + + lightningcss-linux-arm64-gnu@1.32.0: + optional: true + + lightningcss-linux-arm64-musl@1.32.0: + optional: true + + lightningcss-linux-x64-gnu@1.32.0: + optional: true + + lightningcss-linux-x64-musl@1.32.0: + optional: true + + lightningcss-win32-arm64-msvc@1.32.0: + optional: true + + lightningcss-win32-x64-msvc@1.32.0: + optional: true + + lightningcss@1.32.0: dependencies: - p-locate: 4.1.0 + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 locate-path@6.0.0: dependencies: @@ -3212,8 +2943,6 @@ snapshots: lodash.escape@4.0.1: {} - lodash.flattendeep@4.4.0: {} - lodash.forown@4.4.0: {} lodash.kebabcase@4.1.1: {} @@ -3222,49 +2951,26 @@ snapshots: lodash.uniq@4.5.0: {} - log-symbols@4.1.0: - dependencies: - chalk: 4.1.2 - is-unicode-supported: 0.1.0 - - loupe@2.3.7: - dependencies: - get-func-name: 2.0.2 - - lru-cache@10.4.3: {} - lru-cache@11.5.1: {} - lru-cache@5.1.1: + magic-string@0.30.21: dependencies: - yallist: 3.1.1 + '@jridgewell/sourcemap-codec': 1.5.5 - make-dir@3.1.0: + magicast@0.5.3: dependencies: - semver: 6.3.1 + '@babel/parser': 7.29.7 + '@babel/types': 7.29.7 + source-map-js: 1.2.1 make-dir@4.0.0: dependencies: semver: 7.8.4 - make-error@1.3.6: {} - - md5@2.3.0: - dependencies: - charenc: 0.0.2 - crypt: 0.0.2 - is-buffer: 1.1.6 - minimatch@10.2.5: dependencies: brace-expansion: 5.0.6 - minimatch@9.0.9: - dependencies: - brace-expansion: 2.1.1 - - minimist@1.2.8: {} - minipass@4.2.8: {} minipass@7.1.2: {} @@ -3275,80 +2981,21 @@ snapshots: dependencies: minipass: 7.1.2 - mocha-ctrf-json-reporter@0.0.9: - dependencies: - md5: 2.3.0 - - mocha@11.7.6: - dependencies: - browser-stdout: 1.3.1 - chokidar: 4.0.3 - debug: 4.4.3(supports-color@8.1.1) - diff: 9.0.0 - escape-string-regexp: 4.0.0 - find-up: 5.0.0 - glob: 10.5.0 - he: 1.2.0 - is-path-inside: 3.0.3 - js-yaml: 4.2.0 - log-symbols: 4.1.0 - minimatch: 9.0.9 - ms: 2.1.3 - picocolors: 1.1.1 - serialize-javascript: 7.0.5 - strip-json-comments: 3.1.1 - supports-color: 8.1.1 - workerpool: 9.3.4 - yargs: 17.7.2 - yargs-parser: 21.1.1 - yargs-unparser: 2.0.0 + mrmime@2.0.1: + optional: true ms@2.1.3: {} + nanoid@3.3.12: {} + napi-postinstall@0.3.4: {} natural-compare@1.4.0: {} - node-preload@0.2.1: - dependencies: - process-on-spawn: 1.1.0 - - node-releases@2.0.47: {} - - nyc@18.0.0: - dependencies: - '@istanbuljs/load-nyc-config': 1.1.0 - '@istanbuljs/schema': 0.1.6 - caching-transform: 4.0.0 - convert-source-map: 1.9.0 - decamelize: 1.2.0 - find-cache-dir: 3.3.2 - find-up: 4.1.0 - foreground-child: 3.3.1 - get-package-type: 0.1.0 - glob: 13.0.6 - istanbul-lib-coverage: 3.2.2 - istanbul-lib-hook: 3.0.0 - istanbul-lib-instrument: 6.0.3 - istanbul-lib-processinfo: 3.0.1 - istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 4.0.1 - istanbul-reports: 3.2.0 - make-dir: 3.1.0 - node-preload: 0.2.1 - p-map: 3.0.0 - process-on-spawn: 1.1.0 - resolve-from: 5.0.0 - rimraf: 6.1.3 - signal-exit: 3.0.7 - spawn-wrap: 3.0.0 - test-exclude: 8.0.0 - yargs: 15.4.1 - transitivePeerDependencies: - - supports-color - object-assign@4.1.1: {} + obug@2.1.3: {} + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -3358,35 +3005,14 @@ snapshots: type-check: 0.4.0 word-wrap: 1.2.5 - p-limit@2.3.0: - dependencies: - p-try: 2.2.0 - p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 - p-locate@4.1.0: - dependencies: - p-limit: 2.3.0 - p-locate@5.0.0: dependencies: p-limit: 3.1.0 - p-map@3.0.0: - dependencies: - aggregate-error: 3.1.0 - - p-try@2.2.0: {} - - package-hash@4.0.0: - dependencies: - graceful-fs: 4.2.11 - hasha: 5.2.2 - lodash.flattendeep: 4.4.0 - release-zalgo: 1.0.0 - package-json-from-dist@1.0.1: {} parse-sel@1.0.0: @@ -3401,25 +3027,35 @@ snapshots: path-key@3.1.1: {} - path-scurry@1.11.1: - dependencies: - lru-cache: 10.4.3 - minipass: 7.1.3 - path-scurry@2.0.2: dependencies: lru-cache: 11.5.1 minipass: 7.1.3 - pathval@1.1.1: {} + pathe@2.0.3: {} picocolors@1.1.1: {} picomatch@4.0.4: {} - pkg-dir@4.2.0: + playwright-core@1.61.0: + optional: true + + playwright@1.61.0: + dependencies: + playwright-core: 1.61.0 + optionalDependencies: + fsevents: 2.3.2 + optional: true + + pngjs@7.0.0: + optional: true + + postcss@8.5.15: dependencies: - find-up: 4.1.0 + nanoid: 3.3.12 + picocolors: 1.1.1 + source-map-js: 1.2.1 prelude-ls@1.2.1: {} @@ -3431,26 +3067,12 @@ snapshots: prettier@3.8.4: {} - process-on-spawn@1.1.0: - dependencies: - fromentries: 1.3.2 - punycode@2.3.1: {} - readdirp@4.1.2: {} - reflect-metadata@0.2.2: {} - release-zalgo@1.0.0: - dependencies: - es6-error: 4.1.1 - require-directory@2.1.1: {} - require-main-filename@2.0.0: {} - - resolve-from@5.0.0: {} - resolve-pkg-maps@1.0.0: {} rimraf@6.1.3: @@ -3458,18 +3080,33 @@ snapshots: glob: 13.0.6 package-json-from-dist: 1.0.1 + rolldown@1.0.3: + dependencies: + '@oxc-project/types': 0.133.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.3 + '@rolldown/binding-darwin-arm64': 1.0.3 + '@rolldown/binding-darwin-x64': 1.0.3 + '@rolldown/binding-freebsd-x64': 1.0.3 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.3 + '@rolldown/binding-linux-arm64-gnu': 1.0.3 + '@rolldown/binding-linux-arm64-musl': 1.0.3 + '@rolldown/binding-linux-ppc64-gnu': 1.0.3 + '@rolldown/binding-linux-s390x-gnu': 1.0.3 + '@rolldown/binding-linux-x64-gnu': 1.0.3 + '@rolldown/binding-linux-x64-musl': 1.0.3 + '@rolldown/binding-openharmony-arm64': 1.0.3 + '@rolldown/binding-wasm32-wasi': 1.0.3 + '@rolldown/binding-win32-arm64-msvc': 1.0.3 + '@rolldown/binding-win32-x64-msvc': 1.0.3 + rxjs@7.8.2: dependencies: tslib: 2.8.1 - semver@6.3.1: {} - semver@7.8.4: {} - serialize-javascript@7.0.5: {} - - set-blocking@2.0.0: {} - shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -3478,16 +3115,14 @@ snapshots: shell-quote@1.8.4: {} - signal-exit@3.0.7: {} - - signal-exit@4.1.0: {} + siginfo@2.0.0: {} - sinon@22.0.0: + sirv@3.0.2: dependencies: - '@sinonjs/commons': 3.0.1 - '@sinonjs/fake-timers': 15.4.0 - '@sinonjs/samsam': 10.0.2 - diff: 9.0.0 + '@polka/url': 1.0.0-next.29 + mrmime: 2.0.1 + totalist: 3.0.1 + optional: true snabbdom-to-html@7.1.0: dependencies: @@ -3513,17 +3148,7 @@ snapshots: sort-object-keys: 2.1.0 tinyglobby: 0.2.17 - source-map@0.6.1: {} - - spawn-wrap@3.0.0: - dependencies: - cross-spawn: 7.0.6 - foreground-child: 2.0.0 - is-windows: 1.0.2 - make-dir: 3.1.0 - rimraf: 6.1.3 - signal-exit: 3.0.7 - which: 2.0.2 + source-map-js@1.2.1: {} sprotty-protocol@1.4.0: {} @@ -3540,32 +3165,20 @@ snapshots: stable-hash-x@0.2.0: {} + stackback@0.0.2: {} + + std-env@4.1.0: {} + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - string-width@5.1.2: - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.2.0 - strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 - strip-ansi@7.2.0: - dependencies: - ansi-regex: 6.2.2 - - strip-bom@3.0.0: {} - - strip-bom@4.0.0: {} - - strip-json-comments@3.1.1: {} - supports-color@7.2.0: dependencies: has-flag: 4.0.0 @@ -3582,11 +3195,9 @@ snapshots: minizlib: 3.1.0 yallist: 5.0.0 - test-exclude@8.0.0: - dependencies: - '@istanbuljs/schema': 0.1.6 - glob: 13.0.6 - minimatch: 10.2.5 + tinybench@2.9.0: {} + + tinyexec@1.2.4: {} tinyglobby@0.2.17: dependencies: @@ -3595,52 +3206,23 @@ snapshots: tinyqueue@2.0.3: {} + tinyrainbow@3.1.0: {} + + totalist@3.0.1: + optional: true + tree-kill@1.2.2: {} ts-api-utils@2.5.0(typescript@5.9.2): dependencies: typescript: 5.9.2 - ts-node@10.9.2(@types/node@22.19.15)(typescript@5.9.2): - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.12 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 22.19.15 - acorn: 8.17.0 - acorn-walk: 8.3.5 - arg: 4.1.3 - create-require: 1.1.1 - diff: 9.0.0 - make-error: 1.3.6 - typescript: 5.9.2 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - - tsconfig-paths@4.2.0: - dependencies: - json5: 2.2.3 - minimist: 1.2.8 - strip-bom: 3.0.0 - tslib@2.8.1: {} type-check@0.4.0: dependencies: prelude-ls: 1.2.1 - type-detect@4.0.8: {} - - type-detect@4.1.0: {} - - type-fest@0.8.1: {} - - typedarray-to-buffer@3.1.5: - dependencies: - is-typedarray: 1.0.0 - typescript-eslint@8.61.0(eslint@10.5.0)(typescript@5.9.2): dependencies: '@typescript-eslint/eslint-plugin': 8.61.0(@typescript-eslint/parser@8.61.0(eslint@10.5.0)(typescript@5.9.2))(eslint@10.5.0)(typescript@5.9.2) @@ -3683,37 +3265,69 @@ snapshots: '@unrs/resolver-binding-win32-ia32-msvc': 1.12.2 '@unrs/resolver-binding-win32-x64-msvc': 1.12.2 - update-browserslist-db@1.2.3(browserslist@4.28.2): - dependencies: - browserslist: 4.28.2 - escalade: 3.2.0 - picocolors: 1.1.1 - uri-js@4.4.1: dependencies: punycode: 2.3.1 uuid@14.0.0: {} - v8-compile-cache-lib@3.0.1: {} + vite@8.0.16(@types/node@22.19.15)(esbuild@0.28.1): + dependencies: + lightningcss: 1.32.0 + picomatch: 4.0.4 + postcss: 8.5.15 + rolldown: 1.0.3 + tinyglobby: 0.2.17 + optionalDependencies: + '@types/node': 22.19.15 + esbuild: 0.28.1 + fsevents: 2.3.3 + + vitest@4.1.9(@types/node@22.19.15)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(happy-dom@20.10.5)(vite@8.0.16(@types/node@22.19.15)(esbuild@0.28.1)): + dependencies: + '@vitest/expect': 4.1.9 + '@vitest/mocker': 4.1.9(vite@8.0.16(@types/node@22.19.15)(esbuild@0.28.1)) + '@vitest/pretty-format': 4.1.9 + '@vitest/runner': 4.1.9 + '@vitest/snapshot': 4.1.9 + '@vitest/spy': 4.1.9 + '@vitest/utils': 4.1.9 + es-module-lexer: 2.1.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.3 + pathe: 2.0.3 + picomatch: 4.0.4 + std-env: 4.1.0 + tinybench: 2.9.0 + tinyexec: 1.2.4 + tinyglobby: 0.2.17 + tinyrainbow: 3.1.0 + vite: 8.0.16(@types/node@22.19.15)(esbuild@0.28.1) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 22.19.15 + '@vitest/browser-playwright': 4.1.9(playwright@1.61.0)(vite@8.0.16(@types/node@22.19.15)(esbuild@0.28.1))(vitest@4.1.9) + '@vitest/coverage-v8': 4.1.9(@vitest/browser@4.1.9)(vitest@4.1.9) + happy-dom: 20.10.5 + transitivePeerDependencies: + - msw vscode-jsonrpc@8.2.0: {} - which-module@2.0.1: {} + whatwg-mimetype@3.0.0: + optional: true which@2.0.2: dependencies: isexe: 2.0.0 - word-wrap@1.2.5: {} - - workerpool@9.3.4: {} - - wrap-ansi@6.2.0: + why-is-node-running@2.3.0: dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 + siginfo: 2.0.0 + stackback: 0.0.2 + + word-wrap@1.2.5: {} wrap-ansi@7.0.0: dependencies: @@ -3721,55 +3335,15 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 - wrap-ansi@8.1.0: - dependencies: - ansi-styles: 6.2.3 - string-width: 5.1.2 - strip-ansi: 7.2.0 - - write-file-atomic@3.0.3: - dependencies: - imurmurhash: 0.1.4 - is-typedarray: 1.0.0 - signal-exit: 3.0.7 - typedarray-to-buffer: 3.1.5 - - y18n@4.0.3: {} + ws@8.21.0: + optional: true y18n@5.0.8: {} - yallist@3.1.1: {} - yallist@5.0.0: {} - yargs-parser@18.1.3: - dependencies: - camelcase: 5.3.1 - decamelize: 1.2.0 - yargs-parser@21.1.1: {} - yargs-unparser@2.0.0: - dependencies: - camelcase: 6.3.0 - decamelize: 4.0.0 - flat: 5.0.2 - is-plain-obj: 2.1.0 - - yargs@15.4.1: - dependencies: - cliui: 6.0.0 - decamelize: 1.2.0 - find-up: 4.1.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - require-main-filename: 2.0.0 - set-blocking: 2.0.0 - string-width: 4.2.3 - which-module: 2.0.1 - y18n: 4.0.3 - yargs-parser: 18.1.3 - yargs@17.7.2: dependencies: cliui: 8.0.1 @@ -3780,6 +3354,4 @@ snapshots: y18n: 5.0.8 yargs-parser: 21.1.1 - yn@3.1.1: {} - yocto-queue@0.1.0: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 53ff8174..2021ca3c 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,15 +2,15 @@ packages: - 'packages/*' - 'examples/*' -# Security overrides: force patched versions of transitive (dev-only) dependencies that upstream -# tooling (concurrently, mocha, nyc) still pins to ranges flagged by `pnpm audit`. +# Security overrides: minimum floors that lift vulnerable transitive (dev-only) deps to patched +# versions flagged by `pnpm audit`. They only raise versions that resolve below the patched range. overrides: shell-quote: '>=1.8.4' serialize-javascript: '>=7.0.5' diff: '>=8.0.3' js-yaml: '>=4.1.2' -# Tooling (eslint, prettier, mocha, ts-node, rimraf, @eclipse-glsp/*-config, ...) is provided +# Tooling (eslint, prettier, vitest, rimraf, @eclipse-glsp/*-config, ...) is provided # as transitive dependencies of the @eclipse-glsp/dev meta-package and must be resolvable from # the workspace root (tsconfig `extends`, lint/test/build script bins). Rather than flat-hoisting # everything (shamefullyHoist), only the dev tooling is public-hoisted; app/runtime deps stay @@ -23,12 +23,9 @@ publicHoistPattern: - '@typescript-eslint/*' - 'prettier' - 'prettier-plugin-*' - - 'mocha' - - 'chai' - - 'sinon' - - 'ts-node' + - 'vitest' + - '@vitest/*' - 'rimraf' - - 'nyc' # type stubs are compile-time-only dev tooling; hoist them all so `@types/` resolves at the root - '@types/*' diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json index d85cf228..7da89089 100644 --- a/tsconfig.eslint.json +++ b/tsconfig.eslint.json @@ -3,5 +3,5 @@ "compilerOptions": { "noEmit": true }, - "include": ["packages/*/src", "examples/*/src"] + "include": ["packages/*/src", "examples/*/src", "vite.config.ts"] } diff --git a/tsconfig.json b/tsconfig.json index cd59512b..a66ee8ea 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@eclipse-glsp/ts-config/mocha", + "extends": "@eclipse-glsp/ts-config", "include": [], "compilerOptions": { "composite": true, diff --git a/tsconfig.test.json b/tsconfig.test.json new file mode 100644 index 00000000..16adba3c --- /dev/null +++ b/tsconfig.test.json @@ -0,0 +1,13 @@ +{ + "extends": "@eclipse-glsp/ts-config", + "compilerOptions": { + "composite": true, + "noEmit": true + }, + "include": [], + "files": [], + "references": [ + { "path": "./packages/protocol/tsconfig.test.json" }, + { "path": "./packages/client/tsconfig.test.json" } + ] +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 00000000..c75845e8 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,29 @@ +/******************************************************************************** + * Copyright (c) 2026 EclipseSource and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the Eclipse + * Public License v. 2.0 are satisfied: GNU General Public License, version 2 + * with the GNU Classpath Exception which is available at + * https://www.gnu.org/software/classpath/license.html. + * + * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + ********************************************************************************/ +import glspVitestConfig, { defineConfig, mergeConfig } from '@eclipse-glsp/vitest-config'; + +// Single flat config for the whole monorepo: the shared base globs every package's specs under +// `src`, so one `vitest run --coverage` produces a merged report without per-package configs. +// `reflect-metadata` is loaded globally for inversify-based DI specs (matching the former +// .mocharc); it is harmless for the packages that don't use DI. +export default mergeConfig( + glspVitestConfig, + defineConfig({ + test: { + setupFiles: ['reflect-metadata'] + } + }) +); From c8e8f2d8347392183b1ec27d4a8268eadd4b7b5c Mon Sep 17 00:00:00 2001 From: Tobias Ortmayr Date: Tue, 23 Jun 2026 09:32:43 +0200 Subject: [PATCH 2/3] GLSP-1635: Restore container load spy in default-modules tests - Add an afterEach to restore the spy created on container.load, since container.restore() only resets Inversify bindings and would otherwise leave the method permanently spied across tests Part of: eclipse-glsp/glsp#1635 --- packages/client/src/default-modules.spec.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/client/src/default-modules.spec.ts b/packages/client/src/default-modules.spec.ts index ced26c34..53513709 100644 --- a/packages/client/src/default-modules.spec.ts +++ b/packages/client/src/default-modules.spec.ts @@ -14,7 +14,7 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ import { FeatureModule } from '@eclipse-glsp/sprotty'; -import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { Container } from 'inversify'; import { defaultModule } from './base/default.module'; import { DEFAULT_MODULES, initializeDiagramContainer } from './default-modules'; @@ -32,6 +32,9 @@ describe('default-modules', () => { container.snapshot(); loadSpy = vi.spyOn(container, 'load'); }); + afterEach(() => { + loadSpy.mockRestore(); + }); it('should initialize the diagram container with the default modules in addition to the given config and load them first', () => { const extraModule = new FeatureModule(() => {}); initializeDiagramContainer(container, { add: extraModule }); From f5f8080c47a088d869d623985f4a9270cd708b9b Mon Sep 17 00:00:00 2001 From: Tobias Ortmayr Date: Tue, 23 Jun 2026 10:18:26 +0200 Subject: [PATCH 3/3] GLSP-1635: Fix copy-pasted ChangeRoutingPointsOperation create test - Rework the ChangeRoutingPointsOperation.create tests so they actually exercise that factory instead of ReconnectEdgeOperation, covering both the defaults and the optional-args cases Part of: eclipse-glsp/glsp#1635 --- .../action-protocol/edge-modification.spec.ts | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/packages/protocol/src/action-protocol/edge-modification.spec.ts b/packages/protocol/src/action-protocol/edge-modification.spec.ts index e5df5e24..33df47a6 100644 --- a/packages/protocol/src/action-protocol/edge-modification.spec.ts +++ b/packages/protocol/src/action-protocol/edge-modification.spec.ts @@ -90,17 +90,6 @@ describe('Edge modification operations', () => { describe('create', () => { it('should return an object conforming to the interface with matching properties for the given required arguments and default values for the optional arguments', () => { - const expected: ReconnectEdgeOperation = { - kind: 'reconnectEdge', - isOperation: true, - edgeElementId: 'edgeElement', - sourceElementId: 'source', - targetElementId: 'target' - }; - const { edgeElementId, sourceElementId, targetElementId } = expected; - expect(ReconnectEdgeOperation.create({ edgeElementId, sourceElementId, targetElementId })).toEqual(expected); - }); - it('should return an object conforming to the interface with matching properties for the given required args', () => { const expected: ChangeRoutingPointsOperation = { kind: 'changeRoutingPoints', isOperation: true, @@ -109,6 +98,16 @@ describe('Edge modification operations', () => { const { newRoutingPoints } = expected; expect(ChangeRoutingPointsOperation.create(newRoutingPoints)).toEqual(expected); }); + it('should return an object conforming to the interface with matching properties for the given required and optional arguments', () => { + const expected: ChangeRoutingPointsOperation = { + kind: 'changeRoutingPoints', + isOperation: true, + newRoutingPoints: [{ elementId: 'element', newRoutingPoints: [Point.ORIGIN] }], + args: { some: 'args' } + }; + const { newRoutingPoints, args } = expected; + expect(ChangeRoutingPointsOperation.create(newRoutingPoints, { args })).toEqual(expected); + }); }); }); });