diff --git a/.eslintrc.json b/.eslintrc.json index 8476c4f20..76f5c51e1 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -14,7 +14,8 @@ // TODO "@typescript-eslint/semi" rule moved to https://eslint.style "semi": "error", "no-console": "warn", - "@typescript-eslint/no-floating-promises": "warn", + "@typescript-eslint/no-floating-promises": ["warn", { "checkThenables": true }], + "@typescript-eslint/await-thenable": "warn", // Mostly fails tests, ex. expect(...).to.be.true returns a Chai.Assertion "@typescript-eslint/no-unused-expressions": "off", "@typescript-eslint/no-non-null-assertion": "off", diff --git a/scripts/check_package_json.ts b/scripts/check_package_json.ts index 394708a67..c247072d5 100644 --- a/scripts/check_package_json.ts +++ b/scripts/check_package_json.ts @@ -15,6 +15,7 @@ import { getExtensionVersion, main } from "./lib/utilities"; +// eslint-disable-next-line @typescript-eslint/no-floating-promises main(async () => { const version = await getExtensionVersion(); if (version.minor % 2 !== 0) { diff --git a/scripts/compile_icons.ts b/scripts/compile_icons.ts index f72f912ba..ca5386477 100644 --- a/scripts/compile_icons.ts +++ b/scripts/compile_icons.ts @@ -51,6 +51,7 @@ function minifyIcon(icon: string, color: string = "#424242"): string { }).data; } +// eslint-disable-next-line @typescript-eslint/no-floating-promises main(async () => { const iconsSourceDirectory = path.join(__dirname, "../src/icons"); const iconAssetsDirectory = path.join(__dirname, "../assets/icons"); diff --git a/scripts/dev_package.ts b/scripts/dev_package.ts index 9fec4c630..7af7c279e 100644 --- a/scripts/dev_package.ts +++ b/scripts/dev_package.ts @@ -15,6 +15,7 @@ import { exec, getExtensionVersion, getRootDirectory, main } from "./lib/utilities"; +// eslint-disable-next-line @typescript-eslint/no-floating-promises main(async () => { const rootDirectory = getRootDirectory(); const version = await getExtensionVersion(); diff --git a/scripts/download_vsix.ts b/scripts/download_vsix.ts index 56729af31..0d846bc46 100644 --- a/scripts/download_vsix.ts +++ b/scripts/download_vsix.ts @@ -33,6 +33,7 @@ const repository = process.env["GITHUB_REPOSITORY"] || "swiftlang/vscode-swift"; const owner = repository.split("/")[0]; const repo = repository.split("/")[1]; +// eslint-disable-next-line @typescript-eslint/no-floating-promises (async function () { const octokit = new Octokit({ auth: token, diff --git a/scripts/preview_package.ts b/scripts/preview_package.ts index a2216d963..bc0531353 100644 --- a/scripts/preview_package.ts +++ b/scripts/preview_package.ts @@ -28,6 +28,7 @@ function formatDate(date: Date): string { return year + month + day; } +// eslint-disable-next-line @typescript-eslint/no-floating-promises main(async () => { const rootDirectory = getRootDirectory(); const version = await getExtensionVersion(); diff --git a/scripts/update_swift_docc_render.ts b/scripts/update_swift_docc_render.ts index d30ddc970..a14c57add 100644 --- a/scripts/update_swift_docc_render.ts +++ b/scripts/update_swift_docc_render.ts @@ -56,6 +56,7 @@ async function cloneSwiftDocCRender(buildDirectory: string): Promise { return swiftDocCRenderDirectory; } +// eslint-disable-next-line @typescript-eslint/no-floating-promises main(async () => { const outputDirectory = path.join(getRootDirectory(), "assets", "swift-docc-render"); if (process.argv.includes("postinstall")) { diff --git a/src/FolderContext.ts b/src/FolderContext.ts index 02cd7f171..d5fde8e21 100644 --- a/src/FolderContext.ts +++ b/src/FolderContext.ts @@ -93,7 +93,7 @@ export class FolderContext implements vscode.Disposable { const error = await swiftPackage.error; if (error) { - vscode.window.showErrorMessage( + void vscode.window.showErrorMessage( `Failed to load ${folderContext.name}/Package.swift: ${error.message}` ); workspaceContext.outputChannel.log( @@ -179,7 +179,7 @@ export class FolderContext implements vscode.Disposable { /** Refresh the tests in the test explorer for this folder */ refreshTestExplorer() { if (this.testExplorer?.controller.resolveHandler) { - this.testExplorer.controller.resolveHandler(undefined); + void this.testExplorer.controller.resolveHandler(undefined); } } diff --git a/src/TestExplorer/TestExplorer.ts b/src/TestExplorer/TestExplorer.ts index 665898218..2ffabb3f6 100644 --- a/src/TestExplorer/TestExplorer.ts +++ b/src/TestExplorer/TestExplorer.ts @@ -204,7 +204,9 @@ export class TestExplorer { */ private updateSwiftTestContext() { const items = flattenTestItemCollection(this.controller.items).map(({ id }) => id); - vscode.commands.executeCommand("setContext", "swift.tests", items); + void vscode.commands.executeCommand("setContext", "swift.tests", items).then(() => { + /* Put in worker queue */ + }); } /** @@ -285,7 +287,7 @@ export class TestExplorer { const ok = "OK"; const enable = "Enable SourceKit-LSP"; if (firstTry && configuration.lsp.disable === true) { - vscode.window + void vscode.window .showInformationMessage( `swift-testing tests will not be detected since SourceKit-LSP has been disabled for this workspace.`, @@ -297,9 +299,12 @@ export class TestExplorer { explorer.folderContext.workspaceContext.outputChannel.log( `Enabling SourceKit-LSP after swift-testing message` ); - vscode.workspace + void vscode.workspace .getConfiguration("swift") - .update("sourcekit-lsp.disable", false); + .update("sourcekit-lsp.disable", false) + .then(() => { + /* Put in worker queue */ + }); } else if (selected === ok) { explorer.folderContext.workspaceContext.outputChannel.log( `User acknowledged that SourceKit-LSP is disabled` diff --git a/src/TestExplorer/TestRunner.ts b/src/TestExplorer/TestRunner.ts index 693efe1c1..ade5a7c1b 100644 --- a/src/TestExplorer/TestRunner.ts +++ b/src/TestExplorer/TestRunner.ts @@ -1021,8 +1021,7 @@ export class TestRunner { "Test Debugging Cancelled", this.folderContext.name ); - vscode.debug.stopDebugging(session); - resolve(); + void vscode.debug.stopDebugging(session).then(() => resolve()); }); subscriptions.push(cancellation); }); @@ -1051,11 +1050,9 @@ export class TestRunner { // dispose terminate debug handler subscriptions.forEach(sub => sub.dispose()); - vscode.commands.executeCommand( - "workbench.view.extension.test" - ); - - resolve(); + void vscode.commands + .executeCommand("workbench.view.extension.test") + .then(() => resolve()); }); subscriptions.push(terminateSession); } else { diff --git a/src/WorkspaceContext.ts b/src/WorkspaceContext.ts index 1aef0b63b..629957549 100644 --- a/src/WorkspaceContext.ts +++ b/src/WorkspaceContext.ts @@ -92,7 +92,7 @@ export class WorkspaceContext implements vscode.Disposable { if (!(await this.needToAutoGenerateLaunchConfig())) { return; } - vscode.window + void vscode.window .showInformationMessage( `Launch configurations need to be updated after changing the Swift runtime path. Custom versions of environment variable '${swiftLibraryPathKey()}' may be overridden. Do you want to update?`, "Update", @@ -111,7 +111,7 @@ export class WorkspaceContext implements vscode.Disposable { if (!(await this.needToAutoGenerateLaunchConfig())) { return; } - vscode.window + void vscode.window .showInformationMessage( `Launch configurations need to be updated after changing the Swift build path. Do you want to update?`, "Update", @@ -154,7 +154,11 @@ export class WorkspaceContext implements vscode.Disposable { event.exitCode !== undefined && configuration.actionAfterBuildError === "Focus Problems" ) { - vscode.commands.executeCommand("workbench.panel.markers.view.focus"); + void vscode.commands + .executeCommand("workbench.panel.markers.view.focus") + .then(() => { + /* Put in worker queue */ + }); } }); const swiftFileWatcher = vscode.workspace.createFileSystemWatcher("**/*.swift"); diff --git a/src/commands.ts b/src/commands.ts index 5ee367e6d..d6708f547 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -106,75 +106,98 @@ export enum Commands { */ export function register(ctx: WorkspaceContext): vscode.Disposable[] { return [ - vscode.commands.registerCommand("swift.generateLaunchConfigurations", () => - generateLaunchConfigurations(ctx) + vscode.commands.registerCommand( + "swift.generateLaunchConfigurations", + async () => await generateLaunchConfigurations(ctx) ), - vscode.commands.registerCommand("swift.newFile", uri => newSwiftFile(uri)), - vscode.commands.registerCommand(Commands.RESOLVE_DEPENDENCIES, () => - resolveDependencies(ctx) + vscode.commands.registerCommand("swift.newFile", async uri => await newSwiftFile(uri)), + vscode.commands.registerCommand( + Commands.RESOLVE_DEPENDENCIES, + async () => await resolveDependencies(ctx) ), - vscode.commands.registerCommand(Commands.UPDATE_DEPENDENCIES, () => - updateDependencies(ctx) + vscode.commands.registerCommand( + Commands.UPDATE_DEPENDENCIES, + async () => await updateDependencies(ctx) ), - vscode.commands.registerCommand(Commands.RUN, target => - runBuild(ctx, ...unwrapTreeItem(target)) + vscode.commands.registerCommand( + Commands.RUN, + async target => await runBuild(ctx, ...unwrapTreeItem(target)) ), - vscode.commands.registerCommand(Commands.DEBUG, target => - debugBuild(ctx, ...unwrapTreeItem(target)) + vscode.commands.registerCommand( + Commands.DEBUG, + async target => await debugBuild(ctx, ...unwrapTreeItem(target)) ), - vscode.commands.registerCommand(Commands.CLEAN_BUILD, () => cleanBuild(ctx)), - vscode.commands.registerCommand(Commands.RUN_TESTS_MULTIPLE_TIMES, item => { + vscode.commands.registerCommand(Commands.CLEAN_BUILD, async () => await cleanBuild(ctx)), + vscode.commands.registerCommand(Commands.RUN_TESTS_MULTIPLE_TIMES, async (item, count) => { if (ctx.currentFolder) { - return runTestMultipleTimes(ctx.currentFolder, item, false); + return await runTestMultipleTimes(ctx.currentFolder, item, false, count); } }), - vscode.commands.registerCommand("swift.runTestsUntilFailure", item => { + vscode.commands.registerCommand("swift.runTestsUntilFailure", async (item, count) => { if (ctx.currentFolder) { - return runTestMultipleTimes(ctx.currentFolder, item, true); + return await runTestMultipleTimes(ctx.currentFolder, item, true, count); } }), // Note: switchPlatform is only available on macOS and Swift 6.1 or later // (gated in `package.json`) because it's the only OS and toolchain combination that // has Darwin SDKs available and supports code editing with SourceKit-LSP - vscode.commands.registerCommand("swift.switchPlatform", () => switchPlatform(ctx)), - vscode.commands.registerCommand(Commands.RESET_PACKAGE, () => resetPackage(ctx)), - vscode.commands.registerCommand("swift.runScript", () => runSwiftScript(ctx)), - vscode.commands.registerCommand("swift.openPackage", () => { + vscode.commands.registerCommand( + "swift.switchPlatform", + async () => await switchPlatform(ctx) + ), + vscode.commands.registerCommand( + Commands.RESET_PACKAGE, + async () => await resetPackage(ctx) + ), + vscode.commands.registerCommand("swift.runScript", async () => await runSwiftScript(ctx)), + vscode.commands.registerCommand("swift.openPackage", async () => { if (ctx.currentFolder) { - return openPackage(ctx.currentFolder.swiftVersion, ctx.currentFolder.folder); + return await openPackage(ctx.currentFolder.swiftVersion, ctx.currentFolder.folder); } }), - vscode.commands.registerCommand(Commands.RUN_SNIPPET, target => - runSnippet(ctx, ...unwrapTreeItem(target)) + vscode.commands.registerCommand( + Commands.RUN_SNIPPET, + async target => await runSnippet(ctx, ...unwrapTreeItem(target)) ), - vscode.commands.registerCommand(Commands.DEBUG_SNIPPET, target => - debugSnippet(ctx, ...unwrapTreeItem(target)) + vscode.commands.registerCommand( + Commands.DEBUG_SNIPPET, + async target => await debugSnippet(ctx, ...unwrapTreeItem(target)) + ), + vscode.commands.registerCommand( + Commands.RUN_PLUGIN_TASK, + async () => await runPluginTask() + ), + vscode.commands.registerCommand(Commands.RUN_TASK, async name => await runTask(ctx, name)), + vscode.commands.registerCommand( + Commands.RESTART_LSP, + async () => await restartLSPServer(ctx) ), - vscode.commands.registerCommand(Commands.RUN_PLUGIN_TASK, () => runPluginTask()), - vscode.commands.registerCommand(Commands.RUN_TASK, name => runTask(ctx, name)), - vscode.commands.registerCommand(Commands.RESTART_LSP, () => restartLSPServer(ctx)), - vscode.commands.registerCommand("swift.reindexProject", () => reindexProject(ctx)), - vscode.commands.registerCommand("swift.insertFunctionComment", () => - insertFunctionComment(ctx) + vscode.commands.registerCommand( + "swift.reindexProject", + async () => await reindexProject(ctx) + ), + vscode.commands.registerCommand( + "swift.insertFunctionComment", + async () => await insertFunctionComment(ctx) ), - vscode.commands.registerCommand(Commands.USE_LOCAL_DEPENDENCY, (item, dep) => { + vscode.commands.registerCommand(Commands.USE_LOCAL_DEPENDENCY, async (item, dep) => { if (item instanceof PackageNode) { - return useLocalDependency(item.name, ctx, dep); + return await useLocalDependency(item.name, ctx, dep); } }), - vscode.commands.registerCommand("swift.editDependency", item => { + vscode.commands.registerCommand("swift.editDependency", async item => { if (item instanceof PackageNode) { - return editDependency(item.name, ctx); + return await editDependency(item.name, ctx); } }), - vscode.commands.registerCommand(Commands.UNEDIT_DEPENDENCY, item => { + vscode.commands.registerCommand(Commands.UNEDIT_DEPENDENCY, async item => { if (item instanceof PackageNode) { - return uneditDependency(item.name, ctx); + return await uneditDependency(item.name, ctx); } }), - vscode.commands.registerCommand("swift.openInWorkspace", item => { + vscode.commands.registerCommand("swift.openInWorkspace", async item => { if (item instanceof PackageNode) { - return openInWorkspace(item); + return await openInWorkspace(item); } }), vscode.commands.registerCommand("swift.openExternal", item => { @@ -186,7 +209,10 @@ export function register(ctx: WorkspaceContext): vscode.Disposable[] { vscode.commands.registerCommand("swift.clearDiagnosticsCollection", () => ctx.diagnostics.clear() ), - vscode.commands.registerCommand("swift.captureDiagnostics", () => captureDiagnostics(ctx)), + vscode.commands.registerCommand( + "swift.captureDiagnostics", + async () => await captureDiagnostics(ctx) + ), vscode.commands.registerCommand( Commands.RUN_ALL_TESTS_PARALLEL, async item => await runAllTests(ctx, TestKind.parallel, ...unwrapTreeItem(item)) @@ -216,9 +242,9 @@ export function register(ctx: WorkspaceContext): vscode.Disposable[] { vscode.commands.registerCommand("swift.openEducationalNote", uri => openEducationalNote(uri) ), - vscode.commands.registerCommand(Commands.OPEN_MANIFEST, (uri: vscode.Uri) => { + vscode.commands.registerCommand(Commands.OPEN_MANIFEST, async (uri: vscode.Uri) => { const packagePath = path.join(uri.fsPath, "Package.swift"); - vscode.commands.executeCommand("vscode.open", vscode.Uri.file(packagePath)); + await vscode.commands.executeCommand("vscode.open", vscode.Uri.file(packagePath)); }), vscode.commands.registerCommand("swift.openDocumentation", () => openDocumentation()), ]; diff --git a/src/commands/captureDiagnostics.ts b/src/commands/captureDiagnostics.ts index b87026a0c..7043f9bac 100644 --- a/src/commands/captureDiagnostics.ts +++ b/src/commands/captureDiagnostics.ts @@ -76,7 +76,7 @@ export async function captureDiagnostics( await showCapturedDiagnosticsResults(diagnosticsDir); } } catch (error) { - vscode.window.showErrorMessage(`Unable to capture diagnostic logs: ${error}`); + void vscode.window.showErrorMessage(`Unable to capture diagnostic logs: ${error}`); } } @@ -149,12 +149,12 @@ async function showCapturedDiagnosticsResults(diagnosticsDir: string) { copyPath ); if (result === copyPath) { - vscode.env.clipboard.writeText(diagnosticsDir); + await vscode.env.clipboard.writeText(diagnosticsDir); } else if (result === showInFinderButton) { exec(showDirectoryCommand(diagnosticsDir), error => { // Opening the explorer on windows returns an exit code of 1 despite opening successfully. if (error && process.platform !== "win32") { - vscode.window.showErrorMessage( + void vscode.window.showErrorMessage( `Failed to open ${showCommandType()}: ${error.message}` ); } diff --git a/src/commands/createNewProject.ts b/src/commands/createNewProject.ts index 16deb6238..016bd346d 100644 --- a/src/commands/createNewProject.ts +++ b/src/commands/createNewProject.ts @@ -38,7 +38,7 @@ export async function createNewProject(toolchain: SwiftToolchain | undefined): P // activated. As such, we also have to allow this command to run when no workspace is // active. Show an error to the user if the command is unavailable. if (!toolchain.swiftVersion.isGreaterThanOrEqual(new Version(5, 8, 0))) { - vscode.window.showErrorMessage( + void vscode.window.showErrorMessage( "Creating a new swift project is only available starting in swift version 5.8.0." ); return; @@ -180,6 +180,6 @@ export async function createNewProject(toolchain: SwiftToolchain | undefined): P }); } else if (action === "addToWorkspace") { const index = vscode.workspace.workspaceFolders?.length ?? 0; - await vscode.workspace.updateWorkspaceFolders(index, 0, { uri: projectUri }); + vscode.workspace.updateWorkspaceFolders(index, 0, { uri: projectUri }); } } diff --git a/src/commands/dependencies/unedit.ts b/src/commands/dependencies/unedit.ts index 816bec70d..68e38974c 100644 --- a/src/commands/dependencies/unedit.ts +++ b/src/commands/dependencies/unedit.ts @@ -91,7 +91,7 @@ async function uneditFolderDependency( await uneditFolderDependency(folder, identifier, ctx, ["--force"]); } else { ctx.outputChannel.log(execError.stderr, folder.name); - vscode.window.showErrorMessage(`${execError.stderr}`); + void vscode.window.showErrorMessage(`${execError.stderr}`); } return false; } diff --git a/src/commands/newFile.ts b/src/commands/newFile.ts index 91365ff6d..69af38926 100644 --- a/src/commands/newFile.ts +++ b/src/commands/newFile.ts @@ -44,7 +44,7 @@ export async function newSwiftFile( await vscode.languages.setTextDocumentLanguage(document, "swift"); await vscode.window.showTextDocument(document); } catch (err) { - vscode.window.showErrorMessage(`Failed to create ${targetUri.fsPath}`); + void vscode.window.showErrorMessage(`Failed to create ${targetUri.fsPath}`); } } else { // If no path is supplied then open an untitled editor w/ Swift language type diff --git a/src/commands/openInExternalEditor.ts b/src/commands/openInExternalEditor.ts index 6dc621765..5137dc534 100644 --- a/src/commands/openInExternalEditor.ts +++ b/src/commands/openInExternalEditor.ts @@ -22,7 +22,7 @@ import { PackageNode } from "../ui/ProjectPanelProvider"; export function openInExternalEditor(packageNode: PackageNode) { try { const uri = vscode.Uri.parse(packageNode.location, true); - vscode.env.openExternal(uri); + void vscode.env.openExternal(uri); } catch { // ignore error } diff --git a/src/commands/openPackage.ts b/src/commands/openPackage.ts index 002c4c579..c6c25aef7 100644 --- a/src/commands/openPackage.ts +++ b/src/commands/openPackage.ts @@ -24,8 +24,7 @@ import { fileExists } from "../utilities/filesystem"; export async function openPackage(swiftVersion: Version, currentFolder: vscode.Uri) { const packagePath = await packageSwiftFile(currentFolder, swiftVersion); if (packagePath) { - const document = await vscode.workspace.openTextDocument(packagePath); - vscode.window.showTextDocument(document); + await vscode.window.showTextDocument(packagePath); } } diff --git a/src/commands/reindexProject.ts b/src/commands/reindexProject.ts index 27e56e854..fa5ddc58a 100644 --- a/src/commands/reindexProject.ts +++ b/src/commands/reindexProject.ts @@ -38,7 +38,7 @@ export async function reindexProject( "Close" ); if (result === "Report Issue") { - vscode.commands.executeCommand( + await vscode.commands.executeCommand( "vscode.open", vscode.Uri.parse( "https://github.com/swiftlang/sourcekit-lsp/issues/new?template=BUG_REPORT.yml&title=Symbol%20Indexing%20Issue" @@ -49,11 +49,11 @@ export async function reindexProject( const error = err as { code: number; message: string }; // methodNotFound, version of sourcekit-lsp is likely too old. if (error.code === -32601) { - vscode.window.showWarningMessage( + void vscode.window.showWarningMessage( "The installed version of SourceKit-LSP does not support background indexing." ); } else { - vscode.window.showWarningMessage(error.message); + void vscode.window.showWarningMessage(error.message); } } }); diff --git a/src/commands/runSwiftScript.ts b/src/commands/runSwiftScript.ts index e7333e5b3..e522c4cd2 100644 --- a/src/commands/runSwiftScript.ts +++ b/src/commands/runSwiftScript.ts @@ -39,7 +39,7 @@ export async function runSwiftScript(ctx: WorkspaceContext) { process.platform === "win32" && ctx.currentFolder.swiftVersion.isLessThan(new Version(5, 7, 0)) ) { - vscode.window.showErrorMessage( + void vscode.window.showErrorMessage( "Run Swift Script is unavailable with the legacy driver on Windows." ); return; diff --git a/src/commands/runTask.ts b/src/commands/runTask.ts index 6b261756e..5f3e03281 100644 --- a/src/commands/runTask.ts +++ b/src/commands/runTask.ts @@ -32,7 +32,7 @@ export const runTask = async (ctx: WorkspaceContext, name: string) => { } if (!task) { - vscode.window.showErrorMessage(`Task "${name}" not found`); + void vscode.window.showErrorMessage(`Task "${name}" not found`); return; } diff --git a/src/commands/switchPlatform.ts b/src/commands/switchPlatform.ts index e65dfda2c..8bc1cfea7 100644 --- a/src/commands/switchPlatform.ts +++ b/src/commands/switchPlatform.ts @@ -50,7 +50,7 @@ export async function switchPlatform(ctx: WorkspaceContext) { if (swiftSDKTriple !== "") { // set a swiftSDK for non-macOS Darwin platforms so that SourceKit-LSP can provide syntax highlighting configuration.swiftSDK = swiftSDKTriple; - vscode.window.showWarningMessage( + void vscode.window.showWarningMessage( `Selecting the ${picked.label} target platform will provide code editing support, but compiling with a ${picked.label} SDK will have undefined results.` ); } else { @@ -58,7 +58,7 @@ export async function switchPlatform(ctx: WorkspaceContext) { configuration.swiftSDK = ""; } } catch { - vscode.window.showErrorMessage( + void vscode.window.showErrorMessage( `Unable set the Swift SDK setting to ${picked.label}, verify that the SDK exists` ); } diff --git a/src/commands/testMultipleTimes.ts b/src/commands/testMultipleTimes.ts index de78562a9..fd04e46ba 100644 --- a/src/commands/testMultipleTimes.ts +++ b/src/commands/testMultipleTimes.ts @@ -28,19 +28,27 @@ export async function runTestMultipleTimes( currentFolder: FolderContext, test: vscode.TestItem, untilFailure: boolean, + count: number | undefined = undefined, testRunner?: () => Promise ) { - const str = await vscode.window.showInputBox({ - prompt: "Label: ", - placeHolder: `${untilFailure ? "Maximum " : ""}# of times to run`, - validateInput: value => (/^[1-9]\d*$/.test(value) ? undefined : "Enter an integer value"), - }); + let numExecutions = count; + if (numExecutions === undefined) { + const str = await vscode.window.showInputBox({ + prompt: "Label: ", + placeHolder: `${untilFailure ? "Maximum " : ""}# of times to run`, + validateInput: value => + /^[1-9]\d*$/.test(value) ? undefined : "Enter an integer value", + }); + if (!str) { + return; + } + numExecutions = parseInt(str); + } - if (!str || !currentFolder.testExplorer) { + if (!currentFolder.testExplorer) { return; } const token = new vscode.CancellationTokenSource(); - const numExecutions = parseInt(str); const testExplorer = currentFolder.testExplorer; const runner = new TestRunner( TestKind.standard, @@ -54,7 +62,7 @@ export async function runTestMultipleTimes( const testRunState = new TestRunnerTestRunState(runner.testRun); - vscode.commands.executeCommand("workbench.panel.testResults.view.focus"); + await vscode.commands.executeCommand("workbench.panel.testResults.view.focus"); const runStates: TestRunState[] = []; for (let i = 0; i < numExecutions; i++) { diff --git a/src/commands/utilities.ts b/src/commands/utilities.ts index 9e911a40f..1131ca0c2 100644 --- a/src/commands/utilities.ts +++ b/src/commands/utilities.ts @@ -46,13 +46,13 @@ export async function executeTaskWithUI( return true; } else { if (showErrors) { - vscode.window.showErrorMessage(`${description} failed`); + void vscode.window.showErrorMessage(`${description} failed`); } return false; } } catch (error) { if (showErrors) { - vscode.window.showErrorMessage(`${description} failed: ${error}`); + void vscode.window.showErrorMessage(`${description} failed: ${error}`); } return false; } diff --git a/src/configuration.ts b/src/configuration.ts index 03af80486..27615108b 100644 --- a/src/configuration.ts +++ b/src/configuration.ts @@ -315,14 +315,24 @@ const configuration = { ); }, set sdk(value: string | undefined) { - vscode.workspace.getConfiguration("swift").update("SDK", value); + void vscode.workspace + .getConfiguration("swift") + .update("SDK", value) + .then(() => { + /* Put in worker queue */ + }); }, /** Path to custom --swift-sdk */ get swiftSDK(): string { return vscode.workspace.getConfiguration("swift").get("swiftSDK", ""); }, set swiftSDK(value: string | undefined) { - vscode.workspace.getConfiguration("swift").update("swiftSDK", value); + void vscode.workspace + .getConfiguration("swift") + .update("swiftSDK", value) + .then(() => { + /* Put in worker queue */ + }); }, /** swift build arguments */ get buildArguments(): string[] { @@ -456,9 +466,12 @@ const configuration = { .get("warnAboutSymlinkCreation", true); }, set warnAboutSymlinkCreation(value: boolean) { - vscode.workspace + void vscode.workspace .getConfiguration("swift") - .update("warnAboutSymlinkCreation", value, vscode.ConfigurationTarget.Global); + .update("warnAboutSymlinkCreation", value, vscode.ConfigurationTarget.Global) + .then(() => { + /* Put in worker queue */ + }); }, /** Whether or not the extension will contribute Swift environment variables to the integrated terminal */ get enableTerminalEnvironment(): boolean { @@ -540,7 +553,9 @@ export function handleConfigurationChangeEvent( event.affectsConfiguration("swift.SDK") || event.affectsConfiguration("swift.swiftSDK") ) { - vscode.commands.executeCommand("swift.restartLSPServer"); + void vscode.commands.executeCommand("swift.restartLSPServer").then(() => { + /* Put in worker queue */ + }); } else if (event.affectsConfiguration("swift.swiftEnvironmentVariables")) { void showReloadExtensionNotification( "Changing environment variables requires the project be reloaded." diff --git a/src/contextKeys.ts b/src/contextKeys.ts index 6e8ee7199..115c0e479 100644 --- a/src/contextKeys.ts +++ b/src/contextKeys.ts @@ -128,7 +128,11 @@ function createContextKeys(): ContextKeys { set isActivated(value: boolean) { isActivated = value; - vscode.commands.executeCommand("setContext", "swift.isActivated", value); + void vscode.commands + .executeCommand("setContext", "swift.isActivated", value) + .then(() => { + /* Put in worker queue */ + }); }, get hasPackage() { @@ -137,7 +141,11 @@ function createContextKeys(): ContextKeys { set hasPackage(value: boolean) { hasPackage = value; - vscode.commands.executeCommand("setContext", "swift.hasPackage", value); + void vscode.commands + .executeCommand("setContext", "swift.hasPackage", value) + .then(() => { + /* Put in worker queue */ + }); }, get hasExecutableProduct() { @@ -146,7 +154,11 @@ function createContextKeys(): ContextKeys { set hasExecutableProduct(value: boolean) { hasExecutableProduct = value; - vscode.commands.executeCommand("setContext", "swift.hasExecutableTarget", value); + void vscode.commands + .executeCommand("setContext", "swift.hasExecutableTarget", value) + .then(() => { + /* Put in worker queue */ + }); }, get packageHasDependencies() { @@ -155,7 +167,11 @@ function createContextKeys(): ContextKeys { set packageHasDependencies(value: boolean) { packageHasDependencies = value; - vscode.commands.executeCommand("setContext", "swift.packageHasDependencies", value); + void vscode.commands + .executeCommand("setContext", "swift.packageHasDependencies", value) + .then(() => { + /* Put in worker queue */ + }); }, get flatDependenciesList() { @@ -164,7 +180,11 @@ function createContextKeys(): ContextKeys { set flatDependenciesList(value: boolean) { flatDependenciesList = value; - vscode.commands.executeCommand("setContext", "swift.flatDependenciesList", value); + void vscode.commands + .executeCommand("setContext", "swift.flatDependenciesList", value) + .then(() => { + /* Put in worker queue */ + }); }, get packageHasPlugins() { @@ -173,7 +193,11 @@ function createContextKeys(): ContextKeys { set packageHasPlugins(value: boolean) { packageHasPlugins = value; - vscode.commands.executeCommand("setContext", "swift.packageHasPlugins", value); + void vscode.commands + .executeCommand("setContext", "swift.packageHasPlugins", value) + .then(() => { + /* Put in worker queue */ + }); }, get currentTargetType() { @@ -182,11 +206,11 @@ function createContextKeys(): ContextKeys { set currentTargetType(value: string | undefined) { currentTargetType = value; - vscode.commands.executeCommand( - "setContext", - "swift.currentTargetType", - value ?? "none" - ); + void vscode.commands + .executeCommand("setContext", "swift.currentTargetType", value ?? "none") + .then(() => { + /* Put in worker queue */ + }); }, get fileIsSnippet() { @@ -195,7 +219,11 @@ function createContextKeys(): ContextKeys { set fileIsSnippet(value: boolean) { fileIsSnippet = value; - vscode.commands.executeCommand("setContext", "swift.fileIsSnippet", value); + void vscode.commands + .executeCommand("setContext", "swift.fileIsSnippet", value) + .then(() => { + /* Put in worker queue */ + }); }, get lldbVSCodeAvailable() { @@ -204,7 +232,11 @@ function createContextKeys(): ContextKeys { set lldbVSCodeAvailable(value: boolean) { lldbVSCodeAvailable = value; - vscode.commands.executeCommand("setContext", "swift.lldbVSCodeAvailable", value); + void vscode.commands + .executeCommand("setContext", "swift.lldbVSCodeAvailable", value) + .then(() => { + /* Put in worker queue */ + }); }, get createNewProjectAvailable() { @@ -213,7 +245,11 @@ function createContextKeys(): ContextKeys { set createNewProjectAvailable(value: boolean) { createNewProjectAvailable = value; - vscode.commands.executeCommand("setContext", "swift.createNewProjectAvailable", value); + void vscode.commands + .executeCommand("setContext", "swift.createNewProjectAvailable", value) + .then(() => { + /* Put in worker queue */ + }); }, get supportsReindexing() { @@ -222,7 +258,11 @@ function createContextKeys(): ContextKeys { set supportsReindexing(value: boolean) { supportsReindexing = value; - vscode.commands.executeCommand("setContext", "swift.supportsReindexing", value); + void vscode.commands + .executeCommand("setContext", "swift.supportsReindexing", value) + .then(() => { + /* Put in worker queue */ + }); }, get supportsDocumentationLivePreview() { @@ -231,11 +271,11 @@ function createContextKeys(): ContextKeys { set supportsDocumentationLivePreview(value: boolean) { supportsDocumentationLivePreview = value; - vscode.commands.executeCommand( - "setContext", - "swift.supportsDocumentationLivePreview", - value - ); + void vscode.commands + .executeCommand("setContext", "swift.supportsDocumentationLivePreview", value) + .then(() => { + /* Put in worker queue */ + }); }, get switchPlatformAvailable() { @@ -244,7 +284,11 @@ function createContextKeys(): ContextKeys { set switchPlatformAvailable(value: boolean) { switchPlatformAvailable = value; - vscode.commands.executeCommand("setContext", "swift.switchPlatformAvailable", value); + void vscode.commands + .executeCommand("setContext", "swift.switchPlatformAvailable", value) + .then(() => { + /* Put in worker queue */ + }); }, }; } diff --git a/src/debugger/debugAdapterFactory.ts b/src/debugger/debugAdapterFactory.ts index 0e6cc7676..be08f7275 100644 --- a/src/debugger/debugAdapterFactory.ts +++ b/src/debugger/debugAdapterFactory.ts @@ -163,7 +163,7 @@ export class LLDBDebugConfigurationProvider implements vscode.DebugConfiguration const lldbDapPath = await DebugAdapter.getLLDBDebugAdapterPath(toolchain); // Verify that the debug adapter exists or bail otherwise if (!(await fileExists(lldbDapPath))) { - vscode.window.showErrorMessage( + void vscode.window.showErrorMessage( `Cannot find the LLDB debug adapter in your Swift toolchain: No such file or directory "${lldbDapPath}"` ); return undefined; @@ -207,7 +207,7 @@ export class LLDBDebugConfigurationProvider implements vscode.DebugConfiguration const libLldbPathResult = await getLLDBLibPath(toolchain); if (!libLldbPathResult.success) { const errorMessage = `Error: ${getErrorDescription(libLldbPathResult.failure)}`; - vscode.window.showWarningMessage( + void vscode.window.showWarningMessage( `Failed to setup CodeLLDB for debugging of Swift code. Debugging may produce unexpected results. ${errorMessage}` ); this.outputChannel.log(`Failed to setup CodeLLDB: ${errorMessage}`); diff --git a/src/documentation/DocumentationPreviewEditor.ts b/src/documentation/DocumentationPreviewEditor.ts index 05c30c596..2ffa13b03 100644 --- a/src/documentation/DocumentationPreviewEditor.ts +++ b/src/documentation/DocumentationPreviewEditor.ts @@ -143,7 +143,7 @@ export class DocumentationPreviewEditor implements vscode.Disposable { if (message.type === "update-content") { this.updateContentEmitter.fire(message.content); } - this.webviewPanel.webview.postMessage(message); + void this.webviewPanel.webview.postMessage(message); } private receiveMessage(message: WebviewMessage) { diff --git a/src/extension.ts b/src/extension.ts index c4e61422e..4ab80c10a 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -155,7 +155,7 @@ export async function activate(context: vscode.ExtensionContext): Promise { const errorMessage = getErrorDescription(error); // show this error message as the VS Code error message only shows when running // the extension through the debugger - vscode.window.showErrorMessage(`Activating Swift extension failed: ${errorMessage}`); + void vscode.window.showErrorMessage(`Activating Swift extension failed: ${errorMessage}`); throw error; } } diff --git a/src/sourcekit-lsp/LanguageClientConfiguration.ts b/src/sourcekit-lsp/LanguageClientConfiguration.ts index 9c4804938..6947a4f4c 100644 --- a/src/sourcekit-lsp/LanguageClientConfiguration.ts +++ b/src/sourcekit-lsp/LanguageClientConfiguration.ts @@ -243,7 +243,7 @@ export function lspClientOptions( handleWorkDoneProgress: (() => { let lastPrompted = new Date(0).getTime(); return async (token, params, next) => { - const result = await next(token, params); + const result = next(token, params); const now = new Date().getTime(); const oneHour = 60 * 60 * 1000; if ( diff --git a/src/sourcekit-lsp/LanguageClientManager.ts b/src/sourcekit-lsp/LanguageClientManager.ts index 3159e115f..146cd2f1a 100644 --- a/src/sourcekit-lsp/LanguageClientManager.ts +++ b/src/sourcekit-lsp/LanguageClientManager.ts @@ -143,7 +143,7 @@ export class LanguageClientManager implements vscode.Disposable { // Ignore configuration changes if SourceKit-LSP is disabled return; } - vscode.window.showInformationMessage(message, restartLSPButton).then(selected => { + void vscode.window.showInformationMessage(message, restartLSPButton).then(selected => { if (selected === restartLSPButton) { void this.restart(); } @@ -589,7 +589,7 @@ export class SourceKitLSPErrorHandler implements ErrorHandler { const diff = this.restarts[this.restarts.length - 1] - this.restarts[0]; if (diff <= 3 * 60 * 1000) { return new Promise(resolve => { - vscode.window + void vscode.window .showErrorMessage( `The SourceKit-LSP server crashed ${ this.maxRestartCount + 1 diff --git a/src/tasks/SwiftProcess.ts b/src/tasks/SwiftProcess.ts index 012587834..18a6355f0 100644 --- a/src/tasks/SwiftProcess.ts +++ b/src/tasks/SwiftProcess.ts @@ -73,6 +73,34 @@ export interface SwiftProcess { setDimensions(dimensions: vscode.TerminalDimensions): void; } +class CloseHandler { + private readonly closeEmitter: vscode.EventEmitter = new vscode.EventEmitter< + number | void + >(); + private exitCode: number | void | undefined; + private closeTimeout: NodeJS.Timeout | undefined; + + event = this.closeEmitter.event; + + handle(exitCode: number | void) { + this.exitCode = exitCode; + this.queueClose(); + } + + reset() { + if (this.closeTimeout) { + clearTimeout(this.closeTimeout); + this.queueClose(); + } + } + + private queueClose() { + this.closeTimeout = setTimeout(() => { + this.closeEmitter.fire(this.exitCode); + }, 250); + } +} + /** * Wraps a {@link nodePty node-pty} instance to handle spawning a `swift` process * and feeds the process state and output through event emitters. @@ -81,9 +109,7 @@ export class SwiftPtyProcess implements SwiftProcess { private readonly spawnEmitter: vscode.EventEmitter = new vscode.EventEmitter(); private readonly writeEmitter: vscode.EventEmitter = new vscode.EventEmitter(); private readonly errorEmitter: vscode.EventEmitter = new vscode.EventEmitter(); - private readonly closeEmitter: vscode.EventEmitter = new vscode.EventEmitter< - number | void - >(); + private readonly closeHandler: CloseHandler = new CloseHandler(); private spawnedProcess?: nodePty.IPty; @@ -110,19 +136,20 @@ export class SwiftPtyProcess implements SwiftProcess { this.spawnEmitter.fire(); this.spawnedProcess.onData(data => { this.writeEmitter.fire(data); + this.closeHandler.reset(); }); this.spawnedProcess.onExit(event => { if (event.signal) { - this.closeEmitter.fire(event.signal); + this.closeHandler.handle(event.signal); } else if (typeof event.exitCode === "number") { - this.closeEmitter.fire(event.exitCode); + this.closeHandler.handle(event.exitCode); } else { - this.closeEmitter.fire(); + this.closeHandler.handle(); } }); } catch (error) { this.errorEmitter.fire(new Error(`${error}`)); - this.closeEmitter.fire(); + this.closeHandler.handle(); } } @@ -152,7 +179,7 @@ export class SwiftPtyProcess implements SwiftProcess { onDidThrowError: vscode.Event = this.errorEmitter.event; - onDidClose: vscode.Event = this.closeEmitter.event; + onDidClose: vscode.Event = this.closeHandler.event; } /** @@ -169,9 +196,7 @@ export class ReadOnlySwiftProcess implements SwiftProcess { private readonly spawnEmitter: vscode.EventEmitter = new vscode.EventEmitter(); private readonly writeEmitter: vscode.EventEmitter = new vscode.EventEmitter(); private readonly errorEmitter: vscode.EventEmitter = new vscode.EventEmitter(); - private readonly closeEmitter: vscode.EventEmitter = new vscode.EventEmitter< - number | void - >(); + private readonly closeHandler: CloseHandler = new CloseHandler(); private spawnedProcess: child_process.ChildProcessWithoutNullStreams | undefined; @@ -191,24 +216,26 @@ export class ReadOnlySwiftProcess implements SwiftProcess { this.spawnedProcess.stdout.on("data", data => { this.writeEmitter.fire(data.toString()); + this.closeHandler.reset(); }); this.spawnedProcess.stderr.on("data", data => { this.writeEmitter.fire(data.toString()); + this.closeHandler.reset(); }); this.spawnedProcess.on("error", error => { this.errorEmitter.fire(new Error(`${error}`)); - this.closeEmitter.fire(); + this.closeHandler.handle(); }); this.spawnedProcess.once("exit", code => { - this.closeEmitter.fire(code ?? undefined); + this.closeHandler.handle(code ?? undefined); this.dispose(); }); } catch (error) { this.errorEmitter.fire(new Error(`${error}`)); - this.closeEmitter.fire(); + this.closeHandler.handle(); this.dispose(); } } @@ -241,5 +268,5 @@ export class ReadOnlySwiftProcess implements SwiftProcess { onDidThrowError: vscode.Event = this.errorEmitter.event; - onDidClose: vscode.Event = this.closeEmitter.event; + onDidClose: vscode.Event = this.closeHandler.event; } diff --git a/src/tasks/SwiftPseudoterminal.ts b/src/tasks/SwiftPseudoterminal.ts index d682af3fd..a83c3d32f 100644 --- a/src/tasks/SwiftPseudoterminal.ts +++ b/src/tasks/SwiftPseudoterminal.ts @@ -51,7 +51,7 @@ export class SwiftPseudoterminal implements vscode.Pseudoterminal, vscode.Dispos this.writeEmitter.fire(data.replace(/\n(\r)?/g, "\n\r")); }), this.swiftProcess.onDidThrowError(e => { - vscode.window.showErrorMessage( + void vscode.window.showErrorMessage( `Failed to run Swift command "${this.commandLine}":\n${e}` ); this.closeEmitter.fire(); diff --git a/src/toolchain/toolchain.ts b/src/toolchain/toolchain.ts index a2a412c4a..7eb9815f2 100644 --- a/src/toolchain/toolchain.ts +++ b/src/toolchain/toolchain.ts @@ -124,7 +124,7 @@ export class SwiftToolchain { const targetInfo = await this.getSwiftTargetInfo( this._getToolchainExecutable(toolchainPath, "swift") ); - const swiftVersion = await this.getSwiftVersion(targetInfo); + const swiftVersion = this.getSwiftVersion(targetInfo); const [runtimePath, defaultSDK] = await Promise.all([ this.getRuntimePath(targetInfo), this.getDefaultSDK(), @@ -579,7 +579,7 @@ export class SwiftToolchain { const { stdout } = await execFile("where", ["swift"]); const paths = stdout.trimEnd().split("\r\n"); if (paths.length > 1) { - vscode.window.showWarningMessage( + void vscode.window.showWarningMessage( `Found multiple swift executables in in %PATH%. Using excutable found at ${paths[0]}` ); } @@ -698,7 +698,7 @@ export class SwiftToolchain { } catch (err: unknown) { const error = err as ExecFileError; // Its possible the toolchain in .swift-version is misconfigured or doesn't exist. - vscode.window.showErrorMessage(`${error.stderr}`); + void vscode.window.showErrorMessage(`${error.stderr}`); } } } @@ -862,7 +862,7 @@ export class SwiftToolchain { if (fallbackPath) { return fallbackPath; } - vscode.window.showWarningMessage( + void vscode.window.showWarningMessage( `${type} not found due to non-standardized library layout. Tests explorer won't work as expected.` ); return undefined; @@ -872,7 +872,7 @@ export class SwiftToolchain { try { infoPlist = plist.parse(data) as unknown as InfoPlist; } catch (error) { - vscode.window.showWarningMessage(`Unable to parse ${platformManifest}: ${error}`); + void vscode.window.showWarningMessage(`Unable to parse ${platformManifest}: ${error}`); return undefined; } const plistKey = type === "XCTest" ? "XCTEST_VERSION" : "SWIFT_TESTING_VERSION"; diff --git a/src/ui/SwiftBuildStatus.ts b/src/ui/SwiftBuildStatus.ts index f0ae661a6..7e08f280c 100644 --- a/src/ui/SwiftBuildStatus.ts +++ b/src/ui/SwiftBuildStatus.ts @@ -90,7 +90,7 @@ export class SwiftBuildStatus implements vscode.Disposable { ); }); if (showBuildStatus === "progress" || showBuildStatus === "notification") { - vscode.window.withProgress( + void vscode.window.withProgress( { location: showBuildStatus === "progress" diff --git a/src/ui/ToolchainSelection.ts b/src/ui/ToolchainSelection.ts index 622f2042c..f3c4de911 100644 --- a/src/ui/ToolchainSelection.ts +++ b/src/ui/ToolchainSelection.ts @@ -179,7 +179,7 @@ async function getQuickPickItems( if (result.label === "swift-latest") { result.label = "Latest Installed Toolchain"; result.onDidSelect = async () => { - vscode.window.showInformationMessage( + void vscode.window.showInformationMessage( `The Swift extension is now configured to always use the most recently installed toolchain pointed at by the symbolic link "${toolchainPath}".` ); }; diff --git a/test/integration-tests/SwiftSnippet.test.ts b/test/integration-tests/SwiftSnippet.test.ts index 000ba341a..d9e628bae 100644 --- a/test/integration-tests/SwiftSnippet.test.ts +++ b/test/integration-tests/SwiftSnippet.test.ts @@ -103,7 +103,7 @@ suite("SwiftSnippet Test Suite @slow", function () { // Once bp is hit, continue await bpPromise; let succeeded = false; - succeededPromise.then(s => (succeeded = s)); + void succeededPromise.then(s => (succeeded = s)); while (!succeeded) { try { await continueSession(); diff --git a/test/integration-tests/commands/build.test.ts b/test/integration-tests/commands/build.test.ts index b9168b44d..00730d114 100644 --- a/test/integration-tests/commands/build.test.ts +++ b/test/integration-tests/commands/build.test.ts @@ -82,7 +82,7 @@ suite("Build Commands @slow", function () { await bpPromise; let succeeded = false; - resultPromise.then(s => (succeeded = s)); + void resultPromise.then(s => (succeeded = s)); while (!succeeded) { await continueSession(); await new Promise(r => setTimeout(r, 500)); diff --git a/test/integration-tests/commands/dependency.test.ts b/test/integration-tests/commands/dependency.test.ts index 98f5883de..899024e6f 100644 --- a/test/integration-tests/commands/dependency.test.ts +++ b/test/integration-tests/commands/dependency.test.ts @@ -28,27 +28,24 @@ suite("Dependency Commmands Test Suite", function () { // 3 minutes for each test should be more than enough this.timeout(3 * 60 * 1000); - let defaultContext: FolderContext; let depsContext: FolderContext; let workspaceContext: WorkspaceContext; activateExtensionForSuite({ async setup(ctx) { workspaceContext = ctx; - defaultContext = await folderInRootWorkspace("defaultPackage", workspaceContext); depsContext = await folderInRootWorkspace("dependencies", workspaceContext); await waitForNoRunningTasks(); + await workspaceContext.focusFolder(depsContext); }, }); test("Swift: Update Package Dependencies", async function () { - await workspaceContext.focusFolder(defaultContext); const result = await vscode.commands.executeCommand(Commands.UPDATE_DEPENDENCIES); expect(result).to.be.true; }); test("Swift: Resolve Package Dependencies", async function () { - await workspaceContext.focusFolder(defaultContext); const result = await vscode.commands.executeCommand(Commands.RESOLVE_DEPENDENCIES); expect(result).to.be.true; }); diff --git a/test/integration-tests/commands/runTestMultipleTimes.test.ts b/test/integration-tests/commands/runTestMultipleTimes.test.ts index 96eabce10..2473d0d94 100644 --- a/test/integration-tests/commands/runTestMultipleTimes.test.ts +++ b/test/integration-tests/commands/runTestMultipleTimes.test.ts @@ -15,14 +15,11 @@ import * as vscode from "vscode"; import { expect } from "chai"; import { runTestMultipleTimes } from "../../../src/commands/testMultipleTimes"; -import { mockGlobalObject } from "../../MockUtils"; import { FolderContext } from "../../../src/FolderContext"; import { TestRunProxy } from "../../../src/TestExplorer/TestRunner"; import { activateExtensionForSuite, folderInRootWorkspace } from "../utilities/testutilities"; suite("Test Multiple Times Command Test Suite", () => { - const windowMock = mockGlobalObject(vscode, "window"); - let folderContext: FolderContext; let testItem: vscode.TestItem; @@ -42,15 +39,12 @@ suite("Test Multiple Times Command Test Suite", () => { }); test("Runs successfully after testing 0 times", async () => { - windowMock.showInputBox.resolves("0"); - const runState = await runTestMultipleTimes(folderContext, testItem, false); + const runState = await runTestMultipleTimes(folderContext, testItem, false, 0); expect(runState).to.be.an("array").that.is.empty; }); test("Runs successfully after testing 3 times", async () => { - windowMock.showInputBox.resolves("3"); - - const runState = await runTestMultipleTimes(folderContext, testItem, false, () => + const runState = await runTestMultipleTimes(folderContext, testItem, false, 3, () => Promise.resolve(TestRunProxy.initialTestRunState()) ); @@ -62,14 +56,12 @@ suite("Test Multiple Times Command Test Suite", () => { }); test("Stops after a failure on the 2nd iteration ", async () => { - windowMock.showInputBox.resolves("3"); - const failure = { ...TestRunProxy.initialTestRunState(), failed: [{ test: testItem, message: new vscode.TestMessage("oh no") }], }; let ctr = 0; - const runState = await runTestMultipleTimes(folderContext, testItem, true, () => { + const runState = await runTestMultipleTimes(folderContext, testItem, true, 3, () => { ctr += 1; if (ctr === 2) { return Promise.resolve(failure); diff --git a/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts b/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts index e50e2d760..7b5833a14 100644 --- a/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts +++ b/test/integration-tests/testexplorer/TestExplorerIntegration.test.ts @@ -35,7 +35,6 @@ import { MessageRenderer, TestSymbol, } from "../../../src/TestExplorer/TestParsers/SwiftTestingOutputParser"; -import { mockGlobalObject } from "../../MockUtils"; import { flattenTestItemCollection, reduceTestItemChildren, @@ -119,7 +118,7 @@ suite("Test Explorer Suite", function () { } resetSettings = await updateSettings({ - "swift.debugger.useDebugAdapterFromToolchain": true, + "swift.debugger.debugAdapter": "lldb-dap", }); }); @@ -424,7 +423,6 @@ suite("Test Explorer Suite", function () { suite("Runs multiple", function () { const numIterations = 5; - const windowMock = mockGlobalObject(vscode, "window"); this.timeout(1000 * 60 * MAX_TEST_RUN_TIME_MINUTES * 5); @@ -434,18 +432,18 @@ suite("Test Explorer Suite", function () { "PackageTests.MixedXCTestSuite/testPassing" ); - await testExplorer.folderContext.workspaceContext.focusFolder( - testExplorer.folderContext - ); - - // Stub the showInputBox method to return the input text - windowMock.showInputBox.resolves(`${numIterations}`); + await workspaceContext.focusFolder(null); + await workspaceContext.focusFolder(testExplorer.folderContext); - vscode.commands.executeCommand(Commands.RUN_TESTS_MULTIPLE_TIMES, testItems[0]); + const testRunPromise = eventPromise(testExplorer.onCreateTestRun); - const testRun = await eventPromise(testExplorer.onCreateTestRun); + await vscode.commands.executeCommand( + Commands.RUN_TESTS_MULTIPLE_TIMES, + testItems[0], + numIterations + ); - await eventPromise(testRun.onTestRunComplete); + const testRun = await testRunPromise; assertTestResults(testRun, { passed: [ @@ -507,7 +505,7 @@ suite("Test Explorer Suite", function () { const testRunPromise = eventPromise(testExplorer.onCreateTestRun); // Deliberately don't await this so we can cancel it. - targetProfile.runHandler(request, tokenSource.token); + void targetProfile.runHandler(request, tokenSource.token); const testRun = await testRunPromise; @@ -558,7 +556,6 @@ suite("Test Explorer Suite", function () { suite("Runs multiple", function () { const numIterations = 5; - const windowMock = mockGlobalObject(vscode, "window"); this.timeout(1000 * 60 * MAX_TEST_RUN_TIME_MINUTES * 5); @@ -568,18 +565,18 @@ suite("Test Explorer Suite", function () { "PackageTests.PassingXCTestSuite/testPassing" ); - await testExplorer.folderContext.workspaceContext.focusFolder( - testExplorer.folderContext - ); - - // Stub the showInputBox method to return the input text - windowMock.showInputBox.resolves(`${numIterations}`); + await workspaceContext.focusFolder(null); + await workspaceContext.focusFolder(testExplorer.folderContext); - vscode.commands.executeCommand(Commands.RUN_TESTS_MULTIPLE_TIMES, testItems[0]); + const testRunPromise = eventPromise(testExplorer.onCreateTestRun); - const testRun = await eventPromise(testExplorer.onCreateTestRun); + await vscode.commands.executeCommand( + Commands.RUN_TESTS_MULTIPLE_TIMES, + testItems[0], + numIterations + ); - await eventPromise(testRun.onTestRunComplete); + const testRun = await testRunPromise; assertTestResults(testRun, { passed: [ diff --git a/test/integration-tests/utilities/testutilities.ts b/test/integration-tests/utilities/testutilities.ts index 8f86e97ef..b5c321eaf 100644 --- a/test/integration-tests/utilities/testutilities.ts +++ b/test/integration-tests/utilities/testutilities.ts @@ -191,6 +191,13 @@ const extensionBootstrapper = (() => { // `vscode.extensions.getExtension("swiftlang.swift-vscode")` once. // Subsequent activations must be done through the returned API object. if (!activator) { + for (const depId of ["vadimcn.vscode-lldb", "llvm-vs-code-extensions.lldb-dap"]) { + const dep = vscode.extensions.getExtension(depId); + if (!dep) { + throw new Error(`Unable to find extension "${depId}"`); + } + await dep.activate(); + } activatedAPI = await ext.activate(); // Save the test name so if the test doesn't clean up by deactivating properly the next // test that tries to activate can throw an error with the name of the test that needs to clean up. diff --git a/test/integration-tests/commands/NewFile.test.ts b/test/unit-tests/commands/newSwiftFile.test.ts similarity index 97% rename from test/integration-tests/commands/NewFile.test.ts rename to test/unit-tests/commands/newSwiftFile.test.ts index 02e2f3efc..9760173e9 100644 --- a/test/integration-tests/commands/NewFile.test.ts +++ b/test/unit-tests/commands/newSwiftFile.test.ts @@ -21,7 +21,7 @@ import { mockGlobalObject } from "../../MockUtils"; import { TemporaryFolder } from "../../../src/utilities/tempFolder"; import { fileExists } from "../../../src/utilities/filesystem"; -suite("NewFile Command Test Suite", () => { +suite("newSwiftFile Command Test Suite", () => { const workspaceMock = mockGlobalObject(vscode, "workspace"); const windowMock = mockGlobalObject(vscode, "window"); const languagesMock = mockGlobalObject(vscode, "languages"); diff --git a/test/integration-tests/commands/openPackage.test.ts b/test/unit-tests/commands/openPackage.test.ts similarity index 92% rename from test/integration-tests/commands/openPackage.test.ts rename to test/unit-tests/commands/openPackage.test.ts index c700c7f5e..bc16f3710 100644 --- a/test/integration-tests/commands/openPackage.test.ts +++ b/test/unit-tests/commands/openPackage.test.ts @@ -22,8 +22,7 @@ import { openPackage } from "../../../src/commands/openPackage"; import { Version } from "../../../src/utilities/version"; import * as fs from "../../../src/utilities/filesystem"; -suite("OpenPackage Command Test Suite", () => { - const workspaceMock = mockGlobalObject(vscode, "workspace"); +suite("openPackage Command Test Suite", () => { const windowMock = mockGlobalObject(vscode, "window"); const filesystemMock = mockGlobalModule(fs); @@ -36,10 +35,9 @@ suite("OpenPackage Command Test Suite", () => { windowMock.showTextDocument.resolves(); await openPackage(version, vscode.Uri.file(basePath)); - expect(workspaceMock.openTextDocument).to.have.been.calledOnceWith( + expect(windowMock.showTextDocument).to.have.been.calledOnceWith( match.has("fsPath", expectedPath) ); - expect(windowMock.showTextDocument).to.have.been.calledOnce; } test("Opens nothing when there is no package.swift", async () => { diff --git a/test/integration-tests/commands/runPluginTask.test.ts b/test/unit-tests/commands/runPluginTask.test.ts similarity index 57% rename from test/integration-tests/commands/runPluginTask.test.ts rename to test/unit-tests/commands/runPluginTask.test.ts index d53f7e615..1f16c98cb 100644 --- a/test/integration-tests/commands/runPluginTask.test.ts +++ b/test/unit-tests/commands/runPluginTask.test.ts @@ -15,28 +15,18 @@ import * as vscode from "vscode"; import { mockGlobalObject } from "../../MockUtils"; import { expect } from "chai"; -import { activateExtensionForSuite, folderInRootWorkspace } from "../utilities/testutilities"; -import { Commands } from "../../../src/commands"; -import { SwiftOutputChannel } from "../../../src/ui/SwiftOutputChannel"; +import { match } from "sinon"; +import { runPluginTask } from "../../../src/commands/runPluginTask"; suite("runPluginTask Test Suite", () => { - const executeCommand = vscode.commands.executeCommand; const commandsMock = mockGlobalObject(vscode, "commands"); - activateExtensionForSuite({ - async setup(ctx) { - const folder = await folderInRootWorkspace("command-plugin", ctx); - const outputChannel = new SwiftOutputChannel("runPluginTask.tests"); - await folder.loadSwiftPlugins(outputChannel); - }, - }); - test("Executes runTask command", async () => { - await executeCommand(Commands.RUN_PLUGIN_TASK); + await runPluginTask(); expect(commandsMock.executeCommand).to.have.been.calledOnceWith( "workbench.action.tasks.runTask", - { type: "swift-plugin" } + match({ type: "swift-plugin" }) ); }); });