feat(lint): add components-v2/pages-v2 boundary zones (no back-port)
Adds three new eslint-plugin-boundaries element zones and their matrix rows so the GUI-redesign v2 surface is structurally isolated: v1 code cannot import from v2 (back-porting forbidden), v2 can reach the narrow FormField/Icon bridge via the components-foundation zone, and pages-v2 can import from components-v2. Backed by a Vitest spec running via the ESLint Node API (node environment; happy-dom's document object breaks the case-police resolver). Adds a placeholder src/components-v2/shared/X.vue so the resolver can classify the import target during the test (unresolvable imports are not boundary- checked by the plugin). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
50
apps/app/tests/unit/boundaries-v2.spec.ts
Normal file
50
apps/app/tests/unit/boundaries-v2.spec.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
// @vitest-environment node
|
||||
// ESLint Node API tests must run in the Node environment — the default
|
||||
// happy-dom environment's `document` object causes case-police's dirs.cjs
|
||||
// (which uses `document.currentScript.src` for __dirname resolution)
|
||||
// to fail with "The URL must be of scheme file".
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import path from 'node:path'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { ESLint } from 'eslint'
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url)
|
||||
const __dirname = path.dirname(__filename)
|
||||
const rootDir = path.resolve(__dirname, '../../')
|
||||
|
||||
const eslint = new ESLint({ cwd: rootDir })
|
||||
|
||||
async function boundaryErrors(filePath: string, code: string) {
|
||||
const [result] = await eslint.lintText(code, { filePath })
|
||||
|
||||
return result.messages.filter(m => m.ruleId === 'boundaries/element-types')
|
||||
}
|
||||
|
||||
describe('boundaries — v2 zones', () => {
|
||||
it('allows pages-v2 → components-v2', async () => {
|
||||
const errs = await boundaryErrors(
|
||||
'src/pages-v2/dashboard.vue',
|
||||
'<script setup lang="ts">import X from \'@/components-v2/shared/X.vue\'</script><template><X /></template>',
|
||||
)
|
||||
|
||||
expect(errs).toHaveLength(0)
|
||||
})
|
||||
|
||||
it('allows components-v2 → components-foundation (FormField bridge)', async () => {
|
||||
const errs = await boundaryErrors(
|
||||
'src/components-v2/forms/Demo.vue',
|
||||
'<script setup lang="ts">import FormField from \'@/components/forms/FormField.vue\'</script><template><FormField /></template>',
|
||||
)
|
||||
|
||||
expect(errs).toHaveLength(0)
|
||||
})
|
||||
|
||||
it('forbids v1 components → components-v2 (no back-porting)', async () => {
|
||||
const errs = await boundaryErrors(
|
||||
'src/components/organizer/Legacy.vue',
|
||||
'<script setup lang="ts">import X from \'@/components-v2/shared/X.vue\'</script><template><X /></template>',
|
||||
)
|
||||
|
||||
expect(errs.length).toBeGreaterThan(0)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user