import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' import { afterEach, describe, expect, it } from 'vitest' import { extractComponent, extractDeprecation, parseComponentExports, } from '../../../scripts/extract-docs-components' const tempDirs: string[] = [] function createTempDir(): string { const dir = mkdtempSync(join(tmpdir(), 'mint-docs-components-')) tempDirs.push(dir) return dir } afterEach(() => { for (const dir of tempDirs.splice(0)) { rmSync(dir, { recursive: true, force: true }) } }) describe('extract docs component helpers', () => { it('parses grouped Vue component exports with JSDoc metadata', () => { const dir = createTempDir() const indexPath = join(dir, 'index.ts') writeFileSync(indexPath, ` // Base Components /** Primary action. */ export { default as MintButton } from './Button.vue' // Scheduling / Booking Components /** * @deprecated Prefer ScheduleCalendar. */ export { default as OldCalendar } from './OldCalendar.vue' // Custom Group export { default as SpecialThing } from './SpecialThing.vue' `) expect(parseComponentExports(indexPath)).toEqual([ { name: 'MintButton', fileBase: 'Button', group: 'base', description: 'Primary action.', }, { name: 'OldCalendar', fileBase: 'OldCalendar', group: 'scheduling', description: '@deprecated Prefer ScheduleCalendar.', deprecated: true, replacement: 'ScheduleCalendar', }, { name: 'SpecialThing', fileBase: 'SpecialThing', group: 'custom-group', }, ]) }) it('extracts deprecation replacements from use/prefer prose', () => { expect(extractDeprecation('@deprecated Use `NewThing()` instead.')).toEqual({ deprecated: true, replacement: 'NewThing', }) expect(extractDeprecation('Stable component.')).toEqual({}) }) it('extracts SFC props, emits, and slots from public components', () => { const dir = createTempDir() const componentPath = join(dir, 'src', 'components', 'FancyButton.vue') mkdirSync(join(dir, 'src', 'components'), { recursive: true }) writeFileSync(componentPath, ` `) expect(extractComponent(componentPath, 'FancyButton', 'base', dir)).toMatchObject({ name: 'FancyButton', kind: 'component', group: 'base', source: 'packages/sdk-frontend/src/components/FancyButton.vue', description: 'Fancy button docs.', examples: [ { title: 'Recommended', language: 'vue', code: '', }, ], props: [ { name: 'label', type: 'string', required: true, description: 'Visible label.', }, { name: 'variant', type: "'primary' | 'secondary'", required: false, default: "'primary'", description: '', }, ], emits: [ { name: 'update:modelValue', type: '(value: string) => void' }, { name: 'click', type: '() => void' }, ], slots: [ { name: 'default', description: '' }, { name: 'suffix', description: '' }, ], }) }) })