UNPKG

synthia-test

Version:

Synthia Engine Test Plugin - 提供测试功能的 Synthia 插件

1 lines 17.8 kB
{"version":3,"sources":["../src/plugin.ts"],"names":["readFileSync","existsSync","join","testPlugin","options","api","pluginOptions","registerCommand","logger","fs","config","detectedFramework","detectTestFramework","cmdOptions","testConfig","runTestsInWatchMode","runTestsWithCoverage","runTests","error","_fs","projectRoot","packageJsonPath","packageJson","dependencies","runVitestTests","runJestTests","runMochaTests","runCypressTests","runPlaywrightTests","_projectRoot","_config"],"mappings":"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","sourcesContent":["/**\n * Synthia Test 插件 - 函数式插件\n * 提供统一的测试运行和覆盖率报告功能\n */\n\nimport { PluginAPI, PluginFunction, PluginOptions } from 'synthia-shared';\nimport { readFileSync, existsSync } from 'fs';\nimport { join } from 'path';\n\nexport interface TestPluginOptions {\n enabled?: boolean;\n framework?: 'vitest' | 'jest' | 'mocha' | 'cypress' | 'playwright';\n watch?: boolean;\n coverage?: boolean;\n ci?: boolean;\n pattern?: string;\n config?: string;\n // Vitest 配置\n vitest?: {\n enabled?: boolean;\n config?: string;\n ui?: boolean;\n };\n // Jest 配置\n jest?: {\n enabled?: boolean;\n config?: string;\n watchAll?: boolean;\n };\n // Mocha 配置\n mocha?: {\n enabled?: boolean;\n config?: string;\n reporter?: string;\n };\n // Cypress 配置\n cypress?: {\n enabled?: boolean;\n config?: string;\n headless?: boolean;\n browser?: string;\n };\n // Playwright 配置\n playwright?: {\n enabled?: boolean;\n config?: string;\n headless?: boolean;\n browser?: string;\n };\n // 覆盖率配置\n coverageConfig?: {\n enabled?: boolean;\n threshold?: number;\n reporters?: string[];\n output?: string;\n };\n}\n\n/**\n * Test 插件函数工厂\n */\nexport function testPlugin(options: TestPluginOptions = {}): PluginFunction {\n return async (api: PluginAPI, pluginOptions: PluginOptions) => {\n const { registerCommand, logger, fs } = api;\n\n logger.info('🧪 初始化 Test 插件...');\n\n const config = {\n enabled: true,\n framework: 'vitest' as const,\n watch: false,\n coverage: false,\n ci: false,\n pattern: 'src/**/*.test.{ts,js,tsx,jsx}',\n config: '',\n vitest: {\n enabled: true,\n config: 'vitest.config.ts',\n ui: false,\n },\n jest: {\n enabled: false,\n config: 'jest.config.ts',\n watchAll: false,\n },\n mocha: {\n enabled: false,\n config: '.mocharc.js',\n reporter: 'spec',\n },\n cypress: {\n enabled: false,\n config: 'cypress.config.ts',\n headless: false,\n browser: 'chromium',\n },\n playwright: {\n enabled: false,\n config: 'playwright.config.ts',\n headless: false,\n browser: 'chromium',\n },\n coverageConfig: {\n enabled: false,\n threshold: 80,\n reporters: ['text', 'html'],\n output: 'coverage',\n },\n ...options,\n };\n\n // 检测测试框架\n const detectedFramework = await detectTestFramework(fs, pluginOptions.project.root);\n if (detectedFramework && ['vitest', 'jest', 'mocha', 'cypress', 'playwright'].includes(detectedFramework)) {\n config.framework = detectedFramework as 'vitest' | 'jest' | 'mocha' | 'cypress' | 'playwright';\n logger.info(`🔍 检测到测试框架: ${detectedFramework}`);\n }\n\n registerCommand({\n name: 'test',\n description: '运行测试套件',\n options: [\n { flags: '--watch', description: '监听模式运行测试', type: 'boolean' },\n { flags: '--coverage', description: '生成测试覆盖率报告', type: 'boolean' },\n { flags: '--ci', description: 'CI模式运行测试', type: 'boolean' },\n { flags: '--framework <framework>', description: '指定测试框架 (vitest|jest|mocha|cypress|playwright)' },\n { flags: '--pattern <pattern>', description: '文件匹配模式' },\n { flags: '--config <config>', description: '指定配置文件' },\n { flags: '--ui', description: '启动UI界面 (仅Vitest)', type: 'boolean' },\n { flags: '--headless', description: '无头模式运行 (仅Cypress|Playwright)', type: 'boolean' },\n { flags: '--browser <browser>', description: '指定浏览器 (仅Cypress|Playwright)', defaultValue: 'chromium' },\n { flags: '--threshold <threshold>', description: '设置覆盖率阈值', type: 'number' },\n ],\n action: async cmdOptions => {\n const testConfig = {\n ...config,\n watch: cmdOptions.watch || config.watch,\n coverage: cmdOptions.coverage || config.coverage,\n ci: cmdOptions.ci || config.ci,\n framework: cmdOptions.framework || config.framework,\n pattern: cmdOptions.pattern || config.pattern,\n config: cmdOptions.config || config.config,\n ui: cmdOptions.ui || config.vitest?.ui,\n headless: cmdOptions.headless || config.cypress?.headless || config.playwright?.headless,\n browser: cmdOptions.browser || config.cypress?.browser || config.playwright?.browser,\n threshold: cmdOptions.threshold ? parseInt(cmdOptions.threshold) : config.coverageConfig.threshold,\n };\n\n try {\n if (testConfig.watch) {\n logger.info('👀 启动测试监听模式...');\n await runTestsInWatchMode(testConfig, logger, fs, pluginOptions.project.root);\n } else if (testConfig.coverage) {\n logger.info('📊 生成测试覆盖率报告...');\n await runTestsWithCoverage(testConfig, logger, fs, pluginOptions.project.root);\n } else if (testConfig.ci) {\n logger.info('🚀 CI模式运行测试...');\n await runTests(testConfig, logger, fs, pluginOptions.project.root);\n } else {\n logger.info('🏃 运行测试...');\n await runTests(testConfig, logger, fs, pluginOptions.project.root);\n }\n } catch (error) {\n logger.error('❌ 测试运行失败:', error);\n }\n },\n });\n\n logger.success('Test 插件初始化完成');\n };\n}\n\n/**\n * 检测可用的测试框架\n */\nasync function detectTestFramework(_fs: any, projectRoot: string): Promise<string | null> {\n const packageJsonPath = join(projectRoot, 'package.json');\n if (!existsSync(packageJsonPath)) {\n return null;\n }\n\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));\n const dependencies = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n };\n\n if (dependencies['vitest']) return 'vitest';\n if (dependencies['jest']) return 'jest';\n if (dependencies['mocha']) return 'mocha';\n if (dependencies['cypress']) return 'cypress';\n if (dependencies['playwright']) return 'playwright';\n\n return null;\n}\n\n/**\n * 运行测试\n */\nasync function runTests(config: any, logger: any, _fs: any, projectRoot: string): Promise<void> {\n logger.info(`🔧 使用测试框架: ${config.framework}`);\n\n switch (config.framework) {\n case 'vitest':\n await runVitestTests(config, logger, projectRoot);\n break;\n case 'jest':\n await runJestTests(config, logger, projectRoot);\n break;\n case 'mocha':\n await runMochaTests(config, logger, projectRoot);\n break;\n case 'cypress':\n await runCypressTests(config, logger, projectRoot);\n break;\n case 'playwright':\n await runPlaywrightTests(config, logger, projectRoot);\n break;\n default:\n logger.warn(`⚠️ 不支持的测试框架: ${config.framework}`);\n }\n logger.success('测试运行完成');\n}\n\n/**\n * 运行测试监听模式\n */\nasync function runTestsInWatchMode(config: any, logger: any, _fs: any, _projectRoot: string): Promise<void> {\n logger.info('👀 启动测试监听模式...');\n \n switch (config.framework) {\n case 'vitest':\n logger.info('⚡ 启动 Vitest 监听模式...');\n // TODO: 实现 Vitest 监听模式\n break;\n case 'jest':\n logger.info('🎯 启动 Jest 监听模式...');\n // TODO: 实现 Jest 监听模式\n break;\n default:\n logger.warn(`⚠️ ${config.framework} 暂不支持监听模式`);\n }\n \n logger.success('测试监听模式已启动');\n}\n\n/**\n * 运行测试覆盖率报告\n */\nasync function runTestsWithCoverage(config: any, logger: any, _fs: any, _projectRoot: string): Promise<void> {\n logger.info('📊 启动测试覆盖率报告...');\n \n switch (config.framework) {\n case 'vitest':\n logger.info('⚡ 生成 Vitest 覆盖率报告...');\n // TODO: 实现 Vitest 覆盖率报告\n break;\n case 'jest':\n logger.info('🎯 生成 Jest 覆盖率报告...');\n // TODO: 实现 Jest 覆盖率报告\n break;\n default:\n logger.warn(`⚠️ ${config.framework} 暂不支持覆盖率报告`);\n }\n \n logger.success('测试覆盖率报告生成完成');\n}\n\n/**\n * 运行 Vitest 测试\n */\nasync function runVitestTests(_config: any, logger: any, projectRoot: string): Promise<void> {\n logger.info('⚡ 运行 Vitest 测试...');\n \n // 检查 vitest 是否安装\n const packageJsonPath = join(projectRoot, 'package.json');\n if (existsSync(packageJsonPath)) {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));\n const dependencies = { ...packageJson.dependencies, ...packageJson.devDependencies };\n \n if (!dependencies['vitest']) {\n logger.warn('⚠️ Vitest 未安装,请先安装: pnpm add -D vitest');\n return;\n }\n }\n \n // TODO: 实现实际的 Vitest 测试运行逻辑\n logger.success('Vitest 测试完成');\n}\n\n/**\n * 运行 Jest 测试\n */\nasync function runJestTests(_config: any, logger: any, projectRoot: string): Promise<void> {\n logger.info('🎯 运行 Jest 测试...');\n \n // 检查 jest 是否安装\n const packageJsonPath = join(projectRoot, 'package.json');\n if (existsSync(packageJsonPath)) {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));\n const dependencies = { ...packageJson.dependencies, ...packageJson.devDependencies };\n \n if (!dependencies['jest']) {\n logger.warn('⚠️ Jest 未安装,请先安装: pnpm add -D jest');\n return;\n }\n }\n \n // TODO: 实现实际的 Jest 测试运行逻辑\n logger.success('Jest 测试完成');\n}\n\n/**\n * 运行 Mocha 测试\n */\nasync function runMochaTests(_config: any, logger: any, projectRoot: string): Promise<void> {\n logger.info('☕ 运行 Mocha 测试...');\n \n // 检查 mocha 是否安装\n const packageJsonPath = join(projectRoot, 'package.json');\n if (existsSync(packageJsonPath)) {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));\n const dependencies = { ...packageJson.dependencies, ...packageJson.devDependencies };\n \n if (!dependencies['mocha']) {\n logger.warn('⚠️ Mocha 未安装,请先安装: pnpm add -D mocha');\n return;\n }\n }\n \n // TODO: 实现实际的 Mocha 测试运行逻辑\n logger.success('Mocha 测试完成');\n}\n\n/**\n * 运行 Cypress 测试\n */\nasync function runCypressTests(_config: any, logger: any, projectRoot: string): Promise<void> {\n logger.info('🌲 运行 Cypress 测试...');\n \n // 检查 cypress 是否安装\n const packageJsonPath = join(projectRoot, 'package.json');\n if (existsSync(packageJsonPath)) {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));\n const dependencies = { ...packageJson.dependencies, ...packageJson.devDependencies };\n \n if (!dependencies['cypress']) {\n logger.warn('⚠️ Cypress 未安装,请先安装: pnpm add -D cypress');\n return;\n }\n }\n \n // TODO: 实现实际的 Cypress 测试运行逻辑\n logger.success('Cypress 测试完成');\n}\n\n/**\n * 运行 Playwright 测试\n */\nasync function runPlaywrightTests(_config: any, logger: any, projectRoot: string): Promise<void> {\n logger.info('🎭 运行 Playwright 测试...');\n \n // 检查 playwright 是否安装\n const packageJsonPath = join(projectRoot, 'package.json');\n if (existsSync(packageJsonPath)) {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));\n const dependencies = { ...packageJson.dependencies, ...packageJson.devDependencies };\n \n if (!dependencies['playwright']) {\n logger.warn('⚠️ Playwright 未安装,请先安装: pnpm add -D playwright');\n return;\n }\n }\n \n // TODO: 实现实际的 Playwright 测试运行逻辑\n logger.success('Playwright 测试完成');\n}\n"]}