import { describe, it, expect, vi, beforeEach } from 'vitest'; import { createSourceMappingPlugin } from '../../packages/plugin/src/core/sourceMapper'; import type { DesignModeOptions } from '../../packages/plugin/src/types'; import * as babel from '@babel/standalone'; describe('sourceMapper', () => { const mockOptions: Required = { enabled: true, enableInProduction: false, attributePrefix: 'data-source', verbose: false, exclude: ['node_modules'], include: ['**/*.{js,jsx,ts,tsx}'], }; beforeEach(() => { vi.clearAllMocks(); }); describe('createSourceMappingPlugin', () => { it('应该创建Babel插件', () => { const plugin = createSourceMappingPlugin('test.tsx', mockOptions); expect(plugin).toBeDefined(); expect(plugin.visitor).toBeDefined(); expect(plugin.visitor.JSXOpeningElement).toBeDefined(); }); it('应该为JSX元素添加源码映射属性', () => { const code = ` function App() { return
Hello
; } `; const plugin = createSourceMappingPlugin('test.tsx', mockOptions); const result = babel.transform(code, { plugins: [plugin], presets: ['react'], }); expect(result?.code).toBeDefined(); expect(result?.code).toContain('data-source'); }); it('应该生成正确的elementId', () => { const code = ` function App() { return
Hello
; } `; const plugin = createSourceMappingPlugin('src/App.tsx', mockOptions); const result = babel.transform(code, { plugins: [plugin], presets: ['react'], }); expect(result?.code).toBeDefined(); expect(result?.code).toContain('data-source-element-id'); }); it('应该添加位置信息属性', () => { const code = ` function App() { return
Hello
; } `; const plugin = createSourceMappingPlugin('test.tsx', mockOptions); const result = babel.transform(code, { plugins: [plugin], presets: ['react'], }); expect(result?.code).toBeDefined(); expect(result?.code).toContain('data-source-position'); }); it('应该添加完整的源码信息属性', () => { const code = ` function App() { return
Hello
; } `; const plugin = createSourceMappingPlugin('test.tsx', mockOptions); const result = babel.transform(code, { plugins: [plugin], presets: ['react'], }); expect(result?.code).toBeDefined(); expect(result?.code).toContain('data-source-info'); }); it('应该使用自定义属性前缀', () => { const customOptions: Required = { ...mockOptions, attributePrefix: 'data-appdev', }; const code = ` function App() { return
Hello
; } `; const plugin = createSourceMappingPlugin('test.tsx', customOptions); const result = babel.transform(code, { plugins: [plugin], presets: ['react'], }); expect(result?.code).toBeDefined(); expect(result?.code).toContain('data-appdev'); expect(result?.code).not.toContain('data-source'); }); it('应该处理嵌套的JSX元素', () => { const code = ` function App() { return (
); } `; const plugin = createSourceMappingPlugin('test.tsx', mockOptions); const result = babel.transform(code, { plugins: [plugin], presets: ['react'], }); expect(result?.code).toBeDefined(); // 应该为多个元素添加属性 const matches = result?.code.match(/data-source-element-id/g); expect(matches?.length).toBeGreaterThan(1); }); it('应该处理带id属性的元素', () => { const code = ` function App() { return
Hello
; } `; const plugin = createSourceMappingPlugin('test.tsx', mockOptions); const result = babel.transform(code, { plugins: [plugin], presets: ['react'], }); expect(result?.code).toBeDefined(); expect(result?.code).toContain('data-source-element-id'); }); it('应该处理带className的元素', () => { const code = ` function App() { return
Hello
; } `; const plugin = createSourceMappingPlugin('test.tsx', mockOptions); const result = babel.transform(code, { plugins: [plugin], presets: ['react'], }); expect(result?.code).toBeDefined(); expect(result?.code).toContain('data-source-element-id'); }); it('应该处理函数组件', () => { const code = ` const Button = () => { return ; }; function App() { return