|
|
@@ -0,0 +1,344 @@
|
|
|
+import fs from 'fs';
|
|
|
+import path from 'path';
|
|
|
+import { fileURLToPath } from 'url';
|
|
|
+
|
|
|
+const __filename = fileURLToPath(import.meta.url);
|
|
|
+const __dirname = path.dirname(__filename);
|
|
|
+
|
|
|
+// 测试配置
|
|
|
+const TEST_CONFIG = {
|
|
|
+ sourceDir: path.join(__dirname, '..', 'src'),
|
|
|
+ platformsDir: path.join(__dirname, '..', 'src', 'pages', 'platforms'),
|
|
|
+ zhipuDir: path.join(__dirname, '..', 'src', 'pages', 'platforms', 'zhipu'),
|
|
|
+ deepseekDir: path.join(__dirname, '..', 'src', 'pages', 'deepseek'),
|
|
|
+ routerFile: path.join(__dirname, '..', 'src', 'router.tsx'),
|
|
|
+ apiFile: path.join(__dirname, '..', 'src', 'apis', 'index.ts'),
|
|
|
+};
|
|
|
+
|
|
|
+// 测试结果收集器
|
|
|
+class TestResultCollector {
|
|
|
+ constructor() {
|
|
|
+ this.results = [];
|
|
|
+ this.passed = 0;
|
|
|
+ this.failed = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ addResult(testName, passed, details = '') {
|
|
|
+ const result = { testName, passed, details, timestamp: new Date() };
|
|
|
+ this.results.push(result);
|
|
|
+ if (passed) {
|
|
|
+ this.passed++;
|
|
|
+ } else {
|
|
|
+ this.failed++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ getSummary() {
|
|
|
+ return {
|
|
|
+ total: this.results.length,
|
|
|
+ passed: this.passed,
|
|
|
+ failed: this.failed,
|
|
|
+ successRate: this.results.length > 0 ? (this.passed / this.results.length * 100).toFixed(2) : 0
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ printResults() {
|
|
|
+ console.log('\n📊 测试结果汇总:');
|
|
|
+ console.log(` 总测试数: ${this.results.length}`);
|
|
|
+ console.log(` 通过: ${this.passed}`);
|
|
|
+ console.log(` 失败: ${this.failed}`);
|
|
|
+ console.log(` 成功率: ${this.getSummary().successRate}%`);
|
|
|
+
|
|
|
+ console.log('\n📋 详细结果:');
|
|
|
+ this.results.forEach((result, index) => {
|
|
|
+ const status = result.passed ? '✅' : '❌';
|
|
|
+ console.log(` ${index + 1}. ${status} ${result.testName}`);
|
|
|
+ if (!result.passed && result.details) {
|
|
|
+ console.log(` 详情: ${result.details}`);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 测试工具函数
|
|
|
+class TestUtils {
|
|
|
+ static fileExists(filePath) {
|
|
|
+ try {
|
|
|
+ return fs.existsSync(filePath);
|
|
|
+ } catch (error) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ static readFile(filePath) {
|
|
|
+ try {
|
|
|
+ return fs.readFileSync(filePath, 'utf8');
|
|
|
+ } catch (error) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ static listDirectories(dirPath) {
|
|
|
+ try {
|
|
|
+ return fs.readdirSync(dirPath, { withFileTypes: true })
|
|
|
+ .filter(dirent => dirent.isDirectory())
|
|
|
+ .map(dirent => dirent.name);
|
|
|
+ } catch (error) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ static countOccurrences(text, pattern) {
|
|
|
+ const matches = text.match(new RegExp(pattern, 'g'));
|
|
|
+ return matches ? matches.length : 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 测试用例
|
|
|
+class PlatformMigrationTests {
|
|
|
+ constructor() {
|
|
|
+ this.collector = new TestResultCollector();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 测试1: 验证目录结构
|
|
|
+ testDirectoryStructure() {
|
|
|
+ console.log('\n🏗️ 测试目录结构...');
|
|
|
+
|
|
|
+ // 测试 platforms 目录存在
|
|
|
+ const platformsExists = TestUtils.fileExists(TEST_CONFIG.platformsDir);
|
|
|
+ this.collector.addResult(
|
|
|
+ 'platforms 目录存在',
|
|
|
+ platformsExists,
|
|
|
+ platformsExists ? '' : `目录不存在: ${TEST_CONFIG.platformsDir}`
|
|
|
+ );
|
|
|
+
|
|
|
+ // 测试 zhipu 目录存在
|
|
|
+ const zhipuExists = TestUtils.fileExists(TEST_CONFIG.zhipuDir);
|
|
|
+ this.collector.addResult(
|
|
|
+ 'zhipu 目录存在',
|
|
|
+ zhipuExists,
|
|
|
+ zhipuExists ? '' : `目录不存在: ${TEST_CONFIG.zhipuDir}`
|
|
|
+ );
|
|
|
+
|
|
|
+ // 测试 zhipu 子目录
|
|
|
+ if (zhipuExists) {
|
|
|
+ const zhipuSubDirs = TestUtils.listDirectories(TEST_CONFIG.zhipuDir);
|
|
|
+ const expectedDirs = ['questionAnswer', 'knowledgeLib', 'dataExport'];
|
|
|
+ const missingDirs = expectedDirs.filter(dir => !zhipuSubDirs.includes(dir));
|
|
|
+
|
|
|
+ this.collector.addResult(
|
|
|
+ 'zhipu 子目录完整',
|
|
|
+ missingDirs.length === 0,
|
|
|
+ missingDirs.length > 0 ? `缺少目录: ${missingDirs.join(', ')}` : ''
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ // 测试 deepseek 目录仍然存在
|
|
|
+ const deepseekExists = TestUtils.fileExists(TEST_CONFIG.deepseekDir);
|
|
|
+ this.collector.addResult(
|
|
|
+ 'deepseek 目录保持存在',
|
|
|
+ deepseekExists,
|
|
|
+ deepseekExists ? '' : `目录不存在: ${TEST_CONFIG.deepseekDir}`
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ // 测试2: 验证路由配置
|
|
|
+ testRouterConfiguration() {
|
|
|
+ console.log('\n🛣️ 测试路由配置...');
|
|
|
+
|
|
|
+ const routerContent = TestUtils.readFile(TEST_CONFIG.routerFile);
|
|
|
+ if (!routerContent) {
|
|
|
+ this.collector.addResult('路由文件可读', false, '无法读取路由文件');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 测试 zhipu 路由路径
|
|
|
+ const zhipuPathCount = TestUtils.countOccurrences(routerContent, '/zhipu/');
|
|
|
+ this.collector.addResult(
|
|
|
+ 'zhipu 路由路径配置',
|
|
|
+ zhipuPathCount >= 3,
|
|
|
+ zhipuPathCount < 3 ? `期望至少3个zhipu路径,实际找到${zhipuPathCount}个` : ''
|
|
|
+ );
|
|
|
+
|
|
|
+ // 测试 zhipu 导入路径
|
|
|
+ const zhipuImportCount = TestUtils.countOccurrences(routerContent, '@/pages/platforms/zhipu/');
|
|
|
+ this.collector.addResult(
|
|
|
+ 'zhipu 导入路径配置',
|
|
|
+ zhipuImportCount >= 5,
|
|
|
+ zhipuImportCount < 5 ? `期望至少5个zhipu导入路径,实际找到${zhipuImportCount}个` : ''
|
|
|
+ );
|
|
|
+
|
|
|
+ // 测试没有遗留的旧路径
|
|
|
+ const oldPathCount = TestUtils.countOccurrences(routerContent, '@/pages/(questionAnswer|knowledgeLib|dataExport)');
|
|
|
+ this.collector.addResult(
|
|
|
+ '没有遗留旧路径',
|
|
|
+ oldPathCount === 0,
|
|
|
+ oldPathCount > 0 ? `发现${oldPathCount}个遗留的旧路径引用` : ''
|
|
|
+ );
|
|
|
+
|
|
|
+ // 测试 deepseek 路径仍然正确
|
|
|
+ const deepseekPathCount = TestUtils.countOccurrences(routerContent, '/deepseek/');
|
|
|
+ this.collector.addResult(
|
|
|
+ 'deepseek 路由路径保持',
|
|
|
+ deepseekPathCount >= 3,
|
|
|
+ deepseekPathCount < 3 ? `期望至少3个deepseek路径,实际找到${deepseekPathCount}个` : ''
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ // 测试3: 验证文件完整性
|
|
|
+ testFileIntegrity() {
|
|
|
+ console.log('\n📁 测试文件完整性...');
|
|
|
+
|
|
|
+ // 测试关键文件存在
|
|
|
+ const criticalFiles = [
|
|
|
+ path.join(TEST_CONFIG.zhipuDir, 'questionAnswer', 'list', 'index.tsx'),
|
|
|
+ path.join(TEST_CONFIG.zhipuDir, 'questionAnswer', 'info', 'index.tsx'),
|
|
|
+ path.join(TEST_CONFIG.zhipuDir, 'knowledgeLib', 'list', 'index.tsx'),
|
|
|
+ path.join(TEST_CONFIG.zhipuDir, 'knowledgeLib', 'detail', 'index.tsx'),
|
|
|
+ path.join(TEST_CONFIG.zhipuDir, 'dataExport', 'index.tsx'),
|
|
|
+ ];
|
|
|
+
|
|
|
+ criticalFiles.forEach(filePath => {
|
|
|
+ const exists = TestUtils.fileExists(filePath);
|
|
|
+ const fileName = path.basename(filePath);
|
|
|
+ this.collector.addResult(
|
|
|
+ `文件存在: ${fileName}`,
|
|
|
+ exists,
|
|
|
+ exists ? '' : `文件不存在: ${filePath}`
|
|
|
+ );
|
|
|
+ });
|
|
|
+
|
|
|
+ // 测试文件内容可读
|
|
|
+ const testFile = path.join(TEST_CONFIG.zhipuDir, 'questionAnswer', 'list', 'index.tsx');
|
|
|
+ const content = TestUtils.readFile(testFile);
|
|
|
+ this.collector.addResult(
|
|
|
+ '文件内容可读',
|
|
|
+ content !== null,
|
|
|
+ content === null ? `无法读取文件内容: ${testFile}` : ''
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ // 测试4: 验证导入路径
|
|
|
+ testImportPaths() {
|
|
|
+ console.log('\n📦 测试导入路径...');
|
|
|
+
|
|
|
+ // 检查是否有任何文件引用了旧的路径
|
|
|
+ const oldImportPatterns = [
|
|
|
+ '@/pages/questionAnswer',
|
|
|
+ '@/pages/knowledgeLib',
|
|
|
+ '@/pages/dataExport'
|
|
|
+ ];
|
|
|
+
|
|
|
+ oldImportPatterns.forEach(pattern => {
|
|
|
+ const files = this.findFilesWithPattern(pattern);
|
|
|
+ this.collector.addResult(
|
|
|
+ `没有遗留 ${pattern} 导入`,
|
|
|
+ files.length === 0,
|
|
|
+ files.length > 0 ? `发现${files.length}个文件包含旧导入: ${files.slice(0, 3).join(', ')}` : ''
|
|
|
+ );
|
|
|
+ });
|
|
|
+
|
|
|
+ // 检查新的导入路径
|
|
|
+ const newImportPatterns = [
|
|
|
+ '@/pages/platforms/zhipu/questionAnswer',
|
|
|
+ '@/pages/platforms/zhipu/knowledgeLib',
|
|
|
+ '@/pages/platforms/zhipu/dataExport'
|
|
|
+ ];
|
|
|
+
|
|
|
+ newImportPatterns.forEach(pattern => {
|
|
|
+ const files = this.findFilesWithPattern(pattern);
|
|
|
+ this.collector.addResult(
|
|
|
+ `新导入路径 ${pattern} 被使用`,
|
|
|
+ files.length > 0,
|
|
|
+ files.length === 0 ? `没有找到使用新导入路径的文件` : ''
|
|
|
+ );
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 测试5: 验证构建兼容性
|
|
|
+ testBuildCompatibility() {
|
|
|
+ console.log('\n🔨 测试构建兼容性...');
|
|
|
+
|
|
|
+ // 检查 TypeScript 配置
|
|
|
+ const tsConfigPath = path.join(__dirname, '..', 'tsconfig.json');
|
|
|
+ const tsConfigExists = TestUtils.fileExists(tsConfigPath);
|
|
|
+ this.collector.addResult(
|
|
|
+ 'TypeScript 配置存在',
|
|
|
+ tsConfigExists,
|
|
|
+ tsConfigExists ? '' : 'tsconfig.json 不存在'
|
|
|
+ );
|
|
|
+
|
|
|
+ // 检查 Vite 配置
|
|
|
+ const viteConfigPath = path.join(__dirname, '..', 'vite.config.ts');
|
|
|
+ const viteConfigExists = TestUtils.fileExists(viteConfigPath);
|
|
|
+ this.collector.addResult(
|
|
|
+ 'Vite 配置存在',
|
|
|
+ viteConfigExists,
|
|
|
+ viteConfigExists ? '' : 'vite.config.ts 不存在'
|
|
|
+ );
|
|
|
+
|
|
|
+ // 检查 package.json
|
|
|
+ const packageJsonPath = path.join(__dirname, '..', 'package.json');
|
|
|
+ const packageJsonExists = TestUtils.fileExists(packageJsonPath);
|
|
|
+ this.collector.addResult(
|
|
|
+ 'package.json 存在',
|
|
|
+ packageJsonExists,
|
|
|
+ packageJsonExists ? '' : 'package.json 不存在'
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ // 辅助方法:查找包含特定模式的文件
|
|
|
+ findFilesWithPattern(pattern) {
|
|
|
+ const files = [];
|
|
|
+ this.searchInDirectory(TEST_CONFIG.sourceDir, pattern, files);
|
|
|
+ return files;
|
|
|
+ }
|
|
|
+
|
|
|
+ searchInDirectory(dir, pattern, files) {
|
|
|
+ try {
|
|
|
+ const items = fs.readdirSync(dir);
|
|
|
+ items.forEach(item => {
|
|
|
+ const fullPath = path.join(dir, item);
|
|
|
+ const stat = fs.statSync(fullPath);
|
|
|
+
|
|
|
+ if (stat.isDirectory()) {
|
|
|
+ this.searchInDirectory(fullPath, pattern, files);
|
|
|
+ } else if (stat.isFile() && /\.(ts|tsx|js|jsx)$/.test(item)) {
|
|
|
+ const content = TestUtils.readFile(fullPath);
|
|
|
+ if (content && content.includes(pattern)) {
|
|
|
+ files.push(path.relative(TEST_CONFIG.sourceDir, fullPath));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } catch (error) {
|
|
|
+ // 忽略错误,继续搜索
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 运行所有测试
|
|
|
+ runAllTests() {
|
|
|
+ console.log('🚀 开始平台迁移测试...\n');
|
|
|
+
|
|
|
+ this.testDirectoryStructure();
|
|
|
+ this.testRouterConfiguration();
|
|
|
+ this.testFileIntegrity();
|
|
|
+ this.testImportPaths();
|
|
|
+ this.testBuildCompatibility();
|
|
|
+
|
|
|
+ // 输出结果
|
|
|
+ this.collector.printResults();
|
|
|
+
|
|
|
+ // 返回测试结果
|
|
|
+ const summary = this.collector.getSummary();
|
|
|
+ if (summary.failed > 0) {
|
|
|
+ console.log('\n⚠️ 部分测试失败,请检查上述问题。');
|
|
|
+ process.exit(1);
|
|
|
+ } else {
|
|
|
+ console.log('\n🎉 所有测试通过!平台迁移成功。');
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 运行测试
|
|
|
+const tests = new PlatformMigrationTests();
|
|
|
+tests.runAllTests();
|