Skip to content
Merged
5 changes: 5 additions & 0 deletions assets/test/defaultPackage/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ import PackageDescription

let package = Package(
name: "defaultPackage",
products: [
.library(
name: "PackageLib",
targets: ["PackageLib"]),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
Expand Down
5 changes: 5 additions & 0 deletions assets/test/defaultPackage/[email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ let package = Package(
platforms: [
.macOS(.v13)
],
products: [
.library(
name: "PackageLib",
targets: ["PackageLib"]),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
Expand Down
3 changes: 3 additions & 0 deletions assets/test/defaultPackage/Snippets/hello.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import PackageLib

print("hello \(a)")
13 changes: 13 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1311,6 +1311,7 @@
"@types/xml2js": "^0.4.14",
"@typescript-eslint/eslint-plugin": "^8.16.0",
"@typescript-eslint/parser": "^8.16.0",
"@vscode/debugprotocol": "^1.68.0",
"@vscode/test-cli": "^0.0.10",
"@vscode/test-electron": "^2.4.1",
"@vscode/vsce": "^2.32.0",
Expand Down
13 changes: 7 additions & 6 deletions src/SwiftSnippets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,22 @@ export function setSnippetContextKey(ctx: WorkspaceContext) {
* If current file is a Swift Snippet run it
* @param ctx Workspace Context
*/
export async function runSnippet(ctx: WorkspaceContext) {
await debugSnippetWithOptions(ctx, { noDebug: true });
export async function runSnippet(ctx: WorkspaceContext): Promise<boolean | undefined> {
return await debugSnippetWithOptions(ctx, { noDebug: true });
}

/**
* If current file is a Swift Snippet run it in the debugger
* @param ctx Workspace Context
*/
export async function debugSnippet(ctx: WorkspaceContext) {
await debugSnippetWithOptions(ctx, {});
export async function debugSnippet(ctx: WorkspaceContext): Promise<boolean | undefined> {
return await debugSnippetWithOptions(ctx, {});
}

export async function debugSnippetWithOptions(
ctx: WorkspaceContext,
options: vscode.DebugSessionOptions
) {
): Promise<boolean | undefined> {
const folderContext = ctx.currentFolder;
if (!ctx.currentDocument || !folderContext) {
return;
Expand All @@ -89,7 +89,7 @@ export async function debugSnippetWithOptions(

try {
// queue build task and when it is complete run executable in the debugger
await folderContext.taskQueue
return await folderContext.taskQueue
.queueOperation(new TaskOperation(snippetBuildTask))
.then(result => {
if (result === 0) {
Expand All @@ -106,5 +106,6 @@ export async function debugSnippetWithOptions(
});
} catch {
// ignore error if task failed to run
return;
}
}
2 changes: 1 addition & 1 deletion test/integration-tests/BackgroundCompilation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import * as assert from "assert";
import * as vscode from "vscode";
import { WorkspaceContext } from "../../src/WorkspaceContext";
import { testAssetUri } from "../fixtures";
import { waitForNoRunningTasks } from "../utilities";
import { waitForNoRunningTasks } from "../utilities/tasks";
import { Workbench } from "../../src/utilities/commands";
import { activateExtensionForTest, updateSettings } from "./utilities/testutilities";

Expand Down
2 changes: 1 addition & 1 deletion test/integration-tests/DiagnosticsManager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import * as assert from "assert";
import * as vscode from "vscode";
import { SwiftToolchain } from "../../src/toolchain/toolchain";
import { executeTaskAndWaitForResult, waitForNoRunningTasks } from "../utilities";
import { executeTaskAndWaitForResult, waitForNoRunningTasks } from "../utilities/tasks";
import { WorkspaceContext } from "../../src/WorkspaceContext";
import { testAssetWorkspaceFolder, testSwiftTask } from "../fixtures";
import { createBuildAllTask } from "../../src/tasks/SwiftTaskProvider";
Expand Down
102 changes: 102 additions & 0 deletions test/integration-tests/SwiftSnippet.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
//===----------------------------------------------------------------------===//
//
// 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 { testAssetPath, testAssetUri } from "../fixtures";
import { waitForNoRunningTasks } from "../utilities/tasks";
import { expect } from "chai";
import {
continueSession,
waitForDebugAdapterRequest,
waitUntilDebugSessionTerminates,
} from "../utilities/debug";
import { Version } from "../../src/utilities/version";
import { activateExtensionForSuite, folderInRootWorkspace } from "./utilities/testutilities";
import { WorkspaceContext } from "../../src/WorkspaceContext";
import { join } from "path";
import { closeAllEditors } from "../utilities/commands";

function normalizePath(...segments: string[]): string {
let path = join(...segments);
if (process.platform === "win32") {
path = path.endsWith(".exe") ? path : path + ".exe";
path = path.replace(/\//g, "\\");
}
return path.toLocaleLowerCase(); // Windows may use d:\ or D:\
}

suite("SwiftSnippet Test Suite @slow", function () {
this.timeout(120000);

const uri = testAssetUri("defaultPackage/Snippets/hello.swift");
const breakpoints = [
new vscode.SourceBreakpoint(new vscode.Location(uri, new vscode.Position(2, 0))),
];
let workspaceContext: WorkspaceContext;

activateExtensionForSuite({
async setup(ctx) {
workspaceContext = ctx;

const folder = await folderInRootWorkspace("defaultPackage", workspaceContext);
if (folder.workspaceContext.toolchain.swiftVersion.isLessThan(new Version(6, 0, 0))) {
this.skip();
}
await waitForNoRunningTasks();

// File needs to be open for command to be enabled
const doc = await vscode.workspace.openTextDocument(uri.fsPath);
await vscode.window.showTextDocument(doc);

// Set a breakpoint
vscode.debug.addBreakpoints(breakpoints);
},
});

suiteTeardown(async () => {
closeAllEditors();
vscode.debug.removeBreakpoints(breakpoints);
});

test("Run `Swift: Run Swift Snippet` command for snippet file", async () => {
const sessionPromise = waitUntilDebugSessionTerminates("Run hello");

const succeeded = await vscode.commands.executeCommand("swift.runSnippet");

expect(succeeded).to.be.true;
const session = await sessionPromise;
expect(normalizePath(session.configuration.program)).to.equal(
normalizePath(testAssetPath("defaultPackage"), ".build", "debug", "hello")
);
expect(session.configuration).to.have.property("noDebug", true);
});

test("Run `Swift: Debug Swift Snippet` command for snippet file", async () => {
const bpPromise = waitForDebugAdapterRequest("Run hello", "stackTrace");
const sessionPromise = waitUntilDebugSessionTerminates("Run hello");

const succeeded = vscode.commands.executeCommand("swift.debugSnippet");

// Once bp is hit, continue
await bpPromise.then(() => continueSession());

await expect(succeeded).to.eventually.be.true;

const session = await sessionPromise;
expect(normalizePath(session.configuration.program)).to.equal(
normalizePath(testAssetPath("defaultPackage"), ".build", "debug", "hello")
);
expect(session.configuration).to.not.have.property("noDebug");
});
});
9 changes: 4 additions & 5 deletions test/integration-tests/commands/build.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ import * as vscode from "vscode";
import * as fs from "fs/promises";
import * as path from "path";
import { expect } from "chai";
import { waitForNoRunningTasks } from "../../utilities";
import { waitForNoRunningTasks } from "../../utilities/tasks";
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";
import { Workbench } from "../../../src/utilities/commands";
import { continueSession, waitForDebugAdapterCommand } from "../../utilities/debug";
import { continueSession, waitForDebugAdapterRequest } from "../../utilities/debug";
import {
activateExtensionForSuite,
folderInRootWorkspace,
Expand Down Expand Up @@ -97,10 +97,9 @@ suite("Build Commands", function () {
// Promise used to indicate we hit the break point.
// NB: "stopped" is the exact command when debuggee has stopped due to break point,
// but "stackTrace" is the deterministic sync point we will use to make sure we can execute continue
const bpPromise = waitForDebugAdapterCommand(
const bpPromise = waitForDebugAdapterRequest(
"Debug PackageExe (defaultPackage)",
"stackTrace",
workspaceContext
"stackTrace"
);

const result = vscode.commands.executeCommand(Commands.DEBUG);
Expand Down
2 changes: 1 addition & 1 deletion test/integration-tests/commands/dependency.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
PackageDependenciesProvider,
PackageNode,
} from "../../../src/ui/PackageDependencyProvider";
import { executeTaskAndWaitForResult, waitForNoRunningTasks } from "../../utilities";
import { executeTaskAndWaitForResult, waitForNoRunningTasks } from "../../utilities/tasks";
import { getBuildAllTask, SwiftTask } from "../../../src/tasks/SwiftTaskProvider";
import { testAssetUri } from "../../fixtures";
import { FolderContext } from "../../../src/FolderContext";
Expand Down
2 changes: 1 addition & 1 deletion test/integration-tests/language/macro.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { LanguageClientManager } from "../../../src/sourcekit-lsp/LanguageClient
import { WorkspaceContext } from "../../../src/WorkspaceContext";
import { testAssetUri } from "../../fixtures";
import { FolderContext } from "../../../src/FolderContext";
import { executeTaskAndWaitForResult, waitForNoRunningTasks } from "../../utilities";
import { executeTaskAndWaitForResult, waitForNoRunningTasks } from "../../utilities/tasks";
import { getBuildAllTask, SwiftTask } from "../../../src/tasks/SwiftTaskProvider";
import { Version } from "../../../src/utilities/version";
import { activateExtensionForSuite, folderInRootWorkspace } from "../utilities/testutilities";
Expand Down
2 changes: 1 addition & 1 deletion test/integration-tests/tasks/SwiftExecution.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import * as vscode from "vscode";
import * as assert from "assert";
import { testSwiftTask } from "../../fixtures";
import { WorkspaceContext } from "../../../src/WorkspaceContext";
import { executeTaskAndWaitForResult, waitForNoRunningTasks } from "../../utilities";
import { executeTaskAndWaitForResult, waitForNoRunningTasks } from "../../utilities/tasks";
import { SwiftToolchain } from "../../../src/toolchain/toolchain";
import { activateExtensionForSuite } from "../utilities/testutilities";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ import { activateExtensionForSuite, folderInRootWorkspace } from "../utilities/t
import {
cleanOutput,
executeTaskAndWaitForResult,
mutable,
waitForEndTaskProcess,
} from "../../utilities";
} from "../../utilities/tasks";
import { mutable } from "../../utilities/types";

suite("SwiftPluginTaskProvider Test Suite", () => {
let workspaceContext: WorkspaceContext;
Expand Down
2 changes: 1 addition & 1 deletion test/integration-tests/tasks/SwiftPseudoterminal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import * as assert from "assert";
import * as vscode from "vscode";
import { TestSwiftProcess } from "../../fixtures";
import { waitForClose, waitForWrite } from "../../utilities";
import { waitForClose, waitForWrite } from "../../utilities/tasks";
import { SwiftPseudoterminal } from "../../../src/tasks/SwiftPseudoterminal";

suite("SwiftPseudoterminal Tests Suite", () => {
Expand Down
2 changes: 1 addition & 1 deletion test/integration-tests/tasks/SwiftTaskProvider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
executeTaskAndWaitForResult,
waitForEndTaskProcess,
waitForNoRunningTasks,
} from "../../utilities";
} from "../../utilities/tasks";
import { Version } from "../../../src/utilities/version";
import { FolderContext } from "../../../src/FolderContext";
import { mockGlobalObject } from "../../MockUtils";
Expand Down
2 changes: 1 addition & 1 deletion test/integration-tests/tasks/TaskManager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import * as vscode from "vscode";
import * as assert from "assert";
import { TaskManager } from "../../../src/tasks/TaskManager";
import { WorkspaceContext } from "../../../src/WorkspaceContext";
import { waitForNoRunningTasks } from "../../utilities";
import { activateExtensionForSuite } from "../utilities/testutilities";
import { waitForNoRunningTasks } from "../../utilities/tasks";

suite("TaskManager Test Suite", () => {
let workspaceContext: WorkspaceContext;
Expand Down
2 changes: 1 addition & 1 deletion test/integration-tests/tasks/TaskQueue.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import * as assert from "assert";
import { testAssetPath } from "../../fixtures";
import { WorkspaceContext } from "../../../src/WorkspaceContext";
import { SwiftExecOperation, TaskOperation, TaskQueue } from "../../../src/tasks/TaskQueue";
import { waitForNoRunningTasks } from "../../utilities";
import { waitForNoRunningTasks } from "../../utilities/tasks";
import { activateExtensionForSuite } from "../utilities/testutilities";

suite("TaskQueue Test Suite", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
PackageDependenciesProvider,
PackageNode,
} from "../../../src/ui/PackageDependencyProvider";
import { executeTaskAndWaitForResult, waitForNoRunningTasks } from "../../utilities";
import { executeTaskAndWaitForResult, waitForNoRunningTasks } from "../../utilities/tasks";
import { getBuildAllTask, SwiftTask } from "../../../src/tasks/SwiftTaskProvider";
import { testAssetPath } from "../../fixtures";
import { activateExtensionForSuite, folderInRootWorkspace } from "../utilities/testutilities";
Expand Down
5 changes: 3 additions & 2 deletions test/integration-tests/utilities/testutilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ import { Api } from "../../../src/extension";
import { testAssetUri } from "../../fixtures";
import { WorkspaceContext } from "../../../src/WorkspaceContext";
import { FolderContext } from "../../../src/FolderContext";
import { waitForNoRunningTasks } from "../../utilities";
import { waitForNoRunningTasks } from "../../utilities/tasks";
import { closeAllEditors } from "../../utilities/commands";

function getRootWorkspaceFolder(): vscode.WorkspaceFolder {
const result = vscode.workspace.workspaceFolders?.at(0);
Expand Down Expand Up @@ -175,7 +176,7 @@ const extensionBootstrapper = (() => {
await waitForNoRunningTasks({ timeout: 10000 });

// Close all editors before deactivating the extension.
await vscode.commands.executeCommand("workbench.action.closeAllEditors");
closeAllEditors();

await activatedAPI.workspaceContext?.removeWorkspaceFolder(getRootWorkspaceFolder());
await activatedAPI.deactivate();
Expand Down
20 changes: 20 additions & 0 deletions test/utilities/commands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===----------------------------------------------------------------------===//
//
// 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 { Workbench } from "../../src/utilities/commands";

export async function closeAllEditors() {
await vscode.commands.executeCommand(Workbench.ACTION_CLOSEALLEDITORS);
}
Loading
Loading