diff --git a/.gitignore b/.gitignore index 67e08e0..688bf80 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,6 @@ AGENTS.md *storybook.log storybook-static + +# Tests +coverage/ diff --git a/package.json b/package.json index 8d7b113..3710949 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,12 @@ "format": "dprint fmt", "format:check": "dprint check", "test:e2e": "playwright test", - "test": "npm run test:e2e", + "test:unit": "vitest run", + "test:unit:watch": "vitest", + "test:unit:ui": "vitest --ui", + "test:unit:coverage": "vitest run --coverage", + "test:component": "vitest run --config vitest.config.component.ts", + "test": "npm run test:e2e && npm run test:unit", "storybook": "storybook dev -p 6006", "build-storybook": "storybook build" }, @@ -31,12 +36,16 @@ "@storybook/svelte-vite": "^10.1.11", "@sveltejs/vite-plugin-svelte": "^6.2.1", "@tailwindcss/vite": "^4.1.18", + "@testing-library/jest-dom": "^6.9.1", + "@testing-library/svelte": "^5.3.1", "@tsconfig/svelte": "^5.0.6", + "@types/jsdom": "^27", "@vitest/browser-playwright": "^4.0.16", "@vitest/coverage-v8": "^4.0.16", "bits-ui": "^2.14.4", "clsx": "^2.1.1", "dprint": "^0.50.2", + "jsdom": "^27.4.0", "lefthook": "^2.0.13", "oxlint": "^1.35.0", "playwright": "^1.57.0", @@ -50,6 +59,7 @@ "tw-animate-css": "^1.4.0", "typescript": "^5.9.3", "vite": "^7.2.6", - "vitest": "^4.0.16" + "vitest": "^4.0.16", + "vitest-browser-svelte": "^2.0.1" } } diff --git a/tsconfig.json b/tsconfig.json index 6e6cdb3..1c223e3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,7 +5,7 @@ "moduleResolution": "bundler", "target": "ESNext", "lib": ["ESNext", "DOM", "DOM.Iterable"], - "types": ["svelte"], + "types": ["svelte", "vitest/globals"], /* Strictness & Safety */ "strict": true, @@ -36,7 +36,8 @@ "src/**/*.ts", "src/**/*.js", "src/**/*.svelte", - "src/**/*.d.ts" + "src/**/*.d.ts", + "vitest.types.d.ts" ], "exclude": [ "node_modules", diff --git a/vitest.config.component.ts b/vitest.config.component.ts new file mode 100644 index 0000000..0cfa05d --- /dev/null +++ b/vitest.config.component.ts @@ -0,0 +1,37 @@ +import { svelte } from '@sveltejs/vite-plugin-svelte'; +import path from 'node:path'; +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + plugins: [svelte()], + + test: { + name: 'component', + environment: 'jsdom', + include: ['src/**/*.svelte.test.ts', 'src/**/*.svelte.test.js'], + exclude: [ + 'node_modules', + 'dist', + 'e2e', + '.storybook', + 'src/shared/shadcn/**/*', + ], + testTimeout: 10000, + hookTimeout: 10000, + restoreMocks: true, + setupFiles: ['./vitest.setup.component.ts'], + globals: false, + }, + + resolve: { + alias: { + $lib: path.resolve(__dirname, './src/lib'), + $app: path.resolve(__dirname, './src/app'), + $shared: path.resolve(__dirname, './src/shared'), + $entities: path.resolve(__dirname, './src/entities'), + $features: path.resolve(__dirname, './src/features'), + $routes: path.resolve(__dirname, './src/routes'), + $widgets: path.resolve(__dirname, './src/widgets'), + }, + }, +}); diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..96e7de8 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,66 @@ +import { svelte } from '@sveltejs/vite-plugin-svelte'; +import path from 'node:path'; +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + plugins: [svelte()], + + test: { + environment: 'node', + include: [ + 'src/**/*.test.ts', + 'src/**/*.test.js', + 'src/**/*.spec.ts', + // Explicitly exclude component tests + '!src/**/*.svelte.test.ts', + '!src/**/*.svelte.test.js', + ], + exclude: [ + 'node_modules', + 'dist', + 'e2e', + '.storybook', + 'src/shared/shadcn/**/*', + ], + restoreMocks: true, + coverage: { + provider: 'v8', + reporter: ['text', 'json', 'html', 'lcov'], + include: ['src/**/*.ts', 'src/**/*.svelte'], + exclude: [ + 'node_modules', + 'dist', + 'e2e', + '.storybook', + '**/*.test.ts', + '**/*.test.js', + '**/*.svelte.test.ts', + '**/*.spec.ts', + '**/*.d.ts', + '**/*.stories.svelte', + 'src/shared/shadcn/**/*', + 'vitest.config.ts', + ], + thresholds: { + lines: 70, + functions: 70, + branches: 60, + statements: 70, + }, + }, + setupFiles: [], + globals: false, + }, + + resolve: { + alias: { + $lib: path.resolve(__dirname, './src/lib'), + $app: path.resolve(__dirname, './src/app'), + $shared: path.resolve(__dirname, './src/shared'), + $entities: path.resolve(__dirname, './src/entities'), + $features: path.resolve(__dirname, './src/features'), + $routes: path.resolve(__dirname, './src/routes'), + $widgets: path.resolve(__dirname, './src/widgets'), + }, + }, +}); diff --git a/vitest.setup.component.ts b/vitest.setup.component.ts new file mode 100644 index 0000000..4f4404a --- /dev/null +++ b/vitest.setup.component.ts @@ -0,0 +1,12 @@ +import * as matchers from '@testing-library/jest-dom/matchers'; +import { cleanup } from '@testing-library/svelte'; +import { + afterEach, + expect, +} from 'vitest'; + +expect.extend(matchers); + +afterEach(() => { + cleanup(); +}); diff --git a/vitest.types.d.ts b/vitest.types.d.ts new file mode 100644 index 0000000..0ee17a6 --- /dev/null +++ b/vitest.types.d.ts @@ -0,0 +1,8 @@ +import '@testing-library/jest-dom/vitest'; +import type { TestingLibraryMatchers } from '@testing-library/jest-dom/matchers'; + +declare global { + namespace Vi { + interface Matchers extends TestingLibraryMatchers {} + } +} diff --git a/yarn.lock b/yarn.lock index f2ce0de..21b3f3f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,6 +5,13 @@ __metadata: version: 8 cacheKey: 10c0 +"@acemir/cssom@npm:^0.9.28": + version: 0.9.30 + resolution: "@acemir/cssom@npm:0.9.30" + checksum: 10c0/f90dd766826315904ab71361aa7b3e0f1ff01124c73b2abc4c6f676ccb036cc6d4fe7c834f89384302e3dfbbd1e819681816fd29da594bb94a5739c634e8282f + languageName: node + linkType: hard + "@adobe/css-tools@npm:^4.4.0": version: 4.4.4 resolution: "@adobe/css-tools@npm:4.4.4" @@ -22,6 +29,50 @@ __metadata: languageName: node linkType: hard +"@asamuzakjp/css-color@npm:^4.1.1": + version: 4.1.1 + resolution: "@asamuzakjp/css-color@npm:4.1.1" + dependencies: + "@csstools/css-calc": "npm:^2.1.4" + "@csstools/css-color-parser": "npm:^3.1.0" + "@csstools/css-parser-algorithms": "npm:^3.0.5" + "@csstools/css-tokenizer": "npm:^3.0.4" + lru-cache: "npm:^11.2.4" + checksum: 10c0/2948ae9cd4c2f326ab5470d6ac7d415bb8062150ef254f830d774b6a77d6dccfbdb4b84ed4ef5c86c5643d42c52d77204b8d94d0d90f2e2cea9ec9b6cbb9c336 + languageName: node + linkType: hard + +"@asamuzakjp/dom-selector@npm:^6.7.6": + version: 6.7.6 + resolution: "@asamuzakjp/dom-selector@npm:6.7.6" + dependencies: + "@asamuzakjp/nwsapi": "npm:^2.3.9" + bidi-js: "npm:^1.0.3" + css-tree: "npm:^3.1.0" + is-potential-custom-element-name: "npm:^1.0.1" + lru-cache: "npm:^11.2.4" + checksum: 10c0/1715faae0787f0c8430b3a0ff3db8576a5b9a4f964408d0808fc2060ab01e0c2f5d8e26409de54b8641433c891dab8b561b196e58798811146084c561a4954ce + languageName: node + linkType: hard + +"@asamuzakjp/nwsapi@npm:^2.3.9": + version: 2.3.9 + resolution: "@asamuzakjp/nwsapi@npm:2.3.9" + checksum: 10c0/869b81382e775499c96c45c6dbe0d0766a6da04bcf0abb79f5333535c4e19946851acaa43398f896e2ecc5a1de9cf3db7cf8c4b1afac1ee3d15e21584546d74d + languageName: node + linkType: hard + +"@babel/code-frame@npm:^7.10.4": + version: 7.27.1 + resolution: "@babel/code-frame@npm:7.27.1" + dependencies: + "@babel/helper-validator-identifier": "npm:^7.27.1" + js-tokens: "npm:^4.0.0" + picocolors: "npm:^1.1.1" + checksum: 10c0/5dd9a18baa5fce4741ba729acc3a3272c49c25cb8736c4b18e113099520e7ef7b545a4096a26d600e4416157e63e87d66db46aa3fbf0a5f2286da2705c12da00 + languageName: node + linkType: hard + "@babel/helper-string-parser@npm:^7.27.1": version: 7.27.1 resolution: "@babel/helper-string-parser@npm:7.27.1" @@ -29,7 +80,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^7.28.5": +"@babel/helper-validator-identifier@npm:^7.27.1, @babel/helper-validator-identifier@npm:^7.28.5": version: 7.28.5 resolution: "@babel/helper-validator-identifier@npm:7.28.5" checksum: 10c0/42aaebed91f739a41f3d80b72752d1f95fd7c72394e8e4bd7cdd88817e0774d80a432451bcba17c2c642c257c483bf1d409dd4548883429ea9493a3bc4ab0847 @@ -47,6 +98,13 @@ __metadata: languageName: node linkType: hard +"@babel/runtime@npm:^7.12.5": + version: 7.28.4 + resolution: "@babel/runtime@npm:7.28.4" + checksum: 10c0/792ce7af9750fb9b93879cc9d1db175701c4689da890e6ced242ea0207c9da411ccf16dc04e689cc01158b28d7898c40d75598f4559109f761c12ce01e959bf7 + languageName: node + linkType: hard + "@babel/types@npm:^7.28.5": version: 7.28.5 resolution: "@babel/types@npm:7.28.5" @@ -79,6 +137,59 @@ __metadata: languageName: node linkType: hard +"@csstools/color-helpers@npm:^5.1.0": + version: 5.1.0 + resolution: "@csstools/color-helpers@npm:5.1.0" + checksum: 10c0/b7f99d2e455cf1c9b41a67a5327d5d02888cd5c8802a68b1887dffef537d9d4bc66b3c10c1e62b40bbed638b6c1d60b85a232f904ed7b39809c4029cb36567db + languageName: node + linkType: hard + +"@csstools/css-calc@npm:^2.1.4": + version: 2.1.4 + resolution: "@csstools/css-calc@npm:2.1.4" + peerDependencies: + "@csstools/css-parser-algorithms": ^3.0.5 + "@csstools/css-tokenizer": ^3.0.4 + checksum: 10c0/42ce5793e55ec4d772083808a11e9fb2dfe36db3ec168713069a276b4c3882205b3507c4680224c28a5d35fe0bc2d308c77f8f2c39c7c09aad8747708eb8ddd8 + languageName: node + linkType: hard + +"@csstools/css-color-parser@npm:^3.1.0": + version: 3.1.0 + resolution: "@csstools/css-color-parser@npm:3.1.0" + dependencies: + "@csstools/color-helpers": "npm:^5.1.0" + "@csstools/css-calc": "npm:^2.1.4" + peerDependencies: + "@csstools/css-parser-algorithms": ^3.0.5 + "@csstools/css-tokenizer": ^3.0.4 + checksum: 10c0/0e0c670ad54ec8ec4d9b07568b80defd83b9482191f5e8ca84ab546b7be6db5d7cc2ba7ac9fae54488b129a4be235d6183d3aab4416fec5e89351f73af4222c5 + languageName: node + linkType: hard + +"@csstools/css-parser-algorithms@npm:^3.0.5": + version: 3.0.5 + resolution: "@csstools/css-parser-algorithms@npm:3.0.5" + peerDependencies: + "@csstools/css-tokenizer": ^3.0.4 + checksum: 10c0/d9a1c888bd43849ae3437ca39251d5c95d2c8fd6b5ccdb7c45491dfd2c1cbdc3075645e80901d120e4d2c1993db9a5b2d83793b779dbbabcfb132adb142eb7f7 + languageName: node + linkType: hard + +"@csstools/css-syntax-patches-for-csstree@npm:^1.0.21": + version: 1.0.22 + resolution: "@csstools/css-syntax-patches-for-csstree@npm:1.0.22" + checksum: 10c0/5ec39dc28b30bb0d5e212e598979707786e152698be820502bdee4b0204983604170dd960a8684de8de89f28376cf4a151de81d9da166d97eeb35f869a44ae08 + languageName: node + linkType: hard + +"@csstools/css-tokenizer@npm:^3.0.4": + version: 3.0.4 + resolution: "@csstools/css-tokenizer@npm:3.0.4" + checksum: 10c0/3b589f8e9942075a642213b389bab75a2d50d05d203727fcdac6827648a5572674caff07907eff3f9a2389d86a4ee47308fafe4f8588f4a77b7167c588d2559f + languageName: node + linkType: hard + "@dprint/darwin-arm64@npm:0.50.2": version: 0.50.2 resolution: "@dprint/darwin-arm64@npm:0.50.2" @@ -377,6 +488,18 @@ __metadata: languageName: node linkType: hard +"@exodus/bytes@npm:^1.6.0": + version: 1.8.0 + resolution: "@exodus/bytes@npm:1.8.0" + peerDependencies: + "@exodus/crypto": ^1.0.0-rc.4 + peerDependenciesMeta: + "@exodus/crypto": + optional: true + checksum: 10c0/1878868519230fa564b80d3d12fa7e2b559dfed143f4e48969eb5f98083caea431bbc70356d6b2f90ba80c8148295fe85af6a5ed8a746dd53baefe4f1ed086e8 + languageName: node + linkType: hard + "@floating-ui/core@npm:^1.7.1, @floating-ui/core@npm:^1.7.3": version: 1.7.3 resolution: "@floating-ui/core@npm:1.7.3" @@ -1169,7 +1292,23 @@ __metadata: languageName: node linkType: hard -"@testing-library/jest-dom@npm:^6.6.3": +"@testing-library/dom@npm:9.x.x || 10.x.x": + version: 10.4.1 + resolution: "@testing-library/dom@npm:10.4.1" + dependencies: + "@babel/code-frame": "npm:^7.10.4" + "@babel/runtime": "npm:^7.12.5" + "@types/aria-query": "npm:^5.0.1" + aria-query: "npm:5.3.0" + dom-accessibility-api: "npm:^0.5.9" + lz-string: "npm:^1.5.0" + picocolors: "npm:1.1.1" + pretty-format: "npm:^27.0.2" + checksum: 10c0/19ce048012d395ad0468b0dbcc4d0911f6f9e39464d7a8464a587b29707eed5482000dad728f5acc4ed314d2f4d54f34982999a114d2404f36d048278db815b1 + languageName: node + linkType: hard + +"@testing-library/jest-dom@npm:^6.6.3, @testing-library/jest-dom@npm:^6.9.1": version: 6.9.1 resolution: "@testing-library/jest-dom@npm:6.9.1" dependencies: @@ -1183,6 +1322,34 @@ __metadata: languageName: node linkType: hard +"@testing-library/svelte-core@npm:1.0.0": + version: 1.0.0 + resolution: "@testing-library/svelte-core@npm:1.0.0" + peerDependencies: + svelte: ^3 || ^4 || ^5 || ^5.0.0-next.0 + checksum: 10c0/79942494df95b559ca6d4abc8398ca2d31a4709f836e42337f41e629e5191e0c0caed9d5fd905df93c2c2e4230e63e08da839e6bc304c21e6960a5777bc40f12 + languageName: node + linkType: hard + +"@testing-library/svelte@npm:^5.3.1": + version: 5.3.1 + resolution: "@testing-library/svelte@npm:5.3.1" + dependencies: + "@testing-library/dom": "npm:9.x.x || 10.x.x" + "@testing-library/svelte-core": "npm:1.0.0" + peerDependencies: + svelte: ^3 || ^4 || ^5 || ^5.0.0-next.0 + vite: "*" + vitest: "*" + peerDependenciesMeta: + vite: + optional: true + vitest: + optional: true + checksum: 10c0/a5279b53514d94b0abbb34b87883886ae2b64ed18ac623c4bda981b05465be02213c778108671e47d56912ec9f4684645cfead852443e6b3810db2021d2823c7 + languageName: node + linkType: hard + "@testing-library/user-event@npm:^14.6.1": version: 14.6.1 resolution: "@testing-library/user-event@npm:14.6.1" @@ -1208,6 +1375,13 @@ __metadata: languageName: node linkType: hard +"@types/aria-query@npm:^5.0.1": + version: 5.0.4 + resolution: "@types/aria-query@npm:5.0.4" + checksum: 10c0/dc667bc6a3acc7bba2bccf8c23d56cb1f2f4defaa704cfef595437107efaa972d3b3db9ec1d66bc2711bfc35086821edd32c302bffab36f2e79b97f312069f08 + languageName: node + linkType: hard + "@types/chai@npm:^5.2.2": version: 5.2.3 resolution: "@types/chai@npm:5.2.3" @@ -1232,6 +1406,17 @@ __metadata: languageName: node linkType: hard +"@types/jsdom@npm:^27": + version: 27.0.0 + resolution: "@types/jsdom@npm:27.0.0" + dependencies: + "@types/node": "npm:*" + "@types/tough-cookie": "npm:*" + parse5: "npm:^7.0.0" + checksum: 10c0/1ec7ff7177e1f7266e51279f07f3cd013e1713766b01eebceac783061675b31c672a47b0a508dcbaf040f7f22d90405858378c6c5358991989fbe8b95adde354 + languageName: node + linkType: hard + "@types/mdx@npm:^2.0.0": version: 2.0.13 resolution: "@types/mdx@npm:2.0.13" @@ -1239,6 +1424,22 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:*": + version: 25.0.3 + resolution: "@types/node@npm:25.0.3" + dependencies: + undici-types: "npm:~7.16.0" + checksum: 10c0/b7568f0d765d9469621615e2bb257c7fd1953d95e9acbdb58dffb6627a2c4150d405a4600aa1ad8a40182a94fe5f903cafd3c0a2f5132814debd0e3bfd61f835 + languageName: node + linkType: hard + +"@types/tough-cookie@npm:*": + version: 4.0.5 + resolution: "@types/tough-cookie@npm:4.0.5" + checksum: 10c0/68c6921721a3dcb40451543db2174a145ef915bc8bcbe7ad4e59194a0238e776e782b896c7a59f4b93ac6acefca9161fccb31d1ce3b3445cb6faa467297fb473 + languageName: node + linkType: hard + "@vitest/browser-playwright@npm:^4.0.16": version: 4.0.16 resolution: "@vitest/browser-playwright@npm:4.0.16" @@ -1484,6 +1685,13 @@ __metadata: languageName: node linkType: hard +"ansi-regex@npm:^5.0.1": + version: 5.0.1 + resolution: "ansi-regex@npm:5.0.1" + checksum: 10c0/9a64bb8627b434ba9327b60c027742e5d17ac69277960d041898596271d992d4d52ba7267a63ca10232e29f6107fc8a835f6ce8d719b88c5f8493f8254813737 + languageName: node + linkType: hard + "ansi-regex@npm:^6.0.1": version: 6.2.2 resolution: "ansi-regex@npm:6.2.2" @@ -1491,6 +1699,22 @@ __metadata: languageName: node linkType: hard +"ansi-styles@npm:^5.0.0": + version: 5.2.0 + resolution: "ansi-styles@npm:5.2.0" + checksum: 10c0/9c4ca80eb3c2fb7b33841c210d2f20807f40865d27008d7c3f707b7f95cab7d67462a565e2388ac3285b71cb3d9bb2173de8da37c57692a362885ec34d6e27df + languageName: node + linkType: hard + +"aria-query@npm:5.3.0": + version: 5.3.0 + resolution: "aria-query@npm:5.3.0" + dependencies: + dequal: "npm:^2.0.3" + checksum: 10c0/2bff0d4eba5852a9dd578ecf47eaef0e82cc52569b48469b0aac2db5145db0b17b7a58d9e01237706d1e14b7a1b0ac9b78e9c97027ad97679dd8f91b85da1469 + languageName: node + linkType: hard + "aria-query@npm:^5.0.0, aria-query@npm:^5.3.0, aria-query@npm:^5.3.1": version: 5.3.2 resolution: "aria-query@npm:5.3.2" @@ -1539,6 +1763,15 @@ __metadata: languageName: node linkType: hard +"bidi-js@npm:^1.0.3": + version: 1.0.3 + resolution: "bidi-js@npm:1.0.3" + dependencies: + require-from-string: "npm:^2.0.2" + checksum: 10c0/fdddea4aa4120a34285486f2267526cd9298b6e8b773ad25e765d4f104b6d7437ab4ba542e6939e3ac834a7570bcf121ee2cf6d3ae7cd7082c4b5bedc8f271e1 + languageName: node + linkType: hard + "bits-ui@npm:^2.14.4": version: 2.14.4 resolution: "bits-ui@npm:2.14.4" @@ -1676,6 +1909,16 @@ __metadata: languageName: node linkType: hard +"css-tree@npm:^3.1.0": + version: 3.1.0 + resolution: "css-tree@npm:3.1.0" + dependencies: + mdn-data: "npm:2.12.2" + source-map-js: "npm:^1.0.1" + checksum: 10c0/b5715852c2f397c715ca00d56ec53fc83ea596295ae112eb1ba6a1bda3b31086380e596b1d8c4b980fe6da09e7d0fc99c64d5bb7313030dd0fba9c1415f30979 + languageName: node + linkType: hard + "css.escape@npm:^1.5.1": version: 1.5.1 resolution: "css.escape@npm:1.5.1" @@ -1683,6 +1926,28 @@ __metadata: languageName: node linkType: hard +"cssstyle@npm:^5.3.4": + version: 5.3.7 + resolution: "cssstyle@npm:5.3.7" + dependencies: + "@asamuzakjp/css-color": "npm:^4.1.1" + "@csstools/css-syntax-patches-for-csstree": "npm:^1.0.21" + css-tree: "npm:^3.1.0" + lru-cache: "npm:^11.2.4" + checksum: 10c0/9330f014f4209df06305264b92b8e963dfef636fdc2ae7d13f24ea7da6468aba1dc5eb13082621258bdd22cbd7fb7cb291894e188a3cdf660e8b79cd2c5e5e0e + languageName: node + linkType: hard + +"data-urls@npm:^6.0.0": + version: 6.0.0 + resolution: "data-urls@npm:6.0.0" + dependencies: + whatwg-mimetype: "npm:^4.0.0" + whatwg-url: "npm:^15.0.0" + checksum: 10c0/952102a8e6282fea112f7120d79fac482a2f99e20c67f9cb069d661c00627305b042e1f7e3cef8e4bbc795b42c5d481bbc9c6effeff5bb1427f9acaf1722bd35 + languageName: node + linkType: hard + "debug@npm:4, debug@npm:^4.1.1, debug@npm:^4.3.4, debug@npm:^4.4.1": version: 4.4.3 resolution: "debug@npm:4.4.3" @@ -1695,6 +1960,13 @@ __metadata: languageName: node linkType: hard +"decimal.js@npm:^10.6.0": + version: 10.6.0 + resolution: "decimal.js@npm:10.6.0" + checksum: 10c0/07d69fbcc54167a340d2d97de95f546f9ff1f69d2b45a02fd7a5292412df3cd9eb7e23065e532a318f5474a2e1bccf8392fdf0443ef467f97f3bf8cb0477e5aa + languageName: node + linkType: hard + "dedent-js@npm:^1.0.1": version: 1.0.1 resolution: "dedent-js@npm:1.0.1" @@ -1773,6 +2045,13 @@ __metadata: languageName: node linkType: hard +"dom-accessibility-api@npm:^0.5.9": + version: 0.5.16 + resolution: "dom-accessibility-api@npm:0.5.16" + checksum: 10c0/b2c2eda4fae568977cdac27a9f0c001edf4f95a6a6191dfa611e3721db2478d1badc01db5bb4fa8a848aeee13e442a6c2a4386d65ec65a1436f24715a2f8d053 + languageName: node + linkType: hard + "dom-accessibility-api@npm:^0.6.3": version: 0.6.3 resolution: "dom-accessibility-api@npm:0.6.3" @@ -1847,6 +2126,13 @@ __metadata: languageName: node linkType: hard +"entities@npm:^6.0.0": + version: 6.0.1 + resolution: "entities@npm:6.0.1" + checksum: 10c0/ed836ddac5acb34341094eb495185d527bd70e8632b6c0d59548cbfa23defdbae70b96f9a405c82904efa421230b5b3fd2283752447d737beffd3f3e6ee74414 + languageName: node + linkType: hard + "env-paths@npm:^2.2.0": version: 2.2.1 resolution: "env-paths@npm:2.2.1" @@ -2143,12 +2429,16 @@ __metadata: "@storybook/svelte-vite": "npm:^10.1.11" "@sveltejs/vite-plugin-svelte": "npm:^6.2.1" "@tailwindcss/vite": "npm:^4.1.18" + "@testing-library/jest-dom": "npm:^6.9.1" + "@testing-library/svelte": "npm:^5.3.1" "@tsconfig/svelte": "npm:^5.0.6" + "@types/jsdom": "npm:^27" "@vitest/browser-playwright": "npm:^4.0.16" "@vitest/coverage-v8": "npm:^4.0.16" bits-ui: "npm:^2.14.4" clsx: "npm:^2.1.1" dprint: "npm:^0.50.2" + jsdom: "npm:^27.4.0" lefthook: "npm:^2.0.13" oxlint: "npm:^1.35.0" playwright: "npm:^1.57.0" @@ -2163,6 +2453,7 @@ __metadata: typescript: "npm:^5.9.3" vite: "npm:^7.2.6" vitest: "npm:^4.0.16" + vitest-browser-svelte: "npm:^2.0.1" languageName: unknown linkType: soft @@ -2180,6 +2471,15 @@ __metadata: languageName: node linkType: hard +"html-encoding-sniffer@npm:^6.0.0": + version: 6.0.0 + resolution: "html-encoding-sniffer@npm:6.0.0" + dependencies: + "@exodus/bytes": "npm:^1.6.0" + checksum: 10c0/66dc3f6f5539cc3beb814fcbfae7eacf4ec38cf824d6e1425b72039b51a40f4456bd8541ba66f4f4fe09cdf885ab5cd5bae6ec6339d6895a930b2fdb83c53025 + languageName: node + linkType: hard + "html-escaper@npm:^2.0.0": version: 2.0.2 resolution: "html-escaper@npm:2.0.2" @@ -2194,7 +2494,7 @@ __metadata: languageName: node linkType: hard -"http-proxy-agent@npm:^7.0.0": +"http-proxy-agent@npm:^7.0.0, http-proxy-agent@npm:^7.0.2": version: 7.0.2 resolution: "http-proxy-agent@npm:7.0.2" dependencies: @@ -2204,7 +2504,7 @@ __metadata: languageName: node linkType: hard -"https-proxy-agent@npm:^7.0.1": +"https-proxy-agent@npm:^7.0.1, https-proxy-agent@npm:^7.0.6": version: 7.0.6 resolution: "https-proxy-agent@npm:7.0.6" dependencies: @@ -2271,6 +2571,13 @@ __metadata: languageName: node linkType: hard +"is-potential-custom-element-name@npm:^1.0.1": + version: 1.0.1 + resolution: "is-potential-custom-element-name@npm:1.0.1" + checksum: 10c0/b73e2f22bc863b0939941d369486d308b43d7aef1f9439705e3582bfccaa4516406865e32c968a35f97a99396dac84e2624e67b0a16b0a15086a785e16ce7db9 + languageName: node + linkType: hard + "is-reference@npm:^3.0.0, is-reference@npm:^3.0.1, is-reference@npm:^3.0.3": version: 3.0.3 resolution: "is-reference@npm:3.0.3" @@ -2344,6 +2651,13 @@ __metadata: languageName: node linkType: hard +"js-tokens@npm:^4.0.0": + version: 4.0.0 + resolution: "js-tokens@npm:4.0.0" + checksum: 10c0/e248708d377aa058eacf2037b07ded847790e6de892bbad3dac0abba2e759cb9f121b00099a65195616badcb6eca8d14d975cb3e89eb1cfda644756402c8aeed + languageName: node + linkType: hard + "js-tokens@npm:^9.0.1": version: 9.0.1 resolution: "js-tokens@npm:9.0.1" @@ -2351,6 +2665,39 @@ __metadata: languageName: node linkType: hard +"jsdom@npm:^27.4.0": + version: 27.4.0 + resolution: "jsdom@npm:27.4.0" + dependencies: + "@acemir/cssom": "npm:^0.9.28" + "@asamuzakjp/dom-selector": "npm:^6.7.6" + "@exodus/bytes": "npm:^1.6.0" + cssstyle: "npm:^5.3.4" + data-urls: "npm:^6.0.0" + decimal.js: "npm:^10.6.0" + html-encoding-sniffer: "npm:^6.0.0" + http-proxy-agent: "npm:^7.0.2" + https-proxy-agent: "npm:^7.0.6" + is-potential-custom-element-name: "npm:^1.0.1" + parse5: "npm:^8.0.0" + saxes: "npm:^6.0.0" + symbol-tree: "npm:^3.2.4" + tough-cookie: "npm:^6.0.0" + w3c-xmlserializer: "npm:^5.0.0" + webidl-conversions: "npm:^8.0.0" + whatwg-mimetype: "npm:^4.0.0" + whatwg-url: "npm:^15.1.0" + ws: "npm:^8.18.3" + xml-name-validator: "npm:^5.0.0" + peerDependencies: + canvas: ^3.0.0 + peerDependenciesMeta: + canvas: + optional: true + checksum: 10c0/291bb71a611dbaed81ce516587b71a5ffd9d43337d65bbd0731e7924cd7018f5871cf66614facadfd0dffec2b23a0fc57b2ee36b5a39e20f0f569e2949b3418c + languageName: node + linkType: hard + "jsonc-parser@npm:^2.3.0": version: 2.3.1 resolution: "jsonc-parser@npm:2.3.1" @@ -2623,7 +2970,7 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:^11.0.0, lru-cache@npm:^11.1.0, lru-cache@npm:^11.2.1": +"lru-cache@npm:^11.0.0, lru-cache@npm:^11.1.0, lru-cache@npm:^11.2.1, lru-cache@npm:^11.2.4": version: 11.2.4 resolution: "lru-cache@npm:11.2.4" checksum: 10c0/4a24f9b17537619f9144d7b8e42cd5a225efdfd7076ebe7b5e7dc02b860a818455201e67fbf000765233fe7e339d3c8229fc815e9b58ee6ede511e07608c19b2 @@ -2694,6 +3041,13 @@ __metadata: languageName: node linkType: hard +"mdn-data@npm:2.12.2": + version: 2.12.2 + resolution: "mdn-data@npm:2.12.2" + checksum: 10c0/b22443b71d70f72ccc3c6ba1608035431a8fc18c3c8fc53523f06d20e05c2ac10f9b53092759a2ca85cf02f0d37036f310b581ce03e7b99ac74d388ef8152ade + languageName: node + linkType: hard + "min-indent@npm:^1.0.0": version: 1.0.1 resolution: "min-indent@npm:1.0.1" @@ -2921,6 +3275,24 @@ __metadata: languageName: node linkType: hard +"parse5@npm:^7.0.0": + version: 7.3.0 + resolution: "parse5@npm:7.3.0" + dependencies: + entities: "npm:^6.0.0" + checksum: 10c0/7fd2e4e247e85241d6f2a464d0085eed599a26d7b0a5233790c49f53473232eb85350e8133344d9b3fd58b89339e7ad7270fe1f89d28abe50674ec97b87f80b5 + languageName: node + linkType: hard + +"parse5@npm:^8.0.0": + version: 8.0.0 + resolution: "parse5@npm:8.0.0" + dependencies: + entities: "npm:^6.0.0" + checksum: 10c0/8279892dcd77b2f2229707f60eb039e303adf0288812b2a8fd5acf506a4d432da833c6c5d07a6554bef722c2367a81ef4a1f7e9336564379a7dba3e798bf16b3 + languageName: node + linkType: hard + "path-scurry@npm:^2.0.0": version: 2.0.1 resolution: "path-scurry@npm:2.0.1" @@ -2956,7 +3328,7 @@ __metadata: languageName: node linkType: hard -"picocolors@npm:^1.0.0, picocolors@npm:^1.1.1": +"picocolors@npm:1.1.1, picocolors@npm:^1.0.0, picocolors@npm:^1.1.1": version: 1.1.1 resolution: "picocolors@npm:1.1.1" checksum: 10c0/e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58 @@ -3042,6 +3414,17 @@ __metadata: languageName: node linkType: hard +"pretty-format@npm:^27.0.2": + version: 27.5.1 + resolution: "pretty-format@npm:27.5.1" + dependencies: + ansi-regex: "npm:^5.0.1" + ansi-styles: "npm:^5.0.0" + react-is: "npm:^17.0.1" + checksum: 10c0/0cbda1031aa30c659e10921fa94e0dd3f903ecbbbe7184a729ad66f2b6e7f17891e8c7d7654c458fa4ccb1a411ffb695b4f17bbcd3fe075fabe181027c4040ed + languageName: node + linkType: hard + "proc-log@npm:^6.0.0": version: 6.1.0 resolution: "proc-log@npm:6.1.0" @@ -3059,6 +3442,13 @@ __metadata: languageName: node linkType: hard +"punycode@npm:^2.3.1": + version: 2.3.1 + resolution: "punycode@npm:2.3.1" + checksum: 10c0/14f76a8206bc3464f794fb2e3d3cc665ae416c01893ad7a02b23766eb07159144ee612ad67af5e84fa4479ccfe67678c4feb126b0485651b302babf66f04f9e9 + languageName: node + linkType: hard + "react-dom@npm:^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0": version: 19.2.3 resolution: "react-dom@npm:19.2.3" @@ -3070,6 +3460,13 @@ __metadata: languageName: node linkType: hard +"react-is@npm:^17.0.1": + version: 17.0.2 + resolution: "react-is@npm:17.0.2" + checksum: 10c0/2bdb6b93fbb1820b024b496042cce405c57e2f85e777c9aabd55f9b26d145408f9f74f5934676ffdc46f3dcff656d78413a6e43968e7b3f92eea35b3052e9053 + languageName: node + linkType: hard + "react@npm:^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0": version: 19.2.3 resolution: "react@npm:19.2.3" @@ -3107,6 +3504,13 @@ __metadata: languageName: node linkType: hard +"require-from-string@npm:^2.0.2": + version: 2.0.2 + resolution: "require-from-string@npm:2.0.2" + checksum: 10c0/aaa267e0c5b022fc5fd4eef49d8285086b15f2a1c54b28240fdf03599cbd9c26049fee3eab894f2e1f6ca65e513b030a7c264201e3f005601e80c49fb2937ce2 + languageName: node + linkType: hard + "retry@npm:^0.12.0": version: 0.12.0 resolution: "retry@npm:0.12.0" @@ -3235,6 +3639,15 @@ __metadata: languageName: node linkType: hard +"saxes@npm:^6.0.0": + version: 6.0.0 + resolution: "saxes@npm:6.0.0" + dependencies: + xmlchars: "npm:^2.2.0" + checksum: 10c0/3847b839f060ef3476eb8623d099aa502ad658f5c40fd60c105ebce86d244389b0d76fcae30f4d0c728d7705ceb2f7e9b34bb54717b6a7dbedaf5dad2d9a4b74 + languageName: node + linkType: hard + "scheduler@npm:^0.27.0": version: 0.27.0 resolution: "scheduler@npm:0.27.0" @@ -3534,6 +3947,13 @@ __metadata: languageName: node linkType: hard +"symbol-tree@npm:^3.2.4": + version: 3.2.4 + resolution: "symbol-tree@npm:3.2.4" + checksum: 10c0/dfbe201ae09ac6053d163578778c53aa860a784147ecf95705de0cd23f42c851e1be7889241495e95c37cabb058edb1052f141387bef68f705afc8f9dd358509 + languageName: node + linkType: hard + "tabbable@npm:^6.2.0": version: 6.3.0 resolution: "tabbable@npm:6.3.0" @@ -3640,6 +4060,24 @@ __metadata: languageName: node linkType: hard +"tldts-core@npm:^7.0.19": + version: 7.0.19 + resolution: "tldts-core@npm:7.0.19" + checksum: 10c0/8f9fa5838aa7b3adbe80a6588ad802019f21faef34e04aa1aeab3a20275bba5e22c60b66a6b3bdd830b0bd6a2d57b92e0605c3cdb2c6317f111e586fa2f37927 + languageName: node + linkType: hard + +"tldts@npm:^7.0.5": + version: 7.0.19 + resolution: "tldts@npm:7.0.19" + dependencies: + tldts-core: "npm:^7.0.19" + bin: + tldts: bin/cli.js + checksum: 10c0/d77d2fe6f8ec07e27248cd6647b91fc814dfc82e15dce104277f317d861576908409f6549ff46e21277677f823a037f57b7a748ada7d0fcdcb08535890f71050 + languageName: node + linkType: hard + "totalist@npm:^3.0.0": version: 3.0.1 resolution: "totalist@npm:3.0.1" @@ -3647,6 +4085,24 @@ __metadata: languageName: node linkType: hard +"tough-cookie@npm:^6.0.0": + version: 6.0.0 + resolution: "tough-cookie@npm:6.0.0" + dependencies: + tldts: "npm:^7.0.5" + checksum: 10c0/7b17a461e9c2ac0d0bea13ab57b93b4346d0b8c00db174c963af1e46e4ea8d04148d2a55f2358fc857db0c0c65208a98e319d0c60693e32e0c559a9d9cf20cb5 + languageName: node + linkType: hard + +"tr46@npm:^6.0.0": + version: 6.0.0 + resolution: "tr46@npm:6.0.0" + dependencies: + punycode: "npm:^2.3.1" + checksum: 10c0/83130df2f649228aa91c17754b66248030a3af34911d713b5ea417066fa338aa4bc8668d06bd98aa21a2210f43fc0a3db8b9099e7747fb5830e40e39a6a1058e + languageName: node + linkType: hard + "ts-dedent@npm:^2.0.0": version: 2.2.0 resolution: "ts-dedent@npm:2.2.0" @@ -3704,6 +4160,13 @@ __metadata: languageName: node linkType: hard +"undici-types@npm:~7.16.0": + version: 7.16.0 + resolution: "undici-types@npm:7.16.0" + checksum: 10c0/3033e2f2b5c9f1504bdc5934646cb54e37ecaca0f9249c983f7b1fc2e87c6d18399ebb05dc7fd5419e02b2e915f734d872a65da2e3eeed1813951c427d33cc9a + languageName: node + linkType: hard + "unique-filename@npm:^5.0.0": version: 5.0.0 resolution: "unique-filename@npm:5.0.0" @@ -3817,6 +4280,16 @@ __metadata: languageName: node linkType: hard +"vitest-browser-svelte@npm:^2.0.1": + version: 2.0.1 + resolution: "vitest-browser-svelte@npm:2.0.1" + peerDependencies: + svelte: ^3 || ^4 || ^5 || ^5.0.0-next.0 + vitest: ^4.0.0 + checksum: 10c0/47afa35683f0dd08f1b0d5204061cb294eb5a5e0f79cf5c1e7c82581549dd75291713a5ef9a80b2fcdb324a69e90e2f12d844a9d58a3db4626ec1ba52ffbb782 + languageName: node + linkType: hard + "vitest@npm:^4.0.16": version: 4.0.16 resolution: "vitest@npm:4.0.16" @@ -3963,6 +4436,22 @@ __metadata: languageName: node linkType: hard +"w3c-xmlserializer@npm:^5.0.0": + version: 5.0.0 + resolution: "w3c-xmlserializer@npm:5.0.0" + dependencies: + xml-name-validator: "npm:^5.0.0" + checksum: 10c0/8712774c1aeb62dec22928bf1cdfd11426c2c9383a1a63f2bcae18db87ca574165a0fbe96b312b73652149167ac6c7f4cf5409f2eb101d9c805efe0e4bae798b + languageName: node + linkType: hard + +"webidl-conversions@npm:^8.0.0": + version: 8.0.1 + resolution: "webidl-conversions@npm:8.0.1" + checksum: 10c0/3f6f327ca5fa0c065ed8ed0ef3b72f33623376e68f958e9b7bd0df49fdb0b908139ac2338d19fb45bd0e05595bda96cb6d1622222a8b413daa38a17aacc4dd46 + languageName: node + linkType: hard + "webpack-virtual-modules@npm:^0.6.2": version: 0.6.2 resolution: "webpack-virtual-modules@npm:0.6.2" @@ -3970,6 +4459,23 @@ __metadata: languageName: node linkType: hard +"whatwg-mimetype@npm:^4.0.0": + version: 4.0.0 + resolution: "whatwg-mimetype@npm:4.0.0" + checksum: 10c0/a773cdc8126b514d790bdae7052e8bf242970cebd84af62fb2f35a33411e78e981f6c0ab9ed1fe6ec5071b09d5340ac9178e05b52d35a9c4bcf558ba1b1551df + languageName: node + linkType: hard + +"whatwg-url@npm:^15.0.0, whatwg-url@npm:^15.1.0": + version: 15.1.0 + resolution: "whatwg-url@npm:15.1.0" + dependencies: + tr46: "npm:^6.0.0" + webidl-conversions: "npm:^8.0.0" + checksum: 10c0/40c49b47044787c87486aaaa5b504da122820661c45ae20ab466c62595ed03c64be7c10c1d180d028949a393cd455db14144966a68359cd37fe6417e3426d128 + languageName: node + linkType: hard + "which@npm:^6.0.0": version: 6.0.0 resolution: "which@npm:6.0.0" @@ -4017,6 +4523,20 @@ __metadata: languageName: node linkType: hard +"xml-name-validator@npm:^5.0.0": + version: 5.0.0 + resolution: "xml-name-validator@npm:5.0.0" + checksum: 10c0/3fcf44e7b73fb18be917fdd4ccffff3639373c7cb83f8fc35df6001fecba7942f1dbead29d91ebb8315e2f2ff786b508f0c9dc0215b6353f9983c6b7d62cb1f5 + languageName: node + linkType: hard + +"xmlchars@npm:^2.2.0": + version: 2.2.0 + resolution: "xmlchars@npm:2.2.0" + checksum: 10c0/b64b535861a6f310c5d9bfa10834cf49127c71922c297da9d4d1b45eeaae40bf9b4363275876088fbe2667e5db028d2cd4f8ee72eed9bede840a67d57dab7593 + languageName: node + linkType: hard + "yallist@npm:^4.0.0": version: 4.0.0 resolution: "yallist@npm:4.0.0"