Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve tests for "swift" tasks #1092

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@
"testConfiguration": "${workspaceFolder}/.vscode-test.js",
"testConfigurationLabel": "integrationTests",
"args": [
"--profile=testing-debug",
"${workspaceFolder}/assets/test"
"--profile=testing-debug"
],
"outFiles": [
"${workspaceFolder}/out/**/*.js",
Expand Down
14 changes: 14 additions & 0 deletions assets/test/.vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,20 @@
"group": "build",
"label": "swift: Build All (defaultPackage)",
"detail": "swift build --build-tests --verbose"
},
{
"type": "swift",
"args": [
"build",
"--build-tests"
],
"cwd": "defaultPackage",
"problemMatcher": [
"$swiftc"
],
"group": "build",
"label": "swift: Build All from tasks.json",
"detail": "swift build --build-tests"
}
]
}
2 changes: 1 addition & 1 deletion src/FolderContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ export class FolderContext implements vscode.Disposable {
/** Load Swift Plugins and store in Package */
async loadSwiftPlugins() {
const plugins = await SwiftPackage.loadPlugins(
this.workspaceFolder.uri,
this.folder,
this.workspaceContext.toolchain
);
this.swiftPackage.plugins = plugins;
Expand Down
5 changes: 3 additions & 2 deletions src/tasks/SwiftPluginTaskProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import configuration from "../configuration";
import { swiftRuntimeEnv } from "../utilities/utilities";
import { SwiftExecution } from "../tasks/SwiftExecution";
import { resolveTaskCwd } from "../utilities/tasks";
import { SwiftTask } from "./SwiftTaskProvider";

// Interface class for defining task configuration
interface TaskConfig {
Expand Down Expand Up @@ -113,7 +114,7 @@ export class SwiftPluginTaskProvider implements vscode.TaskProvider {
* @param config
* @returns
*/
createSwiftPluginTask(plugin: PackagePlugin, config: TaskConfig): vscode.Task {
createSwiftPluginTask(plugin: PackagePlugin, config: TaskConfig): SwiftTask {
const swift = this.workspaceContext.toolchain.getToolchainExecutable("swift");

// Add relative path current working directory
Expand Down Expand Up @@ -155,7 +156,7 @@ export class SwiftPluginTaskProvider implements vscode.TaskProvider {
}
task.detail = `${prefix}swift ${swiftArgs.join(" ")}`;
task.presentationOptions = presentation;
return task;
return task as SwiftTask;
}

/**
Expand Down
22 changes: 10 additions & 12 deletions src/tasks/SwiftTaskProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,14 @@ const buildAllTaskCache = (() => {
};
})();

function buildAllTaskName(release: boolean): string {
return release ? `${SwiftTaskProvider.buildAllName} - Release` : SwiftTaskProvider.buildAllName;
function buildAllTaskName(folderContext: FolderContext, release: boolean): string {
let buildTaskName = release
? `${SwiftTaskProvider.buildAllName} - Release`
: SwiftTaskProvider.buildAllName;
if (folderContext.relativePath.length > 0) {
buildTaskName += ` (${folderContext.relativePath})`;
}
return buildTaskName;
}

/**
Expand All @@ -128,11 +134,7 @@ export function createBuildAllTask(
release: boolean = false
): SwiftTask {
const args = BuildConfigurationFactory.buildAll(folderContext, false, release).args;
let buildTaskName = buildAllTaskName(release);

if (folderContext.relativePath.length > 0) {
buildTaskName += ` (${folderContext.relativePath})`;
}
const buildTaskName = buildAllTaskName(folderContext, release);

// Create one Build All task per folder context, since this can be called multiple
// times and we want the same instance each time. Otherwise, VS Code may try and execute
Expand Down Expand Up @@ -170,11 +172,7 @@ export async function getBuildAllTask(
folderContext: FolderContext,
release: boolean = false
): Promise<vscode.Task> {
let buildTaskName = buildAllTaskName(release);
if (folderContext.relativePath.length > 0) {
buildTaskName += ` (${folderContext.relativePath})`;
}

const buildTaskName = buildAllTaskName(folderContext, release);
const folderWorkingDir = folderContext.workspaceFolder.uri.fsPath;
// search for build all task in task.json first, that are valid for folder
const workspaceTasks = (await vscode.tasks.fetchTasks()).filter(task => {
Expand Down
4 changes: 2 additions & 2 deletions src/ui/StatusItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import * as path from "path";
export class RunningTask {
constructor(public task: vscode.Task | string) {}
get name(): string {
if (this.task instanceof vscode.Task) {
if (typeof this.task !== "string") {
const folder = this.task.definition.cwd as string;
if (folder) {
return `${this.task.name} (${path.basename(folder)})`;
Expand Down Expand Up @@ -115,7 +115,7 @@ export class StatusItem {
*/
private showTask(task: RunningTask, message?: string) {
message = message ?? task.name;
if (task.task instanceof vscode.Task) {
if (typeof task.task !== "string") {
this.show(`$(sync~spin) ${message}`, message, "workbench.action.tasks.showTasks");
} else {
this.show(`$(sync~spin) ${message}`, message);
Expand Down
146 changes: 93 additions & 53 deletions test/suite/tasks/SwiftTaskProvider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,40 +15,45 @@
import * as vscode from "vscode";
import * as assert from "assert";
import { WorkspaceContext } from "../../../src/WorkspaceContext";
import { globalWorkspaceContextPromise } from "../extension.test";
import { SwiftTaskProvider, createSwiftTask } from "../../../src/tasks/SwiftTaskProvider";
import { folderContextPromise, globalWorkspaceContextPromise } from "../extension.test";
import {
SwiftTaskProvider,
createSwiftTask,
createBuildAllTask,
getBuildAllTask,
} from "../../../src/tasks/SwiftTaskProvider";
import { SwiftToolchain } from "../../../src/toolchain/toolchain";
import { SwiftExecution } from "../../../src/tasks/SwiftExecution";
import { executeTaskAndWaitForResult, waitForNoRunningTasks } from "../../utilities";
import {
executeTaskAndWaitForResult,
waitForEndTaskProcess,
waitForNoRunningTasks,
} from "../../utilities";
import { Version } from "../../../src/utilities/version";
import { FolderContext } from "../../../src/FolderContext";
import { mockNamespace } from "../../unit-tests/MockUtils";
import { anything, when } from "ts-mockito";

suite("SwiftTaskProvider Test Suite", () => {
let workspaceContext: WorkspaceContext;
let toolchain: SwiftToolchain;
let workspaceFolder: vscode.WorkspaceFolder;
let folderContext: FolderContext;

suiteSetup(async () => {
workspaceContext = await globalWorkspaceContextPromise;
toolchain = await SwiftToolchain.create();
toolchain = workspaceContext.toolchain;
assert.notEqual(workspaceContext.folders.length, 0);
workspaceFolder = workspaceContext.folders[0].workspaceFolder;

// Make sure have another folder
folderContext = await folderContextPromise("diagnostics");
});

suite("createSwiftTask", () => {
setup(async () => {
await waitForNoRunningTasks();
});

test("uses SwiftExecution", async () => {
const task = createSwiftTask(
["--help"],
"help",
{ cwd: workspaceFolder.uri, scope: vscode.TaskScope.Workspace },
toolchain
);
assert.equal(task.execution instanceof SwiftExecution, true);
});

test("Exit code on success", async () => {
const task = createSwiftTask(
["--help"],
Expand Down Expand Up @@ -83,20 +88,53 @@ suite("SwiftTaskProvider Test Suite", () => {
});

suite("provideTasks", () => {
test("includes build all task", async () => {
const taskProvider = new SwiftTaskProvider(workspaceContext);
const tasks = await taskProvider.provideTasks(
new vscode.CancellationTokenSource().token
);
const task = tasks.find(t => t.name === "Build All (defaultPackage)");
assert.equal(task?.detail, "swift build --build-tests -Xswiftc -diagnostic-style=llvm");
suite("includes build all task from extension", () => {
let task: vscode.Task | undefined;

setup(async () => {
const tasks = await vscode.tasks.fetchTasks({ type: "swift" });
task = tasks.find(t => t.name === "Build All (defaultPackage)");
});

test("provided", async () => {
assert.equal(
task?.detail,
"swift build --build-tests -Xswiftc -diagnostic-style=llvm"
);
});

test("executes", async () => {
assert(task);
const exitPromise = waitForEndTaskProcess(task);
await vscode.tasks.executeTask(task);
const exitCode = await exitPromise;
assert.equal(exitCode, 0);
}).timeout(120000); // 2 minutes to build
});

suite("includes build all task from tasks.json", () => {
let task: vscode.Task | undefined;

setup(async () => {
const tasks = await vscode.tasks.fetchTasks({ type: "swift" });
task = tasks.find(t => t.name === "swift: Build All from tasks.json");
});

test("provided", async () => {
assert.equal(task?.detail, "swift build --build-tests");
});

test("executes", async () => {
assert(task);
const exitPromise = waitForEndTaskProcess(task);
await vscode.tasks.executeTask(task);
const exitCode = await exitPromise;
assert.equal(exitCode, 0);
}).timeout(120000); // 2 minutes to build
});

test("includes product debug task", async () => {
const taskProvider = new SwiftTaskProvider(workspaceContext);
const tasks = await taskProvider.provideTasks(
new vscode.CancellationTokenSource().token
);
const tasks = await vscode.tasks.fetchTasks({ type: "swift" });
const task = tasks.find(t => t.name === "Build Debug PackageExe (defaultPackage)");
assert.equal(
task?.detail,
Expand All @@ -115,37 +153,39 @@ suite("SwiftTaskProvider Test Suite", () => {
"swift build -c release --product PackageExe -Xswiftc -diagnostic-style=llvm"
);
});

test("includes additional folders", async () => {
const tasks = await vscode.tasks.fetchTasks({ type: "swift" });
const diagnosticTasks = tasks.filter(t => t.name.endsWith("(diagnostics)"));
assert.equal(diagnosticTasks.length, 3);
});
});

suite("resolveTask", () => {
test("uses SwiftExecution", async () => {
const taskProvider = new SwiftTaskProvider(workspaceContext);
const task = new vscode.Task(
{
type: "swift",
args: ["run", "PackageExe"],
env: { FOO: "bar" },
cwd: workspaceFolder.uri.fsPath,
},
workspaceFolder,
"run PackageExe",
"swift"
suite("createBuildAllTask", () => {
test("should return same task instance", async () => {
assert.strictEqual(
createBuildAllTask(folderContext),
createBuildAllTask(folderContext)
);
const resolvedTask = taskProvider.resolveTask(
task,
new vscode.CancellationTokenSource().token
);
assert.equal(resolvedTask.execution instanceof SwiftExecution, true);
const swiftExecution = resolvedTask.execution as SwiftExecution;
assert.equal(
swiftExecution.options.cwd,
workspaceFolder.uri.fsPath,
"Sets correct cwd"
});

test("different task returned for release mode", async () => {
assert.notEqual(
createBuildAllTask(folderContext),
createBuildAllTask(folderContext, true)
);
assert.equal(
swiftExecution.options.env?.FOO,
"bar",
"Sets provided environment variables"
});
});

suite("getBuildAllTask", () => {
const tasksMock = mockNamespace(vscode, "tasks");

test("creates build all task when it cannot find one", async () => {
when(tasksMock.fetchTasks()).thenReturn(Promise.resolve([]));
when(tasksMock.fetchTasks(anything())).thenReturn(Promise.resolve([]));
assert.strictEqual(
await getBuildAllTask(folderContext),
createBuildAllTask(folderContext)
);
});
});
Expand Down
Loading