From 082e11629cc5db39a5bcfe7ac6ae6fdb0906f7a3 Mon Sep 17 00:00:00 2001 From: Chris Bachhuber Date: Fri, 8 Aug 2025 15:45:02 +0200 Subject: [PATCH 1/4] link to plain preview for rendered files --- src/extension.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/extension.ts b/src/extension.ts index 3b93b12..1ab0d40 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -68,6 +68,12 @@ export function activate(context: vscode.ExtensionContext) { const relativePath = path.relative(upperPath, absolutePath); let filePath = upath.toUnix(relativePath); + const fileExtension = path.extname(absolutePath).toLowerCase(); + const fileExtensionsWithGitHubPreview = ['.md', '.rst', '.asciidoc', '.adoc']; + if (fileExtensionsWithGitHubPreview.includes(fileExtension)) { + filePath += '?plain=1'; + } + const selection = activeTextEditor.selection; if (selection) { const start = selection.start.line + 1; From 4a90258034776c450232cc3fdaeb38aabb93b5c4 Mon Sep 17 00:00:00 2001 From: Chris Bachhuber Date: Fri, 8 Aug 2025 16:17:03 +0200 Subject: [PATCH 2/4] Try to add unit tests --- src/__tests__/__mocks__/vscode.js | 18 ++++ src/__tests__/extension.test.ts | 137 ++++++++++++++++++++++++++++++ src/__tests__/setup.ts | 2 + 3 files changed, 157 insertions(+) create mode 100644 src/__tests__/__mocks__/vscode.js create mode 100644 src/__tests__/extension.test.ts create mode 100644 src/__tests__/setup.ts diff --git a/src/__tests__/__mocks__/vscode.js b/src/__tests__/__mocks__/vscode.js new file mode 100644 index 0000000..40f1178 --- /dev/null +++ b/src/__tests__/__mocks__/vscode.js @@ -0,0 +1,18 @@ +// Mock for VS Code API +module.exports = { + commands: { + registerCommand: jest.fn() + }, + extensions: { + getExtension: jest.fn() + }, + window: { + activeTextEditor: null, + showInformationMessage: jest.fn() + }, + env: { + clipboard: { + writeText: jest.fn() + } + } +}; diff --git a/src/__tests__/extension.test.ts b/src/__tests__/extension.test.ts new file mode 100644 index 0000000..13020ad --- /dev/null +++ b/src/__tests__/extension.test.ts @@ -0,0 +1,137 @@ +// Unit tests for the activate function + +// Mock dependencies first +const mockNormalizeGitUrl = jest.fn(); +jest.mock('normalize-git-url', () => mockNormalizeGitUrl); + +const mockMakeHttpsUrl = jest.fn(); +jest.mock('../makeHttpsUrl', () => ({ + makeHttpsUrl: mockMakeHttpsUrl +})); + +// Mock VS Code module +const mockCommands = { + registerCommand: jest.fn() +}; + +const mockExtensions = { + getExtension: jest.fn() +}; + +const mockWindow = { + activeTextEditor: null as any, + showInformationMessage: jest.fn() +}; + +const mockEnv = { + clipboard: { + writeText: jest.fn() + } +}; + +jest.mock('vscode', () => ({ + commands: mockCommands, + extensions: mockExtensions, + window: mockWindow, + env: mockEnv +}), { virtual: true }); + +import { activate } from '../extension'; + +describe('extension activate function', () => { + const mockContext = { + subscriptions: [] as any[] + } as any; + + beforeEach(() => { + jest.clearAllMocks(); + mockContext.subscriptions = []; + mockNormalizeGitUrl.mockReturnValue({ + url: 'https://github.com/test/repo', + branch: 'main' + }); + mockMakeHttpsUrl.mockImplementation((url: string) => url); + }); + + describe('successful permalink generation with file extensions', () => { + let commandCallback: Function; + const mockRepository = { + rootUri: { fsPath: '/test/repo' }, + state: { + remotes: [{ name: 'origin', fetchUrl: 'https://github.com/test/repo.git' }], + submodules: [] + }, + getCommit: jest.fn().mockResolvedValue({ hash: 'abc123' }) + }; + + const mockGitExtension = { + exports: { + getAPI: jest.fn().mockReturnValue({ + repositories: [mockRepository] + }) + } + }; + + beforeEach(() => { + mockExtensions.getExtension.mockReturnValue(mockGitExtension); + activate(mockContext); + commandCallback = mockCommands.registerCommand.mock.calls[0][1]; + }); + + it('should add ?plain=1 for markdown files', async () => { + mockWindow.activeTextEditor = { + document: { fileName: '/test/repo/README.md' }, + selection: { start: { line: 0 }, end: { line: 0 } } + }; + + await commandCallback(); + await new Promise(resolve => setImmediate(resolve)); + + expect(mockEnv.clipboard.writeText).toHaveBeenCalledWith( + expect.stringContaining('README.md?plain=1#L1') + ); + }); + + it('should not add ?plain=1 for other file types', async () => { + mockWindow.activeTextEditor = { + document: { fileName: '/test/repo/script.js' }, + selection: { start: { line: 0 }, end: { line: 0 } } + }; + + await commandCallback(); + await new Promise(resolve => setImmediate(resolve)); + + expect(mockEnv.clipboard.writeText).toHaveBeenCalledWith( + expect.not.stringContaining('?plain=1') + ); + }); + + it('should handle single line selection correctly', async () => { + mockWindow.activeTextEditor = { + document: { fileName: '/test/repo/test.js' }, + selection: { start: { line: 5 }, end: { line: 5 } } + }; + + await commandCallback(); + await new Promise(resolve => setImmediate(resolve)); + + expect(mockEnv.clipboard.writeText).toHaveBeenCalledWith( + expect.stringMatching(/#L6$/) + ); + }); + + it('should handle multi-line selection correctly', async () => { + mockWindow.activeTextEditor = { + document: { fileName: '/test/repo/test.js' }, + selection: { start: { line: 5 }, end: { line: 10 } } + }; + + await commandCallback(); + await new Promise(resolve => setImmediate(resolve)); + + expect(mockEnv.clipboard.writeText).toHaveBeenCalledWith( + expect.stringContaining('#L6-L11') + ); + }); + }); +}); diff --git a/src/__tests__/setup.ts b/src/__tests__/setup.ts new file mode 100644 index 0000000..4ab96f8 --- /dev/null +++ b/src/__tests__/setup.ts @@ -0,0 +1,2 @@ +// Jest test setup +import 'jest'; From a27b22af35787652f8a1b7db04653aedcd7ec272 Mon Sep 17 00:00:00 2001 From: Chris Bachhuber Date: Fri, 8 Aug 2025 16:18:53 +0200 Subject: [PATCH 3/4] Also run on PR --- .github/workflows/nodejs.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 32c6827..b295765 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -4,7 +4,8 @@ name: Node.js CI on: - push + - push + - pull_request jobs: test: From de80a501ed81252e7be7ed85888af44e3b6b3c0f Mon Sep 17 00:00:00 2001 From: Chris Bachhuber Date: Tue, 12 Aug 2025 18:33:21 +0200 Subject: [PATCH 4/4] Fix unit tests --- src/{__tests__ => }/__mocks__/vscode.js | 0 src/__tests__/setup.ts | 2 -- 2 files changed, 2 deletions(-) rename src/{__tests__ => }/__mocks__/vscode.js (100%) delete mode 100644 src/__tests__/setup.ts diff --git a/src/__tests__/__mocks__/vscode.js b/src/__mocks__/vscode.js similarity index 100% rename from src/__tests__/__mocks__/vscode.js rename to src/__mocks__/vscode.js diff --git a/src/__tests__/setup.ts b/src/__tests__/setup.ts deleted file mode 100644 index 4ab96f8..0000000 --- a/src/__tests__/setup.ts +++ /dev/null @@ -1,2 +0,0 @@ -// Jest test setup -import 'jest';