Adds a custom ESLint rule (local-rules/require-v2-layout-meta) that
fails any src/pages-v2/**.vue page missing
definePage({ meta: { layout: 'OrganizerLayoutV2' } }) (or PortalLayoutV2
under pages-v2/portal), preventing a silent wrong-shell fallback to the
default layout (RFC-WS-GUI-REDESIGN AD-G2). Wires eslint-plugin-local-rules
+ a pages-v2 override. The RuleTester spec is called at top level (ESLint
RuleTester self-manages describe/it under Vitest) and vitest.config.ts
gains the eslint-rules test glob so the spec is discovered.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
86 lines
3.0 KiB
TypeScript
86 lines
3.0 KiB
TypeScript
import { fileURLToPath } from 'node:url'
|
|
import vue from '@vitejs/plugin-vue'
|
|
import AutoImport from 'unplugin-auto-import/vite'
|
|
import { defineConfig } from 'vitest/config'
|
|
|
|
// Two projects share one config:
|
|
//
|
|
// - "unit" — pure-logic tests under tests/unit/ + src/**/__tests__/.
|
|
// No Vuetify, no SCSS plugin, happy-dom only. Fast path.
|
|
// - "component" — component / integration / a11y tests under tests/component/,
|
|
// tests/integration/, tests/a11y/. Loads CSS imports so
|
|
// `import '@/styles/tokens/_timetable.css'` resolves and
|
|
// getComputedStyle() returns var(--tt-…) values in jsdom.
|
|
//
|
|
// Both share the same alias map and AutoImport bag so test paths and the
|
|
// auto-imported `ref/computed/watch` etc. work identically.
|
|
const sharedAliases = {
|
|
'@': fileURLToPath(new URL('./src', import.meta.url)),
|
|
'@core': fileURLToPath(new URL('./src/@core', import.meta.url)),
|
|
'@layouts': fileURLToPath(new URL('./src/@layouts', import.meta.url)),
|
|
'@images': fileURLToPath(new URL('./src/assets/images/', import.meta.url)),
|
|
'@styles': fileURLToPath(new URL('./src/assets/styles/', import.meta.url)),
|
|
}
|
|
|
|
const sharedAutoImport = AutoImport({
|
|
imports: ['vue', '@vueuse/core', 'vue-router'],
|
|
dirs: ['./src/@core/utils', './src/@core/composable/', './src/composables/', './src/utils/'],
|
|
vueTemplate: true,
|
|
dts: false,
|
|
})
|
|
|
|
export default defineConfig({
|
|
test: {
|
|
projects: [
|
|
{
|
|
plugins: [vue(), sharedAutoImport],
|
|
resolve: { alias: sharedAliases },
|
|
test: {
|
|
name: 'unit',
|
|
environment: 'happy-dom',
|
|
globals: true,
|
|
include: [
|
|
'tests/unit/**/*.{test,spec}.ts',
|
|
'tests/*.{test,spec}.ts',
|
|
'src/**/__tests__/**/*.{test,spec}.ts',
|
|
'eslint-rules/**/__tests__/**/*.{test,spec}.ts',
|
|
],
|
|
setupFiles: ['./tests/setup.ts'],
|
|
},
|
|
},
|
|
{
|
|
plugins: [vue(), sharedAutoImport],
|
|
resolve: { alias: sharedAliases },
|
|
|
|
// Inline Vuetify so its ESM bits are processed by Vite's transform.
|
|
ssr: { noExternal: ['vuetify'] },
|
|
test: {
|
|
name: 'component',
|
|
environment: 'jsdom',
|
|
globals: true,
|
|
include: [
|
|
'tests/component/**/*.{test,spec}.ts',
|
|
'tests/integration/**/*.{test,spec}.ts',
|
|
'tests/a11y/**/*.{test,spec}.ts',
|
|
],
|
|
|
|
// Intentionally NOT including ./tests/setup.ts — it stubs `vue-router`
|
|
// globally for the unit project, which would defeat the real router
|
|
// wired by mountWithVuexy. setup.component.ts handles its own
|
|
// crypto/JSDOM stubs.
|
|
setupFiles: ['./tests/setup.component.ts'],
|
|
|
|
// CSS @import statements (e.g. `@/styles/tokens/_timetable.css`)
|
|
// need to actually load so getComputedStyle resolves CSS variables.
|
|
css: true,
|
|
server: {
|
|
deps: {
|
|
inline: ['vuetify'],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
],
|
|
},
|
|
})
|