test(web): add v8 coverage with truthful baseline floor

Adds @vitest/coverage-v8 (catalog-pinned), a test:coverage script wired
through turbo (inputs + coverage/** output), and coverage thresholds set
to a floor measured on main (lines 18 / funcs 10 / branches 10 / stmts
17 against current 19.3/11.4/11.7/18.9). Ratchet upward as tests grow.

Adapts the coverage config from @BenSheridanEdwards's fork; the multi-job
CI fan-out from that branch was intentionally left out.

Co-authored-by: Ben Sheridan-Edwards <BenSheridanEdwards@users.noreply.github.com>
This commit is contained in:
Offending Commit
2026-05-28 14:05:43 -05:00
parent ac20ab6271
commit 94c423522a
6 changed files with 176 additions and 2 deletions

3
.gitignore vendored
View File

@@ -44,3 +44,6 @@ packages/desktop/src-tauri/gen/
# Drafts from scripts/pr-evidence.sh # Drafts from scripts/pr-evidence.sh
PR_BODY.md PR_BODY.md
# Test coverage
coverage

View File

@@ -10,6 +10,7 @@
"lint": "biome check src/", "lint": "biome check src/",
"lint:fix": "biome check --write src/", "lint:fix": "biome check --write src/",
"test": "vitest run --passWithNoTests", "test": "vitest run --passWithNoTests",
"test:coverage": "vitest run --coverage",
"test:e2e": "playwright test", "test:e2e": "playwright test",
"generate:api": "openapi-typescript openapi.json -o src/api/schema.d.ts" "generate:api": "openapi-typescript openapi.json -o src/api/schema.d.ts"
}, },
@@ -54,6 +55,7 @@
"@types/react": "catalog:", "@types/react": "catalog:",
"@types/react-dom": "catalog:", "@types/react-dom": "catalog:",
"@vitejs/plugin-react": "catalog:", "@vitejs/plugin-react": "catalog:",
"@vitest/coverage-v8": "catalog:",
"jsdom": "catalog:", "jsdom": "catalog:",
"openapi-typescript": "^7.8.0", "openapi-typescript": "^7.8.0",
"typescript": "catalog:", "typescript": "catalog:",

View File

@@ -22,5 +22,26 @@ export default defineConfig({
css: false, css: false,
include: ["src/**/*.{test,spec}.{ts,tsx}"], include: ["src/**/*.{test,spec}.{ts,tsx}"],
exclude: ["node_modules", "dist", "e2e"], exclude: ["node_modules", "dist", "e2e"],
coverage: {
provider: "v8",
reporter: ["text", "html", "json-summary", "lcov"],
include: ["src/**/*.{ts,tsx}"],
exclude: [
"src/**/*.{test,spec}.{ts,tsx}",
"src/test/**",
"src/routeTree.gen.ts",
"src/api/schema.d.ts",
"src/main.tsx",
"src/vite-env.d.ts",
],
// Truthful baseline floor measured on main (not copied from the
// fork). Ratchet upward as feature tests grow.
thresholds: {
lines: 18,
functions: 10,
branches: 10,
statements: 17,
},
},
}, },
}); });

147
pnpm-lock.yaml generated
View File

