From 2873d70ff5c6994598144a3e9ebbd1e62f1c9fce Mon Sep 17 00:00:00 2001 From: Lo Date: Mon, 11 Nov 2024 01:17:01 +0800 Subject: [PATCH 1/8] test: add vitest and basic test suits --- package.json | 10 +- pnpm-lock.yaml | 1040 +++++++++++++++++++++++++++++++++++- src/__test__/basic.test.ts | 270 ++++++++++ tsconfig.json | 2 +- vitest.workspace.ts | 21 + 5 files changed, 1331 insertions(+), 12 deletions(-) create mode 100644 src/__test__/basic.test.ts create mode 100644 vitest.workspace.ts diff --git a/package.json b/package.json index 4fb5d03b..8bab992a 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,8 @@ "serve": "cross-env NODE_ENV=production vitepress serve .docs --host", "lint": "eslint src/**/*.ts", "lint-fix": "pnpm lint --fix", - "release": "np" + "release": "np", + "test": "vitest --workspace=vitest.workspace.ts" }, "publishConfig": { "access": "public", @@ -71,6 +72,7 @@ "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", "@vitejs/plugin-vue": "^5.0.4", + "@vitest/browser": "^2.1.4", "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-define-config": "^1.24.1", @@ -80,6 +82,7 @@ "fs-extra": "^11.2.0", "np": "^7.7.0", "npm-run-all": "^4.1.5", + "playwright": "^1.48.2", "prettier": "^2.8.8", "sortablejs": "^1.15.2", "typescript": "^5.4.5", @@ -87,6 +90,8 @@ "vite": "^5.2.12", "vite-plugin-dts": "^1.7.3", "vitepress": "1.0.0-rc.44", + "vitest": "^2.1.4", + "vitest-browser-vue": "^0.0.1", "vue": "^3.4.27", "vue-demi": "^0.13.11", "vue-eslint-parser": "^9.4.2" @@ -101,5 +106,6 @@ "@vue/composition-api": { "optional": true } - } + }, + "packageManager": "pnpm@9.12.3+sha512.cce0f9de9c5a7c95bef944169cc5dfe8741abfb145078c0d508b868056848a87c81e626246cb60967cbd7fd29a6c062ef73ff840d96b3c86c40ac92cf4a813ee" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 46181bf0..01000b37 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -33,6 +33,9 @@ importers: '@vitejs/plugin-vue': specifier: ^5.0.4 version: 5.0.4(vite@5.2.12(@types/node@20.12.13))(vue@3.4.27(typescript@5.4.5)) + '@vitest/browser': + specifier: ^2.1.4 + version: 2.1.4(@types/node@20.12.13)(playwright@1.48.2)(typescript@5.4.5)(vite@5.2.12(@types/node@20.12.13))(vitest@2.1.4) cross-env: specifier: ^7.0.3 version: 7.0.3 @@ -60,6 +63,9 @@ importers: npm-run-all: specifier: ^4.1.5 version: 4.1.5 + playwright: + specifier: ^1.48.2 + version: 1.48.2 prettier: specifier: ^2.8.8 version: 2.8.8 @@ -81,6 +87,12 @@ importers: vitepress: specifier: 1.0.0-rc.44 version: 1.0.0-rc.44(@algolia/client-search@4.23.3)(@types/node@20.12.13)(postcss@8.4.38)(search-insights@2.14.0)(sortablejs@1.15.2)(typescript@5.4.5) + vitest: + specifier: ^2.1.4 + version: 2.1.4(@types/node@20.12.13)(@vitest/browser@2.1.4)(msw@2.6.2(@types/node@20.12.13)(typescript@5.4.5)) + vitest-browser-vue: + specifier: ^0.0.1 + version: 0.0.1(@vitest/browser@2.1.4)(vitest@2.1.4)(vue@3.4.27(typescript@5.4.5)) vue: specifier: ^3.4.27 version: 3.4.27(typescript@5.4.5) @@ -305,6 +317,10 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/runtime@7.26.0': + resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==} + engines: {node: '>=6.9.0'} + '@babel/template@7.24.6': resolution: {integrity: sha512-3vgazJlLwNXi9jhrR1ef8qiB65L1RK90+lEQwv4OxveHnqC3BfmnHdgySwRLzf6akhlOYenT+b7AfWq+a//AHw==} engines: {node: '>=6.9.0'} @@ -317,6 +333,15 @@ packages: resolution: {integrity: sha512-WaMsgi6Q8zMgMth93GvWPXkhAIEobfsIkLTacoVZoK1J0CevIPGYY2Vo5YvJGqyHqXM6P4ppOYGsIRU8MM9pFQ==} engines: {node: '>=6.9.0'} + '@bundled-es-modules/cookie@2.0.1': + resolution: {integrity: sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw==} + + '@bundled-es-modules/statuses@1.0.1': + resolution: {integrity: sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==} + + '@bundled-es-modules/tough-cookie@0.1.6': + resolution: {integrity: sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==} + '@docsearch/css@3.6.0': resolution: {integrity: sha512-+sbxb71sWre+PwDK7X2T8+bhS6clcVMLwBPznX45Qu6opJcgRjAp7gYSDzVFp187J+feSj5dNBN1mJoi6ckkUQ==} @@ -525,6 +550,30 @@ packages: '@iconify/utils@2.1.23': resolution: {integrity: sha512-YGNbHKM5tyDvdWZ92y2mIkrfvm5Fvhe6WJSkWu7vvOFhMtYDP0casZpoRz0XEHZCrYsR4stdGT3cZ52yp5qZdQ==} + '@inquirer/confirm@5.0.1': + resolution: {integrity: sha512-6ycMm7k7NUApiMGfVc32yIPp28iPKxhGRMqoNDiUjq2RyTAkbs5Fx0TdzBqhabcKvniDdAAvHCmsRjnNfTsogw==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + + '@inquirer/core@10.0.1': + resolution: {integrity: sha512-KKTgjViBQUi3AAssqjUFMnMO3CM3qwCHvePV9EW+zTKGKafFGFF01sc1yOIYjLJ7QU52G/FbzKc+c01WLzXmVQ==} + engines: {node: '>=18'} + + '@inquirer/figures@1.0.7': + resolution: {integrity: sha512-m+Trk77mp54Zma6xLkLuY+mvanPxlE4A7yNKs2HBiyZ4UkVs28Mv5c/pgWrHeInx+USHeX/WEPzjrWrcJiQgjw==} + engines: {node: '>=18'} + + '@inquirer/type@3.0.0': + resolution: {integrity: sha512-YYykfbw/lefC7yKj7nanzQXILM7r3suIvyFlCcMskc99axmsSewXWkAfXKwMbgxL76iAFVmRwmYdwNZNc8gjog==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + '@jridgewell/gen-mapping@0.3.5': resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} @@ -540,6 +589,9 @@ packages: '@jridgewell/sourcemap-codec@1.4.15': resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} @@ -556,6 +608,10 @@ packages: '@microsoft/tsdoc@0.15.0': resolution: {integrity: sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==} + '@mswjs/interceptors@0.36.10': + resolution: {integrity: sha512-GXrJgakgJW3DWKueebkvtYgGKkxA7s0u5B0P5syJM5rvQUnrpLPigvci8Hukl7yEM+sU06l+er2Fgvx/gmiRgg==} + engines: {node: '>=18'} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -568,6 +624,22 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@one-ini/wasm@0.1.1': + resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==} + + '@open-draft/deferred-promise@2.2.0': + resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} + + '@open-draft/logger@0.3.0': + resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} + + '@open-draft/until@2.1.0': + resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + '@polka/url@1.0.0-next.25': resolution: {integrity: sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==} @@ -604,55 +676,46 @@ packages: resolution: {integrity: sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==} cpu: [arm] os: [linux] - libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.18.0': resolution: {integrity: sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==} cpu: [arm] os: [linux] - libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.18.0': resolution: {integrity: sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==} cpu: [arm64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.18.0': resolution: {integrity: sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==} cpu: [arm64] os: [linux] - libc: [musl] '@rollup/rollup-linux-powerpc64le-gnu@4.18.0': resolution: {integrity: sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==} cpu: [ppc64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-riscv64-gnu@4.18.0': resolution: {integrity: sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==} cpu: [riscv64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-s390x-gnu@4.18.0': resolution: {integrity: sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==} cpu: [s390x] os: [linux] - libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.18.0': resolution: {integrity: sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==} cpu: [x64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-x64-musl@4.18.0': resolution: {integrity: sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==} cpu: [x64] os: [linux] - libc: [musl] '@rollup/rollup-win32-arm64-msvc@4.18.0': resolution: {integrity: sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==} @@ -750,15 +813,31 @@ packages: resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} engines: {node: '>=10'} + '@testing-library/dom@10.4.0': + resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} + engines: {node: '>=18'} + + '@testing-library/user-event@14.5.2': + resolution: {integrity: sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==} + engines: {node: '>=12', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' + '@ts-morph/common@0.18.1': resolution: {integrity: sha512-RVE+zSRICWRsfrkAw5qCAK+4ZH9kwEFv5h0+/YeHTLieWP7F4wWq4JsKFuNWG+fYh/KF+8rAtgdj5zb2mm+DVA==} '@types/argparse@1.0.38': resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==} + '@types/aria-query@5.0.4': + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + '@types/cacheable-request@6.0.3': resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} + '@types/cookie@0.6.0': + resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} @@ -804,6 +883,12 @@ packages: '@types/sortablejs@1.15.8': resolution: {integrity: sha512-b79830lW+RZfwaztgs1aVPgbasJ8e7AXtZYHTELNXZPsERt4ymJdjV4OccDbHQAvHrCcFpbF78jkm0R6h/pZVg==} + '@types/statuses@2.0.5': + resolution: {integrity: sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A==} + + '@types/tough-cookie@4.0.5': + resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + '@types/web-bluetooth@0.0.16': resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==} @@ -971,6 +1056,50 @@ packages: vite: ^5.0.0 vue: ^3.2.25 + '@vitest/browser@2.1.4': + resolution: {integrity: sha512-89SrvShW6kWzmEYtBj5k1gBq88emoC2qrngw5hE1vNpRFteQ5/1URbKIVww391rIALTpzhhCt5yJt5tjLPZxYw==} + peerDependencies: + playwright: '*' + safaridriver: '*' + vitest: 2.1.4 + webdriverio: '*' + peerDependenciesMeta: + playwright: + optional: true + safaridriver: + optional: true + webdriverio: + optional: true + + '@vitest/expect@2.1.4': + resolution: {integrity: sha512-DOETT0Oh1avie/D/o2sgMHGrzYUFFo3zqESB2Hn70z6QB1HrS2IQ9z5DfyTqU8sg4Bpu13zZe9V4+UTNQlUeQA==} + + '@vitest/mocker@2.1.4': + resolution: {integrity: sha512-Ky/O1Lc0QBbutJdW0rqLeFNbuLEyS+mIPiNdlVlp2/yhJ0SbyYqObS5IHdhferJud8MbbwMnexg4jordE5cCoQ==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@2.1.4': + resolution: {integrity: sha512-L95zIAkEuTDbUX1IsjRl+vyBSLh3PwLLgKpghl37aCK9Jvw0iP+wKwIFhfjdUtA2myLgjrG6VU6JCFLv8q/3Ww==} + + '@vitest/runner@2.1.4': + resolution: {integrity: sha512-sKRautINI9XICAMl2bjxQM8VfCMTB0EbsBc/EDFA57V6UQevEKY/TOPOF5nzcvCALltiLfXWbq4MaAwWx/YxIA==} + + '@vitest/snapshot@2.1.4': + resolution: {integrity: sha512-3Kab14fn/5QZRog5BPj6Rs8dc4B+mim27XaKWFWHWA87R56AKjHTGcBFKpvZKDzC4u5Wd0w/qKsUIio3KzWW4Q==} + + '@vitest/spy@2.1.4': + resolution: {integrity: sha512-4JOxa+UAizJgpZfaCPKK2smq9d8mmjZVPMt2kOsg/R8QkoRzydHH1qHxIYNvr1zlEaFj4SXiaaJWxq/LPLKaLg==} + + '@vitest/utils@2.1.4': + resolution: {integrity: sha512-MXDnZn0Awl2S86PSNIim5PWXgIAx8CIkzu35mBdSApUip6RFOGXBCf3YFyeEu8n1IHk4bWD46DeYFu9mQlFIRg==} + '@vue/compiler-core@3.4.27': resolution: {integrity: sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==} @@ -1014,6 +1143,9 @@ packages: '@vue/shared@3.4.27': resolution: {integrity: sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==} + '@vue/test-utils@2.4.6': + resolution: {integrity: sha512-FMxEjOpYNYiFe0GkaHsnJPXFHxQ6m4t8vI/ElPGpMWxZKpmRvQ33OIrvRXemy6yha03RxhOlQuy+gZMC3CQSow==} + '@vueuse/core@10.10.0': resolution: {integrity: sha512-vexJ/YXYs2S42B783rI95lMt3GzEwkxzC8Hb0Ndpd8rD+p+Lk/Za4bd797Ym7yq4jXqdSyj3JLChunF/vyYjUw==} @@ -1073,6 +1205,10 @@ packages: '@vueuse/shared@9.13.0': resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==} + abbrev@2.0.0: + resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -1142,6 +1278,10 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + ansi-styles@2.2.1: resolution: {integrity: sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==} engines: {node: '>=0.10.0'} @@ -1154,6 +1294,14 @@ packages: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + any-observable@0.3.0: resolution: {integrity: sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==} engines: {node: '>=6'} @@ -1188,6 +1336,9 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + array-buffer-byte-length@1.0.1: resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} engines: {node: '>= 0.4'} @@ -1220,6 +1371,10 @@ packages: resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} engines: {node: '>=0.10.0'} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + async-exit-hook@2.0.1: resolution: {integrity: sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==} engines: {node: '>=0.12.0'} @@ -1302,6 +1457,10 @@ packages: caniuse-lite@1.0.30001625: resolution: {integrity: sha512-4KE9N2gcRH+HQhpeiRZXd+1niLB/XNLAhSy4z7fI8EzcbcPoAqjNInxVHTiTwWfTIV4w096XG8OtCOCQQKPv3w==} + chai@5.1.2: + resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} + engines: {node: '>=12'} + chalk@1.1.3: resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==} engines: {node: '>=0.10.0'} @@ -1317,6 +1476,10 @@ packages: chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} + chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -1351,6 +1514,14 @@ packages: resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} engines: {node: '>= 10'} + cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + clone-response@1.0.3: resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} @@ -1381,6 +1552,10 @@ packages: resolution: {integrity: sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==} engines: {node: '>=0.1.90'} + commander@10.0.1: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} + engines: {node: '>=14'} + commander@9.5.0: resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} engines: {node: ^12.20.0 || >=14} @@ -1391,6 +1566,9 @@ packages: confbox@0.1.7: resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} + config-chain@1.1.13: + resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} + configstore@5.0.1: resolution: {integrity: sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==} engines: {node: '>=8'} @@ -1402,6 +1580,10 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + cosmiconfig@7.1.0: resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} engines: {node: '>=10'} @@ -1467,6 +1649,15 @@ packages: supports-color: optional: true + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + decamelize-keys@1.1.1: resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} engines: {node: '>=0.10.0'} @@ -1483,6 +1674,10 @@ packages: resolution: {integrity: sha512-TLZWWybuxWgoW7Lykv+gq9xvzOsUjQ9tF09Tj6NSTYGMTCHNXzrPnD6Hi+TgZq19PyTAGH4Ll/NIM/eTGglnMw==} engines: {node: '>=10'} + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + deep-extend@0.6.0: resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} engines: {node: '>=4.0.0'} @@ -1512,6 +1707,10 @@ packages: resolution: {integrity: sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==} engines: {node: '>=10'} + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + destr@2.0.3: resolution: {integrity: sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==} @@ -1527,6 +1726,9 @@ packages: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} + dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + dot-prop@5.3.0: resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} engines: {node: '>=8'} @@ -1541,6 +1743,14 @@ packages: duplexer@0.1.2: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + editorconfig@1.0.4: + resolution: {integrity: sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==} + engines: {node: '>=14'} + hasBin: true + electron-to-chromium@1.4.786: resolution: {integrity: sha512-i/A2UB0sxYViMN0M2zIotQFRIOt1jLuVXudACHBDiJ5gGuAUzf/crZxwlBTdA0O52Hy4CNtTzS7AKRAacs/08Q==} @@ -1551,6 +1761,9 @@ packages: emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + end-of-stream@1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} @@ -1851,6 +2064,9 @@ packages: estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + 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'} @@ -1859,6 +2075,10 @@ packages: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} + expect-type@1.1.0: + resolution: {integrity: sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==} + engines: {node: '>=12.0.0'} + extend-shallow@2.0.1: resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} engines: {node: '>=0.10.0'} @@ -1924,6 +2144,10 @@ packages: for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + foreground-child@3.3.0: + resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} + engines: {node: '>=14'} + fs-extra@10.1.0: resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} engines: {node: '>=12'} @@ -1939,6 +2163,11 @@ packages: fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -1958,6 +2187,10 @@ packages: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + get-intrinsic@1.2.4: resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} @@ -1989,6 +2222,10 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Glob versions prior to v9 are no longer supported @@ -2038,6 +2275,10 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + graphql@16.9.0: + resolution: {integrity: sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==} + engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + gray-matter@4.0.3: resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} engines: {node: '>=6.0'} @@ -2088,6 +2329,9 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} + headers-polyfill@4.0.3: + resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==} + hookable@5.5.3: resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} @@ -2263,6 +2507,9 @@ packages: resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} + is-node-process@1.2.0: + resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} + is-npm@5.0.0: resolution: {integrity: sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==} engines: {node: '>=10'} @@ -2365,6 +2612,9 @@ packages: resolution: {integrity: sha512-0RHjbtw9QXeSYnIEY5Yrp2QZrdtz21xBDV9C/GIlY2POmgoS6a7qjkYS5siRKXScnuAj5/SPv1C3YForNCHTJA==} engines: {node: '>=10'} + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + jiti@1.21.0: resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==} hasBin: true @@ -2372,6 +2622,15 @@ packages: jju@1.4.0: resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} + js-beautify@1.15.1: + resolution: {integrity: sha512-ESjNzSlt/sWE8sciZH8kBF8BPlwXPwhR6pWKAw8bw4Bwj+iZcnKW6ONWUutJ7eObuBZQpiIb8S7OYspWrKt7rA==} + engines: {node: '>=14'} + hasBin: true + + js-cookie@3.0.5: + resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} + engines: {node: '>=14'} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -2519,6 +2778,9 @@ packages: resolution: {integrity: sha512-vlP11XfFGyeNQlmEn9tJ66rEW1coA/79m5z6BCkudjbAGE83uhAcGYrBFwfs3AdLiLzGRusRPAbSPK9xZteCmg==} engines: {node: '>=4'} + loupe@3.1.2: + resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} + lowercase-keys@1.0.1: resolution: {integrity: sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==} engines: {node: '>=0.10.0'} @@ -2527,6 +2789,9 @@ packages: resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} engines: {node: '>=8'} + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -2534,9 +2799,16 @@ packages: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} + lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + magic-string@0.30.10: resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} + magic-string@0.30.12: + resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==} + make-dir@3.1.0: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} engines: {node: '>=8'} @@ -2619,6 +2891,14 @@ packages: resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} engines: {node: '>=10'} + minimatch@9.0.1: + resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==} + engines: {node: '>=16 || 14 >=14.17'} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + minimist-options@4.1.0: resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} engines: {node: '>= 6'} @@ -2626,6 +2906,10 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + minisearch@6.3.0: resolution: {integrity: sha512-ihFnidEeU8iXzcVHy74dhkxh/dn8Dc08ERl0xwoMMGqp4+LvRSCgicb+zGqWthVokQKvCSxITlh3P08OzdTYCQ==} @@ -2650,12 +2934,26 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + msw@2.6.2: + resolution: {integrity: sha512-RdRgPvjfuzMIACkWv7VOVAeSRYMU3ofokLv1w0RsbFX960qnj/tFEyOFXY0G2GTUd9trA6rHuHciM/FKpBp6/A==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + typescript: '>= 4.8.x' + peerDependenciesMeta: + typescript: + optional: true + mute-stream@0.0.7: resolution: {integrity: sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==} mute-stream@0.0.8: resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} + mute-stream@2.0.0: + resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} + engines: {node: ^18.17.0 || >=20.5.0} + nanoid@3.3.7: resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -2680,6 +2978,11 @@ packages: node-releases@2.0.14: resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + nopt@7.2.1: + resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} @@ -2781,6 +3084,9 @@ packages: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} + outvariant@1.4.3: + resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} + ow@0.21.0: resolution: {integrity: sha512-dlsoDe39g7mhdsdrC1R/YwjT7yjVqE3svWwOlMGvN690waBkgEZBmKBdkmKvSt5/wZ6E0Jn/nIesPqMZOpPKqw==} engines: {node: '>=10'} @@ -2857,6 +3163,9 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + package-json@6.5.0: resolution: {integrity: sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==} engines: {node: '>=8'} @@ -2895,6 +3204,13 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + path-to-regexp@6.3.0: + resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + path-type@3.0.0: resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} engines: {node: '>=4'} @@ -2906,6 +3222,10 @@ packages: pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} + perfect-debounce@1.0.0: resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} @@ -2936,6 +3256,16 @@ packages: pkg-types@1.1.1: resolution: {integrity: sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==} + playwright-core@1.48.2: + resolution: {integrity: sha512-sjjw+qrLFlriJo64du+EK0kJgZzoQPsabGF4lBvsid+3CNIZIYLgnMj9V6JY5VhM2Peh20DJWIVpVljLLnlawA==} + engines: {node: '>=18'} + hasBin: true + + playwright@1.48.2: + resolution: {integrity: sha512-NjYvYgp4BPmiwfe31j4gHLa3J7bD2WiBz8Lk2RoSsmX38SVIARZ18VYjxLjAcDsAhA+F4iSEXTSGgjua0rrlgQ==} + engines: {node: '>=18'} + hasBin: true + possible-typed-array-names@1.0.0: resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} engines: {node: '>= 0.4'} @@ -2964,6 +3294,16 @@ packages: engines: {node: '>=10.13.0'} hasBin: true + pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + proto-list@1.2.4: + resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + + psl@1.10.0: + resolution: {integrity: sha512-KSKHEbjAnpUuAUserOq0FxGXCUrzC3WniuSJhvdbs102rL55266ZcHBqLWOsG30spQMlPdpy7icATiAQehg/iA==} + pump@3.0.0: resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} @@ -2975,6 +3315,9 @@ packages: resolution: {integrity: sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==} engines: {node: '>=8'} + querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -2986,6 +3329,9 @@ packages: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true + react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + read-pkg-up@7.0.1: resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} engines: {node: '>=8'} @@ -3006,6 +3352,9 @@ packages: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + regexp.prototype.flags@1.5.2: resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} engines: {node: '>= 0.4'} @@ -3022,10 +3371,17 @@ packages: resolution: {integrity: sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==} engines: {node: '>=8'} + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + require-from-string@2.0.2: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} + requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + resolve-cwd@3.0.0: resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} engines: {node: '>=8'} @@ -3170,13 +3526,24 @@ packages: resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} engines: {node: '>= 0.4'} + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + 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'} + sirv@2.0.4: resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} engines: {node: '>= 10'} + sirv@3.0.0: + resolution: {integrity: sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==} + engines: {node: '>=18'} + slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} @@ -3222,6 +3589,19 @@ packages: sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + + std-env@3.7.0: + resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + + strict-event-emitter@0.5.1: + resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} + string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} @@ -3238,6 +3618,10 @@ packages: 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'} + string.prototype.padend@3.1.6: resolution: {integrity: sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==} engines: {node: '>= 0.4'} @@ -3269,6 +3653,10 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + strip-bom-string@1.0.0: resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} engines: {node: '>=0.10.0'} @@ -3338,6 +3726,24 @@ packages: through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@0.3.1: + resolution: {integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==} + + tinypool@1.0.1: + resolution: {integrity: sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + + tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + engines: {node: '>=14.0.0'} + tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -3362,6 +3768,10 @@ packages: resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} engines: {node: '>=6'} + tough-cookie@4.1.4: + resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} + engines: {node: '>=6'} + trim-newlines@3.0.1: resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} engines: {node: '>=8'} @@ -3413,6 +3823,10 @@ packages: resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} engines: {node: '>=8'} + type-fest@4.26.1: + resolution: {integrity: sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==} + engines: {node: '>=16'} + typed-array-buffer@1.0.2: resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} engines: {node: '>= 0.4'} @@ -3465,6 +3879,10 @@ packages: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} + universalify@0.2.0: + resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} + engines: {node: '>= 4.0.0'} + universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} @@ -3498,6 +3916,9 @@ packages: resolution: {integrity: sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==} engines: {node: '>=4'} + url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -3515,6 +3936,11 @@ packages: resolution: {integrity: sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==} engines: {node: '>= 0.10'} + vite-node@2.1.4: + resolution: {integrity: sha512-kqa9v+oi4HwkG6g8ufRnb5AeplcRw8jUF6/7/Qz1qRQOXHImG8YnLbB+LLszENwFnoBl9xIf9nVdCFzNd7GQEg==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + vite-plugin-dts@1.7.3: resolution: {integrity: sha512-u3t45p6fTbzUPMkwYe0ESwuUeiRMlwdPfD3dRyDKUwLe2WmEYcFyVp2o9/ke2EMrM51lQcmNWdV9eLcgjD1/ng==} engines: {node: ^14.18.0 || >=16.0.0} @@ -3590,12 +4016,48 @@ packages: postcss: optional: true + vitest-browser-vue@0.0.1: + resolution: {integrity: sha512-r4UoOR2zFg0p5FFmYhcdIp6gFVXcQrVr5+zpm4h+1uAD1V+x7WUWrVzkFAFzeXVU2DfjhHMGxIvEBQT2HOw4Ew==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + '@vitest/browser': ^2.1.0-beta.4 + vitest: ^2.1.0-beta.4 + vue: ^3.0.0 + + vitest@2.1.4: + resolution: {integrity: sha512-eDjxbVAJw1UJJCHr5xr/xM86Zx+YxIEXGAR+bmnEID7z9qWfoxpHw0zdobz+TQAFOLT+nEXz3+gx6nUJ7RgmlQ==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 2.1.4 + '@vitest/ui': 2.1.4 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + vscode-oniguruma@1.7.0: resolution: {integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==} vscode-textmate@6.0.0: resolution: {integrity: sha512-gu73tuZfJgu+mvCSy4UZwd2JXykjK9zAZsfmDeut5dx/1a7FeTk0XwJsSuqQn+cuMCGVbIBfl+s53X4T19DnzQ==} + vue-component-type-helpers@2.1.10: + resolution: {integrity: sha512-lfgdSLQKrUmADiSV6PbBvYgQ33KF3Ztv6gP85MfGaGaSGMTXORVaHT1EHfsqCgzRNBstPKYDmvAV9Do5CmJ07A==} + vue-demi@0.13.11: resolution: {integrity: sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==} engines: {node: '>=12'} @@ -3648,6 +4110,11 @@ packages: engines: {node: '>= 8'} hasBin: true + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + widest-line@3.1.0: resolution: {integrity: sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==} engines: {node: '>=8'} @@ -3660,16 +4127,36 @@ packages: resolution: {integrity: sha512-iXR3tDXpbnTpzjKSylUJRkLuOrEC7hwEB221cgn6wtF8wpmz28puFXAEfPT5zrjM3wahygB//VuWEr1vTkDcNQ==} engines: {node: '>=4'} + 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'} + wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} write-file-atomic@3.0.3: resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + 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 + xdg-basedir@4.0.0: resolution: {integrity: sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==} engines: {node: '>=8'} @@ -3678,6 +4165,10 @@ packages: resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} engines: {node: '>=12'} + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} @@ -3692,10 +4183,22 @@ packages: resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} engines: {node: '>=10'} + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + yoctocolors-cjs@2.1.2: + resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==} + engines: {node: '>=18'} + z-schema@5.0.5: resolution: {integrity: sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==} engines: {node: '>=8.0.0'} @@ -3987,6 +4490,10 @@ snapshots: '@babel/plugin-transform-modules-commonjs': 7.24.6(@babel/core@7.24.6) '@babel/plugin-transform-typescript': 7.24.6(@babel/core@7.24.6) + '@babel/runtime@7.26.0': + dependencies: + regenerator-runtime: 0.14.1 + '@babel/template@7.24.6': dependencies: '@babel/code-frame': 7.24.6 @@ -4014,6 +4521,19 @@ snapshots: '@babel/helper-validator-identifier': 7.24.6 to-fast-properties: 2.0.0 + '@bundled-es-modules/cookie@2.0.1': + dependencies: + cookie: 0.7.2 + + '@bundled-es-modules/statuses@1.0.1': + dependencies: + statuses: 2.0.1 + + '@bundled-es-modules/tough-cookie@0.1.6': + dependencies: + '@types/tough-cookie': 4.0.5 + tough-cookie: 4.1.4 + '@docsearch/css@3.6.0': {} '@docsearch/js@3.6.0(@algolia/client-search@4.23.3)(search-insights@2.14.0)': @@ -4162,6 +4682,41 @@ snapshots: transitivePeerDependencies: - supports-color + '@inquirer/confirm@5.0.1(@types/node@20.12.13)': + dependencies: + '@inquirer/core': 10.0.1(@types/node@20.12.13) + '@inquirer/type': 3.0.0(@types/node@20.12.13) + '@types/node': 20.12.13 + + '@inquirer/core@10.0.1(@types/node@20.12.13)': + dependencies: + '@inquirer/figures': 1.0.7 + '@inquirer/type': 3.0.0(@types/node@20.12.13) + ansi-escapes: 4.3.2 + cli-width: 4.1.0 + mute-stream: 2.0.0 + signal-exit: 4.1.0 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.2 + transitivePeerDependencies: + - '@types/node' + + '@inquirer/figures@1.0.7': {} + + '@inquirer/type@3.0.0(@types/node@20.12.13)': + dependencies: + '@types/node': 20.12.13 + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + '@jridgewell/gen-mapping@0.3.5': dependencies: '@jridgewell/set-array': 1.2.1 @@ -4174,6 +4729,8 @@ snapshots: '@jridgewell/sourcemap-codec@1.4.15': {} + '@jridgewell/sourcemap-codec@1.5.0': {} + '@jridgewell/trace-mapping@0.3.25': dependencies: '@jridgewell/resolve-uri': 3.1.2 @@ -4214,6 +4771,15 @@ snapshots: '@microsoft/tsdoc@0.15.0': {} + '@mswjs/interceptors@0.36.10': + dependencies: + '@open-draft/deferred-promise': 2.2.0 + '@open-draft/logger': 0.3.0 + '@open-draft/until': 2.1.0 + is-node-process: 1.2.0 + outvariant: 1.4.3 + strict-event-emitter: 0.5.1 + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -4226,6 +4792,20 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.17.1 + '@one-ini/wasm@0.1.1': {} + + '@open-draft/deferred-promise@2.2.0': {} + + '@open-draft/logger@0.3.0': + dependencies: + is-node-process: 1.2.0 + outvariant: 1.4.3 + + '@open-draft/until@2.1.0': {} + + '@pkgjs/parseargs@0.11.0': + optional: true + '@polka/url@1.0.0-next.25': {} '@rollup/pluginutils@5.1.0(rollup@4.18.0)': @@ -4426,6 +5006,21 @@ snapshots: dependencies: defer-to-connect: 2.0.1 + '@testing-library/dom@10.4.0': + dependencies: + '@babel/code-frame': 7.24.6 + '@babel/runtime': 7.26.0 + '@types/aria-query': 5.0.4 + aria-query: 5.3.0 + chalk: 4.1.2 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + pretty-format: 27.5.1 + + '@testing-library/user-event@14.5.2(@testing-library/dom@10.4.0)': + dependencies: + '@testing-library/dom': 10.4.0 + '@ts-morph/common@0.18.1': dependencies: fast-glob: 3.3.2 @@ -4435,6 +5030,8 @@ snapshots: '@types/argparse@1.0.38': {} + '@types/aria-query@5.0.4': {} + '@types/cacheable-request@6.0.3': dependencies: '@types/http-cache-semantics': 4.0.4 @@ -4442,6 +5039,8 @@ snapshots: '@types/node': 20.12.13 '@types/responselike': 1.0.3 + '@types/cookie@0.6.0': {} + '@types/estree@1.0.5': {} '@types/http-cache-semantics@4.0.4': {} @@ -4481,6 +5080,10 @@ snapshots: '@types/sortablejs@1.15.8': {} + '@types/statuses@2.0.5': {} + + '@types/tough-cookie@4.0.5': {} + '@types/web-bluetooth@0.0.16': {} '@types/web-bluetooth@0.0.20': {} @@ -4734,6 +5337,68 @@ snapshots: vite: 5.2.12(@types/node@20.12.13) vue: 3.4.27(typescript@5.4.5) + '@vitest/browser@2.1.4(@types/node@20.12.13)(playwright@1.48.2)(typescript@5.4.5)(vite@5.2.12(@types/node@20.12.13))(vitest@2.1.4)': + dependencies: + '@testing-library/dom': 10.4.0 + '@testing-library/user-event': 14.5.2(@testing-library/dom@10.4.0) + '@vitest/mocker': 2.1.4(msw@2.6.2(@types/node@20.12.13)(typescript@5.4.5))(vite@5.2.12(@types/node@20.12.13)) + '@vitest/utils': 2.1.4 + magic-string: 0.30.12 + msw: 2.6.2(@types/node@20.12.13)(typescript@5.4.5) + sirv: 3.0.0 + tinyrainbow: 1.2.0 + vitest: 2.1.4(@types/node@20.12.13)(@vitest/browser@2.1.4)(msw@2.6.2(@types/node@20.12.13)(typescript@5.4.5)) + ws: 8.18.0 + optionalDependencies: + playwright: 1.48.2 + transitivePeerDependencies: + - '@types/node' + - bufferutil + - typescript + - utf-8-validate + - vite + + '@vitest/expect@2.1.4': + dependencies: + '@vitest/spy': 2.1.4 + '@vitest/utils': 2.1.4 + chai: 5.1.2 + tinyrainbow: 1.2.0 + + '@vitest/mocker@2.1.4(msw@2.6.2(@types/node@20.12.13)(typescript@5.4.5))(vite@5.2.12(@types/node@20.12.13))': + dependencies: + '@vitest/spy': 2.1.4 + estree-walker: 3.0.3 + magic-string: 0.30.12 + optionalDependencies: + msw: 2.6.2(@types/node@20.12.13)(typescript@5.4.5) + vite: 5.2.12(@types/node@20.12.13) + + '@vitest/pretty-format@2.1.4': + dependencies: + tinyrainbow: 1.2.0 + + '@vitest/runner@2.1.4': + dependencies: + '@vitest/utils': 2.1.4 + pathe: 1.1.2 + + '@vitest/snapshot@2.1.4': + dependencies: + '@vitest/pretty-format': 2.1.4 + magic-string: 0.30.12 + pathe: 1.1.2 + + '@vitest/spy@2.1.4': + dependencies: + tinyspy: 3.0.2 + + '@vitest/utils@2.1.4': + dependencies: + '@vitest/pretty-format': 2.1.4 + loupe: 3.1.2 + tinyrainbow: 1.2.0 + '@vue/compiler-core@3.4.27': dependencies: '@babel/parser': 7.24.6 @@ -4808,6 +5473,11 @@ snapshots: '@vue/shared@3.4.27': {} + '@vue/test-utils@2.4.6': + dependencies: + js-beautify: 1.15.1 + vue-component-type-helpers: 2.1.10 + '@vueuse/core@10.10.0(vue@3.4.27(typescript@5.4.5))': dependencies: '@types/web-bluetooth': 0.0.20 @@ -4858,6 +5528,8 @@ snapshots: - '@vue/composition-api' - vue + abbrev@2.0.0: {} + acorn-jsx@5.3.2(acorn@8.11.3): dependencies: acorn: 8.11.3 @@ -4934,6 +5606,8 @@ snapshots: ansi-regex@5.0.1: {} + ansi-regex@6.1.0: {} + ansi-styles@2.2.1: {} ansi-styles@3.2.1: @@ -4944,6 +5618,10 @@ snapshots: dependencies: color-convert: 2.0.1 + ansi-styles@5.2.0: {} + + ansi-styles@6.2.1: {} + any-observable@0.3.0(rxjs@6.6.7): optionalDependencies: rxjs: 6.6.7 @@ -4963,6 +5641,10 @@ snapshots: argparse@2.0.1: {} + aria-query@5.3.0: + dependencies: + dequal: 2.0.3 + array-buffer-byte-length@1.0.1: dependencies: call-bind: 1.0.7 @@ -5015,6 +5697,8 @@ snapshots: arrify@1.0.1: {} + assertion-error@2.0.1: {} + async-exit-hook@2.0.1: {} available-typed-arrays@1.0.7: @@ -5111,6 +5795,14 @@ snapshots: caniuse-lite@1.0.30001625: {} + chai@5.1.2: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.2 + pathval: 2.0.0 + chalk@1.1.3: dependencies: ansi-styles: 2.2.1 @@ -5132,6 +5824,8 @@ snapshots: chardet@0.7.0: {} + check-error@2.1.1: {} + chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -5167,6 +5861,14 @@ snapshots: cli-width@3.0.0: {} + cli-width@4.1.0: {} + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + clone-response@1.0.3: dependencies: mimic-response: 1.0.1 @@ -5191,6 +5893,8 @@ snapshots: colors@1.2.5: {} + commander@10.0.1: {} + commander@9.5.0: optional: true @@ -5198,6 +5902,11 @@ snapshots: confbox@0.1.7: {} + config-chain@1.1.13: + dependencies: + ini: 1.3.8 + proto-list: 1.2.4 + configstore@5.0.1: dependencies: dot-prop: 5.3.0 @@ -5211,6 +5920,8 @@ snapshots: convert-source-map@2.0.0: {} + cookie@0.7.2: {} + cosmiconfig@7.1.0: dependencies: '@types/parse-json': 4.0.2 @@ -5276,6 +5987,10 @@ snapshots: dependencies: ms: 2.1.2 + debug@4.3.7: + dependencies: + ms: 2.1.3 + decamelize-keys@1.1.1: dependencies: decamelize: 1.2.0 @@ -5291,6 +6006,8 @@ snapshots: dependencies: mimic-response: 2.1.0 + deep-eql@5.0.2: {} + deep-extend@0.6.0: {} deep-is@0.1.4: {} @@ -5324,6 +6041,8 @@ snapshots: rimraf: 3.0.2 slash: 3.0.0 + dequal@2.0.3: {} + destr@2.0.3: {} dir-glob@3.0.1: @@ -5338,6 +6057,8 @@ snapshots: dependencies: esutils: 2.0.3 + dom-accessibility-api@0.5.16: {} + dot-prop@5.3.0: dependencies: is-obj: 2.0.0 @@ -5350,12 +6071,23 @@ snapshots: duplexer@0.1.2: {} + eastasianwidth@0.2.0: {} + + editorconfig@1.0.4: + dependencies: + '@one-ini/wasm': 0.1.1 + commander: 10.0.1 + minimatch: 9.0.1 + semver: 7.6.2 + electron-to-chromium@1.4.786: {} elegant-spinner@1.0.1: {} emoji-regex@8.0.0: {} + emoji-regex@9.2.2: {} + end-of-stream@1.4.4: dependencies: once: 1.4.0 @@ -5724,6 +6456,10 @@ snapshots: estree-walker@2.0.2: {} + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.5 + esutils@2.0.3: {} execa@5.1.1: @@ -5738,6 +6474,8 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 2.0.0 + expect-type@1.1.0: {} + extend-shallow@2.0.1: dependencies: is-extendable: 0.1.1 @@ -5813,6 +6551,11 @@ snapshots: dependencies: is-callable: 1.2.7 + foreground-child@3.3.0: + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + fs-extra@10.1.0: dependencies: graceful-fs: 4.2.11 @@ -5833,6 +6576,9 @@ snapshots: fs.realpath@1.0.0: {} + fsevents@2.3.2: + optional: true + fsevents@2.3.3: optional: true @@ -5849,6 +6595,8 @@ snapshots: gensync@1.0.0-beta.2: {} + get-caller-file@2.0.5: {} + get-intrinsic@1.2.4: dependencies: es-errors: 1.3.0 @@ -5883,6 +6631,15 @@ snapshots: dependencies: is-glob: 4.0.3 + glob@10.4.5: + dependencies: + foreground-child: 3.3.0 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + glob@7.2.3: dependencies: fs.realpath: 1.0.0 @@ -5972,6 +6729,8 @@ snapshots: graphemer@1.4.0: {} + graphql@16.9.0: {} + gray-matter@4.0.3: dependencies: js-yaml: 3.14.1 @@ -6013,6 +6772,8 @@ snapshots: dependencies: function-bind: 1.1.2 + headers-polyfill@4.0.3: {} + hookable@5.5.3: {} hosted-git-info@2.8.9: {} @@ -6186,6 +6947,8 @@ snapshots: is-negative-zero@2.0.3: {} + is-node-process@1.2.0: {} + is-npm@5.0.0: {} is-number-object@1.0.7: @@ -6261,10 +7024,26 @@ snapshots: issue-regex@3.1.0: {} + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + jiti@1.21.0: {} jju@1.4.0: {} + js-beautify@1.15.1: + dependencies: + config-chain: 1.1.13 + editorconfig: 1.0.4 + glob: 10.4.5 + js-cookie: 3.0.5 + nopt: 7.2.1 + + js-cookie@3.0.5: {} + js-tokens@4.0.0: {} js-yaml@3.14.1: @@ -6425,10 +7204,14 @@ snapshots: cli-cursor: 2.1.0 wrap-ansi: 3.0.1 + loupe@3.1.2: {} + lowercase-keys@1.0.1: {} lowercase-keys@2.0.0: {} + lru-cache@10.4.3: {} + lru-cache@5.1.1: dependencies: yallist: 3.1.1 @@ -6437,10 +7220,16 @@ snapshots: dependencies: yallist: 4.0.0 + lz-string@1.5.0: {} + magic-string@0.30.10: dependencies: '@jridgewell/sourcemap-codec': 1.4.15 + magic-string@0.30.12: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + make-dir@3.1.0: dependencies: semver: 6.3.1 @@ -6516,6 +7305,14 @@ snapshots: dependencies: brace-expansion: 2.0.1 + minimatch@9.0.1: + dependencies: + brace-expansion: 2.0.1 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + minimist-options@4.1.0: dependencies: arrify: 1.0.1 @@ -6524,6 +7321,8 @@ snapshots: minimist@1.2.8: {} + minipass@7.1.2: {} + minisearch@6.3.0: {} mitt@3.0.1: {} @@ -6543,10 +7342,37 @@ snapshots: ms@2.1.3: {} + msw@2.6.2(@types/node@20.12.13)(typescript@5.4.5): + dependencies: + '@bundled-es-modules/cookie': 2.0.1 + '@bundled-es-modules/statuses': 1.0.1 + '@bundled-es-modules/tough-cookie': 0.1.6 + '@inquirer/confirm': 5.0.1(@types/node@20.12.13) + '@mswjs/interceptors': 0.36.10 + '@open-draft/deferred-promise': 2.2.0 + '@open-draft/until': 2.1.0 + '@types/cookie': 0.6.0 + '@types/statuses': 2.0.5 + chalk: 4.1.2 + graphql: 16.9.0 + headers-polyfill: 4.0.3 + is-node-process: 1.2.0 + outvariant: 1.4.3 + path-to-regexp: 6.3.0 + strict-event-emitter: 0.5.1 + type-fest: 4.26.1 + yargs: 17.7.2 + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - '@types/node' + mute-stream@0.0.7: {} mute-stream@0.0.8: {} + mute-stream@2.0.0: {} + nanoid@3.3.7: {} natural-compare-lite@1.4.0: {} @@ -6563,6 +7389,10 @@ snapshots: node-releases@2.0.14: {} + nopt@7.2.1: + dependencies: + abbrev: 2.0.0 + normalize-package-data@2.5.0: dependencies: hosted-git-info: 2.8.9 @@ -6730,6 +7560,8 @@ snapshots: os-tmpdir@1.0.2: {} + outvariant@1.4.3: {} + ow@0.21.0: dependencies: '@sindresorhus/is': 4.6.0 @@ -6798,6 +7630,8 @@ snapshots: p-try@2.2.0: {} + package-json-from-dist@1.0.1: {} + package-json@6.5.0: dependencies: got: 9.6.0 @@ -6833,6 +7667,13 @@ snapshots: path-parse@1.0.7: {} + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + path-to-regexp@6.3.0: {} + path-type@3.0.0: dependencies: pify: 3.0.0 @@ -6841,6 +7682,8 @@ snapshots: pathe@1.1.2: {} + pathval@2.0.0: {} + perfect-debounce@1.0.0: {} picocolors@1.0.1: {} @@ -6865,6 +7708,14 @@ snapshots: mlly: 1.7.0 pathe: 1.1.2 + playwright-core@1.48.2: {} + + playwright@1.48.2: + dependencies: + playwright-core: 1.48.2 + optionalDependencies: + fsevents: 2.3.2 + possible-typed-array-names@1.0.0: {} postcss-selector-parser@6.1.0: @@ -6886,6 +7737,18 @@ snapshots: prettier@2.8.8: {} + pretty-format@27.5.1: + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + + proto-list@1.2.4: {} + + psl@1.10.0: + dependencies: + punycode: 2.3.1 + pump@3.0.0: dependencies: end-of-stream: 1.4.4 @@ -6897,6 +7760,8 @@ snapshots: dependencies: escape-goat: 2.1.1 + querystringify@2.2.0: {} + queue-microtask@1.2.3: {} quick-lru@4.0.1: {} @@ -6908,6 +7773,8 @@ snapshots: minimist: 1.2.8 strip-json-comments: 2.0.1 + react-is@17.0.2: {} + read-pkg-up@7.0.1: dependencies: find-up: 4.1.0 @@ -6936,6 +7803,8 @@ snapshots: indent-string: 4.0.0 strip-indent: 3.0.0 + regenerator-runtime@0.14.1: {} + regexp.prototype.flags@1.5.2: dependencies: call-bind: 1.0.7 @@ -6953,8 +7822,12 @@ snapshots: dependencies: rc: 1.2.8 + require-directory@2.1.1: {} + require-from-string@2.0.2: {} + requires-port@1.0.0: {} + resolve-cwd@3.0.0: dependencies: resolve-from: 5.0.0 @@ -7116,14 +7989,24 @@ snapshots: get-intrinsic: 1.2.4 object-inspect: 1.13.1 + siginfo@2.0.0: {} + signal-exit@3.0.7: {} + signal-exit@4.1.0: {} + sirv@2.0.4: dependencies: '@polka/url': 1.0.0-next.25 mrmime: 2.0.0 totalist: 3.0.1 + sirv@3.0.0: + dependencies: + '@polka/url': 1.0.0-next.25 + mrmime: 2.0.0 + totalist: 3.0.1 + slash@3.0.0: {} slash@4.0.0: {} @@ -7158,6 +8041,14 @@ snapshots: sprintf-js@1.0.3: {} + stackback@0.0.2: {} + + statuses@2.0.1: {} + + std-env@3.7.0: {} + + strict-event-emitter@0.5.1: {} + string-argv@0.3.2: {} string-width@1.0.2: @@ -7177,6 +8068,12 @@ snapshots: 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.1.0 + string.prototype.padend@3.1.6: dependencies: call-bind: 1.0.7 @@ -7219,6 +8116,10 @@ snapshots: dependencies: ansi-regex: 5.0.1 + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + strip-bom-string@1.0.0: {} strip-bom@3.0.0: {} @@ -7269,6 +8170,16 @@ snapshots: through@2.3.8: {} + tinybench@2.9.0: {} + + tinyexec@0.3.1: {} + + tinypool@1.0.1: {} + + tinyrainbow@1.2.0: {} + + tinyspy@3.0.2: {} + tmp@0.0.33: dependencies: os-tmpdir: 1.0.2 @@ -7285,6 +8196,13 @@ snapshots: totalist@3.0.1: {} + tough-cookie@4.1.4: + dependencies: + psl: 1.10.0 + punycode: 2.3.1 + universalify: 0.2.0 + url-parse: 1.5.10 + trim-newlines@3.0.1: {} ts-morph@17.0.1: @@ -7324,6 +8242,8 @@ snapshots: type-fest@0.8.1: {} + type-fest@4.26.1: {} + typed-array-buffer@1.0.2: dependencies: call-bind: 1.0.7 @@ -7389,6 +8309,8 @@ snapshots: universalify@0.1.2: {} + universalify@0.2.0: {} + universalify@2.0.1: {} unocss@0.60.3(postcss@8.4.38)(rollup@4.18.0)(vite@5.2.12(@types/node@20.12.13)): @@ -7451,6 +8373,11 @@ snapshots: dependencies: prepend-http: 2.0.0 + url-parse@1.5.10: + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + util-deprecate@1.0.2: {} vali-date@1.0.0: {} @@ -7466,6 +8393,22 @@ snapshots: validator@13.12.0: {} + vite-node@2.1.4(@types/node@20.12.13): + dependencies: + cac: 6.7.14 + debug: 4.3.7 + pathe: 1.1.2 + vite: 5.2.12(@types/node@20.12.13) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + vite-plugin-dts@1.7.3(@types/node@20.12.13)(rollup@4.18.0)(vite@5.2.12(@types/node@20.12.13)): dependencies: '@microsoft/api-extractor': 7.46.2(@types/node@20.12.13) @@ -7573,10 +8516,54 @@ snapshots: - typescript - universal-cookie + vitest-browser-vue@0.0.1(@vitest/browser@2.1.4)(vitest@2.1.4)(vue@3.4.27(typescript@5.4.5)): + dependencies: + '@vitest/browser': 2.1.4(@types/node@20.12.13)(playwright@1.48.2)(typescript@5.4.5)(vite@5.2.12(@types/node@20.12.13))(vitest@2.1.4) + '@vue/test-utils': 2.4.6 + vitest: 2.1.4(@types/node@20.12.13)(@vitest/browser@2.1.4)(msw@2.6.2(@types/node@20.12.13)(typescript@5.4.5)) + vue: 3.4.27(typescript@5.4.5) + + vitest@2.1.4(@types/node@20.12.13)(@vitest/browser@2.1.4)(msw@2.6.2(@types/node@20.12.13)(typescript@5.4.5)): + dependencies: + '@vitest/expect': 2.1.4 + '@vitest/mocker': 2.1.4(msw@2.6.2(@types/node@20.12.13)(typescript@5.4.5))(vite@5.2.12(@types/node@20.12.13)) + '@vitest/pretty-format': 2.1.4 + '@vitest/runner': 2.1.4 + '@vitest/snapshot': 2.1.4 + '@vitest/spy': 2.1.4 + '@vitest/utils': 2.1.4 + chai: 5.1.2 + debug: 4.3.7 + expect-type: 1.1.0 + magic-string: 0.30.12 + pathe: 1.1.2 + std-env: 3.7.0 + tinybench: 2.9.0 + tinyexec: 0.3.1 + tinypool: 1.0.1 + tinyrainbow: 1.2.0 + vite: 5.2.12(@types/node@20.12.13) + vite-node: 2.1.4(@types/node@20.12.13) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 20.12.13 + '@vitest/browser': 2.1.4(@types/node@20.12.13)(playwright@1.48.2)(typescript@5.4.5)(vite@5.2.12(@types/node@20.12.13))(vitest@2.1.4) + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - stylus + - sugarss + - supports-color + - terser + vscode-oniguruma@1.7.0: {} vscode-textmate@6.0.0: {} + vue-component-type-helpers@2.1.10: {} + vue-demi@0.13.11(vue@3.4.27(typescript@5.4.5)): dependencies: vue: 3.4.27(typescript@5.4.5) @@ -7632,6 +8619,11 @@ snapshots: dependencies: isexe: 2.0.0 + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + widest-line@3.1.0: dependencies: string-width: 4.2.3 @@ -7643,12 +8635,24 @@ snapshots: string-width: 2.1.1 strip-ansi: 4.0.0 + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 string-width: 4.2.3 strip-ansi: 6.0.1 + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + wrappy@1.0.2: {} write-file-atomic@3.0.3: @@ -7658,10 +8662,14 @@ snapshots: signal-exit: 3.0.7 typedarray-to-buffer: 3.1.5 + ws@8.18.0: {} + xdg-basedir@4.0.0: {} xml-name-validator@4.0.0: {} + y18n@5.0.8: {} + yallist@3.1.1: {} yallist@4.0.0: {} @@ -7670,8 +8678,22 @@ snapshots: yargs-parser@20.2.9: {} + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.1.2 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + yocto-queue@0.1.0: {} + yoctocolors-cjs@2.1.2: {} + z-schema@5.0.5: dependencies: lodash.get: 4.4.2 diff --git a/src/__test__/basic.test.ts b/src/__test__/basic.test.ts new file mode 100644 index 00000000..481d71e5 --- /dev/null +++ b/src/__test__/basic.test.ts @@ -0,0 +1,270 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest' +import { render, RenderResult } from 'vitest-browser-vue' +import { useDraggable, VueDraggable } from '..' +import { computed, defineComponent, h, nextTick, ref } from 'vue' +import { userEvent } from '@vitest/browser/context' +import type { SortableEvent } from 'sortablejs' + +describe('basic', () => { + const data = Array.from({ length: 4 }).map((_, i) => `item${i + 1}`) + + describe('component', () => { + const list = ref([]) + const screen = ref any + }> | null>(null) + + const itemElements = computed(() => + screen.value!.getByTestId('item').elements() + ) + + beforeEach(() => { + list.value = data + screen.value = render(VueDraggable, { + props: { + modelValue: list.value, + 'onUpdate:modelValue': (e: any) => (list.value = e) + }, + slots: { + default: () => + list.value.map(item => h('div', { 'data-testid': 'item' }, item)) + } + }) + }) + + it('should render', () => { + expect(itemElements.value.map(el => el.textContent)) + .toMatchInlineSnapshot(` + [ + "item1", + "item2", + "item3", + "item4", + ] + `) + }) + + it('should render after list change', async () => { + list.value = list.value.slice().reverse() + + await nextTick() + + expect(itemElements.value.map(el => el.textContent)) + .toMatchInlineSnapshot(` + [ + "item4", + "item3", + "item2", + "item1", + ] + `) + }) + + it('should update list after item is dragged and dropped', async () => { + await userEvent.dragAndDrop( + screen.value!.getByText('item1').element(), + screen.value!.getByText('item4').element() + ) + + expect(itemElements.value.map(el => el.textContent)) + .toMatchInlineSnapshot(` + [ + "item2", + "item3", + "item4", + "item1", + ] + `) + + expect(list.value).toMatchInlineSnapshot(` + [ + "item2", + "item3", + "item4", + "item1", + ] + `) + }) + + it('should emit after item is dragged and dropped', async () => { + await userEvent.dragAndDrop( + screen.value!.getByText('item1').element(), + screen.value!.getByText('item4').element() + ) + + expect(screen.value!.emitted('update:modelValue')).toHaveLength(1) + + const onStartEvent = + screen.value!.emitted('start')?.[0]?.[0] + expect(onStartEvent?.oldIndex).toBe(0) + expect(onStartEvent?.newIndex).toBe(null) + + const onUpdateEvent = + screen.value!.emitted('update')?.[0]?.[0] + expect(onUpdateEvent?.oldIndex).toBe(0) + expect(onUpdateEvent?.newIndex).toBe(3) + + const onEndEvent = screen.value!.emitted('end')?.[0]?.[0] + expect(onEndEvent?.oldIndex).toBe(0) + expect(onEndEvent?.newIndex).toBe(3) + }) + }) + + describe('composable', () => { + const list = ref([]) + const screen = ref | null>(null) + + const itemElements = computed(() => + screen.value!.getByTestId('item').elements() + ) + + const sortableEventCallback = (event: SortableEvent) => [ + event.oldIndex, + event.newIndex + ] + + const onStart = vi.fn().mockImplementation(sortableEventCallback) + const onUpdate = vi.fn().mockImplementation(sortableEventCallback) + const onEnd = vi.fn().mockImplementation(sortableEventCallback) + + beforeEach(() => { + list.value = data + screen.value = render( + defineComponent({ + setup() { + const el = ref() + const { pause, resume } = useDraggable(el, list, { + onStart, + onUpdate, + onEnd + }) + + return () => [ + h( + 'div', + { ref: el }, + list.value.map(item => + h('div', { 'data-testid': 'item' }, item) + ) + ), + h('button', { onClick: pause }, 'pause'), + h('button', { onClick: resume }, 'resume') + ] + } + }) + ) + }) + + it('should render', () => { + expect(itemElements.value.map(el => el.textContent)) + .toMatchInlineSnapshot(` + [ + "item1", + "item2", + "item3", + "item4", + ] + `) + }) + + it('should render after list change', async () => { + list.value = list.value.slice().reverse() + + await nextTick() + + expect(itemElements.value.map(el => el.textContent)) + .toMatchInlineSnapshot(` + [ + "item4", + "item3", + "item2", + "item1", + ] + `) + }) + + it('should update list after item is dragged and dropped', async () => { + await userEvent.dragAndDrop( + screen.value!.getByText('item1').element(), + screen.value!.getByText('item4').element() + ) + + expect(itemElements.value.map(el => el.textContent)) + .toMatchInlineSnapshot(` + [ + "item2", + "item3", + "item4", + "item1", + ] + `) + + expect(list.value).toMatchInlineSnapshot(` + [ + "item2", + "item3", + "item4", + "item1", + ] + `) + }) + + it('should emit after item is dragged and dropped', async () => { + await userEvent.dragAndDrop( + screen.value!.getByText('item1').element(), + screen.value!.getByText('item4').element() + ) + + expect(onStart).toReturnWith([0, null]) + expect(onUpdate).toReturnWith([0, 3]) + expect(onEnd).toReturnWith([0, 3]) + }) + + it('should pause and resume', async () => { + await userEvent.click(screen.value!.getByText('pause')) + + await userEvent.dragAndDrop( + screen.value!.getByText('item1').element(), + screen.value!.getByText('item4').element() + ) + + expect(itemElements.value.map(el => el.textContent)).toMatchInlineSnapshot(` + [ + "item1", + "item2", + "item3", + "item4", + ] + `) + + expect(onStart).not.toHaveBeenCalled() + expect(onUpdate).not.toHaveBeenCalled() + expect(onEnd).not.toHaveBeenCalled() + + await userEvent.click(screen.value!.getByText('resume')) + + await userEvent.dragAndDrop( + screen.value!.getByText('item1').element(), + screen.value!.getByText('item4').element() + ) + + expect(itemElements.value.map(el => el.textContent)).toMatchInlineSnapshot(` + [ + "item2", + "item3", + "item4", + "item1", + ] + `) + + expect(onStart).toHaveBeenCalledOnce() + expect(onUpdate).toHaveBeenCalledOnce() + expect(onEnd).toHaveBeenCalledOnce() + + expect(onStart).toReturnWith([0, null]) + expect(onUpdate).toReturnWith([0, 3]) + expect(onEnd).toReturnWith([0, 3]) + }) + }) +}) diff --git a/tsconfig.json b/tsconfig.json index 14aa1e81..85ee5ffb 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,7 +19,7 @@ "isolatedModules": true, "jsx": "preserve", "lib": ["esnext", "dom"], - "types": [], + "types": [ "@vitest/browser/providers/playwright"], "skipLibCheck": true, "emitDeclarationOnly": true, "declarationDir": "dist", diff --git a/vitest.workspace.ts b/vitest.workspace.ts new file mode 100644 index 00000000..a30413be --- /dev/null +++ b/vitest.workspace.ts @@ -0,0 +1,21 @@ +import { defineWorkspace } from 'vitest/config' + +export default defineWorkspace([ + // If you want to keep running your existing tests in Node.js, uncomment the next line. + // 'vite.config.ts', + { + extends: 'vite.config.ts', + test: { + clearMocks: true, + browser: { + enabled: true, + headless: true, + screenshotFailures:false, + name: 'chromium', + provider: 'playwright', + // https://playwright.dev + providerOptions: {}, + }, + }, + }, +]) From 97e3d1763014f3285b436ba97a439a290cf8934d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=B6=E8=BF=9C=E6=96=B9?= Date: Thu, 14 Nov 2024 23:28:19 +0800 Subject: [PATCH 2/8] fix: fixed the index error when dragging and dropping to update --- src/useDraggable.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/useDraggable.ts b/src/useDraggable.ts index 70da3e0c..a08fa30d 100644 --- a/src/useDraggable.ts +++ b/src/useDraggable.ts @@ -201,15 +201,19 @@ export function useDraggable(...args: any[]): UseDraggableReturn { customUpdate(evt) return } - const { from, item, oldIndex, newIndex } = evt + const { from, item, oldIndex, oldDraggableIndex, newDraggableIndex } = evt removeNode(item) insertNodeAt(from, item, oldIndex!) if (isRef(list)) { const newList = [...unref(list)] - list.value = moveArrayElement(newList, oldIndex!, newIndex!) + list.value = moveArrayElement( + newList, + oldDraggableIndex!, + newDraggableIndex! + ) return } - moveArrayElement(unref(list), oldIndex!, newIndex!) + moveArrayElement(unref(list), oldDraggableIndex!, newDraggableIndex!) } function onEnd(e: DraggableEvent) { From fde8ec9378e86e5bfec5e4b568006a3db49b228b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=B6=E8=BF=9C=E6=96=B9?= Date: Thu, 14 Nov 2024 23:28:44 +0800 Subject: [PATCH 3/8] release: 0.6.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8bab992a..357069ac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vue-draggable-plus", - "version": "0.5.6", + "version": "0.6.0", "author": { "name": "yangpanteng", "email": "yangpanteng@gmail.com" From 4b76ce461233d3c026c5f2841c9c5437ca06b19a Mon Sep 17 00:00:00 2001 From: Lo Date: Fri, 15 Nov 2024 09:47:01 +0800 Subject: [PATCH 4/8] chore: update vitest configs --- package.json | 4 +- pnpm-lock.yaml | 142 +++++++++++++++++++++++++++++++++++++ src/__test__/basic.test.ts | 6 +- tsconfig.json | 2 +- vite.config.ts | 6 ++ vitest.workspace.ts | 6 +- 6 files changed, 158 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 357069ac..ec0a7b98 100644 --- a/package.json +++ b/package.json @@ -73,6 +73,7 @@ "@typescript-eslint/parser": "^5.62.0", "@vitejs/plugin-vue": "^5.0.4", "@vitest/browser": "^2.1.4", + "@vitest/coverage-v8": "2.1.4", "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-define-config": "^1.24.1", @@ -106,6 +107,5 @@ "@vue/composition-api": { "optional": true } - }, - "packageManager": "pnpm@9.12.3+sha512.cce0f9de9c5a7c95bef944169cc5dfe8741abfb145078c0d508b868056848a87c81e626246cb60967cbd7fd29a6c062ef73ff840d96b3c86c40ac92cf4a813ee" + } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 01000b37..ac5c0bf9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -36,6 +36,9 @@ importers: '@vitest/browser': specifier: ^2.1.4 version: 2.1.4(@types/node@20.12.13)(playwright@1.48.2)(typescript@5.4.5)(vite@5.2.12(@types/node@20.12.13))(vitest@2.1.4) + '@vitest/coverage-v8': + specifier: 2.1.4 + version: 2.1.4(@vitest/browser@2.1.4)(vitest@2.1.4) cross-env: specifier: ^7.0.3 version: 7.0.3 @@ -266,10 +269,18 @@ packages: resolution: {integrity: sha512-WdJjwMEkmBicq5T9fm/cHND3+UlFa2Yj8ALLgmoSQAJZysYbBjw+azChSGPN4DSPLXOcooGRvDwZWMcF/mLO2Q==} engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.25.9': + resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.24.6': resolution: {integrity: sha512-4yA7s865JHaqUdRbnaxarZREuPTHrjpDT+pXoAZ1yhyo6uFnIEpS8VMu16siFOHDpZNKYv5BObhsB//ycbICyw==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.24.6': resolution: {integrity: sha512-Jktc8KkF3zIkePb48QO+IapbXlSapOW9S+ogZZkcO6bABgYAxtZcjZ/O005111YLf+j4M84uEgwYoidDkXbCkQ==} engines: {node: '>=6.9.0'} @@ -287,6 +298,11 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.26.2': + resolution: {integrity: sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/plugin-syntax-jsx@7.24.6': resolution: {integrity: sha512-lWfvAIFNWMlCsU0DRUun2GpFwZdGTukLaHJqRh1JRb80NdAP5Sb1HDHB5X9P9OtgZHQl089UzQkpYlBq2VTPRw==} engines: {node: '>=6.9.0'} @@ -333,6 +349,13 @@ packages: resolution: {integrity: sha512-WaMsgi6Q8zMgMth93GvWPXkhAIEobfsIkLTacoVZoK1J0CevIPGYY2Vo5YvJGqyHqXM6P4ppOYGsIRU8MM9pFQ==} engines: {node: '>=6.9.0'} + '@babel/types@7.26.0': + resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} + engines: {node: '>=6.9.0'} + + '@bcoe/v8-coverage@0.2.3': + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + '@bundled-es-modules/cookie@2.0.1': resolution: {integrity: sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw==} @@ -574,6 +597,10 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + '@jridgewell/gen-mapping@0.3.5': resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} @@ -1071,6 +1098,15 @@ packages: webdriverio: optional: true + '@vitest/coverage-v8@2.1.4': + resolution: {integrity: sha512-FPKQuJfR6VTfcNMcGpqInmtJuVXFSCd9HQltYncfR01AzXhLucMEtQ5SinPdZxsT5x/5BK7I5qFJ5/ApGCmyTQ==} + peerDependencies: + '@vitest/browser': 2.1.4 + vitest: 2.1.4 + peerDependenciesMeta: + '@vitest/browser': + optional: true + '@vitest/expect@2.1.4': resolution: {integrity: sha512-DOETT0Oh1avie/D/o2sgMHGrzYUFFo3zqESB2Hn70z6QB1HrS2IQ9z5DfyTqU8sg4Bpu13zZe9V4+UTNQlUeQA==} @@ -2346,6 +2382,9 @@ packages: resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} engines: {node: '>=10'} + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + http-cache-semantics@4.1.1: resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} @@ -2612,6 +2651,22 @@ packages: resolution: {integrity: sha512-0RHjbtw9QXeSYnIEY5Yrp2QZrdtz21xBDV9C/GIlY2POmgoS6a7qjkYS5siRKXScnuAj5/SPv1C3YForNCHTJA==} engines: {node: '>=10'} + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@5.0.6: + resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} + engines: {node: '>=10'} + + istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} + jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} @@ -2809,10 +2864,17 @@ packages: magic-string@0.30.12: resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==} + magicast@0.3.5: + resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} + make-dir@3.1.0: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} engines: {node: '>=8'} + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + map-age-cleaner@0.1.3: resolution: {integrity: sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==} engines: {node: '>=6'} @@ -3720,6 +3782,10 @@ packages: resolution: {integrity: sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==} engines: {node: '>=8'} + test-exclude@7.0.1: + resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} + engines: {node: '>=18'} + text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} @@ -4436,8 +4502,12 @@ snapshots: '@babel/helper-string-parser@7.24.6': {} + '@babel/helper-string-parser@7.25.9': {} + '@babel/helper-validator-identifier@7.24.6': {} + '@babel/helper-validator-identifier@7.25.9': {} + '@babel/helper-validator-option@7.24.6': {} '@babel/helpers@7.24.6': @@ -4456,6 +4526,10 @@ snapshots: dependencies: '@babel/types': 7.24.6 + '@babel/parser@7.26.2': + dependencies: + '@babel/types': 7.26.0 + '@babel/plugin-syntax-jsx@7.24.6(@babel/core@7.24.6)': dependencies: '@babel/core': 7.24.6 @@ -4521,6 +4595,13 @@ snapshots: '@babel/helper-validator-identifier': 7.24.6 to-fast-properties: 2.0.0 + '@babel/types@7.26.0': + dependencies: + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + + '@bcoe/v8-coverage@0.2.3': {} + '@bundled-es-modules/cookie@2.0.1': dependencies: cookie: 0.7.2 @@ -4717,6 +4798,8 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@istanbuljs/schema@0.1.3': {} + '@jridgewell/gen-mapping@0.3.5': dependencies: '@jridgewell/set-array': 1.2.1 @@ -5358,6 +5441,26 @@ snapshots: - utf-8-validate - vite + '@vitest/coverage-v8@2.1.4(@vitest/browser@2.1.4)(vitest@2.1.4)': + dependencies: + '@ampproject/remapping': 2.3.0 + '@bcoe/v8-coverage': 0.2.3 + debug: 4.3.7 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 5.0.6 + istanbul-reports: 3.1.7 + magic-string: 0.30.12 + magicast: 0.3.5 + std-env: 3.7.0 + test-exclude: 7.0.1 + tinyrainbow: 1.2.0 + vitest: 2.1.4(@types/node@20.12.13)(@vitest/browser@2.1.4)(msw@2.6.2(@types/node@20.12.13)(typescript@5.4.5)) + optionalDependencies: + '@vitest/browser': 2.1.4(@types/node@20.12.13)(playwright@1.48.2)(typescript@5.4.5)(vite@5.2.12(@types/node@20.12.13))(vitest@2.1.4) + transitivePeerDependencies: + - supports-color + '@vitest/expect@2.1.4': dependencies: '@vitest/spy': 2.1.4 @@ -6786,6 +6889,8 @@ snapshots: dependencies: lru-cache: 6.0.0 + html-escaper@2.0.2: {} + http-cache-semantics@4.1.1: {} human-signals@2.1.0: {} @@ -7024,6 +7129,27 @@ snapshots: issue-regex@3.1.0: {} + istanbul-lib-coverage@3.2.2: {} + + 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@5.0.6: + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + debug: 4.3.7 + istanbul-lib-coverage: 3.2.2 + transitivePeerDependencies: + - supports-color + + istanbul-reports@3.1.7: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + jackspeak@3.4.3: dependencies: '@isaacs/cliui': 8.0.2 @@ -7230,10 +7356,20 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 + magicast@0.3.5: + dependencies: + '@babel/parser': 7.26.2 + '@babel/types': 7.26.0 + source-map-js: 1.2.0 + make-dir@3.1.0: dependencies: semver: 6.3.1 + make-dir@4.0.0: + dependencies: + semver: 7.6.2 + map-age-cleaner@0.1.3: dependencies: p-defer: 1.0.0 @@ -8166,6 +8302,12 @@ snapshots: ansi-escapes: 4.3.2 supports-hyperlinks: 2.3.0 + test-exclude@7.0.1: + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 10.4.5 + minimatch: 9.0.5 + text-table@0.2.0: {} through@2.3.8: {} diff --git a/src/__test__/basic.test.ts b/src/__test__/basic.test.ts index 481d71e5..bd64f6a1 100644 --- a/src/__test__/basic.test.ts +++ b/src/__test__/basic.test.ts @@ -229,7 +229,8 @@ describe('basic', () => { screen.value!.getByText('item4').element() ) - expect(itemElements.value.map(el => el.textContent)).toMatchInlineSnapshot(` + expect(itemElements.value.map(el => el.textContent)) + .toMatchInlineSnapshot(` [ "item1", "item2", @@ -249,7 +250,8 @@ describe('basic', () => { screen.value!.getByText('item4').element() ) - expect(itemElements.value.map(el => el.textContent)).toMatchInlineSnapshot(` + expect(itemElements.value.map(el => el.textContent)) + .toMatchInlineSnapshot(` [ "item2", "item3", diff --git a/tsconfig.json b/tsconfig.json index 85ee5ffb..b8fbe842 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,7 +19,7 @@ "isolatedModules": true, "jsx": "preserve", "lib": ["esnext", "dom"], - "types": [ "@vitest/browser/providers/playwright"], + "types": ["@vitest/browser/providers/playwright"], "skipLibCheck": true, "emitDeclarationOnly": true, "declarationDir": "dist", diff --git a/vite.config.ts b/vite.config.ts index 938ceecd..9ab9f04b 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -41,5 +41,11 @@ export default defineConfig({ alias: { '@': resolve(__dirname, 'src') } + }, + test: { + coverage: { + enabled: true, + include: ['src/component.ts', 'src/useDraggable.ts', 'src/directive.ts'] + } } }) diff --git a/vitest.workspace.ts b/vitest.workspace.ts index a30413be..0b32a26b 100644 --- a/vitest.workspace.ts +++ b/vitest.workspace.ts @@ -10,12 +10,12 @@ export default defineWorkspace([ browser: { enabled: true, headless: true, - screenshotFailures:false, + screenshotFailures: false, name: 'chromium', provider: 'playwright', // https://playwright.dev - providerOptions: {}, + providerOptions: {} }, }, - }, + } ]) From 4277353f3bab22a6e3cbbaee336be1f151e80dc9 Mon Sep 17 00:00:00 2001 From: Lo Date: Sun, 17 Nov 2024 23:39:14 +0800 Subject: [PATCH 5/8] chore: update basic.test.ts --- src/__test__/basic.test.ts | 211 ++++++++++++++++++++++++++++--------- src/component.ts | 4 +- 2 files changed, 165 insertions(+), 50 deletions(-) diff --git a/src/__test__/basic.test.ts b/src/__test__/basic.test.ts index bd64f6a1..2a3c569a 100644 --- a/src/__test__/basic.test.ts +++ b/src/__test__/basic.test.ts @@ -1,36 +1,54 @@ import { beforeEach, describe, expect, it, vi } from 'vitest' import { render, RenderResult } from 'vitest-browser-vue' -import { useDraggable, VueDraggable } from '..' -import { computed, defineComponent, h, nextTick, ref } from 'vue' +import { useDraggable, VueDraggable, vDraggable } from '..' +import { + computed, + defineComponent, + h, + nextTick, + ref, + withDirectives +} from 'vue' import { userEvent } from '@vitest/browser/context' import type { SortableEvent } from 'sortablejs' describe('basic', () => { const data = Array.from({ length: 4 }).map((_, i) => `item${i + 1}`) - describe('component', () => { - const list = ref([]) - const screen = ref any - }> | null>(null) + const list = ref([]) + const screen = ref | null>(null) + const itemElements = computed(() => + screen.value!.getByTestId('item').elements() + ) + + const sortableEventCallback = (event: SortableEvent) => [ + event.oldIndex, + event.newIndex + ] - const itemElements = computed(() => - screen.value!.getByTestId('item').elements() - ) + const onStart = vi.fn().mockImplementation(sortableEventCallback) + const onUpdate = vi.fn().mockImplementation(sortableEventCallback) + const onEnd = vi.fn().mockImplementation(sortableEventCallback) + + describe('component', () => { + const draggableRef = ref | null>(null) beforeEach(() => { list.value = data - screen.value = render(VueDraggable, { - props: { - modelValue: list.value, - 'onUpdate:modelValue': (e: any) => (list.value = e) - }, - slots: { - default: () => - list.value.map(item => h('div', { 'data-testid': 'item' }, item)) - } - }) + screen.value = render(() => + h( + VueDraggable, + { + ref: draggableRef, + modelValue: list.value, + 'onUpdate:modelValue': (v: any) => (list.value = v), + onStart, + onUpdate, + onEnd + }, + list.value.map(item => h('div', { 'data-testid': 'item' }, item)) + ) + ) }) it('should render', () => { @@ -93,41 +111,61 @@ describe('basic', () => { screen.value!.getByText('item4').element() ) - expect(screen.value!.emitted('update:modelValue')).toHaveLength(1) + expect(onStart).toReturnWith([0, null]) + expect(onUpdate).toReturnWith([0, 3]) + expect(onEnd).toReturnWith([0, 3]) + }) - const onStartEvent = - screen.value!.emitted('start')?.[0]?.[0] - expect(onStartEvent?.oldIndex).toBe(0) - expect(onStartEvent?.newIndex).toBe(null) + it('should pause and resume', async () => { + draggableRef.value?.pause() - const onUpdateEvent = - screen.value!.emitted('update')?.[0]?.[0] - expect(onUpdateEvent?.oldIndex).toBe(0) - expect(onUpdateEvent?.newIndex).toBe(3) + await userEvent.dragAndDrop( + screen.value!.getByText('item1').element(), + screen.value!.getByText('item4').element() + ) - const onEndEvent = screen.value!.emitted('end')?.[0]?.[0] - expect(onEndEvent?.oldIndex).toBe(0) - expect(onEndEvent?.newIndex).toBe(3) - }) - }) + expect(itemElements.value.map(el => el.textContent)) + .toMatchInlineSnapshot(` + [ + "item1", + "item2", + "item3", + "item4", + ] + `) - describe('composable', () => { - const list = ref([]) - const screen = ref | null>(null) + expect(onStart).not.toHaveBeenCalled() + expect(onUpdate).not.toHaveBeenCalled() + expect(onEnd).not.toHaveBeenCalled() - const itemElements = computed(() => - screen.value!.getByTestId('item').elements() - ) + draggableRef.value?.resume() - const sortableEventCallback = (event: SortableEvent) => [ - event.oldIndex, - event.newIndex - ] + await userEvent.dragAndDrop( + screen.value!.getByText('item1').element(), + screen.value!.getByText('item4').element() + ) - const onStart = vi.fn().mockImplementation(sortableEventCallback) - const onUpdate = vi.fn().mockImplementation(sortableEventCallback) - const onEnd = vi.fn().mockImplementation(sortableEventCallback) + expect(itemElements.value.map(el => el.textContent)) + .toMatchInlineSnapshot(` + [ + "item2", + "item3", + "item4", + "item1", + ] + `) + expect(onStart).toHaveBeenCalledOnce() + expect(onUpdate).toHaveBeenCalledOnce() + expect(onEnd).toHaveBeenCalledOnce() + + expect(onStart).toReturnWith([0, null]) + expect(onUpdate).toReturnWith([0, 3]) + expect(onEnd).toReturnWith([0, 3]) + }) + }) + + describe('composable', () => { beforeEach(() => { list.value = data screen.value = render( @@ -269,4 +307,81 @@ describe('basic', () => { expect(onEnd).toReturnWith([0, 3]) }) }) + + describe('directive', () => { + beforeEach(() => { + list.value = data + screen.value = render( + defineComponent({ + directives: { draggable: vDraggable }, + setup() { + return () => + withDirectives( + h( + 'ul', + list.value.map(item => + h('li', { 'data-testid': 'item' }, item) + ) + ), + [[vDraggable, [list, { onStart, onUpdate, onEnd }]]] + ) + } + }) + ) + }) + + it('should render', () => { + expect(itemElements.value.map(el => el.textContent)) + .toMatchInlineSnapshot(` + [ + "item1", + "item2", + "item3", + "item4", + ] + `) + }) + + it('should render after list change', async () => { + list.value = list.value.slice().reverse() + + await nextTick() + + expect(itemElements.value.map(el => el.textContent)) + .toMatchInlineSnapshot(` + [ + "item4", + "item3", + "item2", + "item1", + ] + `) + }) + + it('should update list after item is dragged and dropped', async () => { + await userEvent.dragAndDrop( + screen.value!.getByText('item1').element(), + screen.value!.getByText('item4').element() + ) + + expect(itemElements.value.map(el => el.textContent)) + .toMatchInlineSnapshot(` + [ + "item2", + "item3", + "item4", + "item1", + ] + `) + + expect(list.value).toMatchInlineSnapshot(` + [ + "item2", + "item3", + "item4", + "item1", + ] + `) + }) + }) }) diff --git a/src/component.ts b/src/component.ts index 2502b24a..1e95ee41 100644 --- a/src/component.ts +++ b/src/component.ts @@ -8,7 +8,7 @@ import { toRefs } from 'vue-demi' import { objectMap } from './utils' -import { useDraggable, UseDraggableOptions } from './useDraggable' +import { useDraggable, UseDraggableOptions, UseDraggableReturn } from './useDraggable' interface IProps extends UseDraggableOptions { modelValue: any[] @@ -78,7 +78,7 @@ const props = [ ...emits.map(key => `on${key.replace(/^\S/, s => s.toUpperCase())}`) ] as const -export const VueDraggable = defineComponent({ +export const VueDraggable = defineComponent({ name: 'VueDraggable', model: { prop: 'modelValue', From e18416b54c1ab5514abda9f7e7b60c742a0372af Mon Sep 17 00:00:00 2001 From: Lo Date: Thu, 21 Nov 2024 17:43:36 +0800 Subject: [PATCH 6/8] test: add clone component tests --- package.json | 3 +- src/__test__/clone.test.ts | 110 +++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 src/__test__/clone.test.ts diff --git a/package.json b/package.json index ec0a7b98..88da7699 100644 --- a/package.json +++ b/package.json @@ -107,5 +107,6 @@ "@vue/composition-api": { "optional": true } - } + }, + "packageManager": "pnpm@9.13.2+sha512.88c9c3864450350e65a33587ab801acf946d7c814ed1134da4a924f6df5a2120fd36b46aab68f7cd1d413149112d53c7db3a4136624cfd00ff1846a0c6cef48a" } diff --git a/src/__test__/clone.test.ts b/src/__test__/clone.test.ts new file mode 100644 index 00000000..127eb8a0 --- /dev/null +++ b/src/__test__/clone.test.ts @@ -0,0 +1,110 @@ +import { userEvent } from '@vitest/browser/context' +import { VueDraggable } from '..' +import { beforeEach, describe, expect, it, vi } from 'vitest' +import { render, RenderResult } from 'vitest-browser-vue' +import { computed, h, ref, toValue } from 'vue' + +describe('clone', () => { + const data = Array.from({ length: 4 }).map((_, i) => `item${i + 1}`) + + const list1 = ref([]) + const list2 = ref([]) + const screen = ref | null>(null) + + const list1Elements = computed(() => + screen.value!.getByTestId('list1').elements() + ) + const list2Elements = computed(() => + screen.value!.getByTestId('list2').elements() + ) + + const onClone = vi.fn() + + describe('component', () => { + beforeEach(() => { + list1.value = data.map(d => `${d}-1`) + list2.value = data.map(d => `${d}-2`) + + screen.value = render(() => [ + h( + VueDraggable, + { + modelValue: list1.value, + 'onUpdate:modelValue': (v: any) => (list1.value = v), + sort: false, + group: { name: 'people', pull: 'clone', put: false }, + onClone + }, + { + default: () => + list1.value.map(item => + h('div', { 'data-testid': 'list1' }, item) + ) + } + ), + h( + VueDraggable, + { + modelValue: list2.value, + 'onUpdate:modelValue': (v: any) => (list2.value = v), + group: 'people' + }, + { + default: () => + list2.value.map(item => + h('div', { 'data-testid': 'list2' }, item) + ) + } + ) + ]) + }) + + it("shouldn't sort list1", async () => { + const list1Snap = toValue(list1.value) + + expect(list1Elements.value.map(el => el.textContent)).toEqual(list1Snap) + + await userEvent.dragAndDrop( + screen.value!.getByText(list1Snap[0]).element(), + screen.value!.getByText(list1Snap[1]).element() + ) + + expect(list1Elements.value.map(el => el.textContent)).toEqual(list1Snap) + }) + + it('should sort list2', async () => { + const list2Snap = toValue(list2.value) + + expect(list2Elements.value.map(el => el.textContent)).toEqual(list2Snap) + + await userEvent.dragAndDrop( + screen.value!.getByText(list2Snap[0]).element(), + screen.value!.getByText(list2Snap[1]).element() + ) + + expect(list2Elements.value.map(el => el.textContent)).toEqual([ + list2Snap[1], + list2Snap[0], + ...list2Snap.slice(2) + ]) + }) + + // TODO: it works when the headless option is false + it.skip('should clone item from list1 to list2', async () => { + const list1Snap = toValue(list1.value) + const list2Snap = toValue(list2.value) + + await userEvent.dragAndDrop( + screen.value!.getByText(list1Snap[0]).element(), + screen.value!.getByText(list2Snap[0]).element() + ) + + expect(list2Elements.value.map(el => el.textContent)).toEqual([ + list1Snap[0], + ...list2Snap + ]) + + expect(onClone).toHaveBeenCalledTimes(1) + }) + }) +}) From f4f15b0f506ec76f214b22eb3ece9cb98f26a3da Mon Sep 17 00:00:00 2001 From: Lo Date: Thu, 21 Nov 2024 17:57:40 +0800 Subject: [PATCH 7/8] chore: update vitest and disable headless --- package.json | 11 +-- pnpm-lock.yaml | 190 +++++++++++++++++++------------------ src/__test__/clone.test.ts | 4 +- vitest.workspace.ts | 2 +- 4 files changed, 106 insertions(+), 101 deletions(-) diff --git a/package.json b/package.json index 88da7699..3633e809 100644 --- a/package.json +++ b/package.json @@ -72,8 +72,8 @@ "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", "@vitejs/plugin-vue": "^5.0.4", - "@vitest/browser": "^2.1.4", - "@vitest/coverage-v8": "2.1.4", + "@vitest/browser": "^2.1.5", + "@vitest/coverage-v8": "2.1.5", "cross-env": "^7.0.3", "eslint": "^8.57.0", "eslint-define-config": "^1.24.1", @@ -83,7 +83,7 @@ "fs-extra": "^11.2.0", "np": "^7.7.0", "npm-run-all": "^4.1.5", - "playwright": "^1.48.2", + "playwright": "^1.49.0", "prettier": "^2.8.8", "sortablejs": "^1.15.2", "typescript": "^5.4.5", @@ -91,7 +91,7 @@ "vite": "^5.2.12", "vite-plugin-dts": "^1.7.3", "vitepress": "1.0.0-rc.44", - "vitest": "^2.1.4", + "vitest": "^2.1.5", "vitest-browser-vue": "^0.0.1", "vue": "^3.4.27", "vue-demi": "^0.13.11", @@ -107,6 +107,5 @@ "@vue/composition-api": { "optional": true } - }, - "packageManager": "pnpm@9.13.2+sha512.88c9c3864450350e65a33587ab801acf946d7c814ed1134da4a924f6df5a2120fd36b46aab68f7cd1d413149112d53c7db3a4136624cfd00ff1846a0c6cef48a" + } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ac5c0bf9..630b9322 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,11 +34,11 @@ importers: specifier: ^5.0.4 version: 5.0.4(vite@5.2.12(@types/node@20.12.13))(vue@3.4.27(typescript@5.4.5)) '@vitest/browser': - specifier: ^2.1.4 - version: 2.1.4(@types/node@20.12.13)(playwright@1.48.2)(typescript@5.4.5)(vite@5.2.12(@types/node@20.12.13))(vitest@2.1.4) + specifier: ^2.1.5 + version: 2.1.5(@types/node@20.12.13)(playwright@1.49.0)(typescript@5.4.5)(vite@5.2.12(@types/node@20.12.13))(vitest@2.1.5) '@vitest/coverage-v8': - specifier: 2.1.4 - version: 2.1.4(@vitest/browser@2.1.4)(vitest@2.1.4) + specifier: 2.1.5 + version: 2.1.5(@vitest/browser@2.1.5)(vitest@2.1.5) cross-env: specifier: ^7.0.3 version: 7.0.3 @@ -67,8 +67,8 @@ importers: specifier: ^4.1.5 version: 4.1.5 playwright: - specifier: ^1.48.2 - version: 1.48.2 + specifier: ^1.49.0 + version: 1.49.0 prettier: specifier: ^2.8.8 version: 2.8.8 @@ -91,11 +91,11 @@ importers: specifier: 1.0.0-rc.44 version: 1.0.0-rc.44(@algolia/client-search@4.23.3)(@types/node@20.12.13)(postcss@8.4.38)(search-insights@2.14.0)(sortablejs@1.15.2)(typescript@5.4.5) vitest: - specifier: ^2.1.4 - version: 2.1.4(@types/node@20.12.13)(@vitest/browser@2.1.4)(msw@2.6.2(@types/node@20.12.13)(typescript@5.4.5)) + specifier: ^2.1.5 + version: 2.1.5(@types/node@20.12.13)(@vitest/browser@2.1.5)(msw@2.6.5(@types/node@20.12.13)(typescript@5.4.5)) vitest-browser-vue: specifier: ^0.0.1 - version: 0.0.1(@vitest/browser@2.1.4)(vitest@2.1.4)(vue@3.4.27(typescript@5.4.5)) + version: 0.0.1(@vitest/browser@2.1.5)(vitest@2.1.5)(vue@3.4.27(typescript@5.4.5)) vue: specifier: ^3.4.27 version: 3.4.27(typescript@5.4.5) @@ -635,8 +635,8 @@ packages: '@microsoft/tsdoc@0.15.0': resolution: {integrity: sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==} - '@mswjs/interceptors@0.36.10': - resolution: {integrity: sha512-GXrJgakgJW3DWKueebkvtYgGKkxA7s0u5B0P5syJM5rvQUnrpLPigvci8Hukl7yEM+sU06l+er2Fgvx/gmiRgg==} + '@mswjs/interceptors@0.37.1': + resolution: {integrity: sha512-SvE+tSpcX884RJrPCskXxoS965Ky/pYABDEhWW6oeSRhpUDLrS5nTvT5n1LLSDVDYvty4imVmXsy+3/ROVuknA==} engines: {node: '>=18'} '@nodelib/fs.scandir@2.1.5': @@ -1083,12 +1083,12 @@ packages: vite: ^5.0.0 vue: ^3.2.25 - '@vitest/browser@2.1.4': - resolution: {integrity: sha512-89SrvShW6kWzmEYtBj5k1gBq88emoC2qrngw5hE1vNpRFteQ5/1URbKIVww391rIALTpzhhCt5yJt5tjLPZxYw==} + '@vitest/browser@2.1.5': + resolution: {integrity: sha512-JrpnxvkrjlBrF7oXbK/YytWVYfJIzWYeDKppANlUaisBKwDso+yXlWocAJrANx8gUxyirF355Yx80S+SKQqayg==} peerDependencies: playwright: '*' safaridriver: '*' - vitest: 2.1.4 + vitest: 2.1.5 webdriverio: '*' peerDependenciesMeta: playwright: @@ -1098,20 +1098,20 @@ packages: webdriverio: optional: true - '@vitest/coverage-v8@2.1.4': - resolution: {integrity: sha512-FPKQuJfR6VTfcNMcGpqInmtJuVXFSCd9HQltYncfR01AzXhLucMEtQ5SinPdZxsT5x/5BK7I5qFJ5/ApGCmyTQ==} + '@vitest/coverage-v8@2.1.5': + resolution: {integrity: sha512-/RoopB7XGW7UEkUndRXF87A9CwkoZAJW01pj8/3pgmDVsjMH2IKy6H1A38po9tmUlwhSyYs0az82rbKd9Yaynw==} peerDependencies: - '@vitest/browser': 2.1.4 - vitest: 2.1.4 + '@vitest/browser': 2.1.5 + vitest: 2.1.5 peerDependenciesMeta: '@vitest/browser': optional: true - '@vitest/expect@2.1.4': - resolution: {integrity: sha512-DOETT0Oh1avie/D/o2sgMHGrzYUFFo3zqESB2Hn70z6QB1HrS2IQ9z5DfyTqU8sg4Bpu13zZe9V4+UTNQlUeQA==} + '@vitest/expect@2.1.5': + resolution: {integrity: sha512-nZSBTW1XIdpZvEJyoP/Sy8fUg0b8od7ZpGDkTUcfJ7wz/VoZAFzFfLyxVxGFhUjJzhYqSbIpfMtl/+k/dpWa3Q==} - '@vitest/mocker@2.1.4': - resolution: {integrity: sha512-Ky/O1Lc0QBbutJdW0rqLeFNbuLEyS+mIPiNdlVlp2/yhJ0SbyYqObS5IHdhferJud8MbbwMnexg4jordE5cCoQ==} + '@vitest/mocker@2.1.5': + resolution: {integrity: sha512-XYW6l3UuBmitWqSUXTNXcVBUCRytDogBsWuNXQijc00dtnU/9OqpXWp4OJroVrad/gLIomAq9aW8yWDBtMthhQ==} peerDependencies: msw: ^2.4.9 vite: ^5.0.0 @@ -1121,20 +1121,20 @@ packages: vite: optional: true - '@vitest/pretty-format@2.1.4': - resolution: {integrity: sha512-L95zIAkEuTDbUX1IsjRl+vyBSLh3PwLLgKpghl37aCK9Jvw0iP+wKwIFhfjdUtA2myLgjrG6VU6JCFLv8q/3Ww==} + '@vitest/pretty-format@2.1.5': + resolution: {integrity: sha512-4ZOwtk2bqG5Y6xRGHcveZVr+6txkH7M2e+nPFd6guSoN638v/1XQ0K06eOpi0ptVU/2tW/pIU4IoPotY/GZ9fw==} - '@vitest/runner@2.1.4': - resolution: {integrity: sha512-sKRautINI9XICAMl2bjxQM8VfCMTB0EbsBc/EDFA57V6UQevEKY/TOPOF5nzcvCALltiLfXWbq4MaAwWx/YxIA==} + '@vitest/runner@2.1.5': + resolution: {integrity: sha512-pKHKy3uaUdh7X6p1pxOkgkVAFW7r2I818vHDthYLvUyjRfkKOU6P45PztOch4DZarWQne+VOaIMwA/erSSpB9g==} - '@vitest/snapshot@2.1.4': - resolution: {integrity: sha512-3Kab14fn/5QZRog5BPj6Rs8dc4B+mim27XaKWFWHWA87R56AKjHTGcBFKpvZKDzC4u5Wd0w/qKsUIio3KzWW4Q==} + '@vitest/snapshot@2.1.5': + resolution: {integrity: sha512-zmYw47mhfdfnYbuhkQvkkzYroXUumrwWDGlMjpdUr4jBd3HZiV2w7CQHj+z7AAS4VOtWxI4Zt4bWt4/sKcoIjg==} - '@vitest/spy@2.1.4': - resolution: {integrity: sha512-4JOxa+UAizJgpZfaCPKK2smq9d8mmjZVPMt2kOsg/R8QkoRzydHH1qHxIYNvr1zlEaFj4SXiaaJWxq/LPLKaLg==} + '@vitest/spy@2.1.5': + resolution: {integrity: sha512-aWZF3P0r3w6DiYTVskOYuhBc7EMc3jvn1TkBg8ttylFFRqNN2XGD7V5a4aQdk6QiUzZQ4klNBSpCLJgWNdIiNw==} - '@vitest/utils@2.1.4': - resolution: {integrity: sha512-MXDnZn0Awl2S86PSNIim5PWXgIAx8CIkzu35mBdSApUip6RFOGXBCf3YFyeEu8n1IHk4bWD46DeYFu9mQlFIRg==} + '@vitest/utils@2.1.5': + resolution: {integrity: sha512-yfj6Yrp0Vesw2cwJbP+cl04OC+IHFsuQsrsJBL9pyGeQXE56v1UAOQco+SR55Vf1nQzfV0QJg1Qum7AaWUwwYg==} '@vue/compiler-core@3.4.27': resolution: {integrity: sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==} @@ -1826,6 +1826,9 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} + es-module-lexer@1.5.4: + resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==} + es-object-atoms@1.0.0: resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} engines: {node: '>= 0.4'} @@ -2996,8 +2999,8 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - msw@2.6.2: - resolution: {integrity: sha512-RdRgPvjfuzMIACkWv7VOVAeSRYMU3ofokLv1w0RsbFX960qnj/tFEyOFXY0G2GTUd9trA6rHuHciM/FKpBp6/A==} + msw@2.6.5: + resolution: {integrity: sha512-PnlnTpUlOrj441kYQzzFhzMzMCGFT6a2jKUBG7zSpLkYS5oh8Arrbc0dL8/rNAtxaoBy0EVs2mFqj2qdmWK7lQ==} engines: {node: '>=18'} hasBin: true peerDependencies: @@ -3318,13 +3321,13 @@ packages: pkg-types@1.1.1: resolution: {integrity: sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==} - playwright-core@1.48.2: - resolution: {integrity: sha512-sjjw+qrLFlriJo64du+EK0kJgZzoQPsabGF4lBvsid+3CNIZIYLgnMj9V6JY5VhM2Peh20DJWIVpVljLLnlawA==} + playwright-core@1.49.0: + resolution: {integrity: sha512-R+3KKTQF3npy5GTiKH/T+kdhoJfJojjHESR1YEWhYuEKRVfVaxH3+4+GvXE5xyCngCxhxnykk0Vlah9v8fs3jA==} engines: {node: '>=18'} hasBin: true - playwright@1.48.2: - resolution: {integrity: sha512-NjYvYgp4BPmiwfe31j4gHLa3J7bD2WiBz8Lk2RoSsmX38SVIARZ18VYjxLjAcDsAhA+F4iSEXTSGgjua0rrlgQ==} + playwright@1.49.0: + resolution: {integrity: sha512-eKpmys0UFDnfNb3vfsf8Vx2LEOtflgRebl0Im2eQQnYMA4Aqd+Zw8bEOB+7ZKvN76901mRnqdsiOGKxzVTbi7A==} engines: {node: '>=18'} hasBin: true @@ -3658,8 +3661,8 @@ packages: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} - std-env@3.7.0: - resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + std-env@3.8.0: + resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==} strict-event-emitter@0.5.1: resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} @@ -4002,8 +4005,8 @@ packages: resolution: {integrity: sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==} engines: {node: '>= 0.10'} - vite-node@2.1.4: - resolution: {integrity: sha512-kqa9v+oi4HwkG6g8ufRnb5AeplcRw8jUF6/7/Qz1qRQOXHImG8YnLbB+LLszENwFnoBl9xIf9nVdCFzNd7GQEg==} + vite-node@2.1.5: + resolution: {integrity: sha512-rd0QIgx74q4S1Rd56XIiL2cYEdyWn13cunYBIuqh9mpmQr7gGS0IxXoP8R6OaZtNQQLyXSWbd4rXKYUbhFpK5w==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true @@ -4090,15 +4093,15 @@ packages: vitest: ^2.1.0-beta.4 vue: ^3.0.0 - vitest@2.1.4: - resolution: {integrity: sha512-eDjxbVAJw1UJJCHr5xr/xM86Zx+YxIEXGAR+bmnEID7z9qWfoxpHw0zdobz+TQAFOLT+nEXz3+gx6nUJ7RgmlQ==} + vitest@2.1.5: + resolution: {integrity: sha512-P4ljsdpuzRTPI/kbND2sDZ4VmieerR2c9szEZpjc+98Z9ebvnXmM5+0tHEKqYZumXqlvnmfWsjeFOjXVriDG7A==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@types/node': ^18.0.0 || >=20.0.0 - '@vitest/browser': 2.1.4 - '@vitest/ui': 2.1.4 + '@vitest/browser': 2.1.5 + '@vitest/ui': 2.1.5 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -4854,7 +4857,7 @@ snapshots: '@microsoft/tsdoc@0.15.0': {} - '@mswjs/interceptors@0.36.10': + '@mswjs/interceptors@0.37.1': dependencies: '@open-draft/deferred-promise': 2.2.0 '@open-draft/logger': 0.3.0 @@ -5420,20 +5423,20 @@ snapshots: vite: 5.2.12(@types/node@20.12.13) vue: 3.4.27(typescript@5.4.5) - '@vitest/browser@2.1.4(@types/node@20.12.13)(playwright@1.48.2)(typescript@5.4.5)(vite@5.2.12(@types/node@20.12.13))(vitest@2.1.4)': + '@vitest/browser@2.1.5(@types/node@20.12.13)(playwright@1.49.0)(typescript@5.4.5)(vite@5.2.12(@types/node@20.12.13))(vitest@2.1.5)': dependencies: '@testing-library/dom': 10.4.0 '@testing-library/user-event': 14.5.2(@testing-library/dom@10.4.0) - '@vitest/mocker': 2.1.4(msw@2.6.2(@types/node@20.12.13)(typescript@5.4.5))(vite@5.2.12(@types/node@20.12.13)) - '@vitest/utils': 2.1.4 + '@vitest/mocker': 2.1.5(msw@2.6.5(@types/node@20.12.13)(typescript@5.4.5))(vite@5.2.12(@types/node@20.12.13)) + '@vitest/utils': 2.1.5 magic-string: 0.30.12 - msw: 2.6.2(@types/node@20.12.13)(typescript@5.4.5) + msw: 2.6.5(@types/node@20.12.13)(typescript@5.4.5) sirv: 3.0.0 tinyrainbow: 1.2.0 - vitest: 2.1.4(@types/node@20.12.13)(@vitest/browser@2.1.4)(msw@2.6.2(@types/node@20.12.13)(typescript@5.4.5)) + vitest: 2.1.5(@types/node@20.12.13)(@vitest/browser@2.1.5)(msw@2.6.5(@types/node@20.12.13)(typescript@5.4.5)) ws: 8.18.0 optionalDependencies: - playwright: 1.48.2 + playwright: 1.49.0 transitivePeerDependencies: - '@types/node' - bufferutil @@ -5441,7 +5444,7 @@ snapshots: - utf-8-validate - vite - '@vitest/coverage-v8@2.1.4(@vitest/browser@2.1.4)(vitest@2.1.4)': + '@vitest/coverage-v8@2.1.5(@vitest/browser@2.1.5)(vitest@2.1.5)': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 0.2.3 @@ -5452,53 +5455,53 @@ snapshots: istanbul-reports: 3.1.7 magic-string: 0.30.12 magicast: 0.3.5 - std-env: 3.7.0 + std-env: 3.8.0 test-exclude: 7.0.1 tinyrainbow: 1.2.0 - vitest: 2.1.4(@types/node@20.12.13)(@vitest/browser@2.1.4)(msw@2.6.2(@types/node@20.12.13)(typescript@5.4.5)) + vitest: 2.1.5(@types/node@20.12.13)(@vitest/browser@2.1.5)(msw@2.6.5(@types/node@20.12.13)(typescript@5.4.5)) optionalDependencies: - '@vitest/browser': 2.1.4(@types/node@20.12.13)(playwright@1.48.2)(typescript@5.4.5)(vite@5.2.12(@types/node@20.12.13))(vitest@2.1.4) + '@vitest/browser': 2.1.5(@types/node@20.12.13)(playwright@1.49.0)(typescript@5.4.5)(vite@5.2.12(@types/node@20.12.13))(vitest@2.1.5) transitivePeerDependencies: - supports-color - '@vitest/expect@2.1.4': + '@vitest/expect@2.1.5': dependencies: - '@vitest/spy': 2.1.4 - '@vitest/utils': 2.1.4 + '@vitest/spy': 2.1.5 + '@vitest/utils': 2.1.5 chai: 5.1.2 tinyrainbow: 1.2.0 - '@vitest/mocker@2.1.4(msw@2.6.2(@types/node@20.12.13)(typescript@5.4.5))(vite@5.2.12(@types/node@20.12.13))': + '@vitest/mocker@2.1.5(msw@2.6.5(@types/node@20.12.13)(typescript@5.4.5))(vite@5.2.12(@types/node@20.12.13))': dependencies: - '@vitest/spy': 2.1.4 + '@vitest/spy': 2.1.5 estree-walker: 3.0.3 magic-string: 0.30.12 optionalDependencies: - msw: 2.6.2(@types/node@20.12.13)(typescript@5.4.5) + msw: 2.6.5(@types/node@20.12.13)(typescript@5.4.5) vite: 5.2.12(@types/node@20.12.13) - '@vitest/pretty-format@2.1.4': + '@vitest/pretty-format@2.1.5': dependencies: tinyrainbow: 1.2.0 - '@vitest/runner@2.1.4': + '@vitest/runner@2.1.5': dependencies: - '@vitest/utils': 2.1.4 + '@vitest/utils': 2.1.5 pathe: 1.1.2 - '@vitest/snapshot@2.1.4': + '@vitest/snapshot@2.1.5': dependencies: - '@vitest/pretty-format': 2.1.4 + '@vitest/pretty-format': 2.1.5 magic-string: 0.30.12 pathe: 1.1.2 - '@vitest/spy@2.1.4': + '@vitest/spy@2.1.5': dependencies: tinyspy: 3.0.2 - '@vitest/utils@2.1.4': + '@vitest/utils@2.1.5': dependencies: - '@vitest/pretty-format': 2.1.4 + '@vitest/pretty-format': 2.1.5 loupe: 3.1.2 tinyrainbow: 1.2.0 @@ -6258,6 +6261,8 @@ snapshots: es-errors@1.3.0: {} + es-module-lexer@1.5.4: {} + es-object-atoms@1.0.0: dependencies: es-errors: 1.3.0 @@ -7478,13 +7483,13 @@ snapshots: ms@2.1.3: {} - msw@2.6.2(@types/node@20.12.13)(typescript@5.4.5): + msw@2.6.5(@types/node@20.12.13)(typescript@5.4.5): dependencies: '@bundled-es-modules/cookie': 2.0.1 '@bundled-es-modules/statuses': 1.0.1 '@bundled-es-modules/tough-cookie': 0.1.6 '@inquirer/confirm': 5.0.1(@types/node@20.12.13) - '@mswjs/interceptors': 0.36.10 + '@mswjs/interceptors': 0.37.1 '@open-draft/deferred-promise': 2.2.0 '@open-draft/until': 2.1.0 '@types/cookie': 0.6.0 @@ -7844,11 +7849,11 @@ snapshots: mlly: 1.7.0 pathe: 1.1.2 - playwright-core@1.48.2: {} + playwright-core@1.49.0: {} - playwright@1.48.2: + playwright@1.49.0: dependencies: - playwright-core: 1.48.2 + playwright-core: 1.49.0 optionalDependencies: fsevents: 2.3.2 @@ -8181,7 +8186,7 @@ snapshots: statuses@2.0.1: {} - std-env@3.7.0: {} + std-env@3.8.0: {} strict-event-emitter@0.5.1: {} @@ -8535,10 +8540,11 @@ snapshots: validator@13.12.0: {} - vite-node@2.1.4(@types/node@20.12.13): + vite-node@2.1.5(@types/node@20.12.13): dependencies: cac: 6.7.14 debug: 4.3.7 + es-module-lexer: 1.5.4 pathe: 1.1.2 vite: 5.2.12(@types/node@20.12.13) transitivePeerDependencies: @@ -8658,38 +8664,38 @@ snapshots: - typescript - universal-cookie - vitest-browser-vue@0.0.1(@vitest/browser@2.1.4)(vitest@2.1.4)(vue@3.4.27(typescript@5.4.5)): + vitest-browser-vue@0.0.1(@vitest/browser@2.1.5)(vitest@2.1.5)(vue@3.4.27(typescript@5.4.5)): dependencies: - '@vitest/browser': 2.1.4(@types/node@20.12.13)(playwright@1.48.2)(typescript@5.4.5)(vite@5.2.12(@types/node@20.12.13))(vitest@2.1.4) + '@vitest/browser': 2.1.5(@types/node@20.12.13)(playwright@1.49.0)(typescript@5.4.5)(vite@5.2.12(@types/node@20.12.13))(vitest@2.1.5) '@vue/test-utils': 2.4.6 - vitest: 2.1.4(@types/node@20.12.13)(@vitest/browser@2.1.4)(msw@2.6.2(@types/node@20.12.13)(typescript@5.4.5)) + vitest: 2.1.5(@types/node@20.12.13)(@vitest/browser@2.1.5)(msw@2.6.5(@types/node@20.12.13)(typescript@5.4.5)) vue: 3.4.27(typescript@5.4.5) - vitest@2.1.4(@types/node@20.12.13)(@vitest/browser@2.1.4)(msw@2.6.2(@types/node@20.12.13)(typescript@5.4.5)): + vitest@2.1.5(@types/node@20.12.13)(@vitest/browser@2.1.5)(msw@2.6.5(@types/node@20.12.13)(typescript@5.4.5)): dependencies: - '@vitest/expect': 2.1.4 - '@vitest/mocker': 2.1.4(msw@2.6.2(@types/node@20.12.13)(typescript@5.4.5))(vite@5.2.12(@types/node@20.12.13)) - '@vitest/pretty-format': 2.1.4 - '@vitest/runner': 2.1.4 - '@vitest/snapshot': 2.1.4 - '@vitest/spy': 2.1.4 - '@vitest/utils': 2.1.4 + '@vitest/expect': 2.1.5 + '@vitest/mocker': 2.1.5(msw@2.6.5(@types/node@20.12.13)(typescript@5.4.5))(vite@5.2.12(@types/node@20.12.13)) + '@vitest/pretty-format': 2.1.5 + '@vitest/runner': 2.1.5 + '@vitest/snapshot': 2.1.5 + '@vitest/spy': 2.1.5 + '@vitest/utils': 2.1.5 chai: 5.1.2 debug: 4.3.7 expect-type: 1.1.0 magic-string: 0.30.12 pathe: 1.1.2 - std-env: 3.7.0 + std-env: 3.8.0 tinybench: 2.9.0 tinyexec: 0.3.1 tinypool: 1.0.1 tinyrainbow: 1.2.0 vite: 5.2.12(@types/node@20.12.13) - vite-node: 2.1.4(@types/node@20.12.13) + vite-node: 2.1.5(@types/node@20.12.13) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 20.12.13 - '@vitest/browser': 2.1.4(@types/node@20.12.13)(playwright@1.48.2)(typescript@5.4.5)(vite@5.2.12(@types/node@20.12.13))(vitest@2.1.4) + '@vitest/browser': 2.1.5(@types/node@20.12.13)(playwright@1.49.0)(typescript@5.4.5)(vite@5.2.12(@types/node@20.12.13))(vitest@2.1.5) transitivePeerDependencies: - less - lightningcss diff --git a/src/__test__/clone.test.ts b/src/__test__/clone.test.ts index 127eb8a0..1582a574 100644 --- a/src/__test__/clone.test.ts +++ b/src/__test__/clone.test.ts @@ -89,8 +89,8 @@ describe('clone', () => { ]) }) - // TODO: it works when the headless option is false - it.skip('should clone item from list1 to list2', async () => { + // TODO: it only works when the headless option is false + it('should clone item from list1 to list2', async () => { const list1Snap = toValue(list1.value) const list2Snap = toValue(list2.value) diff --git a/vitest.workspace.ts b/vitest.workspace.ts index 0b32a26b..cd2987f0 100644 --- a/vitest.workspace.ts +++ b/vitest.workspace.ts @@ -9,7 +9,7 @@ export default defineWorkspace([ clearMocks: true, browser: { enabled: true, - headless: true, + headless: false, screenshotFailures: false, name: 'chromium', provider: 'playwright', From 67f12a47c13dc4d1f33da0d95cfc7d14834efcaf Mon Sep 17 00:00:00 2001 From: Lo Date: Fri, 22 Nov 2024 14:16:03 +0800 Subject: [PATCH 8/8] test: optimize --- src/__test__/basic.test.ts | 285 ++++++++++++------------------------- src/__test__/clone.test.ts | 47 +++--- src/__test__/helpers.ts | 3 + 3 files changed, 119 insertions(+), 216 deletions(-) create mode 100644 src/__test__/helpers.ts diff --git a/src/__test__/basic.test.ts b/src/__test__/basic.test.ts index 2a3c569a..784f152f 100644 --- a/src/__test__/basic.test.ts +++ b/src/__test__/basic.test.ts @@ -10,15 +10,16 @@ import { withDirectives } from 'vue' import { userEvent } from '@vitest/browser/context' -import type { SortableEvent } from 'sortablejs' +import { type SortableEvent } from 'sortablejs' +import { getTextContents } from './helpers' describe('basic', () => { const data = Array.from({ length: 4 }).map((_, i) => `item${i + 1}`) const list = ref([]) const screen = ref | null>(null) - const itemElements = computed(() => - screen.value!.getByTestId('item').elements() + const listItemElements = computed(() => + screen.value!.getByRole('listitem').elements() ) const sortableEventCallback = (event: SortableEvent) => [ @@ -40,75 +41,65 @@ describe('basic', () => { VueDraggable, { ref: draggableRef, + tag: 'ul', modelValue: list.value, 'onUpdate:modelValue': (v: any) => (list.value = v), onStart, onUpdate, onEnd }, - list.value.map(item => h('div', { 'data-testid': 'item' }, item)) + { + default: () => list.value.map(item => h('li', item)) + } ) ) }) it('should render', () => { - expect(itemElements.value.map(el => el.textContent)) - .toMatchInlineSnapshot(` - [ - "item1", - "item2", - "item3", - "item4", - ] - `) + expect(draggableRef.value?.$el.tagName).toBe('UL') + expect(getTextContents(listItemElements.value)).toEqual(data) }) it('should render after list change', async () => { - list.value = list.value.slice().reverse() + const updatedList = list.value.slice().reverse() + list.value = updatedList await nextTick() - expect(itemElements.value.map(el => el.textContent)) - .toMatchInlineSnapshot(` - [ - "item4", - "item3", - "item2", - "item1", - ] - `) + expect(getTextContents(listItemElements.value)).toEqual(updatedList) }) it('should update list after item is dragged and dropped', async () => { await userEvent.dragAndDrop( - screen.value!.getByText('item1').element(), - screen.value!.getByText('item4').element() + screen.value!.getByText(data[0]).element(), + screen.value!.getByText(data[3]).element() ) - expect(itemElements.value.map(el => el.textContent)) - .toMatchInlineSnapshot(` - [ - "item2", - "item3", - "item4", - "item1", - ] - `) - - expect(list.value).toMatchInlineSnapshot(` - [ - "item2", - "item3", - "item4", - "item1", - ] - `) + const updatedList = [...data.slice(1), data[0]] + + expect(getTextContents(listItemElements.value)).toEqual(updatedList) + expect(list.value).toEqual(updatedList) + + await userEvent.dragAndDrop( + screen.value!.getByText(updatedList[1]).element(), + screen.value!.getByText(updatedList[2]).element() + ) + + const updatedList2 = [ + updatedList[0], + updatedList[2], + updatedList[1], + updatedList[3] + ] + + expect(getTextContents(listItemElements.value)).toEqual(updatedList2) + expect(list.value).toEqual(updatedList2) }) it('should emit after item is dragged and dropped', async () => { await userEvent.dragAndDrop( - screen.value!.getByText('item1').element(), - screen.value!.getByText('item4').element() + screen.value!.getByText(data[0]).element(), + screen.value!.getByText(data[3]).element() ) expect(onStart).toReturnWith([0, null]) @@ -120,19 +111,12 @@ describe('basic', () => { draggableRef.value?.pause() await userEvent.dragAndDrop( - screen.value!.getByText('item1').element(), - screen.value!.getByText('item4').element() + screen.value!.getByText(data[0]).element(), + screen.value!.getByText(data[3]).element() ) - expect(itemElements.value.map(el => el.textContent)) - .toMatchInlineSnapshot(` - [ - "item1", - "item2", - "item3", - "item4", - ] - `) + expect(getTextContents(listItemElements.value)).toEqual(data) + expect(list.value).toEqual(data) expect(onStart).not.toHaveBeenCalled() expect(onUpdate).not.toHaveBeenCalled() @@ -141,27 +125,22 @@ describe('basic', () => { draggableRef.value?.resume() await userEvent.dragAndDrop( - screen.value!.getByText('item1').element(), - screen.value!.getByText('item4').element() + screen.value!.getByText(data[0]).element(), + screen.value!.getByText(data[2]).element() ) - expect(itemElements.value.map(el => el.textContent)) - .toMatchInlineSnapshot(` - [ - "item2", - "item3", - "item4", - "item1", - ] - `) + const updatedList = [data[1], data[2], data[0], data[3]] + + expect(getTextContents(listItemElements.value)).toEqual(updatedList) + expect(list.value).toEqual(updatedList) expect(onStart).toHaveBeenCalledOnce() expect(onUpdate).toHaveBeenCalledOnce() expect(onEnd).toHaveBeenCalledOnce() expect(onStart).toReturnWith([0, null]) - expect(onUpdate).toReturnWith([0, 3]) - expect(onEnd).toReturnWith([0, 3]) + expect(onUpdate).toReturnWith([0, 2]) + expect(onEnd).toReturnWith([0, 2]) }) }) @@ -171,7 +150,7 @@ describe('basic', () => { screen.value = render( defineComponent({ setup() { - const el = ref() + const el = ref(null) const { pause, resume } = useDraggable(el, list, { onStart, onUpdate, @@ -180,11 +159,11 @@ describe('basic', () => { return () => [ h( - 'div', + 'ul', { ref: el }, - list.value.map(item => - h('div', { 'data-testid': 'item' }, item) - ) + { + default: () => list.value.map(item => h('li', item)) + } ), h('button', { onClick: pause }, 'pause'), h('button', { onClick: resume }, 'resume') @@ -195,63 +174,34 @@ describe('basic', () => { }) it('should render', () => { - expect(itemElements.value.map(el => el.textContent)) - .toMatchInlineSnapshot(` - [ - "item1", - "item2", - "item3", - "item4", - ] - `) + expect(getTextContents(listItemElements.value)).toEqual(data) }) it('should render after list change', async () => { - list.value = list.value.slice().reverse() + const updatedList = list.value.slice().reverse() + list.value = updatedList await nextTick() - expect(itemElements.value.map(el => el.textContent)) - .toMatchInlineSnapshot(` - [ - "item4", - "item3", - "item2", - "item1", - ] - `) + expect(getTextContents(listItemElements.value)).toEqual(updatedList) }) it('should update list after item is dragged and dropped', async () => { await userEvent.dragAndDrop( - screen.value!.getByText('item1').element(), - screen.value!.getByText('item4').element() + screen.value!.getByText(data[0]).element(), + screen.value!.getByText(data[3]).element() ) - expect(itemElements.value.map(el => el.textContent)) - .toMatchInlineSnapshot(` - [ - "item2", - "item3", - "item4", - "item1", - ] - `) - - expect(list.value).toMatchInlineSnapshot(` - [ - "item2", - "item3", - "item4", - "item1", - ] - `) + const updatedList = [...data.slice(1), data[0]] + + expect(getTextContents(listItemElements.value)).toEqual(updatedList) + expect(list.value).toEqual(updatedList) }) it('should emit after item is dragged and dropped', async () => { await userEvent.dragAndDrop( - screen.value!.getByText('item1').element(), - screen.value!.getByText('item4').element() + screen.value!.getByText(data[0]).element(), + screen.value!.getByText(data[3]).element() ) expect(onStart).toReturnWith([0, null]) @@ -263,19 +213,12 @@ describe('basic', () => { await userEvent.click(screen.value!.getByText('pause')) await userEvent.dragAndDrop( - screen.value!.getByText('item1').element(), - screen.value!.getByText('item4').element() + screen.value!.getByText(data[0]).element(), + screen.value!.getByText(data[3]).element() ) - expect(itemElements.value.map(el => el.textContent)) - .toMatchInlineSnapshot(` - [ - "item1", - "item2", - "item3", - "item4", - ] - `) + expect(getTextContents(listItemElements.value)).toEqual(data) + expect(list.value).toEqual(data) expect(onStart).not.toHaveBeenCalled() expect(onUpdate).not.toHaveBeenCalled() @@ -284,19 +227,14 @@ describe('basic', () => { await userEvent.click(screen.value!.getByText('resume')) await userEvent.dragAndDrop( - screen.value!.getByText('item1').element(), - screen.value!.getByText('item4').element() + screen.value!.getByText(data[0]).element(), + screen.value!.getByText(data[3]).element() ) - expect(itemElements.value.map(el => el.textContent)) - .toMatchInlineSnapshot(` - [ - "item2", - "item3", - "item4", - "item1", - ] - `) + const updatedList = [...data.slice(1), data[0]] + + expect(getTextContents(listItemElements.value)).toEqual(updatedList) + expect(list.value).toEqual(updatedList) expect(onStart).toHaveBeenCalledOnce() expect(onUpdate).toHaveBeenCalledOnce() @@ -311,77 +249,40 @@ describe('basic', () => { describe('directive', () => { beforeEach(() => { list.value = data - screen.value = render( - defineComponent({ - directives: { draggable: vDraggable }, - setup() { - return () => - withDirectives( - h( - 'ul', - list.value.map(item => - h('li', { 'data-testid': 'item' }, item) - ) - ), - [[vDraggable, [list, { onStart, onUpdate, onEnd }]]] - ) - } - }) + screen.value = render(() => + withDirectives( + h( + 'ul', + list.value.map(item => h('li', item)) + ), + [[vDraggable, [list, { onStart, onUpdate, onEnd }]]] + ) ) }) it('should render', () => { - expect(itemElements.value.map(el => el.textContent)) - .toMatchInlineSnapshot(` - [ - "item1", - "item2", - "item3", - "item4", - ] - `) + expect(getTextContents(listItemElements.value)).toEqual(data) }) it('should render after list change', async () => { - list.value = list.value.slice().reverse() + const updatedList = list.value.slice().reverse() + list.value = updatedList await nextTick() - expect(itemElements.value.map(el => el.textContent)) - .toMatchInlineSnapshot(` - [ - "item4", - "item3", - "item2", - "item1", - ] - `) + expect(getTextContents(listItemElements.value)).toEqual(updatedList) }) it('should update list after item is dragged and dropped', async () => { await userEvent.dragAndDrop( - screen.value!.getByText('item1').element(), - screen.value!.getByText('item4').element() + screen.value!.getByText(data[0]).element(), + screen.value!.getByText(data[3]).element() ) - expect(itemElements.value.map(el => el.textContent)) - .toMatchInlineSnapshot(` - [ - "item2", - "item3", - "item4", - "item1", - ] - `) - - expect(list.value).toMatchInlineSnapshot(` - [ - "item2", - "item3", - "item4", - "item1", - ] - `) + const updatedList = [...data.slice(1), data[0]] + + expect(getTextContents(listItemElements.value)).toEqual(updatedList) + expect(list.value).toEqual(updatedList) }) }) }) diff --git a/src/__test__/clone.test.ts b/src/__test__/clone.test.ts index 1582a574..1c89d8c3 100644 --- a/src/__test__/clone.test.ts +++ b/src/__test__/clone.test.ts @@ -3,6 +3,7 @@ import { VueDraggable } from '..' import { beforeEach, describe, expect, it, vi } from 'vitest' import { render, RenderResult } from 'vitest-browser-vue' import { computed, h, ref, toValue } from 'vue' +import { getTextContents } from './helpers' describe('clone', () => { const data = Array.from({ length: 4 }).map((_, i) => `item${i + 1}`) @@ -11,11 +12,11 @@ describe('clone', () => { const list2 = ref([]) const screen = ref | null>(null) - const list1Elements = computed(() => - screen.value!.getByTestId('list1').elements() + const list1ItemElements = computed(() => + screen.value!.getByTestId('list1').getByRole('listitem').elements() ) - const list2Elements = computed(() => - screen.value!.getByTestId('list2').elements() + const list2ItemElements = computed(() => + screen.value!.getByTestId('list2').getByRole('listitem').elements() ) const onClone = vi.fn() @@ -29,6 +30,8 @@ describe('clone', () => { h( VueDraggable, { + tag: 'ul', + 'data-testid': 'list1', modelValue: list1.value, 'onUpdate:modelValue': (v: any) => (list1.value = v), sort: false, @@ -36,24 +39,20 @@ describe('clone', () => { onClone }, { - default: () => - list1.value.map(item => - h('div', { 'data-testid': 'list1' }, item) - ) + default: () => list1.value.map(item => h('li', item)) } ), h( VueDraggable, { + tag: 'ul', + 'data-testid': 'list2', modelValue: list2.value, 'onUpdate:modelValue': (v: any) => (list2.value = v), group: 'people' }, { - default: () => - list2.value.map(item => - h('div', { 'data-testid': 'list2' }, item) - ) + default: () => list2.value.map(item => h('li', item)) } ) ]) @@ -62,31 +61,31 @@ describe('clone', () => { it("shouldn't sort list1", async () => { const list1Snap = toValue(list1.value) - expect(list1Elements.value.map(el => el.textContent)).toEqual(list1Snap) + expect(getTextContents(list1ItemElements.value)).toEqual(list1Snap) await userEvent.dragAndDrop( screen.value!.getByText(list1Snap[0]).element(), screen.value!.getByText(list1Snap[1]).element() ) - expect(list1Elements.value.map(el => el.textContent)).toEqual(list1Snap) + expect(getTextContents(list1ItemElements.value)).toEqual(list1Snap) + expect(list1.value).toEqual(list1Snap) }) it('should sort list2', async () => { const list2Snap = toValue(list2.value) - expect(list2Elements.value.map(el => el.textContent)).toEqual(list2Snap) + expect(getTextContents(list2ItemElements.value)).toEqual(list2Snap) await userEvent.dragAndDrop( screen.value!.getByText(list2Snap[0]).element(), screen.value!.getByText(list2Snap[1]).element() ) - expect(list2Elements.value.map(el => el.textContent)).toEqual([ - list2Snap[1], - list2Snap[0], - ...list2Snap.slice(2) - ]) + const updatedList2 = [list2Snap[1], list2Snap[0], ...list2Snap.slice(2)] + + expect(getTextContents(list2ItemElements.value)).toEqual(updatedList2) + expect(list2.value).toEqual(updatedList2) }) // TODO: it only works when the headless option is false @@ -99,10 +98,10 @@ describe('clone', () => { screen.value!.getByText(list2Snap[0]).element() ) - expect(list2Elements.value.map(el => el.textContent)).toEqual([ - list1Snap[0], - ...list2Snap - ]) + const updatedList2 = [list1Snap[0], ...list2Snap] + + expect(getTextContents(list2ItemElements.value)).toEqual(updatedList2) + expect(list2.value).toEqual(updatedList2) expect(onClone).toHaveBeenCalledTimes(1) }) diff --git a/src/__test__/helpers.ts b/src/__test__/helpers.ts new file mode 100644 index 00000000..ddde1a5e --- /dev/null +++ b/src/__test__/helpers.ts @@ -0,0 +1,3 @@ +export function getTextContents(elements: Element[]) { + return elements.map(el => el.textContent) +}