Skip to content

Commit f804a2f

Browse files
committed
Add tests for the Swift snippets workflows
* Created some common utilities for dealing with debug sessions * Add integration test for run command and debug variant, big difference being whether the breakpoint is hit or not Issue: #1125
1 parent 9464a2f commit f804a2f

12 files changed

+160
-27
lines changed

test/integration-tests/BackgroundCompilation.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import * as assert from "assert";
1616
import * as vscode from "vscode";
1717
import { WorkspaceContext } from "../../src/WorkspaceContext";
1818
import { testAssetUri } from "../fixtures";
19-
import { waitForNoRunningTasks } from "../utilities";
19+
import { waitForNoRunningTasks } from "../utilities/tasks";
2020
import { Workbench } from "../../src/utilities/commands";
2121
import { activateExtensionForTest, updateSettings } from "./utilities/testutilities";
2222

test/integration-tests/DiagnosticsManager.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import * as assert from "assert";
1616
import * as vscode from "vscode";
1717
import { SwiftToolchain } from "../../src/toolchain/toolchain";
18-
import { executeTaskAndWaitForResult, waitForNoRunningTasks } from "../utilities";
18+
import { executeTaskAndWaitForResult, waitForNoRunningTasks } from "../utilities/tasks";
1919
import { WorkspaceContext } from "../../src/WorkspaceContext";
2020
import { testAssetWorkspaceFolder, testSwiftTask } from "../fixtures";
2121
import { createBuildAllTask } from "../../src/tasks/SwiftTaskProvider";
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the VS Code Swift open source project
4+
//
5+
// Copyright (c) 2024 the VS Code Swift project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of VS Code Swift project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import * as vscode from "vscode";
16+
import { folderContextPromise } from "./extension.test";
17+
import { testAssetPath, testAssetUri } from "../fixtures";
18+
import { waitForNoRunningTasks } from "../utilities/tasks";
19+
import { expect } from "chai";
20+
import {
21+
continueSession,
22+
waitForDebugAdapterCommand,
23+
waitForDebugAdapterExit,
24+
waitUntilDebugSessionTerminates,
25+
} from "../utilities/debug";
26+
27+
suite("SwiftSnippet Test Suite", () => {
28+
const uri = testAssetUri("defaultPackage/Snippets/hello.swift");
29+
const breakpoints = [
30+
new vscode.SourceBreakpoint(new vscode.Location(uri, new vscode.Position(2, 0))),
31+
];
32+
33+
suiteSetup(async () => {
34+
await folderContextPromise("defaultPackage");
35+
await waitForNoRunningTasks();
36+
37+
// File needs to be open for command to be enabled
38+
const doc = await vscode.workspace.openTextDocument(uri.fsPath);
39+
await vscode.window.showTextDocument(doc);
40+
41+
// Set a breakpoint
42+
vscode.debug.addBreakpoints(breakpoints);
43+
});
44+
45+
suiteTeardown(async () => {
46+
await vscode.commands.executeCommand("workbench.action.closeAllEditors");
47+
vscode.debug.removeBreakpoints(breakpoints);
48+
});
49+
50+
test("Run `Swift: Run Swift Snippet` command for snippet file", async () => {
51+
const sessionPromise = waitUntilDebugSessionTerminates("Run hello");
52+
const exitPromise = waitForDebugAdapterExit("Run hello");
53+
54+
await vscode.commands.executeCommand("swift.runSnippet");
55+
56+
const exitCode = await exitPromise;
57+
expect(exitCode).to.equal(0);
58+
59+
const session = await sessionPromise;
60+
expect(session.configuration).to.have.property(
61+
"program",
62+
`${testAssetPath("defaultPackage")}/.build/debug/hello`
63+
);
64+
expect(session.configuration).to.have.property("noDebug", true);
65+
}).timeout(120000);
66+
67+
test("Run `Swift: Debug Swift Snippet` command for snippet file", async () => {
68+
const bpPromise = waitForDebugAdapterCommand("Run hello", "stackTrace");
69+
const sessionPromise = waitUntilDebugSessionTerminates("Run hello");
70+
const exitPromise = waitForDebugAdapterExit("Run hello");
71+
72+
vscode.commands.executeCommand("swift.debugSnippet");
73+
74+
// Once bp is hit, continue
75+
await bpPromise.then(() => continueSession());
76+
77+
const exitCode = await exitPromise;
78+
expect(exitCode).to.equal(0);
79+
80+
const session = await sessionPromise;
81+
expect(session.configuration).to.have.property(
82+
"program",
83+
`${testAssetPath("defaultPackage")}/.build/debug/hello`
84+
);
85+
expect(session.configuration).to.not.have.property("noDebug");
86+
}).timeout(120000);
87+
});

test/integration-tests/tasks/SwiftExecution.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import * as vscode from "vscode";
1616
import * as assert from "assert";
1717
import { testSwiftTask } from "../../fixtures";
1818
import { WorkspaceContext } from "../../../src/WorkspaceContext";
19-
import { executeTaskAndWaitForResult, waitForNoRunningTasks } from "../../utilities";
19+
import { executeTaskAndWaitForResult, waitForNoRunningTasks } from "../../utilities/tasks";
2020
import { SwiftToolchain } from "../../../src/toolchain/toolchain";
2121
import { activateExtensionForSuite } from "../utilities/testutilities";
2222

