diff --git a/extensions/ql-vscode/src/cli.ts b/extensions/ql-vscode/src/cli.ts index ae24e905b..45c6a7f6c 100644 --- a/extensions/ql-vscode/src/cli.ts +++ b/extensions/ql-vscode/src/cli.ts @@ -9,7 +9,7 @@ import { Readable } from "stream"; import { StringDecoder } from "string_decoder"; import tk from "tree-kill"; import { promisify } from "util"; -import { CancellationToken, commands, Disposable, Uri } from "vscode"; +import { CancellationToken, Disposable, Uri } from "vscode"; import { BQRSInfo, DecodedBqrsChunk } from "./pure/bqrs-cli-types"; import { allowCanaryQueryServer, CliConfig } from "./config"; @@ -1375,7 +1375,7 @@ export class CodeQLCliServer implements Disposable { if (!this._version) { this._version = this.refreshVersion(); // this._version is only undefined upon config change, so we reset CLI-based context key only when necessary. - await commands.executeCommand( + await this.app.commands.execute( "setContext", "codeql.supportsEvalLog", await this.cliConstraints.supportsPerQueryEvalLog(), diff --git a/extensions/ql-vscode/src/common/commands.ts b/extensions/ql-vscode/src/common/commands.ts index aa7792624..74b6c3313 100644 --- a/extensions/ql-vscode/src/common/commands.ts +++ b/extensions/ql-vscode/src/common/commands.ts @@ -1,5 +1,5 @@ import type { CommandManager } from "../packages/commands"; -import type { Uri, Range } from "vscode"; +import type { Uri, Range, TextDocumentShowOptions } from "vscode"; import type { AstItem } from "../astViewer"; import type { DbTreeViewItem } from "../databases/ui/db-tree-view-item"; import type { DatabaseItem } from "../local-databases"; @@ -35,12 +35,22 @@ export type SingleSelectionCommandFunction = ( // Builtin commands where the implementation is provided by VS Code and not by this extension. // See https://code.visualstudio.com/api/references/commands export type BuiltInVsCodeCommands = { + // The codeQLDatabases.focus command is provided by VS Code because we've registered the custom view + "codeQLDatabases.focus": () => Promise; "markdown.showPreviewToSide": (uri: Uri) => Promise; setContext: ( key: `${"codeql" | "codeQL"}${string}`, value: unknown, ) => Promise; "workbench.action.reloadWindow": () => Promise; + "vscode.diff": ( + leftSideResource: Uri, + rightSideResource: Uri, + title?: string, + columnOrOptions?: TextDocumentShowOptions, + ) => Promise; + "vscode.open": (uri: Uri) => Promise; + "vscode.openFolder": (uri: Uri) => Promise; }; // Commands that are available before the extension is fully activated. diff --git a/extensions/ql-vscode/src/databaseFetcher.ts b/extensions/ql-vscode/src/databaseFetcher.ts index ac63fffbb..cd6c9acf9 100644 --- a/extensions/ql-vscode/src/databaseFetcher.ts +++ b/extensions/ql-vscode/src/databaseFetcher.ts @@ -1,7 +1,7 @@ import fetch, { Response } from "node-fetch"; import { zip } from "zip-a-folder"; import { Open } from "unzipper"; -import { Uri, CancellationToken, commands, window } from "vscode"; +import { Uri, CancellationToken, window } from "vscode"; import { CodeQLCliServer } from "./cli"; import { ensureDir, @@ -26,6 +26,7 @@ import { isValidGitHubNwo, } from "./common/github-url-identifier-helper"; import { Credentials } from "./common/authentication"; +import { AppCommandManager } from "./common/commands"; /** * Prompts a user to fetch a database from a remote location. Database is assumed to be an archive file. @@ -34,6 +35,7 @@ import { Credentials } from "./common/authentication"; * @param storagePath where to store the unzipped database. */ export async function promptImportInternetDatabase( + commandManager: AppCommandManager, databaseManager: DatabaseManager, storagePath: string, progress: ProgressCallback, @@ -61,7 +63,7 @@ export async function promptImportInternetDatabase( ); if (item) { - await commands.executeCommand("codeQLDatabases.focus"); + await commandManager.execute("codeQLDatabases.focus"); void showAndLogInformationMessage( "Database downloaded and imported successfully.", ); @@ -78,6 +80,7 @@ export async function promptImportInternetDatabase( * @param storagePath where to store the unzipped database. */ export async function promptImportGithubDatabase( + commandManager: AppCommandManager, databaseManager: DatabaseManager, storagePath: string, credentials: Credentials | undefined, @@ -141,7 +144,7 @@ export async function promptImportGithubDatabase( cli, ); if (item) { - await commands.executeCommand("codeQLDatabases.focus"); + await commandManager.execute("codeQLDatabases.focus"); void showAndLogInformationMessage( "Database downloaded and imported successfully.", ); @@ -158,6 +161,7 @@ export async function promptImportGithubDatabase( * @param storagePath where to store the unzipped database. */ export async function importArchiveDatabase( + commandManager: AppCommandManager, databaseUrl: string, databaseManager: DatabaseManager, storagePath: string, @@ -177,7 +181,7 @@ export async function importArchiveDatabase( cli, ); if (item) { - await commands.executeCommand("codeQLDatabases.focus"); + await commandManager.execute("codeQLDatabases.focus"); void showAndLogInformationMessage( "Database unzipped and imported successfully.", ); diff --git a/extensions/ql-vscode/src/databases/db-module.ts b/extensions/ql-vscode/src/databases/db-module.ts index 8c287cc32..8d47f75a8 100644 --- a/extensions/ql-vscode/src/databases/db-module.ts +++ b/extensions/ql-vscode/src/databases/db-module.ts @@ -43,7 +43,7 @@ export class DbModule extends DisposableObject { await this.dbConfigStore.initialize(); - this.dbPanel = new DbPanel(this.dbManager, app.credentials); + this.dbPanel = new DbPanel(app, this.dbManager); this.push(this.dbPanel); this.push(this.dbConfigStore); diff --git a/extensions/ql-vscode/src/databases/ui/db-panel.ts b/extensions/ql-vscode/src/databases/ui/db-panel.ts index 7df235347..80a0eec5b 100644 --- a/extensions/ql-vscode/src/databases/ui/db-panel.ts +++ b/extensions/ql-vscode/src/databases/ui/db-panel.ts @@ -1,5 +1,4 @@ import { - commands, QuickPickItem, TreeView, TreeViewExpansionEvent, @@ -31,8 +30,8 @@ import { DbTreeViewItem } from "./db-tree-view-item"; import { getGitHubUrl } from "./db-tree-view-item-action"; import { getControllerRepo } from "../../variant-analysis/run-remote-query"; import { getErrorMessage } from "../../pure/helpers-pure"; -import { Credentials } from "../../common/authentication"; import { DatabasePanelCommands } from "../../common/commands"; +import { App } from "../../common/app"; export interface RemoteDatabaseQuickPickItem extends QuickPickItem { kind: string; @@ -47,8 +46,8 @@ export class DbPanel extends DisposableObject { private readonly treeView: TreeView; public constructor( + private readonly app: App, private readonly dbManager: DbManager, - private readonly credentials: Credentials, ) { super(); @@ -369,13 +368,13 @@ export class DbPanel extends DisposableObject { ); } - await commands.executeCommand("vscode.open", Uri.parse(githubUrl)); + await this.app.commands.execute("vscode.open", Uri.parse(githubUrl)); } private async setupControllerRepository(): Promise { try { // This will also validate that the controller repository is valid - await getControllerRepo(this.credentials); + await getControllerRepo(this.app.credentials); } catch (e: unknown) { if (e instanceof UserCancellationException) { return; diff --git a/extensions/ql-vscode/src/extension.ts b/extensions/ql-vscode/src/extension.ts index 26e301bb9..c6accece0 100644 --- a/extensions/ql-vscode/src/extension.ts +++ b/extensions/ql-vscode/src/extension.ts @@ -575,7 +575,7 @@ async function installOrUpdateThenTryActivate( await installOrUpdateDistribution(ctx, app, distributionManager, config); try { - await prepareCodeTour(); + await prepareCodeTour(app.commands); } catch (e: unknown) { void extLogger.log( `Could not open tutorial workspace automatically: ${getErrorMessage(e)}`, @@ -669,7 +669,12 @@ async function activateWithInstalledDistribution( ctx.subscriptions.push(statusBar); void extLogger.log("Initializing query server client."); - const qs = await createQueryServer(qlConfigurationListener, cliServer, ctx); + const qs = await createQueryServer( + app, + qlConfigurationListener, + cliServer, + ctx, + ); for (const glob of PACK_GLOBS) { const fsWatcher = workspace.createFileSystemWatcher(glob); @@ -680,7 +685,7 @@ async function activateWithInstalledDistribution( } void extLogger.log("Initializing database manager."); - const dbm = new DatabaseManager(ctx, qs, cliServer, extLogger); + const dbm = new DatabaseManager(ctx, app, qs, cliServer, extLogger); // Let this run async. void dbm.loadPersistedState(); @@ -853,7 +858,7 @@ async function activateWithInstalledDistribution( ); ctx.subscriptions.push(testAdapterFactory); - const testUIService = new TestUIService(testHub); + const testUIService = new TestUIService(app, testHub); ctx.subscriptions.push(testUIService); testUiCommands = testUIService.getCommands(); @@ -881,6 +886,7 @@ async function activateWithInstalledDistribution( const allCommands: AllExtensionCommands = { ...getCommands(app, cliServer, qs), ...getQueryEditorCommands({ + commandManager: app.commands, queryRunner: qs, cliServer, qhelpTmpDir: qhelpTmpDir.name, @@ -1046,6 +1052,7 @@ function addUnhandledRejectionListener() { } async function createQueryServer( + app: ExtensionApp, qlConfigurationListener: QueryServerConfigListener, cliServer: CodeQLCliServer, ctx: ExtensionContext, @@ -1076,6 +1083,7 @@ async function createQueryServer( return new NewQueryRunner(qs); } else { const qs = new LegacyQueryServerClient( + app, qlConfigurationListener, cliServer, qsOpts, diff --git a/extensions/ql-vscode/src/helpers.ts b/extensions/ql-vscode/src/helpers.ts index 33f5abd45..2576f6b48 100644 --- a/extensions/ql-vscode/src/helpers.ts +++ b/extensions/ql-vscode/src/helpers.ts @@ -16,7 +16,6 @@ import { window as Window, workspace, env, - commands, } from "vscode"; import { CodeQLCliServer, QlpacksInfo } from "./cli"; import { UserCancellationException } from "./progress"; @@ -27,6 +26,7 @@ import { RedactableError } from "./pure/errors"; import { getQlPackPath } from "./pure/ql"; import { dbSchemeToLanguage } from "./common/query-language"; import { isCodespacesTemplate } from "./config"; +import { AppCommandManager } from "./common/commands"; // Shared temporary folder for the extension. export const tmpDir = dirSync({ @@ -271,7 +271,9 @@ export function isFolderAlreadyInWorkspace(folderName: string) { /** Check if the current workspace is the CodeTour and open the workspace folder. * Without this, we can't run the code tour correctly. **/ -export async function prepareCodeTour(): Promise { +export async function prepareCodeTour( + commandManager: AppCommandManager, +): Promise { if (workspace.workspaceFolders?.length) { const currentFolder = workspace.workspaceFolders[0].uri.fsPath; @@ -308,7 +310,7 @@ export async function prepareCodeTour(): Promise { `In prepareCodeTour() method, going to open the tutorial workspace file: ${tutorialWorkspacePath}`, ); - await commands.executeCommand("vscode.openFolder", tutorialWorkspaceUri); + await commandManager.execute("vscode.openFolder", tutorialWorkspaceUri); } } } diff --git a/extensions/ql-vscode/src/legacy-query-server/queryserver-client.ts b/extensions/ql-vscode/src/legacy-query-server/queryserver-client.ts index 25e60db23..50c0278db 100644 --- a/extensions/ql-vscode/src/legacy-query-server/queryserver-client.ts +++ b/extensions/ql-vscode/src/legacy-query-server/queryserver-client.ts @@ -1,7 +1,7 @@ import { ensureFile } from "fs-extra"; import { DisposableObject } from "../pure/disposable-object"; -import { CancellationToken, commands } from "vscode"; +import { CancellationToken } from "vscode"; import { createMessageConnection, RequestType } from "vscode-jsonrpc/node"; import * as cli from "../cli"; import { QueryServerConfig } from "../config"; @@ -15,6 +15,7 @@ import { } from "../pure/legacy-messages"; import { ProgressCallback, ProgressTask } from "../progress"; import { ServerProcess } from "../json-rpc-server"; +import { App } from "../common/app"; type WithProgressReporting = ( task: ( @@ -56,6 +57,7 @@ export class QueryServerClient extends DisposableObject { public activeQueryLogger: Logger; constructor( + app: App, readonly config: QueryServerConfig, readonly cliServer: cli.CodeQLCliServer, readonly opts: ServerOpts, @@ -69,7 +71,7 @@ export class QueryServerClient extends DisposableObject { if (config.onDidChangeConfiguration !== undefined) { this.push( config.onDidChangeConfiguration(() => - commands.executeCommand("codeQL.restartQueryServer"), + app.commands.execute("codeQL.restartQueryServer"), ), ); } diff --git a/extensions/ql-vscode/src/local-databases-ui.ts b/extensions/ql-vscode/src/local-databases-ui.ts index 81bf64097..f1d88edb6 100644 --- a/extensions/ql-vscode/src/local-databases-ui.ts +++ b/extensions/ql-vscode/src/local-databases-ui.ts @@ -451,6 +451,7 @@ export class DatabaseUI extends DisposableObject { return withProgress( async (progress, token) => { await promptImportInternetDatabase( + this.app.commands, this.databaseManager, this.storagePath, progress, @@ -470,6 +471,7 @@ export class DatabaseUI extends DisposableObject { const credentials = isCanary() ? this.app.credentials : undefined; await promptImportGithubDatabase( + this.app.commands, this.databaseManager, this.storagePath, credentials, @@ -607,6 +609,7 @@ export class DatabaseUI extends DisposableObject { // Assume user has selected an archive if the file has a .zip extension if (uri.path.endsWith(".zip")) { await importArchiveDatabase( + this.app.commands, uri.toString(true), this.databaseManager, this.storagePath, @@ -762,6 +765,7 @@ export class DatabaseUI extends DisposableObject { // we are selecting a database archive. Must unzip into a workspace-controlled area // before importing. return await importArchiveDatabase( + this.app.commands, uri.toString(true), this.databaseManager, this.storagePath, diff --git a/extensions/ql-vscode/src/local-databases.ts b/extensions/ql-vscode/src/local-databases.ts index 3d390b472..918ddd5fc 100644 --- a/extensions/ql-vscode/src/local-databases.ts +++ b/extensions/ql-vscode/src/local-databases.ts @@ -28,6 +28,7 @@ import { redactableError } from "./pure/errors"; import { isCodespacesTemplate } from "./config"; import { QlPackGenerator } from "./qlpack-generator"; import { QueryLanguage } from "./common/query-language"; +import { App } from "./common/app"; /** * databases.ts @@ -593,6 +594,7 @@ export class DatabaseManager extends DisposableObject { constructor( private readonly ctx: ExtensionContext, + private readonly app: App, private readonly qs: QueryRunner, private readonly cli: cli.CodeQLCliServer, public logger: Logger, @@ -875,7 +877,7 @@ export class DatabaseManager extends DisposableObject { this._currentDatabaseItem = item; this.updatePersistedCurrentDatabaseItem(); - await vscode.commands.executeCommand( + await this.app.commands.execute( "setContext", "codeQL.currentDatabaseItem", item?.name, diff --git a/extensions/ql-vscode/src/query-editor.ts b/extensions/ql-vscode/src/query-editor.ts index 23b8101c7..5821dc781 100644 --- a/extensions/ql-vscode/src/query-editor.ts +++ b/extensions/ql-vscode/src/query-editor.ts @@ -1,13 +1,15 @@ -import { commands, Uri, window } from "vscode"; +import { Uri, window } from "vscode"; import { CodeQLCliServer } from "./cli"; import { QueryRunner } from "./queryRunner"; import { basename, join } from "path"; import { getErrorMessage } from "./pure/helpers-pure"; import { redactableError } from "./pure/errors"; import { showAndLogExceptionWithTelemetry } from "./helpers"; -import { QueryEditorCommands } from "./common/commands"; +import { AppCommandManager, QueryEditorCommands } from "./common/commands"; type QueryEditorOptions = { + commandManager: AppCommandManager; + queryRunner: QueryRunner; cliServer: CodeQLCliServer; @@ -15,6 +17,7 @@ type QueryEditorOptions = { }; export function getQueryEditorCommands({ + commandManager, queryRunner, cliServer, qhelpTmpDir, @@ -29,11 +32,17 @@ export function getQueryEditorCommands({ // Since we are tracking extension usage through commands, this command mirrors the "codeQL.openReferencedFile" command "codeQL.openReferencedFileContextExplorer": openReferencedFileCommand, "codeQL.previewQueryHelp": async (selectedQuery: Uri) => - await previewQueryHelp(cliServer, qhelpTmpDir, selectedQuery), + await previewQueryHelp( + commandManager, + cliServer, + qhelpTmpDir, + selectedQuery, + ), }; } async function previewQueryHelp( + commandManager: AppCommandManager, cliServer: CodeQLCliServer, qhelpTmpDir: string, selectedQuery: Uri, @@ -49,7 +58,7 @@ async function previewQueryHelp( const uri = Uri.file(absolutePathToMd); try { await cliServer.generateQueryHelp(pathToQhelp, absolutePathToMd); - await commands.executeCommand("markdown.showPreviewToSide", uri); + await commandManager.execute("markdown.showPreviewToSide", uri); } catch (e) { const errorMessage = getErrorMessage(e).includes( "Generating qhelp in markdown", diff --git a/extensions/ql-vscode/src/test-ui.ts b/extensions/ql-vscode/src/test-ui.ts index 5739d438f..45b8f41a7 100644 --- a/extensions/ql-vscode/src/test-ui.ts +++ b/extensions/ql-vscode/src/test-ui.ts @@ -1,6 +1,6 @@ import { lstat, copy, pathExists, createFile } from "fs-extra"; import { basename } from "path"; -import { Uri, TextDocumentShowOptions, commands, window } from "vscode"; +import { Uri, TextDocumentShowOptions, window } from "vscode"; import { TestHub, TestController, @@ -16,6 +16,7 @@ import { TestTreeNode } from "./test-tree-node"; import { DisposableObject } from "./pure/disposable-object"; import { QLTestAdapter, getExpectedFile, getActualFile } from "./test-adapter"; import { TestUICommands } from "./common/commands"; +import { App } from "./common/app"; type VSCodeTestEvent = | TestRunStartedEvent @@ -44,7 +45,7 @@ class QLTestListener extends DisposableObject { export class TestUIService extends DisposableObject implements TestController { private readonly listeners: Map = new Map(); - constructor(private readonly testHub: TestHub) { + constructor(private readonly app: App, private readonly testHub: TestHub) { super(); testHub.registerTestController(this); @@ -105,7 +106,7 @@ export class TestUIService extends DisposableObject implements TestController { if (await pathExists(actualPath)) { const actualUri = Uri.file(actualPath); - await commands.executeCommand( + await this.app.commands.execute( "vscode.diff", expectedUri, actualUri, diff --git a/extensions/ql-vscode/test/vscode-tests/cli-integration/databaseFetcher.test.ts b/extensions/ql-vscode/test/vscode-tests/cli-integration/databaseFetcher.test.ts index 407c22176..3ba6d5806 100644 --- a/extensions/ql-vscode/test/vscode-tests/cli-integration/databaseFetcher.test.ts +++ b/extensions/ql-vscode/test/vscode-tests/cli-integration/databaseFetcher.test.ts @@ -9,6 +9,7 @@ import { promptImportInternetDatabase, } from "../../../src/databaseFetcher"; import { cleanDatabases, dbLoc, DB_URL, storagePath } from "../global.helper"; +import { createMockCommandManager } from "../../__mocks__/commandsMock"; jest.setTimeout(60_000); @@ -53,6 +54,7 @@ describe("DatabaseFetcher", () => { it("should add a database from a folder", async () => { const uri = Uri.file(dbLoc); let dbItem = await importArchiveDatabase( + createMockCommandManager(), uri.toString(true), databaseManager, storagePath, @@ -75,6 +77,7 @@ describe("DatabaseFetcher", () => { inputBoxStub.mockResolvedValue(DB_URL); let dbItem = await promptImportInternetDatabase( + createMockCommandManager(), databaseManager, storagePath, progressCallback, diff --git a/extensions/ql-vscode/test/vscode-tests/cli-integration/legacy-query.test.ts b/extensions/ql-vscode/test/vscode-tests/cli-integration/legacy-query.test.ts index 6c014b609..faacb6db2 100644 --- a/extensions/ql-vscode/test/vscode-tests/cli-integration/legacy-query.test.ts +++ b/extensions/ql-vscode/test/vscode-tests/cli-integration/legacy-query.test.ts @@ -12,6 +12,7 @@ import { CodeQLExtensionInterface } from "../../../src/extension"; import { describeWithCodeQL } from "../cli"; import { QueryServerClient } from "../../../src/legacy-query-server/queryserver-client"; import { extLogger, ProgressReporter } from "../../../src/common"; +import { createMockApp } from "../../__mocks__/appMock"; const baseDir = join(__dirname, "../../../test/data"); @@ -121,6 +122,7 @@ describeWithCodeQL()("using the legacy query server", () => { cliServer.quiet = true; qs = new QueryServerClient( + createMockApp({}), { codeQlPath: (await extension.distributionManager.getCodeQlPathWithoutVersionCheck()) || diff --git a/extensions/ql-vscode/test/vscode-tests/cli-integration/new-query.test.ts b/extensions/ql-vscode/test/vscode-tests/cli-integration/new-query.test.ts index a7d8f9d4b..4d47f3b02 100644 --- a/extensions/ql-vscode/test/vscode-tests/cli-integration/new-query.test.ts +++ b/extensions/ql-vscode/test/vscode-tests/cli-integration/new-query.test.ts @@ -13,6 +13,7 @@ import { extLogger, ProgressReporter } from "../../../src/common"; import { QueryResultType } from "../../../src/pure/new-messages"; import { cleanDatabases, dbLoc, storagePath } from "../global.helper"; import { importArchiveDatabase } from "../../../src/databaseFetcher"; +import { createMockCommandManager } from "../../__mocks__/commandsMock"; const baseDir = join(__dirname, "../../../test/data"); @@ -147,6 +148,7 @@ describeWithCodeQL()("using the new query server", () => { await cleanDatabases(extension.databaseManager); const uri = Uri.file(dbLoc); const maybeDbItem = await importArchiveDatabase( + createMockCommandManager(), uri.toString(true), extension.databaseManager, storagePath, diff --git a/extensions/ql-vscode/test/vscode-tests/cli-integration/queries.test.ts b/extensions/ql-vscode/test/vscode-tests/cli-integration/queries.test.ts index 65b304235..b750bbae9 100644 --- a/extensions/ql-vscode/test/vscode-tests/cli-integration/queries.test.ts +++ b/extensions/ql-vscode/test/vscode-tests/cli-integration/queries.test.ts @@ -26,6 +26,7 @@ import { createInitialQueryInfo } from "../../../src/run-queries-shared"; import { QueryRunner } from "../../../src/queryRunner"; import { CompletedQueryInfo } from "../../../src/query-results"; import { SELECT_QUERY_NAME } from "../../../src/contextual/locationFinder"; +import { createMockCommandManager } from "../../__mocks__/commandsMock"; jest.setTimeout(20_000); @@ -78,6 +79,7 @@ describeWithCodeQL()("Queries", () => { await cleanDatabases(databaseManager); const uri = Uri.file(dbLoc); const maybeDbItem = await importArchiveDatabase( + createMockCommandManager(), uri.toString(true), databaseManager, storagePath, diff --git a/extensions/ql-vscode/test/vscode-tests/minimal-workspace/local-databases.test.ts b/extensions/ql-vscode/test/vscode-tests/minimal-workspace/local-databases.test.ts index 6c4167c06..c106110e8 100644 --- a/extensions/ql-vscode/test/vscode-tests/minimal-workspace/local-databases.test.ts +++ b/extensions/ql-vscode/test/vscode-tests/minimal-workspace/local-databases.test.ts @@ -25,6 +25,7 @@ import * as helpers from "../../../src/helpers"; import { Setting } from "../../../src/config"; import { QlPackGenerator } from "../../../src/qlpack-generator"; import { mockedObject } from "../utils/mocking.helpers"; +import { createMockApp } from "../../__mocks__/appMock"; describe("local databases", () => { const MOCK_DB_OPTIONS: FullDatabaseOptions = { @@ -87,6 +88,7 @@ describe("local databases", () => { databaseManager = new DatabaseManager( extensionContext, + createMockApp({}), mockedObject({ registerDatabase: registerSpy, deregisterDatabase: deregisterSpy, diff --git a/extensions/ql-vscode/test/vscode-tests/no-workspace/helpers.test.ts b/extensions/ql-vscode/test/vscode-tests/no-workspace/helpers.test.ts index 8fe7a47bd..49bb5117d 100644 --- a/extensions/ql-vscode/test/vscode-tests/no-workspace/helpers.test.ts +++ b/extensions/ql-vscode/test/vscode-tests/no-workspace/helpers.test.ts @@ -1,5 +1,4 @@ import { - commands, EnvironmentVariableCollection, EnvironmentVariableMutator, Event, @@ -41,6 +40,7 @@ import { import { reportStreamProgress } from "../../../src/progress"; import { QueryLanguage } from "../../../src/common/query-language"; import { Setting } from "../../../src/config"; +import { createMockCommandManager } from "../../__mocks__/commandsMock"; describe("helpers", () => { describe("Invocation rate limiter", () => { @@ -612,13 +612,11 @@ describe("prepareCodeTour", () => { await mkdir(tourDirPath); // spy that we open the workspace file by calling the 'vscode.openFolder' command - const commandSpy = jest.spyOn(commands, "executeCommand"); - commandSpy.mockImplementation(() => Promise.resolve()); - - await prepareCodeTour(); + const executeCommand = jest.fn(); + await prepareCodeTour(createMockCommandManager({ executeCommand })); expect(showInformationMessageSpy).toHaveBeenCalled(); - expect(commandSpy).toHaveBeenCalledWith( + expect(executeCommand).toHaveBeenCalledWith( "vscode.openFolder", expect.objectContaining({ path: Uri.parse(tutorialWorkspacePath).fsPath, @@ -641,12 +639,10 @@ describe("prepareCodeTour", () => { await mkdir(tourDirPath); // spy that we open the workspace file by calling the 'vscode.openFolder' command - const commandSpy = jest.spyOn(commands, "executeCommand"); - commandSpy.mockImplementation(() => Promise.resolve()); + const executeCommand = jest.fn(); + await prepareCodeTour(createMockCommandManager({ executeCommand })); - await prepareCodeTour(); - - expect(commandSpy).not.toHaveBeenCalled(); + expect(executeCommand).not.toHaveBeenCalled(); }); }); }); @@ -658,24 +654,20 @@ describe("prepareCodeTour", () => { await mkdir(tourDirPath); // spy that we open the workspace file by calling the 'vscode.openFolder' command - const commandSpy = jest.spyOn(commands, "executeCommand"); - commandSpy.mockImplementation(() => Promise.resolve()); + const executeCommand = jest.fn(); + await prepareCodeTour(createMockCommandManager({ executeCommand })); - await prepareCodeTour(); - - expect(commandSpy).not.toHaveBeenCalled(); + expect(executeCommand).not.toHaveBeenCalled(); }); }); describe("if we're in a different repo with no tour", () => { it("should not open the tutorial workspace", async () => { // spy that we open the workspace file by calling the 'vscode.openFolder' command - const commandSpy = jest.spyOn(commands, "executeCommand"); - commandSpy.mockImplementation(() => Promise.resolve()); + const executeCommand = jest.fn(); + await prepareCodeTour(createMockCommandManager({ executeCommand })); - await prepareCodeTour(); - - expect(commandSpy).not.toHaveBeenCalled(); + expect(executeCommand).not.toHaveBeenCalled(); }); }); });