@@ -30,6 +30,9 @@ catalogs:
'@vitejs/plugin-react': '@vitejs/plugin-react':
specifier: ^6.0.1 specifier: ^6.0.1
version: 6.0.1 version: 6.0.1
'@vitest/coverage-v8':
specifier: ^4.0.0
version: 4.1.7
jsdom: jsdom:
specifier: ^26.1.0 specifier: ^26.1.0
version: 26.1.0 version: 26.1.0
@@ -228,6 +231,9 @@ importers:
'@vitejs/plugin-react': '@vitejs/plugin-react':
specifier: 'catalog:' specifier: 'catalog:'
version: 6.0.1(vite@8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)) version: 6.0.1(vite@8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0))
'@vitest/coverage-v8':
specifier: 'catalog:'
version: 4.1.7(vitest@4.1.5)
jsdom: jsdom:
specifier: 'catalog:' specifier: 'catalog:'
version: 26.1.0 version: 26.1.0
@@ -242,7 +248,7 @@ importers:
version: 8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0) version: 8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)
vitest: vitest:
specifier: 'catalog:' specifier: 'catalog:'
version: 4.1.5(@types/node@25.6.0)(jsdom@26.1.0)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)) version: 4.1.5(@types/node@25.6.0)(@vitest/coverage-v8@4.1.7)(jsdom@26.1.0)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0))
packages: packages:
@@ -306,10 +312,18 @@ packages:
resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
'@babel/helper-string-parser@7.29.7':
resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==}
engines: {node: '>=6.9.0'}
'@babel/helper-validator-identifier@7.28.5': '@babel/helper-validator-identifier@7.28.5':
resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
'@babel/helper-validator-identifier@7.29.7':
resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==}
engines: {node: '>=6.9.0'}
'@babel/helper-validator-option@7.27.1': '@babel/helper-validator-option@7.27.1':
resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
@@ -323,6 +337,11 @@ packages:
engines: {node: '>=6.0.0'} engines: {node: '>=6.0.0'}
hasBin: true hasBin: true
'@babel/parser@7.29.7':
resolution: {integrity: sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==}
engines: {node: '>=6.0.0'}
hasBin: true
'@babel/plugin-syntax-jsx@7.28.6': '@babel/plugin-syntax-jsx@7.28.6':
resolution: {integrity: sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==} resolution: {integrity: sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
@@ -351,6 +370,14 @@ packages:
resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
'@babel/types@7.29.7':
resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==}
engines: {node: '>=6.9.0'}
'@bcoe/v8-coverage@1.0.2':
resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==}
engines: {node: '>=18'}
'@biomejs/biome@2.4.13': '@biomejs/biome@2.4.13':
resolution: {integrity: sha512-gLXOwkOBBg0tr7bDsqlkIh4uFeKuMjxvqsrb1Tukww1iDmHcfr4Uu8MoQxp0Rcte+69+osRNWXwHsu/zxT6XqA==} resolution: {integrity: sha512-gLXOwkOBBg0tr7bDsqlkIh4uFeKuMjxvqsrb1Tukww1iDmHcfr4Uu8MoQxp0Rcte+69+osRNWXwHsu/zxT6XqA==}
engines: {node: '>=14.21.3'} engines: {node: '>=14.21.3'}
@@ -1742,6 +1769,15 @@ packages:
babel-plugin-react-compiler: babel-plugin-react-compiler:
optional: true optional: true
'@vitest/coverage-v8@4.1.7':
resolution: {integrity: sha512-qsYPeXc5Q9dFLd1i8Ap+Bx8sQgcp+rFVQo4R0dDsWNBzl26ldVF1qOO+RL24K7FDrR6pA+50XedRLSoSG24bVQ==}
peerDependencies:
'@vitest/browser': 4.1.7
vitest: 4.1.7
peerDependenciesMeta:
'@vitest/browser':
optional: true
'@vitest/expect@4.1.5': '@vitest/expect@4.1.5':
resolution: {integrity: sha512-PWBaRY5JoKuRnHlUHfpV/KohFylaDZTupcXN1H9vYryNLOnitSw60Mw9IAE2r67NbwwzBw/Cc/8q9BK3kIX8Kw==} resolution: {integrity: sha512-PWBaRY5JoKuRnHlUHfpV/KohFylaDZTupcXN1H9vYryNLOnitSw60Mw9IAE2r67NbwwzBw/Cc/8q9BK3kIX8Kw==}
@@ -1759,6 +1795,9 @@ packages:
'@vitest/pretty-format@4.1.5': '@vitest/pretty-format@4.1.5':
resolution: {integrity: sha512-7I3q6l5qr03dVfMX2wCo9FxwSJbPdwKjy2uu/YPpU3wfHvIL4QHwVRp57OfGrDFeUJ8/8QdfBKIV12FTtLn00g==} resolution: {integrity: sha512-7I3q6l5qr03dVfMX2wCo9FxwSJbPdwKjy2uu/YPpU3wfHvIL4QHwVRp57OfGrDFeUJ8/8QdfBKIV12FTtLn00g==}
'@vitest/pretty-format@4.1.7':
resolution: {integrity: sha512-umgCarTOYQWIaDMvGDRZij+6b9oVeLIyJzfN+AS88e0ZOU3QTgNNSTtjQOpcvWr3np1N0j4WgZj+sb3oYBDscw==}
'@vitest/runner@4.1.5': '@vitest/runner@4.1.5':
resolution: {integrity: sha512-2D+o7Pr82IEO46YPpoA/YU0neeyr6FTerQb5Ro7BUnBuv6NQtT/kmVnczngiMEBhzgqz2UZYl5gArejsyERDSQ==} resolution: {integrity: sha512-2D+o7Pr82IEO46YPpoA/YU0neeyr6FTerQb5Ro7BUnBuv6NQtT/kmVnczngiMEBhzgqz2UZYl5gArejsyERDSQ==}
@@ -1771,6 +1810,9 @@ packages:
'@vitest/utils@4.1.5': '@vitest/utils@4.1.5':
resolution: {integrity: sha512-76wdkrmfXfqGjueGgnb45ITPyUi1ycZ4IHgC2bhPDUfWHklY/q3MdLOAB+TF1e6xfl8NxNY0ZYaPCFNWSsw3Ug==} resolution: {integrity: sha512-76wdkrmfXfqGjueGgnb45ITPyUi1ycZ4IHgC2bhPDUfWHklY/q3MdLOAB+TF1e6xfl8NxNY0ZYaPCFNWSsw3Ug==}
'@vitest/utils@4.1.7':
resolution: {integrity: sha512-T532WBu791cBxJlCl6SO+J14l81DQx6uQHm1bQbmCDY7nqlEIgkza/UFnSBNaUtSf41unldDFjdOBYEQC4b5Hw==}
acorn@8.16.0: acorn@8.16.0:
resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==}
engines: {node: '>=0.4.0'} engines: {node: '>=0.4.0'}
@@ -1858,6 +1900,9 @@ packages:
resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
engines: {node: '>=12'} engines: {node: '>=12'}
ast-v8-to-istanbul@1.0.2:
resolution: {integrity: sha512-dKmJxJsGItLmc5CYZKuEjuG6GnBs6PG4gohMhyFOWKaNQoYCuRZJDECaBlHmcG0lv2wc2E0uU8lESmBEumC3DQ==}
babel-dead-code-elimination@1.0.12: babel-dead-code-elimination@1.0.12:
resolution: {integrity: sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig==} resolution: {integrity: sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig==}
@@ -2400,6 +2445,9 @@ packages:
resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==}
engines: {node: '>=18'} engines: {node: '>=18'}
html-escaper@2.0.2:
resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
html-url-attributes@3.0.1: html-url-attributes@3.0.1:
resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==} resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==}
@@ -2552,6 +2600,18 @@ packages:
resolution: {integrity: sha512-3YZcUUR2Wt1WsapF+S/WiA2WmlW0cWAoPccMqne7AxEBhCdFeTPjfv/Axb8V2gyCgY3nRw+ksZ3xSUX+R47iAg==} resolution: {integrity: sha512-3YZcUUR2Wt1WsapF+S/WiA2WmlW0cWAoPccMqne7AxEBhCdFeTPjfv/Axb8V2gyCgY3nRw+ksZ3xSUX+R47iAg==}
engines: {node: ^18.17 || >=20.6.1} engines: {node: ^18.17 || >=20.6.1}
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-reports@3.2.0:
resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==}
engines: {node: '>=8'}
java-properties@1.0.2: java-properties@1.0.2:
resolution: {integrity: sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==} resolution: {integrity: sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==}
engines: {node: '>= 0.6.0'} engines: {node: '>= 0.6.0'}
@@ -2564,6 +2624,9 @@ packages:
resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==} resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
js-tokens@10.0.0:
resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==}
js-tokens@4.0.0: js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
@@ -2758,10 +2821,17 @@ packages:
magic-string@0.30.21: magic-string@0.30.21:
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
magicast@0.5.3:
resolution: {integrity: sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==}
make-asynchronous@1.1.0: make-asynchronous@1.1.0:
resolution: {integrity: sha512-ayF7iT+44LXdxJLTrTd3TLQpFDDvPCBxXxbv+pMUSuHA5Q8zyAfwkRP6aHHwNVFBUFWtxAHqwNJxF8vMZLAbVg==} resolution: {integrity: sha512-ayF7iT+44LXdxJLTrTd3TLQpFDDvPCBxXxbv+pMUSuHA5Q8zyAfwkRP6aHHwNVFBUFWtxAHqwNJxF8vMZLAbVg==}
engines: {node: '>=18'} engines: {node: '>=18'}
make-dir@4.0.0:
resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==}
engines: {node: '>=10'}
markdown-table@3.0.4: markdown-table@3.0.4:
resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==}
@@ -4112,8 +4182,12 @@ snapshots:
'@babel/helper-string-parser@7.27.1': {} '@babel/helper-string-parser@7.27.1': {}
'@babel/helper-string-parser@7.29.7': {}
'@babel/helper-validator-identifier@7.28.5': {} '@babel/helper-validator-identifier@7.28.5': {}
'@babel/helper-validator-identifier@7.29.7': {}
'@babel/helper-validator-option@7.27.1': {} '@babel/helper-validator-option@7.27.1': {}
'@babel/helpers@7.29.2': '@babel/helpers@7.29.2':
@@ -4125,6 +4199,10 @@ snapshots:
dependencies: dependencies:
'@babel/types': 7.29.0 '@babel/types': 7.29.0
'@babel/parser@7.29.7':
dependencies:
'@babel/types': 7.29.7
'@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0)': '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0)':
dependencies: dependencies:
'@babel/core': 7.29.0 '@babel/core': 7.29.0
@@ -4160,6 +4238,13 @@ snapshots:
'@babel/helper-string-parser': 7.27.1 '@babel/helper-string-parser': 7.27.1
'@babel/helper-validator-identifier': 7.28.5 '@babel/helper-validator-identifier': 7.28.5
'@babel/types@7.29.7':
dependencies:
'@babel/helper-string-parser': 7.29.7
'@babel/helper-validator-identifier': 7.29.7
'@bcoe/v8-coverage@1.0.2': {}
'@biomejs/biome@2.4.13': '@biomejs/biome@2.4.13':
optionalDependencies: optionalDependencies:
'@biomejs/cli-darwin-arm64': 2.4.13 '@biomejs/cli-darwin-arm64': 2.4.13
@@ -5454,6 +5539,20 @@ snapshots:
'@rolldown/pluginutils': 1.0.0-rc.7 '@rolldown/pluginutils': 1.0.0-rc.7
vite: 8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0) vite: 8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)
'@vitest/coverage-v8@4.1.7(vitest@4.1.5)':
dependencies:
'@bcoe/v8-coverage': 1.0.2
'@vitest/utils': 4.1.7
ast-v8-to-istanbul: 1.0.2
istanbul-lib-coverage: 3.2.2
istanbul-lib-report: 3.0.1
istanbul-reports: 3.2.0
magicast: 0.5.3
obug: 2.1.1
std-env: 4.1.0
tinyrainbow: 3.1.0
vitest: 4.1.5(@types/node@25.6.0)(@vitest/coverage-v8@4.1.7)(jsdom@26.1.0)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0))
'@vitest/expect@4.1.5': '@vitest/expect@4.1.5':
dependencies: dependencies:
'@standard-schema/spec': 1.1.0 '@standard-schema/spec': 1.1.0
@@ -5475,6 +5574,10 @@ snapshots:
dependencies: dependencies:
tinyrainbow: 3.1.0 tinyrainbow: 3.1.0
'@vitest/pretty-format@4.1.7':
dependencies:
tinyrainbow: 3.1.0
'@vitest/runner@4.1.5': '@vitest/runner@4.1.5':
dependencies: dependencies:
'@vitest/utils': 4.1.5 '@vitest/utils': 4.1.5
@@ -5495,6 +5598,12 @@ snapshots:
convert-source-map: 2.0.0 convert-source-map: 2.0.0
tinyrainbow: 3.1.0 tinyrainbow: 3.1.0
'@vitest/utils@4.1.7':
dependencies:
'@vitest/pretty-format': 4.1.7
convert-source-map: 2.0.0
tinyrainbow: 3.1.0
acorn@8.16.0: {} acorn@8.16.0: {}
agent-base@7.1.4: {} agent-base@7.1.4: {}
@@ -5565,6 +5674,12 @@ snapshots:
assertion-error@2.0.1: {} assertion-error@2.0.1: {}
ast-v8-to-istanbul@1.0.2:
dependencies:
'@jridgewell/trace-mapping': 0.3.31
estree-walker: 3.0.3
js-tokens: 10.0.0
babel-dead-code-elimination@1.0.12: babel-dead-code-elimination@1.0.12:
dependencies: dependencies:
'@babel/core': 7.29.0 '@babel/core': 7.29.0
@@ -6136,6 +6251,8 @@ snapshots:
dependencies: dependencies:
whatwg-encoding: 3.1.1 whatwg-encoding: 3.1.1
html-escaper@2.0.2: {}
html-url-attributes@3.0.1: {} html-url-attributes@3.0.1: {}
http-proxy-agent@7.0.2: http-proxy-agent@7.0.2:
@@ -6254,12 +6371,27 @@ snapshots:
lodash.isstring: 4.0.1 lodash.isstring: 4.0.1
lodash.uniqby: 4.7.0 lodash.uniqby: 4.7.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-reports@3.2.0:
dependencies:
html-escaper: 2.0.2
istanbul-lib-report: 3.0.1
java-properties@1.0.2: {} java-properties@1.0.2: {}
jiti@2.6.1: {} jiti@2.6.1: {}
js-levenshtein@1.1.6: {} js-levenshtein@1.1.6: {}
js-tokens@10.0.0: {}
js-tokens@4.0.0: {} js-tokens@4.0.0: {}
js-yaml@4.1.1: js-yaml@4.1.1:
@@ -6422,12 +6554,22 @@ snapshots:
dependencies: dependencies:
'@jridgewell/sourcemap-codec': 1.5.5 '@jridgewell/sourcemap-codec': 1.5.5
magicast@0.5.3:
dependencies:
'@babel/parser': 7.29.7
'@babel/types': 7.29.0
source-map-js: 1.2.1
make-asynchronous@1.1.0: make-asynchronous@1.1.0:
dependencies: dependencies:
p-event: 6.0.1 p-event: 6.0.1
type-fest: 4.41.0 type-fest: 4.41.0
web-worker: 1.5.0 web-worker: 1.5.0
make-dir@4.0.0:
dependencies:
semver: 7.7.4
markdown-table@3.0.4: {} markdown-table@3.0.4: {}
marked-terminal@7.3.0(marked@15.0.12): marked-terminal@7.3.0(marked@15.0.12):
@@ -7641,7 +7783,7 @@ snapshots:
jiti: 2.6.1 jiti: 2.6.1
tsx: 4.21.0 tsx: 4.21.0
vitest@4.1.5(@types/node@25.6.0)(jsdom@26.1.0)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)): vitest@4.1.5(@types/node@25.6.0)(@vitest/coverage-v8@4.1.7)(jsdom@26.1.0)(vite@8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)):
dependencies: dependencies:
'@vitest/expect': 4.1.5 '@vitest/expect': 4.1.5
'@vitest/mocker': 4.1.5(vite@8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0)) '@vitest/mocker': 4.1.5(vite@8.0.10(@types/node@25.6.0)(esbuild@0.27.7)(jiti@2.6.1)(tsx@4.21.0))
@@ -7665,6 +7807,7 @@ snapshots:
why-is-node-running: 2.3.0 why-is-node-running: 2.3.0
optionalDependencies: optionalDependencies:
'@types/node': 25.6.0 '@types/node': 25.6.0
'@vitest/coverage-v8': 4.1.7(vitest@4.1.5)
jsdom: 26.1.0 jsdom: 26.1.0
transitivePeerDependencies: transitivePeerDependencies:
- msw - msw

View File

@@ -15,6 +15,7 @@ catalog:
"@types/react": "^19.2.14" "@types/react": "^19.2.14"
"@types/react-dom": "^19.2.3" "@types/react-dom": "^19.2.3"
"@vitejs/plugin-react": "^6.0.1" "@vitejs/plugin-react": "^6.0.1"
"@vitest/coverage-v8": "^4.0.0"
jsdom: "^26.1.0" jsdom: "^26.1.0"
# React # React

View File

@@ -15,6 +15,10 @@
"test": { "test": {
"inputs": ["src/**", "vitest.config.*", "package.json"] "inputs": ["src/**", "vitest.config.*", "package.json"]
}, },
"test:coverage": {
"inputs": ["src/**", "vitest.config.*", "package.json"],
"outputs": ["coverage/**"]
},
"test:e2e": { "test:e2e": {
"cache": false, "cache": false,
"inputs": ["e2e/**", "src/**", "playwright.config.*", "package.json"] "inputs": ["e2e/**", "src/**", "playwright.config.*", "package.json"]