test/integration-tests/tasks/SwiftPluginTaskProvider.test.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,8 @@ import { WorkspaceContext } from "../../../src/WorkspaceContext";
1919
import { SwiftPluginTaskProvider } from "../../../src/tasks/SwiftPluginTaskProvider";
2020
import { FolderContext } from "../../../src/FolderContext";
2121
import { activateExtensionForSuite, folderInRootWorkspace } from "../utilities/testutilities";
22-
import {
23-
cleanOutput,
24-
executeTaskAndWaitForResult,
25-
mutable,
26-
waitForEndTaskProcess,
27-
} from "../../utilities";
22+
import { cleanOutput, executeTaskAndWaitForResult, waitForEndTaskProcess } from "../../utilities/tasks";
23+
import { mutable } from "../../utilities/types";
2824

2925
suite("SwiftPluginTaskProvider Test Suite", () => {
3026
let workspaceContext: WorkspaceContext;

test/integration-tests/tasks/SwiftPseudoterminal.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import * as assert from "assert";
1616
import * as vscode from "vscode";
1717
import { TestSwiftProcess } from "../../fixtures";
18-
import { waitForClose, waitForWrite } from "../../utilities";
18+
import { waitForClose, waitForWrite } from "../../utilities/tasks";
1919
import { SwiftPseudoterminal } from "../../../src/tasks/SwiftPseudoterminal";
2020

2121
suite("SwiftPseudoterminal Tests Suite", () => {

test/integration-tests/tasks/SwiftTaskProvider.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import {
2727
executeTaskAndWaitForResult,
2828
waitForEndTaskProcess,
2929
waitForNoRunningTasks,
30-
} from "../../utilities";
30+
} from "../../utilities/tasks";
3131
import { Version } from "../../../src/utilities/version";
3232
import { FolderContext } from "../../../src/FolderContext";
3333
import { mockGlobalObject } from "../../MockUtils";

test/integration-tests/tasks/TaskManager.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ import * as vscode from "vscode";
1616
import * as assert from "assert";
1717
import { TaskManager } from "../../../src/tasks/TaskManager";
1818
import { WorkspaceContext } from "../../../src/WorkspaceContext";
19-
import { waitForNoRunningTasks } from "../../utilities";
2019
import { activateExtensionForSuite } from "../utilities/testutilities";
20+
import { waitForNoRunningTasks } from "../../utilities/tasks";
2121

2222
suite("TaskManager Test Suite", () => {
2323
let workspaceContext: WorkspaceContext;

test/integration-tests/tasks/TaskQueue.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import * as assert from "assert";
1717
import { testAssetPath } from "../../fixtures";
1818
import { WorkspaceContext } from "../../../src/WorkspaceContext";
1919
import { SwiftExecOperation, TaskOperation, TaskQueue } from "../../../src/tasks/TaskQueue";
20-
import { waitForNoRunningTasks } from "../../utilities";
20+
import { waitForNoRunningTasks } from "../../utilities/tasks";
2121
import { activateExtensionForSuite } from "../utilities/testutilities";
2222

2323
suite("TaskQueue Test Suite", () => {

test/utilities/debug.ts

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,10 @@ export async function continueSession(): Promise<void> {
3131
export async function waitForDebugAdapterMessage(
3232
name: string,
3333
matches: (message: any) => boolean,
34-
workspaceContext: WorkspaceContext
3534
): Promise<any> {
3635
return await new Promise<any>(res => {
3736
const disposable = vscode.debug.registerDebugAdapterTrackerFactory(
38-
DebugAdapter.getLaunchConfigType(workspaceContext.toolchain.swiftVersion),
37+
"swift-lldb",
3938
{
4039
createDebugAdapterTracker: function (
4140
session: vscode.DebugSession
@@ -57,6 +56,22 @@ export async function waitForDebugAdapterMessage(
5756
});
5857
}
5958

59+
/**
60+
* Waits for a specific debug session to terminate.
61+
*
62+
* @param name The name of the debug session to wait for.
63+
* @returns the terminated DebugSession
64+
*/
65+
export async function waitUntilDebugSessionTerminates(name: string): Promise<vscode.DebugSession> {
66+
return await new Promise<vscode.DebugSession>(res =>
67+
vscode.debug.onDidTerminateDebugSession(e => {
68+
if (e.name === name) {
69+
res(e);
70+
}
71+
})
72+
);
73+
}
74+
6075
/**
6176
* Waits for a specific command to be sent by the debug adapter.
6277
*
@@ -65,14 +80,28 @@ export async function waitForDebugAdapterMessage(
6580
* @param workspaceContext The workspace context containing toolchain information.
6681
* @returns A promise that resolves with the matching command message.
6782
*/
68-
export async function waitForDebugAdapterCommand(
69-
name: string,
70-
command: string,
71-
workspaceContext: WorkspaceContext
72-
): Promise<any> {
73-
return await waitForDebugAdapterMessage(
74-
name,
75-
(m: any) => m.command === command,
76-
workspaceContext
77-
);
83+
export async function waitForDebugAdapterCommand(name: string, command: string): Promise<any> {
84+
return await waitForDebugAdapterMessage(name, (m: any) => m.command === command);
85+
}
86+
87+
/**
88+
* Waits for a specific event to be sent by the debug adapter.
89+
*
90+
* @param name The name of the debug session to wait for.
91+
* @param command The command to wait for.
92+
* @param workspaceContext The workspace context containing toolchain information.
93+
* @returns A promise that resolves with the matching command event.
94+
*/
95+
export async function waitForDebugAdapterEvent(name: string, event: string): Promise<any> {
96+
return await waitForDebugAdapterMessage(name, (m: any) => m.event === event);
97+
}
98+
99+
/**
100+
* Waits for a debug adapter for the specified DebugSession name to terminate.
101+
*
102+
* @param name The name of the debug session to wait for.
103+
* @returns exit code of the DAP
104+
*/
105+
export async function waitForDebugAdapterExit(name: string): Promise<number> {
106+
return await waitForDebugAdapterEvent(name, "exited").then(m => m.body.exitCode);
78107
}

0 commit comments

Comments
 (0)