From c38ab7b48321f9a213455aa5f13dcfa85df28868 Mon Sep 17 00:00:00 2001 From: ygqygq2 Date: Thu, 8 Feb 2024 00:05:56 +0800 Subject: [PATCH] =?UTF-8?q?test:=20=E5=A2=9E=E5=8A=A0=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E8=B0=83=E8=AF=95=E6=97=A5=E5=BF=97=E3=80=81=E5=8F=96=E6=B6=88?= =?UTF-8?q?=E8=B0=83=E8=AF=95=E6=97=A5=E5=BF=97=E6=B3=A8=E9=87=8A=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: ygqygq2 --- .../commands/deleteAllLogMessages.spec.ts | 178 ++++++++++++++++++ .../commands/uncommentAllLogMessages.spec.ts | 143 ++++++++++++++ 2 files changed, 321 insertions(+) create mode 100644 src/test/unit/commands/deleteAllLogMessages.spec.ts create mode 100644 src/test/unit/commands/uncommentAllLogMessages.spec.ts diff --git a/src/test/unit/commands/deleteAllLogMessages.spec.ts b/src/test/unit/commands/deleteAllLogMessages.spec.ts new file mode 100644 index 0000000..15d66e1 --- /dev/null +++ b/src/test/unit/commands/deleteAllLogMessages.spec.ts @@ -0,0 +1,178 @@ +import { + Position, + Range, + Selection, + TextDocument, + TextEditor, + TextEditorEdit, + window, +} from 'vscode'; +import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest'; +import { deleteAllLogMessagesCommand } from '@/commands/deleteAllLogMessages'; +import { ExtensionProperties } from '@/typings'; + +vi.mock('vscode'); + +describe('deleteAllLogMessagesCommand', () => { + let mockEditor: TextEditor | undefined; + let mockDocument: TextDocument; + let mockSelection: Selection; + let mockSelections: Selection[]; + let mockEditBuilder: TextEditorEdit; + let mockExtensionProperties: ExtensionProperties; + + beforeEach(() => { + mockExtensionProperties = { + wrapLogMessage: false, + logMessagePrefix: '🚀', + logMessageSuffix: ':', + addSemicolonInTheEnd: true, + insertEmptyLineBeforeLogMessage: false, + insertEmptyLineAfterLogMessage: false, + quote: '"', + delimiterInsideMessage: '~', + includeFileNameAndLineNum: true, + logFunction: {}, + }; + + mockDocument = { + getWordRangeAtPosition: vi + .fn() + .mockReturnValue(new Range(new Position(0, 0), new Position(0, 0))) + .mockReturnValueOnce(new Range(new Position(0, 0), new Position(0, 4))), + getText: vi.fn((range: Range): string => { + if (range.isEmpty) { + return ''; // 未选中字符串,返回空字符串 + } + return 'myVar'; + }), + lineAt: vi.fn().mockImplementation((lineNumber) => { + if (lineNumber === 2) { + return { + text: 'console.info("🚀 ~ file: test.js:2 ~ a:", a)', // 模拟行的文本内容 + firstNonWhitespaceCharacterIndex: 0, // 模拟行的第一个非空格字符的索引 + range: { + start: { line: lineNumber - 1, character: 0 }, // 模拟行的起始位置 + end: { line: lineNumber, character: 0 }, // 模拟行的结束位置 + }, + rangeIncludingLineBreak: { + start: { line: lineNumber - 1, character: 0 }, + end: { line: lineNumber, character: 0 }, + }, + }; + } + return { + text: '', // 模拟行的文本内容 + firstNonWhitespaceCharacterIndex: 0, // 模拟行的第一个非空格字符的索引 + range: { + start: { line: lineNumber - 1, character: 0 }, // 模拟行的起始位置 + end: { line: lineNumber, character: 0 }, // 模拟行的结束位置 + }, + }; + }), + lineCount: 10, // 模拟文档的行数 + fileName: 'test.js', + } as unknown as TextDocument; + + mockSelection = new Selection(new Position(0, 0), new Position(0, 4)); + mockSelections = [mockSelection]; + + mockEditBuilder = { + insert: vi.fn(), + delete: vi.fn(), + } as unknown as TextEditorEdit; + + mockEditor = { + document: mockDocument, + selections: mockSelections, + edit: vi.fn((callback) => { + callback(mockEditBuilder); + return Promise.resolve(true); // 返回一个解析为 true 的 Promise + }), + options: { tabSize: 2 }, + } as unknown as TextEditor; + }); + + afterEach(() => { + vi.restoreAllMocks(); + }); + + it('应该直接返回,当没有调试日志时', async () => { + const mockLineAt = vi.fn().mockImplementation((lineNumber) => { + if (lineNumber === 2) { + return { + text: 'mock text', // 模拟行的文本内容 + firstNonWhitespaceCharacterIndex: 0, // 模拟行的第一个非空格字符的索引 + range: { + start: { line: lineNumber - 1, character: 0 }, // 模拟行的起始位置 + end: { line: lineNumber, character: 0 }, // 模拟行的结束位置 + }, + rangeIncludingLineBreak: { + start: { line: lineNumber - 1, character: 0 }, + end: { line: lineNumber, character: 0 }, + }, + }; + } + return { + text: '', // 模拟行的文本内容 + firstNonWhitespaceCharacterIndex: 0, // 模拟行的第一个非空格字符的索引 + range: { + start: { line: lineNumber - 1, character: 0 }, // 模拟行的起始位置 + end: { line: lineNumber, character: 0 }, // 模拟行的结束位置 + }, + }; + }); + window.activeTextEditor = { + ...mockEditor, + document: { + ...mockDocument, + lineAt: mockLineAt, + }, + } as unknown as TextEditor; + await deleteAllLogMessagesCommand().handler(mockExtensionProperties); + expect(mockEditBuilder!.delete).not.toHaveBeenCalled(); + expect(mockEditBuilder!.insert).not.toHaveBeenCalled(); + }); + + it('应该删除调试日志三行,当有调试日志一行,前后都是空行时', async () => { + window.activeTextEditor = mockEditor; + await deleteAllLogMessagesCommand().handler(mockExtensionProperties); + expect(mockEditBuilder!.delete).toHaveBeenCalledTimes(3); + }); + + it('应该删除调试日志一行,当有调试日志一行,前后不是空行时', async () => { + const mockLineAt = vi.fn().mockImplementation((lineNumber) => { + if (lineNumber === 2) { + return { + text: 'console.info("🚀 ~ file: test.js:2 ~ a:", a)', // 模拟行的文本内容 + firstNonWhitespaceCharacterIndex: 0, // 模拟行的第一个非空格字符的索引 + range: { + start: { line: lineNumber - 1, character: 0 }, // 模拟行的起始位置 + end: { line: lineNumber, character: 0 }, // 模拟行的结束位置 + }, + rangeIncludingLineBreak: { + start: { line: lineNumber - 1, character: 0 }, + end: { line: lineNumber, character: 0 }, + }, + }; + } + return { + text: 'not empty', // 模拟行的文本内容 + firstNonWhitespaceCharacterIndex: 0, // 模拟行的第一个非空格字符的索引 + range: { + start: { line: lineNumber - 1, character: 0 }, // 模拟行的起始位置 + end: { line: lineNumber, character: 0 }, // 模拟行的结束位置 + }, + }; + }); + window.activeTextEditor = { + ...mockEditor, + document: { + ...mockDocument, + lineAt: mockLineAt, + }, + } as unknown as TextEditor; + await deleteAllLogMessagesCommand().handler(mockExtensionProperties); + expect(mockEditBuilder!.delete).toHaveBeenCalledTimes(1); + }); +}); diff --git a/src/test/unit/commands/uncommentAllLogMessages.spec.ts b/src/test/unit/commands/uncommentAllLogMessages.spec.ts new file mode 100644 index 0000000..7ed028a --- /dev/null +++ b/src/test/unit/commands/uncommentAllLogMessages.spec.ts @@ -0,0 +1,143 @@ +import { + Position, + Range, + Selection, + TextDocument, + TextEditor, + TextEditorEdit, + window, +} from 'vscode'; +import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest'; +import { uncommentAllLogMessagesCommand } from '@/commands/uncommentAllLogMessages'; +import { ExtensionProperties } from '@/typings'; + +vi.mock('vscode'); + +describe('uncommentAllLogMessagesCommand', () => { + let mockEditor: TextEditor | undefined; + let mockDocument: TextDocument; + let mockSelection: Selection; + let mockSelections: Selection[]; + let mockEditBuilder: TextEditorEdit; + let mockExtensionProperties: ExtensionProperties; + + beforeEach(() => { + mockExtensionProperties = { + wrapLogMessage: false, + logMessagePrefix: '🚀', + logMessageSuffix: ':', + addSemicolonInTheEnd: true, + insertEmptyLineBeforeLogMessage: false, + insertEmptyLineAfterLogMessage: false, + quote: '"', + delimiterInsideMessage: '~', + includeFileNameAndLineNum: true, + logFunction: {}, + }; + + mockDocument = { + getWordRangeAtPosition: vi + .fn() + .mockReturnValue(new Range(new Position(0, 0), new Position(0, 0))) + .mockReturnValueOnce(new Range(new Position(0, 0), new Position(0, 4))), + getText: vi.fn((range: Range): string => { + if (range.isEmpty) { + return ''; // 未选中字符串,返回空字符串 + } + return 'myVar'; + }), + lineAt: vi.fn().mockImplementation((lineNumber) => { + if (lineNumber === 2) { + return { + text: 'console.info("🚀 ~ file: test.js:2 ~ a:", a)', // 模拟行的文本内容 + firstNonWhitespaceCharacterIndex: 0, // 模拟行的第一个非空格字符的索引 + range: { + start: { line: lineNumber - 1, character: 0 }, // 模拟行的起始位置 + end: { line: lineNumber, character: 0 }, // 模拟行的结束位置 + }, + rangeIncludingLineBreak: { + start: { line: lineNumber - 1, character: 0 }, + end: { line: lineNumber, character: 0 }, + }, + }; + } + return { + text: '', // 模拟行的文本内容 + firstNonWhitespaceCharacterIndex: 0, // 模拟行的第一个非空格字符的索引 + range: { + start: { line: lineNumber - 1, character: 0 }, // 模拟行的起始位置 + end: { line: lineNumber, character: 0 }, // 模拟行的结束位置 + }, + }; + }), + lineCount: 10, // 模拟文档的行数 + fileName: 'test.js', + } as unknown as TextDocument; + + mockSelection = new Selection(new Position(0, 0), new Position(0, 4)); + mockSelections = [mockSelection]; + + mockEditBuilder = { + insert: vi.fn(), + delete: vi.fn(), + } as unknown as TextEditorEdit; + + mockEditor = { + document: mockDocument, + selections: mockSelections, + edit: vi.fn((callback) => { + callback(mockEditBuilder); + return Promise.resolve(true); // 返回一个解析为 true 的 Promise + }), + options: { tabSize: 2 }, + } as unknown as TextEditor; + }); + + afterEach(() => { + vi.restoreAllMocks(); + }); + + it('应该直接返回,当没有调试日志时', async () => { + const mockLineAt = vi.fn().mockImplementation((lineNumber) => { + if (lineNumber === 2) { + return { + text: 'mock text', // 模拟行的文本内容 + firstNonWhitespaceCharacterIndex: 0, // 模拟行的第一个非空格字符的索引 + range: { + start: { line: lineNumber - 1, character: 0 }, // 模拟行的起始位置 + end: { line: lineNumber, character: 0 }, // 模拟行的结束位置 + }, + rangeIncludingLineBreak: { + start: { line: lineNumber - 1, character: 0 }, + end: { line: lineNumber, character: 0 }, + }, + }; + } + return { + text: '', // 模拟行的文本内容 + firstNonWhitespaceCharacterIndex: 0, // 模拟行的第一个非空格字符的索引 + range: { + start: { line: lineNumber - 1, character: 0 }, // 模拟行的起始位置 + end: { line: lineNumber, character: 0 }, // 模拟行的结束位置 + }, + }; + }); + window.activeTextEditor = { + ...mockEditor, + document: { + ...mockDocument, + lineAt: mockLineAt, + }, + } as unknown as TextEditor; + await uncommentAllLogMessagesCommand().handler(mockExtensionProperties); + expect(mockEditBuilder!.delete).not.toHaveBeenCalled(); + expect(mockEditBuilder!.insert).not.toHaveBeenCalled(); + }); + + it('应该删除调试日志,再插入一行有注释的调试日志,当有调试日志时', async () => { + window.activeTextEditor = mockEditor; + await uncommentAllLogMessagesCommand().handler(mockExtensionProperties); + expect(mockEditBuilder!.delete).toHaveBeenCalledTimes(1); + expect(mockEditBuilder!.insert).toHaveBeenCalledWith(expect.any(Position), expect.any(String)); + }); +});