From 114474c57076d7ff6fd708cbfecac59bcccec28c Mon Sep 17 00:00:00 2001 From: Karthik Nadig Date: Fri, 28 Mar 2025 23:57:44 -0700 Subject: [PATCH] fix: use wrapper functions for easier testing --- src/client/common/vscodeApis/commandApis.ts | 15 ++++++++------ src/client/common/vscodeApis/windowApis.ts | 10 ++++++++++ src/client/common/vscodeApis/workspaceApis.ts | 9 +++++++++ src/client/repl/replCommandHandler.ts | 20 +++++++++---------- 4 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/client/common/vscodeApis/commandApis.ts b/src/client/common/vscodeApis/commandApis.ts index 580760e106e1..908cb761c538 100644 --- a/src/client/common/vscodeApis/commandApis.ts +++ b/src/client/common/vscodeApis/commandApis.ts @@ -3,13 +3,16 @@ import { commands, Disposable } from 'vscode'; -/* eslint-disable @typescript-eslint/no-explicit-any */ -/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ +/** + * Wrapper for vscode.commands.executeCommand to make it easier to mock in tests + */ +export function executeCommand(command: string, ...rest: any[]): Thenable { + return commands.executeCommand(command, ...rest); +} +/** + * Wrapper for vscode.commands.registerCommand to make it easier to mock in tests + */ export function registerCommand(command: string, callback: (...args: any[]) => any, thisArg?: any): Disposable { return commands.registerCommand(command, callback, thisArg); } - -export function executeCommand(command: string, ...rest: any[]): Thenable { - return commands.executeCommand(command, ...rest); -} diff --git a/src/client/common/vscodeApis/windowApis.ts b/src/client/common/vscodeApis/windowApis.ts index fc63a189f2ff..fade0a028487 100644 --- a/src/client/common/vscodeApis/windowApis.ts +++ b/src/client/common/vscodeApis/windowApis.ts @@ -22,6 +22,9 @@ import { LogOutputChannel, OutputChannel, TerminalLinkProvider, + NotebookDocument, + NotebookEditor, + NotebookDocumentShowOptions, } from 'vscode'; import { createDeferred, Deferred } from '../utils/async'; import { Resource } from '../types'; @@ -31,6 +34,13 @@ export function showTextDocument(uri: Uri): Thenable { return window.showTextDocument(uri); } +export function showNotebookDocument( + document: NotebookDocument, + options?: NotebookDocumentShowOptions, +): Thenable { + return window.showNotebookDocument(document, options); +} + export function showQuickPick( items: readonly T[] | Thenable, options?: QuickPickOptions, diff --git a/src/client/common/vscodeApis/workspaceApis.ts b/src/client/common/vscodeApis/workspaceApis.ts index cb516da73075..ef06d982c9a7 100644 --- a/src/client/common/vscodeApis/workspaceApis.ts +++ b/src/client/common/vscodeApis/workspaceApis.ts @@ -98,6 +98,15 @@ export function createDirectory(uri: vscode.Uri): Thenable { return vscode.workspace.fs.createDirectory(uri); } +export function openNotebookDocument(uri: vscode.Uri): Thenable; +export function openNotebookDocument( + notebookType: string, + content?: vscode.NotebookData, +): Thenable; +export function openNotebookDocument(notebook: any, content?: vscode.NotebookData): Thenable { + return vscode.workspace.openNotebookDocument(notebook, content); +} + export function copy(source: vscode.Uri, dest: vscode.Uri, options?: { overwrite?: boolean }): Thenable { return vscode.workspace.fs.copy(source, dest, options); } diff --git a/src/client/repl/replCommandHandler.ts b/src/client/repl/replCommandHandler.ts index 89ccbe11c337..f65580dd1e17 100644 --- a/src/client/repl/replCommandHandler.ts +++ b/src/client/repl/replCommandHandler.ts @@ -1,6 +1,4 @@ import { - commands, - window, NotebookController, NotebookEditor, ViewColumn, @@ -9,11 +7,13 @@ import { NotebookCellKind, NotebookEdit, WorkspaceEdit, - workspace, Uri, } from 'vscode'; import { getExistingReplViewColumn, getTabNameForUri } from './replUtils'; import { PVSC_EXTENSION_ID } from '../common/constants'; +import { showNotebookDocument } from '../common/vscodeApis/windowApis'; +import { openNotebookDocument, applyEdit } from '../common/vscodeApis/workspaceApis'; +import { executeCommand } from '../common/vscodeApis/commandApis'; /** * Function that opens/show REPL using IW UI. @@ -26,7 +26,7 @@ export async function openInteractiveREPL( let viewColumn = ViewColumn.Beside; if (notebookDocument instanceof Uri) { // Case where NotebookDocument is undefined, but workspace mementoURI exists. - notebookDocument = await workspace.openNotebookDocument(notebookDocument); + notebookDocument = await openNotebookDocument(notebookDocument); } else if (notebookDocument) { // Case where NotebookDocument (REPL document already exists in the tab) const existingReplViewColumn = getExistingReplViewColumn(notebookDocument); @@ -34,9 +34,9 @@ export async function openInteractiveREPL( } else if (!notebookDocument) { // Case where NotebookDocument doesnt exist, or // became outdated (untitled.ipynb created without Python extension knowing, effectively taking over original Python REPL's URI) - notebookDocument = await workspace.openNotebookDocument('jupyter-notebook'); + notebookDocument = await openNotebookDocument('jupyter-notebook'); } - const editor = await window.showNotebookDocument(notebookDocument!, { + const editor = await showNotebookDocument(notebookDocument!, { viewColumn, asRepl: 'Python REPL', preserveFocus, @@ -52,7 +52,7 @@ export async function openInteractiveREPL( return undefined; } - await commands.executeCommand('notebook.selectKernel', { + await executeCommand('notebook.selectKernel', { editor, id: notebookController.id, extension: PVSC_EXTENSION_ID, @@ -69,7 +69,7 @@ export async function selectNotebookKernel( notebookControllerId: string, extensionId: string, ): Promise { - await commands.executeCommand('notebook.selectKernel', { + await executeCommand('notebook.selectKernel', { notebookEditor, id: notebookControllerId, extension: extensionId, @@ -84,7 +84,7 @@ export async function executeNotebookCell(notebookEditor: NotebookEditor, code: const cellIndex = replOptions?.appendIndex ?? notebook.cellCount; await addCellToNotebook(notebook, cellIndex, code); // Execute the cell - commands.executeCommand('notebook.cell.execute', { + executeCommand('notebook.cell.execute', { ranges: [{ start: cellIndex, end: cellIndex + 1 }], document: notebook.uri, }); @@ -100,5 +100,5 @@ async function addCellToNotebook(notebookDocument: NotebookDocument, index: numb const notebookEdit = NotebookEdit.insertCells(index, [notebookCellData]); const workspaceEdit = new WorkspaceEdit(); workspaceEdit.set(notebookDocument!.uri, [notebookEdit]); - await workspace.applyEdit(workspaceEdit); + await applyEdit(workspaceEdit); }