diff --git a/tools/rst_optimizer/test-sample.rst b/tools/rst_optimizer/test-sample.rst new file mode 100644 index 0000000000000000000000000000000000000000..1a2508c06cfa8ee0e0aa7027fef51279364d148f --- /dev/null +++ b/tools/rst_optimizer/test-sample.rst @@ -0,0 +1,28 @@ +测试文档 +======== + +这是一个测试文档。它有一些问题需要优化。 + +功能介绍 +-------- + +这个函数很有用。它可以做很多事情。但是描述不够清楚。 + +.. code-block:: python + + def test_function(): + # 这是一个测试函数 + pass + +参考链接 +-------- + +参考 :ref:`other-section` 了解更多。 + +.. note:: + 这是一个注意事项。 + +结论 +---- + +总之,这个文档需要优化。 \ No newline at end of file diff --git a/tools/rst_optimizer/test/runTest.js b/tools/rst_optimizer/test/runTest.js new file mode 100644 index 0000000000000000000000000000000000000000..a23c16eed2d1120b16cb231828e07c4b63973384 --- /dev/null +++ b/tools/rst_optimizer/test/runTest.js @@ -0,0 +1,53 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || (function () { + var ownKeys = function(o) { + ownKeys = Object.getOwnPropertyNames || function (o) { + var ar = []; + for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; + return ar; + }; + return ownKeys(o); + }; + return function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); + __setModuleDefault(result, mod); + return result; + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +const path = __importStar(require("path")); +const test_electron_1 = require("@vscode/test-electron"); +async function main() { + try { + // 扩展开发文件夹路径 + const extensionDevelopmentPath = path.resolve(__dirname, '../../'); + // 测试套件路径 + const extensionTestsPath = path.resolve(__dirname, './suite/index'); + // 下载 VS Code,解压并运行集成测试 + await (0, test_electron_1.runTests)({ extensionDevelopmentPath, extensionTestsPath }); + } + catch (err) { + console.error('测试运行失败'); + process.exit(1); + } +} +main(); +//# sourceMappingURL=runTest.js.map \ No newline at end of file diff --git a/tools/rst_optimizer/test/runTest.js.map b/tools/rst_optimizer/test/runTest.js.map new file mode 100644 index 0000000000000000000000000000000000000000..8ce2d31a111c8f56e97ad744b89af7c2a60620db --- /dev/null +++ b/tools/rst_optimizer/test/runTest.js.map @@ -0,0 +1 @@ +{"version":3,"file":"runTest.js","sourceRoot":"","sources":["runTest.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAA6B;AAE7B,yDAAiD;AAEjD,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC;QACH,YAAY;QACZ,MAAM,wBAAwB,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAEnE,SAAS;QACT,MAAM,kBAAkB,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;QAEpE,uBAAuB;QACvB,MAAM,IAAA,wBAAQ,EAAC,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,CAAC,CAAC;IACnE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACxB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC"} \ No newline at end of file diff --git a/tools/rst_optimizer/test/runTest.ts b/tools/rst_optimizer/test/runTest.ts new file mode 100644 index 0000000000000000000000000000000000000000..ec6084df1e3e023421e35a177f75b961a39f7704 --- /dev/null +++ b/tools/rst_optimizer/test/runTest.ts @@ -0,0 +1,21 @@ +import * as path from 'path'; + +import { runTests } from '@vscode/test-electron'; + +async function main() { + try { + // 扩展开发文件夹路径 + const extensionDevelopmentPath = path.resolve(__dirname, '../../'); + + // 测试套件路径 + const extensionTestsPath = path.resolve(__dirname, './suite/index'); + + // 下载 VS Code,解压并运行集成测试 + await runTests({ extensionDevelopmentPath, extensionTestsPath }); + } catch (err) { + console.error('测试运行失败'); + process.exit(1); + } +} + +main(); \ No newline at end of file diff --git a/tools/rst_optimizer/test/suite/extension.test.ts b/tools/rst_optimizer/test/suite/extension.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..25a52ba337984dfd346a5b5aba46eaf96ad89160 --- /dev/null +++ b/tools/rst_optimizer/test/suite/extension.test.ts @@ -0,0 +1,71 @@ +import * as assert from 'assert'; +import * as vscode from 'vscode'; +import { ConfigManager } from '../../src/config'; + +suite('扩展测试套件', () => { + vscode.window.showInformationMessage('开始运行所有测试。'); + + test('扩展应该被激活', async () => { + const extension = vscode.extensions.getExtension('undefined_publisher.rst-optimizer'); + assert.ok(extension); + + if (!extension.isActive) { + await extension.activate(); + } + + assert.ok(extension.isActive); + }); + + test('所有命令应该被注册', async () => { + const commands = await vscode.commands.getCommands(true); + + const expectedCommands = [ + 'rstOptimizer.optimizeCurrent', + 'rstOptimizer.optimizePickFile', + 'rstOptimizer.applyResult', + 'rstOptimizer.openSettings', + 'rstOptimizer.showQuickPick' + ]; + + for (const command of expectedCommands) { + assert.ok(commands.includes(command), `命令 ${command} 应该被注册`); + } + }); +}); + +suite('配置管理测试', () => { + test('应该能够读取默认配置', () => { + const config = ConfigManager.getConfig(); + + assert.strictEqual(config.provider, 'openai-compatible'); + assert.strictEqual(config.baseUrl, 'https://api.openai.com/v1'); + assert.strictEqual(config.model, 'gpt-4o-mini'); + assert.strictEqual(config.maxTokens, 4096); + assert.strictEqual(config.temperature, 0.3); + assert.strictEqual(config.neverUploadIfWorkspaceTrusted, false); + assert.strictEqual(config.rewrapWidth, 0); + }); + + test('应该验证配置错误', () => { + const invalidConfig = { + provider: 'openai-compatible', + baseUrl: '', + model: '', + apiKey: '', + userPrompt: '测试提示', + maxTokens: -1, + temperature: 3, + neverUploadIfWorkspaceTrusted: false, + rewrapWidth: 0 + }; + + const errors = ConfigManager.validateConfig(invalidConfig); + + assert.ok(errors.length > 0, '应该检测到配置错误'); + assert.ok(errors.some(e => e.includes('API 基础 URL')), '应该检测到空的基础 URL'); + assert.ok(errors.some(e => e.includes('模型名称')), '应该检测到空的模型名称'); + assert.ok(errors.some(e => e.includes('API 密钥')), '应该检测到空的 API 密钥'); + assert.ok(errors.some(e => e.includes('最大 token')), '应该检测到无效的最大 token'); + assert.ok(errors.some(e => e.includes('温度值')), '应该检测到无效的温度值'); + }); +}); \ No newline at end of file diff --git a/tools/rst_optimizer/test/suite/index.ts b/tools/rst_optimizer/test/suite/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..9db559f8aa27c620da7712e823d7973441032679 --- /dev/null +++ b/tools/rst_optimizer/test/suite/index.ts @@ -0,0 +1,36 @@ +import * as path from 'path'; +import { glob } from 'glob'; + +export function run(): Promise { + const testsRoot = path.resolve(__dirname, '..'); + + return new Promise((resolve, reject) => { + glob('**/**.test.js', { cwd: testsRoot }) + .then((files: string[]) => { + // 动态导入 Mocha + const Mocha = require('mocha'); + const mocha = new Mocha({ + ui: 'tdd', + color: true + }); + + // 添加文件到测试套件 + files.forEach((f: string) => mocha.addFile(path.resolve(testsRoot, f))); + + try { + // 运行 Mocha 测试 + mocha.run((failures: number) => { + if (failures > 0) { + reject(new Error(`${failures} 个测试失败。`)); + } else { + resolve(); + } + }); + } catch (err) { + console.error(err); + reject(err); + } + }) + .catch(reject); + }); +} diff --git a/tools/rst_optimizer/test/suite/virtualDoc.test.ts b/tools/rst_optimizer/test/suite/virtualDoc.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..4b06108d0a9b5866e27102fb61a8cb6d8dcca18c --- /dev/null +++ b/tools/rst_optimizer/test/suite/virtualDoc.test.ts @@ -0,0 +1,73 @@ +import * as assert from 'assert'; +import * as vscode from 'vscode'; +import { VirtualDocProvider } from '../../src/diff/virtualDocProvider'; + +suite('虚拟文档提供者测试', () => { + let provider: VirtualDocProvider; + + setup(() => { + provider = new VirtualDocProvider(); + }); + + test('应该能够创建 URI', () => { + const filePath = '/test/file.rst'; + const originalUri = VirtualDocProvider.createUri('original', filePath); + const optimizedUri = VirtualDocProvider.createUri('optimized', filePath); + + assert.ok(originalUri.scheme === VirtualDocProvider.getScheme()); + assert.ok(optimizedUri.scheme === VirtualDocProvider.getScheme()); + assert.ok(originalUri.path.includes('original')); + assert.ok(optimizedUri.path.includes('optimized')); + assert.ok(originalUri.path.includes(encodeURIComponent(filePath))); + assert.ok(optimizedUri.path.includes(encodeURIComponent(filePath))); + }); + + test('应该能够设置和获取内容', () => { + const filePath = '/test/file.rst'; + const uri = VirtualDocProvider.createUri('original', filePath); + const content = '这是测试内容'; + + provider.set(uri, content); + const retrievedContent = provider.provideTextDocumentContent(uri); + + assert.strictEqual(retrievedContent, content); + }); + + test('应该能够清除内容', () => { + const filePath = '/test/file.rst'; + const uri = VirtualDocProvider.createUri('original', filePath); + const content = '这是测试内容'; + + provider.set(uri, content); + assert.strictEqual(provider.provideTextDocumentContent(uri), content); + + provider.clear(uri); + assert.strictEqual(provider.provideTextDocumentContent(uri), undefined); + }); + + test('应该能够清除所有内容', () => { + const filePath1 = '/test/file1.rst'; + const filePath2 = '/test/file2.rst'; + const uri1 = VirtualDocProvider.createUri('original', filePath1); + const uri2 = VirtualDocProvider.createUri('optimized', filePath2); + + provider.set(uri1, '内容1'); + provider.set(uri2, '内容2'); + + assert.strictEqual(provider.provideTextDocumentContent(uri1), '内容1'); + assert.strictEqual(provider.provideTextDocumentContent(uri2), '内容2'); + + provider.clearAll(); + + assert.strictEqual(provider.provideTextDocumentContent(uri1), undefined); + assert.strictEqual(provider.provideTextDocumentContent(uri2), undefined); + }); + + test('不存在的 URI 应该返回 undefined', () => { + const filePath = '/test/nonexistent.rst'; + const uri = VirtualDocProvider.createUri('original', filePath); + + const content = provider.provideTextDocumentContent(uri); + assert.strictEqual(content, undefined); + }); +}); \ No newline at end of file