From 2b59455f90c88493d7fd0a5633d9d8c89aca4e03 Mon Sep 17 00:00:00 2001 From: "Michael (SPG) Weng" Date: Tue, 29 Oct 2024 10:53:26 -0400 Subject: [PATCH] Add integration tests for build commands - Validate the workflow of user calling the Swift: Run Build/Clean Build/Debug Build commands. - Ensure Swift: Run Build will not get blocked by pre-set breakpoint. - Ensure Swift: Clean Build will result in a cleaned up .build folder. - Ensure Swift: Debug Build will stop on a breakpoint and resume. Issue: #1184 --- src/commands.ts | 12 ++- src/commands/build.ts | 8 +- src/debugger/launch.ts | 6 +- test/integration-tests/commands/build.test.ts | 78 +++++++++++++++++++ 4 files changed, 95 insertions(+), 9 deletions(-) create mode 100644 test/integration-tests/commands/build.test.ts diff --git a/src/commands.ts b/src/commands.ts index bd366549c..28e33560b 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -64,6 +64,12 @@ export function registerToolchainCommands( ]; } +export enum Commands { + RUN = "swift.run", + DEBUG = "swift.debug", + CLEAN_BUILD = "swift.cleanBuild", +} + /** * Registers this extension's commands in the given {@link vscode.ExtensionContext context}. */ @@ -74,9 +80,9 @@ export function register(ctx: WorkspaceContext): vscode.Disposable[] { resolveDependencies(ctx) ), vscode.commands.registerCommand("swift.updateDependencies", () => updateDependencies(ctx)), - vscode.commands.registerCommand("swift.run", () => runBuild(ctx)), - vscode.commands.registerCommand("swift.debug", () => debugBuild(ctx)), - vscode.commands.registerCommand("swift.cleanBuild", () => cleanBuild(ctx)), + vscode.commands.registerCommand(Commands.RUN, () => runBuild(ctx)), + vscode.commands.registerCommand(Commands.DEBUG, () => debugBuild(ctx)), + vscode.commands.registerCommand(Commands.CLEAN_BUILD, () => cleanBuild(ctx)), vscode.commands.registerCommand("swift.runTestsMultipleTimes", item => { if (ctx.currentFolder) { return runTestMultipleTimes(ctx.currentFolder, item, false); diff --git a/src/commands/build.ts b/src/commands/build.ts index 6a36b521c..b6decb5a1 100644 --- a/src/commands/build.ts +++ b/src/commands/build.ts @@ -23,14 +23,14 @@ import { FolderContext } from "../FolderContext"; * Executes a {@link vscode.Task task} to run swift target. */ export async function runBuild(ctx: WorkspaceContext) { - await debugBuildWithOptions(ctx, { noDebug: true }); + return await debugBuildWithOptions(ctx, { noDebug: true }); } /** * Executes a {@link vscode.Task task} to debug swift target. */ export async function debugBuild(ctx: WorkspaceContext) { - await debugBuildWithOptions(ctx, {}); + return await debugBuildWithOptions(ctx, {}); } /** @@ -41,7 +41,7 @@ export async function cleanBuild(ctx: WorkspaceContext) { if (!current) { return; } - await folderCleanBuild(current); + return await folderCleanBuild(current); } /** @@ -62,7 +62,7 @@ export async function folderCleanBuild(folderContext: FolderContext) { folderContext.workspaceContext.toolchain ); - await executeTaskWithUI(task, "Clean Build", folderContext); + return await executeTaskWithUI(task, "Clean Build", folderContext); } /** diff --git a/src/debugger/launch.ts b/src/debugger/launch.ts index cd15e4984..a210faced 100644 --- a/src/debugger/launch.ts +++ b/src/debugger/launch.ts @@ -175,15 +175,17 @@ export async function debugLaunchConfig( config: vscode.DebugConfiguration, options: vscode.DebugSessionOptions = {} ) { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { vscode.debug.startDebugging(workspaceFolder, config, options).then( started => { if (started) { const terminateSession = vscode.debug.onDidTerminateDebugSession(async () => { // dispose terminate debug handler terminateSession.dispose(); - resolve(); + resolve(true); }); + } else { + resolve(false); } }, reason => { diff --git a/test/integration-tests/commands/build.test.ts b/test/integration-tests/commands/build.test.ts new file mode 100644 index 000000000..9fc0ae98a --- /dev/null +++ b/test/integration-tests/commands/build.test.ts @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the VS Code Swift open source project +// +// Copyright (c) 2024 the VS Code Swift project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of VS Code Swift project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import * as vscode from "vscode"; +import * as fs from "fs"; +import * as path from "path"; +import { expect } from "chai"; +import { folderContextPromise, globalWorkspaceContextPromise } from "../extension.test"; +import { waitForNoRunningTasks } from "../../utilities"; +import { testAssetUri } from "../../fixtures"; +import { FolderContext } from "../../../src/FolderContext"; +import { WorkspaceContext } from "../../../src/WorkspaceContext"; +import { Commands } from "../../../src/commands"; +import { makeDebugConfigurations } from "../../../src/debugger/launch"; + +suite("Build Commands", function () { + let folderContext: FolderContext; + let workspaceContext: WorkspaceContext; + const uri = testAssetUri("defaultPackage/Sources/PackageExe/main.swift"); + const breakpoints = [ + new vscode.SourceBreakpoint(new vscode.Location(uri, new vscode.Position(2, 0))), + ]; + + suiteSetup(async function () { + workspaceContext = await globalWorkspaceContextPromise; + await waitForNoRunningTasks(); + folderContext = await folderContextPromise("defaultPackage"); + await workspaceContext.focusFolder(folderContext); + await vscode.window.showTextDocument(uri); + makeDebugConfigurations(folderContext, undefined, true); + }); + + suiteTeardown(async () => { + await vscode.commands.executeCommand("workbench.action.closeAllEditors"); + }); + + test("Swift: Run Build", async () => { + // A breakpoint will have not effect on the Run command. + vscode.debug.addBreakpoints(breakpoints); + + const result = await vscode.commands.executeCommand(Commands.RUN); + expect(result).to.be.true; + + vscode.debug.removeBreakpoints(breakpoints); + }); + + test("Swift: Clean Build", async () => { + const buildPath = path.join(folderContext.folder.fsPath, ".build"); + const beforeItemCount = fs.readdirSync(buildPath).length; + + const result = await vscode.commands.executeCommand(Commands.CLEAN_BUILD); + expect(result).to.be.true; + + const afterItemCount = fs.readdirSync(buildPath).length; + expect(afterItemCount).to.be.lessThan(beforeItemCount); + }); + + test("Swift: Debug Build", async () => { + vscode.debug.addBreakpoints(breakpoints); + + const result = vscode.commands.executeCommand(Commands.DEBUG); + expect(result).to.eventually.be.true; + + await vscode.commands.executeCommand("workbench.action.debug.continue"); + vscode.debug.removeBreakpoints(breakpoints); + }); +});