From a2c6006e370877ed27ae86bb598cc6b3efeca2c9 Mon Sep 17 00:00:00 2001 From: R2m1liA <15258427350@163.com> Date: Sat, 25 Oct 2025 14:05:47 +0800 Subject: [PATCH 1/8] =?UTF-8?q?build:=20=E6=B7=BB=E5=8A=A0nuxt=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E6=A1=86=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nuxt.config.ts | 2 +- package.json | 8 +- pnpm-lock.yaml | 386 +++++++++++++++++++++++++++++++++++++++++++++-- vitest.config.ts | 23 +++ 4 files changed, 403 insertions(+), 16 deletions(-) create mode 100644 vitest.config.ts diff --git a/nuxt.config.ts b/nuxt.config.ts index 680ffcb..715fddd 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -117,11 +117,11 @@ export default defineNuxtConfig({ '@nuxt/fonts', '@nuxt/icon', '@nuxt/image', - '@nuxt/test-utils', '@vueuse/nuxt', '@pinia/nuxt', '@unocss/nuxt', '@element-plus/nuxt', '@nuxtjs/i18n', + '@nuxt/test-utils/module', ], }); diff --git a/package.json b/package.json index e1a3fed..5aef693 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,6 @@ "@nuxt/fonts": "0.11.4", "@nuxt/icon": "2.0.0", "@nuxt/image": "1.11.0", - "@nuxt/test-utils": "3.19.2", "@nuxtjs/i18n": "10.0.5", "@pinia/nuxt": "^0.11.2", "@types/markdown-it": "^14.1.2", @@ -38,9 +37,14 @@ "@commitlint/cli": "^19.8.1", "@commitlint/config-conventional": "^19.8.1", "@element-plus/nuxt": "^1.1.4", + "@nuxt/test-utils": "3.19.2", + "@vue/test-utils": "^2.4.6", "eslint": "^9.35.0", + "happy-dom": "^20.0.8", "husky": "^9.1.7", "lint-staged": "^16.1.6", - "prettier": "^3.6.2" + "playwright-core": "^1.56.1", + "prettier": "^3.6.2", + "vitest": "^4.0.3" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 650e497..85ef2e9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,9 +26,6 @@ importers: '@nuxt/image': specifier: 1.11.0 version: 1.11.0(db0@0.3.2)(ioredis@5.7.0)(magicast@0.3.5) - '@nuxt/test-utils': - specifier: 3.19.2 - version: 3.19.2(magicast@0.3.5)(typescript@5.9.2) '@nuxtjs/i18n': specifier: 10.0.5 version: 10.0.5(@vue/compiler-dom@3.5.21)(db0@0.3.2)(eslint@9.35.0(jiti@2.5.1))(ioredis@5.7.0)(magicast@0.3.5)(rollup@4.50.2)(vue@3.5.21(typescript@5.9.2)) @@ -84,18 +81,33 @@ importers: '@element-plus/nuxt': specifier: ^1.1.4 version: 1.1.4(@element-plus/icons-vue@2.3.2(vue@3.5.21(typescript@5.9.2)))(element-plus@2.11.2(vue@3.5.21(typescript@5.9.2)))(magicast@0.3.5) + '@nuxt/test-utils': + specifier: 3.19.2 + version: 3.19.2(@vue/test-utils@2.4.6)(happy-dom@20.0.8)(magicast@0.3.5)(playwright-core@1.56.1)(typescript@5.9.2)(vitest@4.0.3(@types/node@24.4.0)(happy-dom@20.0.8)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1)) + '@vue/test-utils': + specifier: ^2.4.6 + version: 2.4.6 eslint: specifier: ^9.35.0 version: 9.35.0(jiti@2.5.1) + happy-dom: + specifier: ^20.0.8 + version: 20.0.8 husky: specifier: ^9.1.7 version: 9.1.7 lint-staged: specifier: ^16.1.6 version: 16.1.6 + playwright-core: + specifier: ^1.56.1 + version: 1.56.1 prettier: specifier: ^3.6.2 version: 3.6.2 + vitest: + specifier: ^4.0.3 + version: 4.0.3(@types/node@24.4.0)(happy-dom@20.0.8)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1) packages: @@ -1004,6 +1016,9 @@ packages: resolution: {integrity: sha512-rLQc/nEVWL0xMJf1a6+ndUpdQtxPBFzm4jeqG4o7HuXtDLn4HOe1dPdu7AsaIqq7EcsEjZ5T4mX4X8XnB8cT0Q==} engines: {node: '>=20.11.1'} + '@one-ini/wasm@0.1.1': + resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==} + '@oxc-minify/binding-android-arm64@0.87.0': resolution: {integrity: sha512-ZbJmAfXvNAamOSnXId3BiM3DiuzlD1isqKjtmRFb/hpvChHHA23FSPrFcO16w+ugZKg33sZ93FinFkKtlC4hww==} engines: {node: '>=14.0.0'} @@ -1770,6 +1785,9 @@ packages: '@speed-highlight/core@1.2.7': resolution: {integrity: sha512-0dxmVj4gxg3Jg879kvFS/msl4s9F3T9UXC1InxgOf7t5NvcPD97u/WTA5vL/IxWHMn7qSxBozqrnnE2wvl1m8g==} + '@standard-schema/spec@1.0.0': + resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} + '@stylistic/eslint-plugin@5.3.1': resolution: {integrity: sha512-Ykums1VYonM0TgkD0VteVq9mrlO2FhF48MDJnPyv3MktIB2ydtuhlO0AfWm7xnW1kyf5bjOqA6xc7JjviuVTxg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1789,9 +1807,15 @@ packages: '@tybys/wasm-util@0.10.1': resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + '@types/conventional-commits-parser@5.0.1': resolution: {integrity: sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ==} + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + '@types/eslint-scope@3.7.7': resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} @@ -1819,6 +1843,9 @@ packages: '@types/mdurl@2.0.0': resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} + '@types/node@20.19.23': + resolution: {integrity: sha512-yIdlVVVHXpmqRhtyovZAcSy0MiPcYWGkoO4CGe/+jpP0hmNuihm4XhHbADpK++MsiLHP5MVlv+bcgdF99kSiFQ==} + '@types/node@24.4.0': resolution: {integrity: sha512-gUuVEAK4/u6F9wRLznPUU4WGUacSEBDPoC2TrBkw3GAnOLHBL45QdfHOXp1kJ4ypBGLxTOB+t7NJLpKoC3gznQ==} @@ -1838,6 +1865,9 @@ packages: '@types/web-bluetooth@0.0.21': resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==} + '@types/whatwg-mimetype@3.0.2': + resolution: {integrity: sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==} + '@typescript-eslint/eslint-plugin@8.43.0': resolution: {integrity: sha512-8tg+gt7ENL7KewsKMKDHXR1vm8tt9eMxjJBYINf6swonlWgkYn5NwyIgXpbbDxTNU5DgpDFfj95prcTq2clIQQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2110,6 +2140,35 @@ packages: vite: ^5.0.0 || ^6.0.0 || ^7.0.0 vue: ^3.2.25 + '@vitest/expect@4.0.3': + resolution: {integrity: sha512-v3eSDx/bF25pzar6aEJrrdTXJduEBU3uSGXHslIdGIpJVP8tQQHV6x1ZfzbFQ/bLIomLSbR/2ZCfnaEGkWkiVQ==} + + '@vitest/mocker@4.0.3': + resolution: {integrity: sha512-evZcRspIPbbiJEe748zI2BRu94ThCBE+RkjCpVF8yoVYuTV7hMe+4wLF/7K86r8GwJHSmAPnPbZhpXWWrg1qbA==} + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@4.0.3': + resolution: {integrity: sha512-N7gly/DRXzxa9w9sbDXwD9QNFYP2hw90LLLGDobPNwiWgyW95GMxsCt29/COIKKh3P7XJICR38PSDePenMBtsw==} + + '@vitest/runner@4.0.3': + resolution: {integrity: sha512-1/aK6fPM0lYXWyGKwop2Gbvz1plyTps/HDbIIJXYtJtspHjpXIeB3If07eWpVH4HW7Rmd3Rl+IS/+zEAXrRtXA==} + + '@vitest/snapshot@4.0.3': + resolution: {integrity: sha512-amnYmvZ5MTjNCP1HZmdeczAPLRD6iOm9+2nMRUGxbe/6sQ0Ymur0NnR9LIrWS8JA3wKE71X25D6ya/3LN9YytA==} + + '@vitest/spy@4.0.3': + resolution: {integrity: sha512-82vVL8Cqz7rbXaNUl35V2G7xeNMAjBdNOVaHbrzznT9BmiCiPOzhf0FhU3eP41nP1bLDm/5wWKZqkG4nyU95DQ==} + + '@vitest/utils@4.0.3': + resolution: {integrity: sha512-qV6KJkq8W3piW6MDIbGOmn1xhvcW4DuA07alqaQ+vdx7YA49J85pnwnxigZVQFQw3tWnQNRKWwhz5wbP6iv/GQ==} + '@volar/language-core@2.4.23': resolution: {integrity: sha512-hEEd5ET/oSmBC6pi1j6NaNYRWoAiDhINbT8rmwtINugR39loROSlufGdYMF9TaKGfz+ViGs1Idi3mAhnuPcoGQ==} @@ -2207,6 +2266,9 @@ packages: '@vue/shared@3.5.21': resolution: {integrity: sha512-+2k1EQpnYuVuu3N7atWyG3/xoFWIVJZq4Mz8XNOdScFI0etES75fbny/oU4lKWk/577P1zmg0ioYvpGEDZ3DLw==} + '@vue/test-utils@2.4.6': + resolution: {integrity: sha512-FMxEjOpYNYiFe0GkaHsnJPXFHxQ6m4t8vI/ElPGpMWxZKpmRvQ33OIrvRXemy6yha03RxhOlQuy+gZMC3CQSow==} + '@vueuse/core@13.9.0': resolution: {integrity: sha512-ts3regBQyURfCE2BcytLqzm8+MmLlo5Ln/KLoxDVcsZ2gzIwVNnQpQOL/UKV8alUqjSZOlpFZcRNsLRqj+OzyA==} peerDependencies: @@ -2290,6 +2352,10 @@ packages: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} hasBin: true + abbrev@2.0.0: + resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + abbrev@3.0.1: resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} engines: {node: ^18.17.0 || >=20.5.0} @@ -2391,6 +2457,10 @@ packages: array-ify@1.0.0: resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + ast-kit@2.1.2: resolution: {integrity: sha512-cl76xfBQM6pztbrFWRnxbrDm9EOqDr1BF6+qQnnDZG2Co2LjyUktkN9GTJfBAfdae+DbT2nJf2nCGAdDDN7W2g==} engines: {node: '>=20.18.0'} @@ -2552,6 +2622,10 @@ packages: caniuse-lite@1.0.30001741: resolution: {integrity: sha512-QGUGitqsc8ARjLdgAfxETDhRbJ0REsP6O3I96TAth/mVjh2cYzN2u+3AzPP3aVSm2FehEItaJw1xd+IGBXWeSw==} + chai@6.2.0: + resolution: {integrity: sha512-aUTnJc/JipRzJrNADXVvpVqi6CO0dn3nx4EVPxijri+fj3LUUDyZQOgVeW54Ob3Y1Xh9Iz8f+CgaCl8v0mn9bA==} + engines: {node: '>=18'} + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -2637,6 +2711,10 @@ packages: colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + commander@10.0.1: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} + engines: {node: '>=14'} + commander@11.1.0: resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} engines: {node: '>=16'} @@ -2678,6 +2756,9 @@ packages: confbox@0.2.2: resolution: {integrity: sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==} + config-chain@1.1.13: + resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} + consola@3.4.2: resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} engines: {node: ^14.18.0 || >=16.10.0} @@ -2960,6 +3041,11 @@ packages: eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + editorconfig@1.0.4: + resolution: {integrity: sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==} + engines: {node: '>=14'} + hasBin: true + ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} @@ -3217,11 +3303,15 @@ packages: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} engines: {node: '>=6'} + expect-type@1.2.2: + resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==} + engines: {node: '>=12.0.0'} + exsolve@1.0.7: resolution: {integrity: sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==} - fake-indexeddb@6.2.2: - resolution: {integrity: sha512-SGbf7fzjeHz3+12NO1dYigcYn4ivviaeULV5yY5rdGihBvvgwMds4r4UBbNIUMwkze57KTDm32rq3j1Az8mzEw==} + fake-indexeddb@6.2.4: + resolution: {integrity: sha512-INKeIKEtSViN4yVtEWEUqbsqmaIy7Ls+MfU0yxQVXg67pOJ/sH1ZxcVrP8XrKULUFohcPD9gnmym+qBfEybACw==} engines: {node: '>=18'} fast-deep-equal@3.1.3: @@ -3416,6 +3506,10 @@ packages: h3@1.15.4: resolution: {integrity: sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==} + happy-dom@20.0.8: + resolution: {integrity: sha512-TlYaNQNtzsZ97rNMBAm8U+e2cUQXNithgfCizkDgc11lgmN4j9CKMhO3FPGKWQYPwwkFcPpoXYF/CqEPLgzfOg==} + engines: {node: '>=20.0.0'} + has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} @@ -3634,6 +3728,15 @@ packages: resolution: {integrity: sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==} hasBin: true + js-beautify@1.15.4: + resolution: {integrity: sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==} + 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==} @@ -3930,6 +4033,10 @@ 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'} @@ -4049,6 +4156,11 @@ packages: node-releases@2.0.21: resolution: {integrity: sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==} + 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 + nopt@8.1.0: resolution: {integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==} engines: {node: ^18.17.0 || >=20.5.0} @@ -4290,6 +4402,11 @@ packages: pkg-types@2.3.0: resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} + playwright-core@1.56.1: + resolution: {integrity: sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ==} + engines: {node: '>=18'} + hasBin: true + pluralize@8.0.0: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} @@ -4500,6 +4617,9 @@ packages: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} + proto-list@1.2.4: + resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + protocols@2.0.2: resolution: {integrity: sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==} @@ -4717,6 +4837,9 @@ packages: resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} engines: {node: '>= 0.4'} + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + signal-exit@4.1.0: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} @@ -4787,6 +4910,9 @@ packages: resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==} engines: {node: '>=12.0.0'} + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + standard-as-callback@2.1.0: resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} @@ -4958,6 +5084,12 @@ packages: tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + tinyexec@1.0.1: resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==} @@ -4965,6 +5097,10 @@ packages: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} + tinyrainbow@3.0.3: + resolution: {integrity: sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==} + engines: {node: '>=14.0.0'} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -5030,6 +5166,9 @@ packages: unctx@2.4.1: resolution: {integrity: sha512-AbaYw0Nm4mK4qjhns67C+kgxR2YWiwlDBPzxrN8h8C6VtAdCgditAY5Dezu3IJy4XVqAnbrXt9oQJvsn3fyozg==} + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + undici-types@7.11.0: resolution: {integrity: sha512-kt1ZriHTi7MU+Z/r9DOdAI3ONdaR3M3csEaRc6ewa4f4dTvX4cQCbJ4NkEn0ohE4hHtq85+PhPSTY+pO/1PwgA==} @@ -5305,12 +5444,49 @@ packages: vitest-environment-nuxt@1.0.1: resolution: {integrity: sha512-eBCwtIQriXW5/M49FjqNKfnlJYlG2LWMSNFsRVKomc8CaMqmhQPBS5LZ9DlgYL9T8xIVsiA6RZn2lk7vxov3Ow==} + vitest@4.0.3: + resolution: {integrity: sha512-IUSop8jgaT7w0g1yOM/35qVtKjr/8Va4PrjzH1OUb0YH4c3OXB2lCZDkMAB6glA8T5w8S164oJGsbcmAecr4sA==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/debug': ^4.1.12 + '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 4.0.3 + '@vitest/browser-preview': 4.0.3 + '@vitest/browser-webdriverio': 4.0.3 + '@vitest/ui': 4.0.3 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/debug': + optional: true + '@types/node': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + vscode-uri@3.1.0: resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} vue-bundle-renderer@2.1.2: resolution: {integrity: sha512-M4WRBO/O/7G9phGaGH9AOwOnYtY9ZpPoDVpBpRzR2jO5rFL9mgIlQIgums2ljCTC2HL1jDXFQc//CzWcAQHgAw==} + vue-component-type-helpers@2.2.12: + resolution: {integrity: sha512-YbGqHZ5/eW4SnkPNR44mKVc6ZKQoRs/Rux1sxC6rdwXb4qpbOSYfDr9DsTHolOTGmIKgM9j141mZbBeg05R1pw==} + vue-demi@0.14.10: resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} engines: {node: '>=12'} @@ -5377,6 +5553,10 @@ packages: webpack-cli: optional: true + whatwg-mimetype@3.0.0: + resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} + engines: {node: '>=12'} + whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} @@ -5390,6 +5570,11 @@ packages: engines: {node: ^18.17.0 || >=20.5.0} hasBin: true + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + word-wrap@1.2.5: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} @@ -6673,7 +6858,7 @@ snapshots: transitivePeerDependencies: - magicast - '@nuxt/test-utils@3.19.2(magicast@0.3.5)(typescript@5.9.2)': + '@nuxt/test-utils@3.19.2(@vue/test-utils@2.4.6)(happy-dom@20.0.8)(magicast@0.3.5)(playwright-core@1.56.1)(typescript@5.9.2)(vitest@4.0.3(@types/node@24.4.0)(happy-dom@20.0.8)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1))': dependencies: '@nuxt/kit': 3.19.2(magicast@0.3.5) c12: 3.2.0(magicast@0.3.5) @@ -6681,7 +6866,7 @@ snapshots: defu: 6.1.4 destr: 2.0.5 estree-walker: 3.0.3 - fake-indexeddb: 6.2.2 + fake-indexeddb: 6.2.4 get-port-please: 3.2.0 h3: 1.15.4 local-pkg: 1.1.2 @@ -6697,8 +6882,13 @@ snapshots: tinyexec: 1.0.1 ufo: 1.6.1 unplugin: 2.3.10 - vitest-environment-nuxt: 1.0.1(magicast@0.3.5)(typescript@5.9.2) + vitest-environment-nuxt: 1.0.1(@vue/test-utils@2.4.6)(happy-dom@20.0.8)(magicast@0.3.5)(playwright-core@1.56.1)(typescript@5.9.2)(vitest@4.0.3(@types/node@24.4.0)(happy-dom@20.0.8)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1)) vue: 3.5.21(typescript@5.9.2) + optionalDependencies: + '@vue/test-utils': 2.4.6 + happy-dom: 20.0.8 + playwright-core: 1.56.1 + vitest: 4.0.3(@types/node@24.4.0)(happy-dom@20.0.8)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1) transitivePeerDependencies: - magicast - typescript @@ -6818,6 +7008,8 @@ snapshots: - uploadthing - vue + '@one-ini/wasm@0.1.1': {} + '@oxc-minify/binding-android-arm64@0.87.0': optional: true @@ -7294,6 +7486,8 @@ snapshots: '@speed-highlight/core@1.2.7': {} + '@standard-schema/spec@1.0.0': {} + '@stylistic/eslint-plugin@5.3.1(eslint@9.35.0(jiti@2.5.1))': dependencies: '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1)) @@ -7318,10 +7512,17 @@ snapshots: tslib: 2.8.1 optional: true + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + '@types/conventional-commits-parser@5.0.1': dependencies: '@types/node': 24.4.0 + '@types/deep-eql@4.0.2': {} + '@types/eslint-scope@3.7.7': dependencies: '@types/eslint': 9.6.1 @@ -7351,6 +7552,10 @@ snapshots: '@types/mdurl@2.0.0': {} + '@types/node@20.19.23': + dependencies: + undici-types: 6.21.0 + '@types/node@24.4.0': dependencies: undici-types: 7.11.0 @@ -7368,6 +7573,8 @@ snapshots: '@types/web-bluetooth@0.0.21': {} + '@types/whatwg-mimetype@3.0.2': {} + '@typescript-eslint/eslint-plugin@8.43.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)': dependencies: '@eslint-community/regexpp': 4.12.1 @@ -7749,6 +7956,45 @@ snapshots: vite: 7.1.5(@types/node@24.4.0)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1) vue: 3.5.21(typescript@5.9.2) + '@vitest/expect@4.0.3': + dependencies: + '@standard-schema/spec': 1.0.0 + '@types/chai': 5.2.3 + '@vitest/spy': 4.0.3 + '@vitest/utils': 4.0.3 + chai: 6.2.0 + tinyrainbow: 3.0.3 + + '@vitest/mocker@4.0.3(vite@7.1.5(@types/node@24.4.0)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1))': + dependencies: + '@vitest/spy': 4.0.3 + estree-walker: 3.0.3 + magic-string: 0.30.19 + optionalDependencies: + vite: 7.1.5(@types/node@24.4.0)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1) + + '@vitest/pretty-format@4.0.3': + dependencies: + tinyrainbow: 3.0.3 + + '@vitest/runner@4.0.3': + dependencies: + '@vitest/utils': 4.0.3 + pathe: 2.0.3 + + '@vitest/snapshot@4.0.3': + dependencies: + '@vitest/pretty-format': 4.0.3 + magic-string: 0.30.19 + pathe: 2.0.3 + + '@vitest/spy@4.0.3': {} + + '@vitest/utils@4.0.3': + dependencies: + '@vitest/pretty-format': 4.0.3 + tinyrainbow: 3.0.3 + '@volar/language-core@2.4.23': dependencies: '@volar/source-map': 2.4.23 @@ -7908,6 +8154,11 @@ snapshots: '@vue/shared@3.5.21': {} + '@vue/test-utils@2.4.6': + dependencies: + js-beautify: 1.15.4 + vue-component-type-helpers: 2.2.12 + '@vueuse/core@13.9.0(vue@3.5.21(typescript@5.9.2))': dependencies: '@types/web-bluetooth': 0.0.21 @@ -8036,6 +8287,8 @@ snapshots: jsonparse: 1.3.1 through: 2.3.8 + abbrev@2.0.0: {} + abbrev@3.0.1: {} abort-controller@3.0.0: @@ -8132,6 +8385,8 @@ snapshots: array-ify@1.0.0: {} + assertion-error@2.0.1: {} + ast-kit@2.1.2: dependencies: '@babel/parser': 7.28.4 @@ -8302,6 +8557,8 @@ snapshots: caniuse-lite@1.0.30001741: {} + chai@6.2.0: {} + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 @@ -8389,6 +8646,8 @@ snapshots: colorette@2.0.20: {} + commander@10.0.1: {} + commander@11.1.0: {} commander@14.0.1: {} @@ -8423,6 +8682,11 @@ snapshots: confbox@0.2.2: {} + config-chain@1.1.13: + dependencies: + ini: 1.3.8 + proto-list: 1.2.4 + consola@3.4.2: {} conventional-changelog-angular@7.0.0: @@ -8675,6 +8939,13 @@ snapshots: 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.7.2 + ee-first@1.1.1: {} electron-to-chromium@1.5.218: {} @@ -9012,9 +9283,11 @@ snapshots: expand-template@2.0.3: optional: true + expect-type@1.2.2: {} + exsolve@1.0.7: {} - fake-indexeddb@6.2.2: {} + fake-indexeddb@6.2.4: {} fast-deep-equal@3.1.3: {} @@ -9223,6 +9496,12 @@ snapshots: ufo: 1.6.1 uncrypto: 0.1.3 + happy-dom@20.0.8: + dependencies: + '@types/node': 20.19.23 + '@types/whatwg-mimetype': 3.0.2 + whatwg-mimetype: 3.0.0 + has-flag@4.0.0: {} hasown@2.0.2: @@ -9287,8 +9566,7 @@ snapshots: inherits@2.0.4: {} - ini@1.3.8: - optional: true + ini@1.3.8: {} ini@4.1.1: {} @@ -9449,6 +9727,16 @@ snapshots: jiti@2.5.1: {} + js-beautify@1.15.4: + 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-tokens@9.0.1: {} @@ -9734,6 +10022,10 @@ snapshots: dependencies: brace-expansion: 2.0.2 + minimatch@9.0.1: + dependencies: + brace-expansion: 2.0.2 + minimatch@9.0.5: dependencies: brace-expansion: 2.0.2 @@ -9910,6 +10202,10 @@ snapshots: node-releases@2.0.21: {} + nopt@7.2.1: + dependencies: + abbrev: 2.0.0 + nopt@8.1.0: dependencies: abbrev: 3.0.1 @@ -10331,6 +10627,8 @@ snapshots: exsolve: 1.0.7 pathe: 2.0.3 + playwright-core@1.56.1: {} + pluralize@8.0.0: {} postcss-calc@10.1.1(postcss@8.5.6): @@ -10531,6 +10829,8 @@ snapshots: kleur: 3.0.3 sisteransi: 1.0.5 + proto-list@1.2.4: {} + protocols@2.0.2: {} pump@3.0.3: @@ -10813,6 +11113,8 @@ snapshots: shell-quote@1.8.3: {} + siginfo@2.0.0: {} + signal-exit@4.1.0: {} simple-concat@1.0.1: @@ -10880,6 +11182,8 @@ snapshots: stable-hash-x@0.2.0: {} + stackback@0.0.2: {} + standard-as-callback@2.1.0: {} statuses@2.0.1: {} @@ -11078,6 +11382,10 @@ snapshots: tiny-invariant@1.3.3: {} + tinybench@2.9.0: {} + + tinyexec@0.3.2: {} + tinyexec@1.0.1: {} tinyglobby@0.2.15: @@ -11085,6 +11393,8 @@ snapshots: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 + tinyrainbow@3.0.3: {} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -11140,6 +11450,8 @@ snapshots: magic-string: 0.30.19 unplugin: 2.3.10 + undici-types@6.21.0: {} + undici-types@7.11.0: {} unenv@2.0.0-rc.21: @@ -11453,9 +11765,9 @@ snapshots: terser: 5.44.0 yaml: 2.8.1 - vitest-environment-nuxt@1.0.1(magicast@0.3.5)(typescript@5.9.2): + vitest-environment-nuxt@1.0.1(@vue/test-utils@2.4.6)(happy-dom@20.0.8)(magicast@0.3.5)(playwright-core@1.56.1)(typescript@5.9.2)(vitest@4.0.3(@types/node@24.4.0)(happy-dom@20.0.8)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1)): dependencies: - '@nuxt/test-utils': 3.19.2(magicast@0.3.5)(typescript@5.9.2) + '@nuxt/test-utils': 3.19.2(@vue/test-utils@2.4.6)(happy-dom@20.0.8)(magicast@0.3.5)(playwright-core@1.56.1)(typescript@5.9.2)(vitest@4.0.3(@types/node@24.4.0)(happy-dom@20.0.8)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1)) transitivePeerDependencies: - '@cucumber/cucumber' - '@jest/globals' @@ -11470,12 +11782,53 @@ snapshots: - typescript - vitest + vitest@4.0.3(@types/node@24.4.0)(happy-dom@20.0.8)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1): + dependencies: + '@vitest/expect': 4.0.3 + '@vitest/mocker': 4.0.3(vite@7.1.5(@types/node@24.4.0)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1)) + '@vitest/pretty-format': 4.0.3 + '@vitest/runner': 4.0.3 + '@vitest/snapshot': 4.0.3 + '@vitest/spy': 4.0.3 + '@vitest/utils': 4.0.3 + debug: 4.4.3 + es-module-lexer: 1.7.0 + expect-type: 1.2.2 + magic-string: 0.30.19 + pathe: 2.0.3 + picomatch: 4.0.3 + std-env: 3.9.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinyglobby: 0.2.15 + tinyrainbow: 3.0.3 + vite: 7.1.5(@types/node@24.4.0)(jiti@2.5.1)(sass@1.92.1)(terser@5.44.0)(yaml@2.8.1) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 24.4.0 + happy-dom: 20.0.8 + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + vscode-uri@3.1.0: {} vue-bundle-renderer@2.1.2: dependencies: ufo: 1.6.1 + vue-component-type-helpers@2.2.12: {} + vue-demi@0.14.10(vue@3.5.21(typescript@5.9.2)): dependencies: vue: 3.5.21(typescript@5.9.2) @@ -11561,6 +11914,8 @@ snapshots: - esbuild - uglify-js + whatwg-mimetype@3.0.0: {} + whatwg-url@5.0.0: dependencies: tr46: 0.0.3 @@ -11574,6 +11929,11 @@ snapshots: dependencies: isexe: 3.1.1 + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + word-wrap@1.2.5: {} wrap-ansi@7.0.0: diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..e007eec --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,23 @@ +import { defineConfig } from 'vitest/config'; +import { defineVitestProject } from '@nuxt/test-utils/config'; + +export default defineConfig({ + test: { + projects: [ + { + test: { + name: 'unit', + include: ['test/{e2e,unit}/*.{test,spec}.ts'], + environment: 'node', + }, + }, + await defineVitestProject({ + test: { + name: 'nuxt', + include: ['test/nuxt/*.{test.spec}.ts'], + environment: 'nuxt', + }, + }), + ], + }, +}); -- 2.49.0 From 57f29e4c067860b2141177fa493229e0d54a877a Mon Sep 17 00:00:00 2001 From: R2m1liA <15258427350@163.com> Date: Sat, 25 Oct 2025 14:55:50 +0800 Subject: [PATCH 2/8] =?UTF-8?q?test:=20=E4=B8=BAutils/file=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 容量进制转换 - 文件拓展名获取与格式化 --- tests/unit/utils/file.test.ts | 36 +++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 tests/unit/utils/file.test.ts diff --git a/tests/unit/utils/file.test.ts b/tests/unit/utils/file.test.ts new file mode 100644 index 0000000..5091966 --- /dev/null +++ b/tests/unit/utils/file.test.ts @@ -0,0 +1,36 @@ +import { + formatFileSize, + getFileExtension, + formatFileExtension, +} from '../../../app/utils/file'; +import { expect, test } from 'vitest'; + +/** + * 单元测试: formatFileSize + */ +test('formatFileSize - format bytes correctly', () => { + expect(formatFileSize(500)).toBe('500.00 B'); +}); +test('formatFileSize - format kilobytes correctly', () => { + expect(formatFileSize(2048)).toBe('2.00 KB'); +}); +test('formatFileSize - format megabytes correctly', () => { + expect(formatFileSize(5 * 1024 * 1024)).toBe('5.00 MB'); +}); + +/** + * 单元测试: getFileExtension, formatFileExtension + */ +test('getFileExtension - extract extension from filename', () => { + expect(getFileExtension('document.pdf')).toBe('pdf'); +}); +test('getFileExtension - handle filenames without extension', () => { + expect(getFileExtension('README')).toBe(''); +}); + +test('formatFileExtension - format extension without dot', () => { + expect(formatFileExtension('txt')).toBe('TXT'); +}); +test('formatFileExtension - format extension with dot', () => { + expect(formatFileExtension('.jpg')).toBe('JPG'); +}); -- 2.49.0 From d33e7e1dd9e454993ae5d6fa4c4295206b80b2a5 Mon Sep 17 00:00:00 2001 From: R2m1liA <15258427350@163.com> Date: Sat, 25 Oct 2025 14:56:02 +0800 Subject: [PATCH 3/8] =?UTF-8?q?build:=20=E8=B0=83=E6=95=B4=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vitest.config.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vitest.config.ts b/vitest.config.ts index e007eec..063f4db 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -7,14 +7,14 @@ export default defineConfig({ { test: { name: 'unit', - include: ['test/{e2e,unit}/*.{test,spec}.ts'], + include: ['tests/{e2e,unit}/**/*.{test,spec}.ts'], environment: 'node', }, }, await defineVitestProject({ test: { name: 'nuxt', - include: ['test/nuxt/*.{test.spec}.ts'], + include: ['tests/nuxt/**/*.{test.spec}.ts'], environment: 'nuxt', }, }), -- 2.49.0 From f2634ca0f407b4c5dcd5bdb8df07da44889646fa Mon Sep 17 00:00:00 2001 From: R2m1liA <15258427350@163.com> Date: Sat, 25 Oct 2025 15:30:00 +0800 Subject: [PATCH 4/8] =?UTF-8?q?test:=20=E8=B0=83=E6=95=B4=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 为单元测试添加分组 --- tests/unit/utils/file.test.ts | 55 ++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/tests/unit/utils/file.test.ts b/tests/unit/utils/file.test.ts index 5091966..b4d0fca 100644 --- a/tests/unit/utils/file.test.ts +++ b/tests/unit/utils/file.test.ts @@ -3,34 +3,49 @@ import { getFileExtension, formatFileExtension, } from '../../../app/utils/file'; -import { expect, test } from 'vitest'; +import { expect, test, describe } from 'vitest'; /** * 单元测试: formatFileSize */ -test('formatFileSize - format bytes correctly', () => { - expect(formatFileSize(500)).toBe('500.00 B'); -}); -test('formatFileSize - format kilobytes correctly', () => { - expect(formatFileSize(2048)).toBe('2.00 KB'); -}); -test('formatFileSize - format megabytes correctly', () => { - expect(formatFileSize(5 * 1024 * 1024)).toBe('5.00 MB'); +describe('formatFileSize', () => { + test('format bytes correctly', () => { + expect(formatFileSize(500)).toBe('500.00 B'); + }); + test('format kilobytes correctly', () => { + expect(formatFileSize(2048)).toBe('2.00 KB'); + }); + test('format megabytes correctly', () => { + expect(formatFileSize(5 * 1024 * 1024)).toBe('5.00 MB'); + }); }); /** - * 单元测试: getFileExtension, formatFileExtension + * 单元测试: getFileExtension */ -test('getFileExtension - extract extension from filename', () => { - expect(getFileExtension('document.pdf')).toBe('pdf'); -}); -test('getFileExtension - handle filenames without extension', () => { - expect(getFileExtension('README')).toBe(''); +describe('getFileExtension', () => { + test('extract extension from filename', () => { + expect(getFileExtension('document.pdf')).toBe('pdf'); + }); + test('handle filenames without extension', () => { + expect(getFileExtension('README')).toBe(''); + }); + test('handle multiple dots in filename', () => { + expect(getFileExtension('archive.tar.gz')).toBe('gz'); + }); + test('handle empty filename', () => { + expect(getFileExtension('')).toBe(''); + }); }); -test('formatFileExtension - format extension without dot', () => { - expect(formatFileExtension('txt')).toBe('TXT'); -}); -test('formatFileExtension - format extension with dot', () => { - expect(formatFileExtension('.jpg')).toBe('JPG'); +/** + * 单元测试: formatFileExtension + */ +describe('formatFileExtension', () => { + test('format extension without dot', () => { + expect(formatFileExtension('txt')).toBe('TXT'); + }); + test('format extension with dot', () => { + expect(formatFileExtension('.jpg')).toBe('JPG'); + }); }); -- 2.49.0 From 75d4d40d39637a0639922f1fa588810d4bd645b7 Mon Sep 17 00:00:00 2001 From: R2m1liA <15258427350@163.com> Date: Sat, 25 Oct 2025 15:30:23 +0800 Subject: [PATCH 5/8] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E6=8B=93=E5=B1=95=E5=90=8D=E8=8E=B7=E5=8F=96=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 若无扩展名则返回空字符串 --- app/utils/file.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/utils/file.ts b/app/utils/file.ts index f21e33a..0193c98 100644 --- a/app/utils/file.ts +++ b/app/utils/file.ts @@ -11,7 +11,9 @@ export function formatFileSize(sizeInBytes: number): string { } export function getFileExtension(filename: string): string { - return filename.split('.').pop() || ''; + const lastDotIndex = filename.lastIndexOf('.'); + if (lastDotIndex === -1) return ''; // 找不到拓展名 + return filename.slice(lastDotIndex + 1); } export function formatFileExtension(ext: string): string { -- 2.49.0 From 5be3c45ac5bd90bfc501076012083f27bdc01f16 Mon Sep 17 00:00:00 2001 From: R2m1liA <15258427350@163.com> Date: Sat, 25 Oct 2025 16:29:15 +0800 Subject: [PATCH 6/8] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3nuxt=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vitest.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vitest.config.ts b/vitest.config.ts index 063f4db..537f354 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -14,7 +14,7 @@ export default defineConfig({ await defineVitestProject({ test: { name: 'nuxt', - include: ['tests/nuxt/**/*.{test.spec}.ts'], + include: ['tests/nuxt/**/*.{test,spec}.ts'], environment: 'nuxt', }, }), -- 2.49.0 From 9294cd3199ba172c507ca4f7eac5ede5a2d69097 Mon Sep 17 00:00:00 2001 From: R2m1liA <15258427350@163.com> Date: Mon, 27 Oct 2025 13:50:36 +0800 Subject: [PATCH 7/8] =?UTF-8?q?fix:=20=E8=B0=83=E6=95=B4nuxt=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将nuxt测试路径调整到组件旁 --- app/models/mappers/productMapper.test.ts | 49 ++++++++++++++++++++++++ {tests/unit => app}/utils/file.test.ts | 2 +- vitest.config.ts | 22 ++--------- 3 files changed, 53 insertions(+), 20 deletions(-) create mode 100644 app/models/mappers/productMapper.test.ts rename {tests/unit => app}/utils/file.test.ts (97%) diff --git a/app/models/mappers/productMapper.test.ts b/app/models/mappers/productMapper.test.ts new file mode 100644 index 0000000..ce5b498 --- /dev/null +++ b/app/models/mappers/productMapper.test.ts @@ -0,0 +1,49 @@ +import { describe, it, expect } from 'vitest'; + +describe('toProductSpecView', () => { + it('should map translations.key an value corrently', () => { + const raw: ProductSpec = { + id: 1, + value: '100W', + translations: [ + { + id: 1, + key: 'Power', + }, + ], + }; + + const expected: ProductSpecView = { + id: 1, + key: 'Power', + value: '100W', + }; + + expect(toProductSpecView(raw)).toEqual(expected); + }); + + it('should handle missing translations gracefully', () => { + const raw: ProductSpec = { id: 2, value: '220V', translations: [] }; + const view = toProductSpecView(raw); + expect(view.key).toBe(''); + }); +}); + +describe('toProductSpecGroupView', () => { + it('should map translations.name and specs correctly', () => { + const raw: ProductSpecGroup = { + id: 1, + translations: [{ id: 1, name: 'Electrical' }], + specs: [ + { id: 1, value: '100W', translations: [{ id: 1, key: 'Power' }] }, + { id: 2, value: '220V', translations: [{ id: 2, key: 'Voltage' }] }, + ], + }; + const view: ProductSpecGroupView = toProductSpecGroupView(raw); + + expect(view.name).toBe('Electrical'); + expect(view.specs).toHaveLength(2); + expect(view.specs[0].key).toBe('Power'); + expect(view.specs[1].value).toBe('220V'); + }); +}); diff --git a/tests/unit/utils/file.test.ts b/app/utils/file.test.ts similarity index 97% rename from tests/unit/utils/file.test.ts rename to app/utils/file.test.ts index b4d0fca..5325b72 100644 --- a/tests/unit/utils/file.test.ts +++ b/app/utils/file.test.ts @@ -2,7 +2,7 @@ import { formatFileSize, getFileExtension, formatFileExtension, -} from '../../../app/utils/file'; +} from '@/utils/file'; import { expect, test, describe } from 'vitest'; /** diff --git a/vitest.config.ts b/vitest.config.ts index 537f354..b519c1f 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -1,23 +1,7 @@ -import { defineConfig } from 'vitest/config'; -import { defineVitestProject } from '@nuxt/test-utils/config'; +import { defineVitestConfig } from '@nuxt/test-utils/config'; -export default defineConfig({ +export default defineVitestConfig({ test: { - projects: [ - { - test: { - name: 'unit', - include: ['tests/{e2e,unit}/**/*.{test,spec}.ts'], - environment: 'node', - }, - }, - await defineVitestProject({ - test: { - name: 'nuxt', - include: ['tests/nuxt/**/*.{test,spec}.ts'], - environment: 'nuxt', - }, - }), - ], + environment: 'nuxt', }, }); -- 2.49.0 From 73e920cd8d52b749ed979d41ef38bb6f0c6edebc Mon Sep 17 00:00:00 2001 From: R2m1liA <15258427350@163.com> Date: Mon, 27 Oct 2025 14:12:43 +0800 Subject: [PATCH 8/8] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/mappers/productMapper.test.ts | 49 --------------- app/models/utils/object.test.ts | 66 ++++++++++++++++++++ app/models/utils/search-converter.test.ts | 75 +++++++++++++++++++++++ app/utils/file.test.ts | 5 -- 4 files changed, 141 insertions(+), 54 deletions(-) delete mode 100644 app/models/mappers/productMapper.test.ts create mode 100644 app/models/utils/object.test.ts create mode 100644 app/models/utils/search-converter.test.ts diff --git a/app/models/mappers/productMapper.test.ts b/app/models/mappers/productMapper.test.ts deleted file mode 100644 index ce5b498..0000000 --- a/app/models/mappers/productMapper.test.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { describe, it, expect } from 'vitest'; - -describe('toProductSpecView', () => { - it('should map translations.key an value corrently', () => { - const raw: ProductSpec = { - id: 1, - value: '100W', - translations: [ - { - id: 1, - key: 'Power', - }, - ], - }; - - const expected: ProductSpecView = { - id: 1, - key: 'Power', - value: '100W', - }; - - expect(toProductSpecView(raw)).toEqual(expected); - }); - - it('should handle missing translations gracefully', () => { - const raw: ProductSpec = { id: 2, value: '220V', translations: [] }; - const view = toProductSpecView(raw); - expect(view.key).toBe(''); - }); -}); - -describe('toProductSpecGroupView', () => { - it('should map translations.name and specs correctly', () => { - const raw: ProductSpecGroup = { - id: 1, - translations: [{ id: 1, name: 'Electrical' }], - specs: [ - { id: 1, value: '100W', translations: [{ id: 1, key: 'Power' }] }, - { id: 2, value: '220V', translations: [{ id: 2, key: 'Voltage' }] }, - ], - }; - const view: ProductSpecGroupView = toProductSpecGroupView(raw); - - expect(view.name).toBe('Electrical'); - expect(view.specs).toHaveLength(2); - expect(view.specs[0].key).toBe('Power'); - expect(view.specs[1].value).toBe('220V'); - }); -}); diff --git a/app/models/utils/object.test.ts b/app/models/utils/object.test.ts new file mode 100644 index 0000000..b217543 --- /dev/null +++ b/app/models/utils/object.test.ts @@ -0,0 +1,66 @@ +import { expect, test, describe } from 'vitest'; + +/** + * 单元测试: isObject + */ +describe('isObject', () => { + test('identify plain object', () => { + expect(isObject({})).toBe(true); + expect(isObject({ key: 'value' })).toBe(true); + }); + test('identify null as non objevt', () => { + expect(isObject(null)).toBe(false); + }); + test('identify non-object types', () => { + expect(isObject(undefined)).toBe(false); + expect(isObject(42)).toBe(false); + expect(isObject('string')).toBe(false); + expect(isObject(Symbol('sym'))).toBe(false); + expect(isObject(true)).toBe(false); + expect(isObject(() => {})).toBe(false); + }); + test('identify arrays as objects', () => { + expect(isObject([])).toBe(true); + }); + test('identify narrowed object type', () => { + const value: unknown = { id: 1 }; + if (isObject<{ id: number }>(value)) { + expect(value.id).toBe(1); + } else { + throw new Error('Type narrowing failed'); + } + }); +}); + +/** + * 单元测试: isArrayOfObject + */ +describe('isArrayOfObject', () => { + test('identify array of plain objects', () => { + const arr = [{ id: 1 }, { name: 'Alice' }]; + expect(isArrayOfObject<{ id?: number; name?: string }>(arr)).toBe(true); + }); + test('identify array containing non-objects', () => { + expect(isArrayOfObject([1, 2, 3])).toBe(false); + expect(isArrayOfObject([{ id: 1 }, null])).toBe(false); + expect(isArrayOfObject([{ id: 1 }, 'string'])).toBe(false); + }); + test('identify non-array types', () => { + expect(isArrayOfObject(null)).toBe(false); + expect(isArrayOfObject({})).toBe(false); + expect(isArrayOfObject(42)).toBe(false); + }); + test('identify empty array as array of objects', () => { + expect(isArrayOfObject([])).toBe(true); + }); + test('identify narrowed array of object type', () => { + const data: unknown = [{ id: 1 }, { id: 2 }]; + if (isArrayOfObject<{ id: number }>(data)) { + // TS 能识别为 { id: number }[] + expect(data[0].id).toBe(1); + expect(data[1].id).toBe(2); + } else { + throw new Error('Type guard failed'); + } + }); +}); diff --git a/app/models/utils/search-converter.test.ts b/app/models/utils/search-converter.test.ts new file mode 100644 index 0000000..e9d9947 --- /dev/null +++ b/app/models/utils/search-converter.test.ts @@ -0,0 +1,75 @@ +import { describe, expect, test } from 'vitest'; + +/** + * 单元测试: converters + */ +describe('converters', () => { + test('convert product item', () => { + const item = { + id: 1, + name: 'Hydraulic Pump', + summary: 'High efficiency', + description: 'Detailed description', + type: 'pump', + }; + const result = converters.products(item); + expect(result).toEqual({ + id: 1, + type: 'product', + title: 'Hydraulic Pump', + summary: 'High efficiency', + }); + }); + + test('convert solution item', () => { + const item = { + id: 1, + title: 'Solution A', + summary: 'Effective solution', + content: 'Detailed content', + type: 'Type A', + }; + const result = converters.solutions(item); + expect(result).toEqual({ + id: 1, + type: 'solution', + title: 'Solution A', + summary: 'Effective solution', + }); + }); + + test('convert question item', () => { + const item = { + id: 1, + title: 'How to use product?', + content: + 'This is a detailed explanation of how to use the product effectively.', + products: ['Product A'], + product_types: ['Type A'], + }; + const result = converters.questions(item); + expect(result).toEqual({ + id: 1, + title: 'How to use product?', + summary: + 'This is a detailed explanation of how to use the product effectively....', + type: 'question', + }); + }); + + test('convert product document item', () => { + const item = { + id: 1, + title: 'User Manual', + products: ['Product A'], + product_types: ['Type A'], + }; + const result = converters.product_documents(item); + expect(result).toEqual({ + id: 1, + title: 'User Manual', + summary: undefined, + type: 'document', + }); + }); +}); diff --git a/app/utils/file.test.ts b/app/utils/file.test.ts index 5325b72..e95541a 100644 --- a/app/utils/file.test.ts +++ b/app/utils/file.test.ts @@ -1,8 +1,3 @@ -import { - formatFileSize, - getFileExtension, - formatFileExtension, -} from '@/utils/file'; import { expect, test, describe } from 'vitest'; /** -- 2.49.0