From 06a25828921e910076dfc3d49dac87bc8fa49ee2 Mon Sep 17 00:00:00 2001 From: Rankin Zheng Date: Mon, 15 Apr 2024 22:50:51 +0800 Subject: [PATCH] feat: Add tests for codeBlockHandler functionality - Implement unit tests for creating and opening files with various content - Introduce mocks for vscode API to simulate file creation and opening - Cover edge cases such as unsupported languages and missing content --- test/handler/codeBlockHandler.test.ts | 74 +++++++++++++++++++++++++++ test/mocks/vscode.js | 39 ++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 test/handler/codeBlockHandler.test.ts create mode 100644 test/mocks/vscode.js diff --git a/test/handler/codeBlockHandler.test.ts b/test/handler/codeBlockHandler.test.ts new file mode 100644 index 0000000..2e4de80 --- /dev/null +++ b/test/handler/codeBlockHandler.test.ts @@ -0,0 +1,74 @@ +import { expect } from 'chai'; +import sinon from 'sinon'; +import vscodeMock from '../mocks/vscode'; +import * as proxyquire from 'proxyquire'; + +const proxy = proxyquire.noCallThru(); + +// 使用 proxyquire 加载业务代码,并替换 'vscode' 模块 +const { createAndOpenFile } = proxy('../../src/handler/codeBlockHandler', { 'vscode': vscodeMock }); + +describe('createAndOpenFile', () => { + let openTextDocumentStub: sinon.SinonStub; + let showTextDocumentStub: sinon.SinonStub; + + beforeEach(() => { + // 模拟 vscode.workspace.openTextDocument + openTextDocumentStub = sinon.stub(vscodeMock.workspace, 'openTextDocument').resolves(); + // 模拟 vscode.window.showTextDocument + showTextDocumentStub = sinon.stub(vscodeMock.window, 'showTextDocument').resolves(); + }); + + afterEach(() => { + sinon.restore(); + }); + + // 1. happy path: 当提供有效的语言和内容时,应该成功创建并打开一个新文档。 + it('当提供有效的语言和内容时,应该成功创建并打开一个新文档', async () => { + const message = { language: 'javascript', content: 'console.log("Hello World");' }; + await createAndOpenFile(message); + expect(openTextDocumentStub.calledOnce).to.be.true; + expect(showTextDocumentStub.calledOnce).to.be.true; + }); + + // 2. happy path: 当提供的语言是VSCode支持的一种常见编程语言时,应该成功创建对应语言的文档。 + it('当提供的语言是VSCode支持的一种常见编程语言时,应该成功创建对应语言的文档', async () => { + const message = { language: 'python', content: 'print("Hello World")' }; + await createAndOpenFile(message); + expect(openTextDocumentStub.calledWith(sinon.match.has('language', 'python'))).to.be.true; + expect(showTextDocumentStub.calledOnce).to.be.true; + }); + + // 3. happy path: 当提供的内容是空字符串时,应该成功创建一个空的文档。 + it('当提供的内容是空字符串时,应该成功创建一个空的文档', async () => { + const message = { language: 'plaintext', content: '' }; + await createAndOpenFile(message); + expect(openTextDocumentStub.calledWith(sinon.match.has('content', ''))).to.be.true; + expect(showTextDocumentStub.calledOnce).to.be.true; + }); + + // 4. edge case: 当提供的语言不被VSCode支持时,应该抛出错误或以默认语言创建文档。 + it('当提供的语言不被VSCode支持时,应该以默认语言创建文档', async () => { + const message = { language: 'nonexistentLanguage', content: 'Hello World' }; + await createAndOpenFile(message); + // TODO: 验证是否以默认语言创建了文档,这需要根据vscode API的实际行为来确定 + }); + + // 5. edge case: 当message对象缺少language属性时,应该抛出错误或以默认设置创建文档。 + it('当message对象缺少language属性时,应该以默认设置创建文档', async () => { + const message = { content: 'Hello World' }; + await createAndOpenFile(message as any); // 强制类型转换以模拟缺少属性 + // TODO: 验证是否以默认设置创建了文档,这需要根据vscode API的实际行为来确定 + }); + + // 6. edge case: 当message对象是null时,应该抛出错误,防止函数执行失败。 + it('当message对象是null时,应该抛出错误,防止函数执行失败', async () => { + let error; + try { + await createAndOpenFile(null as any); // 强制类型转换以模拟null值 + } catch (e) { + error = e; + } + expect(error).to.not.be.null; + }); +}); \ No newline at end of file diff --git a/test/mocks/vscode.js b/test/mocks/vscode.js new file mode 100644 index 0000000..f35e955 --- /dev/null +++ b/test/mocks/vscode.js @@ -0,0 +1,39 @@ +// test/mocks/vscode.js + +// 定义一个模拟的openTextDocument函数 +function openTextDocumentMock() { + return new Promise(resolve => { + // 模拟异步返回一个文档对象 + resolve({ + // 根据需要模拟文档对象的属性和方法 + getText: () => "模拟文档内容", + // 其他需要模拟的方法和属性 + }); + }); +} + +// 定义一个模拟的showTextDocument函数 +function showTextDocumentMock(document, options) { + return new Promise(resolve => { + // 模拟异步打开文档的行为 + resolve({ + // 模拟视图或编辑器的响应 + // 例如: + viewColumn: options?.viewColumn, + // 其他需要模拟的方法和属性 + }); + }); +} + +// 导出一个对象,该对象模拟vscode模块的一些API +module.exports = { + workspace: { + openTextDocument: openTextDocumentMock, + // 其他workspace下需要模拟的API + }, + window: { + showTextDocument: showTextDocumentMock, + // 其他window下需要模拟的API + }, + // 根据需要继续添加其他模拟的vscode API +}; \ No newline at end of file