From fa56bbfa2fff7bd13d0dd40ed4d9ac6137f1af9e Mon Sep 17 00:00:00 2001 From: Paul LeMarquand Date: Tue, 4 Mar 2025 13:53:13 -0500 Subject: [PATCH] Avoid blocking folder addition on package loading When a folder is added to a VSCode workspace we perform a `swift package describe` to load information about the package. This operation must complete before the folder is added to the `workspaceContext`, which prevents the user from taking many actions in the extension that could be made available right away. A `swift package describe` operation can potentially take a good amount of time if package resolution has not been performed. Work around this limitation by wrapping the data pulled from this `package describe` behind promises, allowing clients to wait for package resolution to complete only if they need information that is gated by it. Issue: #1250 --- src/FolderContext.ts | 9 +- src/SwiftPackage.ts | 116 ++++++++++++------ src/TestExplorer/LSPTestDiscovery.ts | 37 +++--- src/TestExplorer/TestDiscovery.ts | 27 ++-- src/TestExplorer/TestExplorer.ts | 102 ++++++++------- src/TestExplorer/TestRunner.ts | 16 +-- src/WorkspaceContext.ts | 44 ++++--- src/commands/build.ts | 5 +- src/coverage/LcovResults.ts | 13 +- src/debugger/buildConfig.ts | 96 ++++++++------- src/debugger/launch.ts | 8 +- src/extension.ts | 6 +- src/tasks/SwiftTaskProvider.ts | 14 +-- src/toolchain/SelectedXcodeWatcher.ts | 4 +- src/ui/LanguageStatusItems.ts | 2 +- src/ui/ProjectPanelProvider.ts | 38 +++--- .../DiagnosticsManager.test.ts | 22 ++-- test/integration-tests/SwiftPackage.test.ts | 26 ++-- .../WorkspaceContext.test.ts | 17 +-- .../tasks/SwiftPluginTaskProvider.test.ts | 4 +- .../tasks/SwiftTaskProvider.test.ts | 10 +- .../testexplorer/LSPTestDiscovery.test.ts | 33 +++-- .../testexplorer/TestDiscovery.test.ts | 14 +-- .../utilities/testutilities.ts | 2 +- .../tasks/SwiftTaskProvider.test.ts | 61 +++++---- test/unit-tests/toolchain/BuildFlags.test.ts | 8 +- test/unit-tests/ui/ReloadExtension.test.ts | 2 +- test/unit-tests/ui/SwiftBuildStatus.test.ts | 2 +- 28 files changed, 416 insertions(+), 322 deletions(-) diff --git a/src/FolderContext.ts b/src/FolderContext.ts index 422cb182c..e2ef75f27 100644 --- a/src/FolderContext.ts +++ b/src/FolderContext.ts @@ -69,14 +69,12 @@ export class FolderContext implements vscode.Disposable { ): Promise { const statusItemText = `Loading Package (${FolderContext.uriName(folder)})`; workspaceContext.statusItem.start(statusItemText); - const { linuxMain, swiftPackage } = await workspaceContext.statusItem.showStatusWhileRunning(statusItemText, async () => { const linuxMain = await LinuxMain.create(folder); const swiftPackage = await SwiftPackage.create(folder, workspaceContext.toolchain); return { linuxMain, swiftPackage }; }); - workspaceContext.statusItem.end(statusItemText); const folderContext = new FolderContext( @@ -87,7 +85,7 @@ export class FolderContext implements vscode.Disposable { workspaceContext ); - const error = swiftPackage.error; + const error = await swiftPackage.error; if (error) { vscode.window.showErrorMessage( `Failed to load ${folderContext.name}/Package.swift: ${error.message}` @@ -97,7 +95,6 @@ export class FolderContext implements vscode.Disposable { folderContext.name ); } - return folderContext; } @@ -186,11 +183,11 @@ export class FolderContext implements vscode.Disposable { * @param uri URI to find target for * @returns Target */ - getTestTarget(uri: vscode.Uri, type?: TargetType): Target | undefined { + async getTestTarget(uri: vscode.Uri, type?: TargetType): Promise { if (!isPathInsidePath(uri.fsPath, this.folder.fsPath)) { return undefined; } - const testTargets = this.swiftPackage.getTargets(type); + const testTargets = await this.swiftPackage.getTargets(type); const target = testTargets.find(element => { const relativeUri = path.relative( path.join(this.folder.fsPath, element.path), diff --git a/src/SwiftPackage.ts b/src/SwiftPackage.ts index 8df08f560..cdb3070e1 100644 --- a/src/SwiftPackage.ts +++ b/src/SwiftPackage.ts @@ -21,7 +21,7 @@ import { SwiftToolchain } from "./toolchain/toolchain"; import { BuildFlags } from "./toolchain/BuildFlags"; /** Swift Package Manager contents */ -export interface PackageContents { +interface PackageContents { name: string; products: Product[]; dependencies: Dependency[]; @@ -184,8 +184,10 @@ function isError(state: SwiftPackageState): state is Error { /** * Class holding Swift Package Manager Package */ -export class SwiftPackage implements PackageContents { +export class SwiftPackage { public plugins: PackagePlugin[] = []; + private _contents: SwiftPackageState | undefined; + /** * SwiftPackage Constructor * @param folder folder package is in @@ -194,7 +196,7 @@ export class SwiftPackage implements PackageContents { */ private constructor( readonly folder: vscode.Uri, - private contents: SwiftPackageState, + private contentsPromise: Promise, public resolved: PackageResolved | undefined, private workspaceState: WorkspaceState | undefined ) {} @@ -208,10 +210,34 @@ export class SwiftPackage implements PackageContents { folder: vscode.Uri, toolchain: SwiftToolchain ): Promise { - const contents = await SwiftPackage.loadPackage(folder, toolchain); - const resolved = await SwiftPackage.loadPackageResolved(folder); - const workspaceState = await SwiftPackage.loadWorkspaceState(folder); - return new SwiftPackage(folder, contents, resolved, workspaceState); + const [resolved, workspaceState] = await Promise.all([ + SwiftPackage.loadPackageResolved(folder), + SwiftPackage.loadWorkspaceState(folder), + ]); + return new SwiftPackage( + folder, + SwiftPackage.loadPackage(folder, toolchain), + resolved, + workspaceState + ); + } + + /** + * Returns the package state once it has loaded. + * A snapshot of the state is stored in `_contents` after initial resolution. + */ + private get contents(): Promise { + return this.contentsPromise.then(contents => { + // If `reload` is called immediately its possible for it to resolve + // before the initial contentsPromise resolution. In that case return + // the newer loaded `_contents`. + if (this._contents === undefined) { + this._contents = contents; + return contents; + } else { + return this._contents; + } + }); } /** @@ -326,7 +352,9 @@ export class SwiftPackage implements PackageContents { /** Reload swift package */ public async reload(toolchain: SwiftToolchain) { - this.contents = await SwiftPackage.loadPackage(this.folder, toolchain); + const loadedContents = await SwiftPackage.loadPackage(this.folder, toolchain); + this._contents = loadedContents; + this.contentsPromise = Promise.resolve(loadedContents); } /** Reload Package.resolved file */ @@ -343,31 +371,26 @@ export class SwiftPackage implements PackageContents { } /** Return if has valid contents */ - public get isValid(): boolean { - return isPackage(this.contents); + public get isValid(): Promise { + return this.contents.then(contents => isPackage(contents)); } /** Load error */ - public get error(): Error | undefined { - if (isError(this.contents)) { - return this.contents; - } else { - return undefined; - } + public get error(): Promise { + return this.contents.then(contents => (isError(contents) ? contents : undefined)); } /** Did we find a Package.swift */ - public get foundPackage(): boolean { - return this.contents !== undefined; + public get foundPackage(): Promise { + return this.contents.then(contents => contents !== undefined); } - public rootDependencies(): ResolvedDependency[] { + public get rootDependencies(): Promise { // Correlate the root dependencies found in the Package.swift with their // checked out versions in the workspace-state.json. - const result = this.dependencies.map(dependency => - this.resolveDependencyAgainstWorkspaceState(dependency) + return this.dependencies.then(dependencies => + dependencies.map(dependency => this.resolveDependencyAgainstWorkspaceState(dependency)) ); - return result; } private resolveDependencyAgainstWorkspaceState(dependency: Dependency): ResolvedDependency { @@ -443,34 +466,47 @@ export class SwiftPackage implements PackageContents { } } - /** name of Swift Package */ - get name(): string { - return (this.contents as PackageContents)?.name ?? ""; + /** getName of Swift Package */ + get name(): Promise { + return this.contents.then(contents => (contents as PackageContents)?.name ?? ""); } /** array of products in Swift Package */ - get products(): Product[] { - return (this.contents as PackageContents)?.products ?? []; + private get products(): Promise { + return this.contents.then(contents => (contents as PackageContents)?.products ?? []); } /** array of dependencies in Swift Package */ - get dependencies(): Dependency[] { - return (this.contents as PackageContents)?.dependencies ?? []; + get dependencies(): Promise { + return this.contents.then(contents => (contents as PackageContents)?.dependencies ?? []); } /** array of targets in Swift Package */ - get targets(): Target[] { - return (this.contents as PackageContents)?.targets ?? []; + get targets(): Promise { + return this.contents.then(contents => (contents as PackageContents)?.targets ?? []); } /** array of executable products in Swift Package */ - get executableProducts(): Product[] { - return this.products.filter(product => product.type.executable !== undefined); + get executableProducts(): Promise { + return this.products.then(products => + products.filter(product => product.type.executable !== undefined) + ); } /** array of library products in Swift Package */ - get libraryProducts(): Product[] { - return this.products.filter(product => product.type.library !== undefined); + get libraryProducts(): Promise { + return this.products.then(products => + products.filter(product => product.type.library !== undefined) + ); + } + + /** + * Array of targets in Swift Package. The targets may not be loaded yet. + * It is preferable to use the `targets` property that returns a promise that + * returns the targets when they're guarenteed to be resolved. + **/ + get currentTargets(): Target[] { + return (this._contents as unknown as { targets: Target[] })?.targets ?? []; } /** @@ -478,20 +514,22 @@ export class SwiftPackage implements PackageContents { * @param type Type of target * @returns Array of targets */ - getTargets(type?: TargetType): Target[] { + async getTargets(type?: TargetType): Promise { if (type === undefined) { return this.targets; } else { - return this.targets.filter(target => target.type === type); + return this.targets.then(targets => targets.filter(target => target.type === type)); } } /** * Get target for file */ - getTarget(file: string): Target | undefined { + async getTarget(file: string): Promise { const filePath = path.relative(this.folder.fsPath, file); - return this.targets.find(target => isPathInsidePath(filePath, target.path)); + return this.targets.then(targets => + targets.find(target => isPathInsidePath(filePath, target.path)) + ); } private static trimStdout(stdout: string): string { diff --git a/src/TestExplorer/LSPTestDiscovery.ts b/src/TestExplorer/LSPTestDiscovery.ts index fa2ebf88f..e6b73e085 100644 --- a/src/TestExplorer/LSPTestDiscovery.ts +++ b/src/TestExplorer/LSPTestDiscovery.ts @@ -19,7 +19,7 @@ import { TextDocumentTestsRequest, WorkspaceTestsRequest, } from "../sourcekit-lsp/extensions"; -import { SwiftPackage, TargetType } from "../SwiftPackage"; +import { SwiftPackage } from "../SwiftPackage"; import { LanguageClientManager } from "../sourcekit-lsp/LanguageClientManager"; import { LanguageClient } from "vscode-languageclient/node"; @@ -68,7 +68,7 @@ export class LSPTestDiscovery { // workspace/tests method, and is at least version 2. if (this.checkExperimentalCapability(client, WorkspaceTestsRequest.method, 2)) { const tests = await client.sendRequest(WorkspaceTestsRequest.type, token); - return this.transformToTestClass(client, swiftPackage, tests); + return await this.transformToTestClass(client, swiftPackage, tests); } else { throw new Error(`${WorkspaceTestsRequest.method} requests not supported`); } @@ -96,20 +96,25 @@ export class LSPTestDiscovery { * Convert from `LSPTestItem[]` to `TestDiscovery.TestClass[]`, * updating the format of the location. */ - private transformToTestClass( + private async transformToTestClass( client: LanguageClient, swiftPackage: SwiftPackage, input: LSPTestItem[] - ): TestDiscovery.TestClass[] { - return input.map(item => { + ): Promise { + let result: TestDiscovery.TestClass[] = []; + for (const item of input) { const location = client.protocol2CodeConverter.asLocation(item.location); - return { - ...item, - id: this.transformId(item, location, swiftPackage), - children: this.transformToTestClass(client, swiftPackage, item.children), - location, - }; - }); + result = [ + ...result, + { + ...item, + id: await this.transformId(item, location, swiftPackage), + children: await this.transformToTestClass(client, swiftPackage, item.children), + location, + }, + ]; + } + return result; } /** @@ -117,17 +122,15 @@ export class LSPTestDiscovery { * swift-testing style ID to one that XCTest can use. This allows the ID to * be used to tell to the test runner (xctest or swift-testing) which tests to run. */ - private transformId( + private async transformId( item: LSPTestItem, location: vscode.Location, swiftPackage: SwiftPackage - ): string { + ): Promise { // XCTest: Target.TestClass/testCase // swift-testing: TestClass/testCase() // TestClassOrStruct/NestedTestSuite/testCase() - const target = swiftPackage - .getTargets(TargetType.test) - .find(target => swiftPackage.getTarget(location.uri.fsPath) === target); + const target = await swiftPackage.getTarget(location.uri.fsPath); // If we're using an older sourcekit-lsp it doesn't prepend the target name // to the test item id. diff --git a/src/TestExplorer/TestDiscovery.ts b/src/TestExplorer/TestDiscovery.ts index a80cf6c9b..a848f6013 100644 --- a/src/TestExplorer/TestDiscovery.ts +++ b/src/TestExplorer/TestDiscovery.ts @@ -43,17 +43,24 @@ const defaultTags = [runnableTag.id, "test-target", "XCTest", "swift-testing"]; * @param swiftPackage A swift package containing test targets * @param testClasses Array of test classes */ -export function updateTestsFromClasses( +export async function updateTestsFromClasses( testController: vscode.TestController, swiftPackage: SwiftPackage, testItems: TestClass[] ) { - const targets = swiftPackage.getTargets(TargetType.test).map(target => { - const filteredItems = testItems.filter( - testItem => - testItem.location && swiftPackage.getTarget(testItem.location.uri.fsPath) === target - ); - return { + const targets = await swiftPackage.getTargets(TargetType.test); + const results: TestClass[] = []; + for (const target of targets) { + const filteredItems: TestClass[] = []; + for (const testItem of testItems) { + if ( + testItem.location && + (await swiftPackage.getTarget(testItem.location.uri.fsPath)) === target + ) { + filteredItems.push(testItem); + } + } + results.push({ id: target.c99name, label: target.name, children: filteredItems, @@ -61,9 +68,9 @@ export function updateTestsFromClasses( disabled: false, style: "test-target", tags: [], - } as TestClass; - }); - updateTests(testController, targets); + }); + } + updateTests(testController, results); } export function updateTestsForTarget( diff --git a/src/TestExplorer/TestExplorer.ts b/src/TestExplorer/TestExplorer.ts index e4123ca20..b7a5e0a3d 100644 --- a/src/TestExplorer/TestExplorer.ts +++ b/src/TestExplorer/TestExplorer.ts @@ -85,17 +85,24 @@ export class TestExplorer { this.testFileEdited ) { this.testFileEdited = false; + // only run discover tests if the library has tests - if (this.folderContext.swiftPackage.getTargets(TargetType.test).length > 0) { - this.discoverTestsInWorkspace(this.tokenSource.token); - } + this.folderContext.swiftPackage.getTargets(TargetType.test).then(targets => { + if (targets.length > 0) { + this.discoverTestsInWorkspace(this.tokenSource.token); + } + }); } }); // add file watcher to catch changes to swift test files const fileWatcher = this.folderContext.workspaceContext.onDidChangeSwiftFiles(({ uri }) => { - if (this.testFileEdited === false && this.folderContext.getTestTarget(uri)) { - this.testFileEdited = true; + if (this.testFileEdited === false) { + this.folderContext.getTestTarget(uri).then(target => { + if (target) { + this.testFileEdited = true; + } + }); } }); @@ -131,7 +138,11 @@ export class TestExplorer { switch (operation) { case FolderOperation.add: if (folder) { - if (folder.swiftPackage.getTargets(TargetType.test).length > 0) { + folder.swiftPackage.getTargets(TargetType.test).then(targets => { + if (targets.length === 0) { + return; + } + folder.addTestExplorer(); // discover tests in workspace but only if disableAutoResolve is not on. // discover tests will kick off a resolve if required @@ -142,29 +153,31 @@ export class TestExplorer { tokenSource.token ); } - } + }); } break; case FolderOperation.packageUpdated: if (folder) { - const hasTestTargets = - folder.swiftPackage.getTargets(TargetType.test).length > 0; - if (hasTestTargets && !folder.hasTestExplorer()) { - folder.addTestExplorer(); - // discover tests in workspace but only if disableAutoResolve is not on. - // discover tests will kick off a resolve if required - if ( - !configuration.folder(folder.workspaceFolder).disableAutoResolve - ) { - folder.testExplorer?.discoverTestsInWorkspace( - tokenSource.token - ); + folder.swiftPackage.getTargets(TargetType.test).then(targets => { + const hasTestTargets = targets.length > 0; + if (hasTestTargets && !folder.hasTestExplorer()) { + folder.addTestExplorer(); + // discover tests in workspace but only if disableAutoResolve is not on. + // discover tests will kick off a resolve if required + if ( + !configuration.folder(folder.workspaceFolder) + .disableAutoResolve + ) { + folder.testExplorer?.discoverTestsInWorkspace( + tokenSource.token + ); + } + } else if (!hasTestTargets && folder.hasTestExplorer()) { + folder.removeTestExplorer(); + } else if (folder.hasTestExplorer()) { + folder.refreshTestExplorer(); } - } else if (!hasTestTargets && folder.hasTestExplorer()) { - folder.removeTestExplorer(); - } else if (folder.hasTestExplorer()) { - folder.refreshTestExplorer(); - } + }); } break; case FolderOperation.focus: @@ -206,24 +219,29 @@ export class TestExplorer { const testExplorer = folder?.testExplorer; if (testExplorer && symbols && uri && uri.scheme === "file") { if (isPathInsidePath(uri.fsPath, folder.folder.fsPath)) { - const target = folder.swiftPackage.getTarget(uri.fsPath); - if (target && target.type === "test") { - testExplorer.lspTestDiscovery - .getDocumentTests(folder.swiftPackage, uri) - .then(tests => - TestDiscovery.updateTestsForTarget( - testExplorer.controller, - { id: target.c99name, label: target.name }, - tests, - uri + folder.swiftPackage.getTarget(uri.fsPath).then(target => { + if (target && target.type === "test") { + testExplorer.lspTestDiscovery + .getDocumentTests(folder.swiftPackage, uri) + .then(tests => + TestDiscovery.updateTestsForTarget( + testExplorer.controller, + { id: target.c99name, label: target.name }, + tests, + uri + ) ) - ) - // Fallback to parsing document symbols for XCTests only - .catch(() => { - const tests = parseTestsFromDocumentSymbols(target.name, symbols, uri); - testExplorer.updateTests(testExplorer.controller, tests, uri); - }); - } + // Fallback to parsing document symbols for XCTests only + .catch(() => { + const tests = parseTestsFromDocumentSymbols( + target.name, + symbols, + uri + ); + testExplorer.updateTests(testExplorer.controller, tests, uri); + }); + } + }); } } } @@ -393,7 +411,7 @@ export class TestExplorer { return; } - TestDiscovery.updateTestsFromClasses( + await TestDiscovery.updateTestsFromClasses( this.controller, this.folderContext.swiftPackage, tests diff --git a/src/TestExplorer/TestRunner.ts b/src/TestExplorer/TestRunner.ts index c740d4e7f..eff713fb7 100644 --- a/src/TestExplorer/TestRunner.ts +++ b/src/TestExplorer/TestRunner.ts @@ -590,11 +590,11 @@ export class TestRunner { this.folderContext, testRunTime ); - const swiftTestingArgs = await SwiftTestingBuildAguments.build( + const swiftTestingArgs = SwiftTestingBuildAguments.build( fifoPipePath, attachmentFolder ); - const testBuildConfig = TestingConfigurationFactory.swiftTestingConfig( + const testBuildConfig = await TestingConfigurationFactory.swiftTestingConfig( this.folderContext, swiftTestingArgs, this.testKind, @@ -629,7 +629,7 @@ export class TestRunner { } if (this.testArgs.hasXCTests) { - const testBuildConfig = TestingConfigurationFactory.xcTestConfig( + const testBuildConfig = await TestingConfigurationFactory.xcTestConfig( this.folderContext, this.testKind, this.testArgs.xcTestArgs, @@ -844,7 +844,7 @@ export class TestRunner { next(); }, }), - BuildConfigurationFactory.buildAll( + await BuildConfigurationFactory.buildAll( this.folderContext, true, isRelease(this.testKind) @@ -874,12 +874,12 @@ export class TestRunner { this.folderContext, testRunTime ); - const swiftTestingArgs = await SwiftTestingBuildAguments.build( + const swiftTestingArgs = SwiftTestingBuildAguments.build( fifoPipePath, attachmentFolder ); - const swiftTestBuildConfig = TestingConfigurationFactory.swiftTestingConfig( + const swiftTestBuildConfig = await TestingConfigurationFactory.swiftTestingConfig( this.folderContext, swiftTestingArgs, this.testKind, @@ -913,7 +913,7 @@ export class TestRunner { // create launch config for testing if (this.testArgs.hasXCTests) { - const xcTestBuildConfig = TestingConfigurationFactory.xcTestConfig( + const xcTestBuildConfig = await TestingConfigurationFactory.xcTestConfig( this.folderContext, this.testKind, this.testArgs.xcTestArgs, @@ -1161,7 +1161,7 @@ class NonDarwinTestItemFinder implements TestItemFinder { return false; } // get target from Package - const target = this.folderContext.swiftPackage.targets.find( + const target = this.folderContext.swiftPackage.currentTargets.find( item => targetTestItem.label === item.name ); if (target) { diff --git a/src/WorkspaceContext.ts b/src/WorkspaceContext.ts index 648b6776d..982e830bb 100644 --- a/src/WorkspaceContext.ts +++ b/src/WorkspaceContext.ts @@ -83,7 +83,7 @@ export class WorkspaceContext implements vscode.Disposable { const onChangeConfig = vscode.workspace.onDidChangeConfiguration(async event => { // on runtime path config change, regenerate launch.json if (event.affectsConfiguration("swift.runtimePath")) { - if (!this.needToAutoGenerateLaunchConfig()) { + if (!(await this.needToAutoGenerateLaunchConfig())) { return; } vscode.window @@ -94,15 +94,15 @@ export class WorkspaceContext implements vscode.Disposable { ) .then(async selected => { if (selected === "Update") { - this.folders.forEach( - async ctx => await makeDebugConfigurations(ctx, undefined, true) + this.folders.forEach(ctx => + makeDebugConfigurations(ctx, undefined, true) ); } }); } // on change of swift build path, regenerate launch.json if (event.affectsConfiguration("swift.buildPath")) { - if (!this.needToAutoGenerateLaunchConfig()) { + if (!(await this.needToAutoGenerateLaunchConfig())) { return; } vscode.window @@ -111,10 +111,10 @@ export class WorkspaceContext implements vscode.Disposable { "Update", "Cancel" ) - .then(async selected => { + .then(selected => { if (selected === "Update") { - this.folders.forEach( - async ctx => await makeDebugConfigurations(ctx, undefined, true) + this.folders.forEach(ctx => + makeDebugConfigurations(ctx, undefined, true) ); } }); @@ -220,23 +220,30 @@ export class WorkspaceContext implements vscode.Disposable { * Update context keys based on package contents */ updateContextKeys(folderContext: FolderContext | null) { - if (!folderContext || !folderContext.swiftPackage.foundPackage) { + if (!folderContext) { contextKeys.hasPackage = false; contextKeys.packageHasDependencies = false; return; } - contextKeys.hasPackage = true; - contextKeys.packageHasDependencies = folderContext.swiftPackage.dependencies.length > 0; + + Promise.all([ + folderContext.swiftPackage.foundPackage, + folderContext.swiftPackage.dependencies, + ]).then(([foundPackage, dependencies]) => { + contextKeys.hasPackage = foundPackage; + contextKeys.packageHasDependencies = dependencies.length > 0; + }); } /** * Update context keys based on package contents */ - updateContextKeysForFile() { + async updateContextKeysForFile() { if (this.currentDocument) { - contextKeys.currentTargetType = this.currentFolder?.swiftPackage.getTarget( + const target = await this.currentFolder?.swiftPackage.getTarget( this.currentDocument?.fsPath - )?.type; + ); + contextKeys.currentTargetType = target?.type; } else { contextKeys.currentTargetType = undefined; } @@ -439,7 +446,6 @@ export class WorkspaceContext implements vscode.Disposable { this.folders.push(folderContext); await this.fireEvent(folderContext, FolderOperation.add); - return folderContext; } @@ -485,7 +491,7 @@ export class WorkspaceContext implements vscode.Disposable { async focusUri(uri?: vscode.Uri) { this.currentDocument = uri ?? null; - this.updateContextKeysForFile(); + await this.updateContextKeysForFile(); if ( this.currentDocument?.scheme === "file" || this.currentDocument?.scheme === "sourcekit-lsp" @@ -615,14 +621,14 @@ export class WorkspaceContext implements vscode.Disposable { this.currentFolder = undefined; } - private needToAutoGenerateLaunchConfig() { + private async needToAutoGenerateLaunchConfig() { let autoGenerate = false; - this.folders.forEach(folder => { + for (const folder of this.folders) { const requiresAutoGenerate = configuration.folder(folder.workspaceFolder).autoGenerateLaunchConfigurations && - folder.swiftPackage.executableProducts.length > 0; + (await folder.swiftPackage.executableProducts).length > 0; autoGenerate = autoGenerate || requiresAutoGenerate; - }); + } return autoGenerate; } diff --git a/src/commands/build.ts b/src/commands/build.ts index 1ce2744d3..b5f230063 100644 --- a/src/commands/build.ts +++ b/src/commands/build.ts @@ -84,7 +84,8 @@ export async function debugBuildWithOptions( let target: Target | undefined; if (targetName) { - target = current.swiftPackage.targets.find(target => target.name === targetName); + const targets = await current.swiftPackage.targets; + target = targets.find(target => target.name === targetName); } else { const file = vscode.window.activeTextEditor?.document.fileName; if (!file) { @@ -92,7 +93,7 @@ export async function debugBuildWithOptions( return; } - target = current.swiftPackage.getTarget(file); + target = await current.swiftPackage.getTarget(file); } if (!target) { diff --git a/src/coverage/LcovResults.ts b/src/coverage/LcovResults.ts index 2196beab5..8bf1d6da0 100644 --- a/src/coverage/LcovResults.ts +++ b/src/coverage/LcovResults.ts @@ -150,7 +150,8 @@ export class TestCoverage { TestLibrary.xctest ); if (process.platform === "darwin") { - xcTestBinary += `/Contents/MacOS/${this.folderContext.swiftPackage.name}PackageTests`; + const packageName = await this.folderContext.swiftPackage.name; + xcTestBinary += `/Contents/MacOS/${packageName}PackageTests`; } coveredBinaries.add(xcTestBinary); } @@ -179,7 +180,7 @@ export class TestCoverage { "--format", "lcov", ...coveredBinaries, - `--ignore-filename-regex=${this.ignoredFilenamesRegex()}`, + `--ignore-filename-regex=${await this.ignoredFilenamesRegex()}`, `--instr-profile=${mergedProfileFile}`, ], writableStream, @@ -199,14 +200,14 @@ export class TestCoverage { * Constructs a string containing all the paths to exclude from the code coverage report. * This should exclude everything in the `.build` folder as well as all the test targets. */ - private ignoredFilenamesRegex(): string { + private async ignoredFilenamesRegex(): Promise { const basePath = this.folderContext.folder.path; const buildFolder = path.join(basePath, ".build"); const snippetsFolder = path.join(basePath, "Snippets"); const pluginsFolder = path.join(basePath, "Plugins"); - const testTargets = this.folderContext.swiftPackage - .getTargets(TargetType.test) - .map(target => path.join(basePath, target.path)); + const testTargets = (await this.folderContext.swiftPackage.getTargets(TargetType.test)).map( + target => path.join(basePath, target.path) + ); const excluded = configuration.excludeFromCodeCoverage.map(target => path.isAbsolute(target) ? target : path.join(basePath, target) diff --git a/src/debugger/buildConfig.ts b/src/debugger/buildConfig.ts index a066a4bf7..bb37fe208 100644 --- a/src/debugger/buildConfig.ts +++ b/src/debugger/buildConfig.ts @@ -33,7 +33,7 @@ export class BuildConfigurationFactory { ctx: FolderContext, isTestBuild: boolean, isRelease: boolean - ): vscode.DebugConfiguration { + ): Promise { return new BuildConfigurationFactory(ctx, isTestBuild, isRelease).build(); } @@ -43,9 +43,9 @@ export class BuildConfigurationFactory { private isRelease: boolean ) {} - private build(): vscode.DebugConfiguration { + private async build(): Promise { let additionalArgs = buildOptions(this.ctx.workspaceContext.toolchain); - if (this.ctx.swiftPackage.getTargets(TargetType.test).length > 0) { + if ((await this.ctx.swiftPackage.getTargets(TargetType.test)).length > 0) { additionalArgs.push(...this.testDiscoveryFlag(this.ctx)); } @@ -68,7 +68,7 @@ export class BuildConfigurationFactory { } return { - ...this.baseConfig, + ...(await this.baseConfig), program: "swift", args: ["build", ...additionalArgs], env: {}, @@ -105,10 +105,10 @@ export class SwiftTestingBuildAguments { public attachmentPath: string | undefined ) {} - public static async build( + public static build( fifoPipePath: string, attachmentPath: string | undefined - ): Promise { + ): SwiftTestingBuildAguments { return new SwiftTestingBuildAguments(fifoPipePath, attachmentPath); } } @@ -192,7 +192,7 @@ export class TestingConfigurationFactory { testKind: TestKind, testList: string[], expandEnvVariables = false - ): vscode.DebugConfiguration | null { + ): Promise { return new TestingConfigurationFactory( ctx, testKind, @@ -208,7 +208,7 @@ export class TestingConfigurationFactory { testKind: TestKind, testList: string[], expandEnvVariables = false - ): vscode.DebugConfiguration | null { + ): Promise { return new TestingConfigurationFactory( ctx, testKind, @@ -223,7 +223,7 @@ export class TestingConfigurationFactory { ctx: FolderContext, testKind: TestKind, testLibrary: TestLibrary - ): string { + ): Promise { return new TestingConfigurationFactory( ctx, testKind, @@ -251,8 +251,8 @@ export class TestingConfigurationFactory { * - Test Kind (coverage, debugging) * - Test Library (XCTest, swift-testing) */ - private build(): vscode.DebugConfiguration | null { - if (!this.hasTestTarget) { + private async build(): Promise { + if (!(await this.hasTestTarget)) { return null; } @@ -267,7 +267,7 @@ export class TestingConfigurationFactory { } /* eslint-disable no-case-declarations */ - private buildWindowsConfig(): vscode.DebugConfiguration | null { + private async buildWindowsConfig(): Promise { if (isDebugging(this.testKind)) { const testEnv = { ...swiftRuntimeEnv(), @@ -286,9 +286,10 @@ export class TestingConfigurationFactory { testEnv.Path = `${swiftTestingPath};${testEnv.Path ?? process.env.Path}`; } + const baseConfig = await this.baseConfig(); return { - ...this.baseConfig, - program: this.testExecutableOutputPath(), + ...baseConfig, + program: await this.testExecutableOutputPath(), args: this.debuggingTestExecutableArgs(), env: testEnv, }; @@ -298,11 +299,12 @@ export class TestingConfigurationFactory { } /* eslint-disable no-case-declarations */ - private buildLinuxConfig(): vscode.DebugConfiguration | null { + private async buildLinuxConfig(): Promise { if (isDebugging(this.testKind) && this.testLibrary === TestLibrary.xctest) { + const baseConfig = await this.baseConfig(); return { - ...this.baseConfig, - program: this.testExecutableOutputPath(), + ...baseConfig, + program: await this.testExecutableOutputPath(), args: this.debuggingTestExecutableArgs(), env: { ...swiftRuntimeEnv( @@ -317,7 +319,8 @@ export class TestingConfigurationFactory { } } - private buildDarwinConfig(): vscode.DebugConfiguration | null { + private async buildDarwinConfig(): Promise { + const baseConfig = await this.baseConfig(); switch (this.testLibrary) { case TestLibrary.swiftTesting: switch (this.testKind) { @@ -337,13 +340,13 @@ export class TestingConfigurationFactory { // then we know we're working with a unified binary. if (swiftPMTestingHelperPath) { const result = { - ...this.baseConfig, + ...baseConfig, program: swiftPMTestingHelperPath, args: this.addBuildOptionsToArgs( this.addTestsToArgs( this.addSwiftTestingFlagsArgs([ "--test-bundle-path", - this.unifiedTestingOutputPath(), + await this.unifiedTestingOutputPath(), "--testing-library", "swift-testing", ]) @@ -361,8 +364,8 @@ export class TestingConfigurationFactory { } const result = { - ...this.baseConfig, - program: this.testExecutableOutputPath(), + ...baseConfig, + program: await this.testExecutableOutputPath(), args: this.debuggingTestExecutableArgs(), env: { ...this.testEnv, @@ -386,7 +389,7 @@ export class TestingConfigurationFactory { } return { - ...this.baseConfig, + ...baseConfig, program: this.swiftProgramPath, args: this.addBuildOptionsToArgs(this.addTestsToArgs(args)), env: { @@ -399,7 +402,7 @@ export class TestingConfigurationFactory { preLaunchTask: this.testKind === TestKind.coverage ? undefined - : this.baseConfig.preLaunchTask, + : baseConfig.preLaunchTask, }; } case TestLibrary.xctest: @@ -413,9 +416,11 @@ export class TestingConfigurationFactory { return null; } return { - ...this.baseConfig, + ...baseConfig, program: path.join(xcTestPath, "xctest"), - args: this.addXCTestExecutableTestsToArgs([this.xcTestOutputPath()]), + args: this.addXCTestExecutableTestsToArgs([ + await this.xcTestOutputPath(), + ]), env: { ...this.testEnv, ...this.sanitizerRuntimeEnvironment, @@ -431,7 +436,7 @@ export class TestingConfigurationFactory { ) { // if debugging on macOS with Swift 5.6 we need to create a custom launch // configuration so we can set the system architecture - return this.createDarwin56TestConfiguration(); + return await this.createDarwin56TestConfiguration(); } let xcTestArgs = [ @@ -453,7 +458,7 @@ export class TestingConfigurationFactory { } return { - ...this.baseConfig, + ...baseConfig, program: this.swiftProgramPath, args: this.addBuildOptionsToArgs(this.addTestsToArgs(xcTestArgs)), env: { @@ -466,7 +471,7 @@ export class TestingConfigurationFactory { preLaunchTask: this.testKind === TestKind.coverage ? undefined - : this.baseConfig.preLaunchTask, + : baseConfig.preLaunchTask, }; } } @@ -476,8 +481,8 @@ export class TestingConfigurationFactory { /** * Return custom Darwin test configuration that works with Swift 5.6 **/ - private createDarwin56TestConfiguration(): vscode.DebugConfiguration | null { - if (this.ctx.swiftPackage.getTargets(TargetType.test).length === 0) { + private async createDarwin56TestConfiguration(): Promise { + if ((await this.ctx.swiftPackage.getTargets(TargetType.test)).length === 0) { return null; } @@ -517,7 +522,7 @@ export class TestingConfigurationFactory { return { type: SWIFT_LAUNCH_CONFIG_TYPE, request: "custom", - name: `Test ${this.ctx.swiftPackage.name}`, + name: `Test ${await this.ctx.swiftPackage.name}`, targetCreateCommands: [`file -a ${arch} ${xctestPath}/xctest`], processCreateCommands: [ ...envCommands, @@ -623,31 +628,33 @@ export class TestingConfigurationFactory { return triple ? path.join(triple, mode) : mode; } - private xcTestOutputPath(): string { + private async xcTestOutputPath(): Promise { + const packageName = await this.ctx.swiftPackage.name; return path.join( this.buildDirectory, this.artifactFolderForTestKind, - `${this.ctx.swiftPackage.name}PackageTests.xctest` + `${packageName}PackageTests.xctest` ); } - private unifiedTestingOutputPath(): string { + private async unifiedTestingOutputPath(): Promise { // The unified binary that contains both swift-testing and XCTests // is named the same as the old style .xctest binary. The swiftpm-testing-helper // requires the full path to the binary. if (process.platform === "darwin") { + const packageName = await this.ctx.swiftPackage.name; return path.join( - this.xcTestOutputPath(), + await this.xcTestOutputPath(), "Contents", "MacOS", - `${this.ctx.swiftPackage.name}PackageTests` + `${packageName}PackageTests` ); } else { return this.xcTestOutputPath(); } } - private testExecutableOutputPath(): string { + private async testExecutableOutputPath(): Promise { switch (this.testLibrary) { case TestLibrary.swiftTesting: return this.unifiedTestingOutputPath(); @@ -682,22 +689,25 @@ export class TestingConfigurationFactory { }; } - private get baseConfig() { + private async baseConfig(): Promise> { return getBaseConfig(this.ctx, this.expandEnvVariables); } - private get hasTestTarget(): boolean { - return this.ctx.swiftPackage.getTargets(TargetType.test).length > 0; + private get hasTestTarget(): Promise { + return this.ctx.swiftPackage + .getTargets(TargetType.test) + .then(targets => targets.length > 0); } } -function getBaseConfig(ctx: FolderContext, expandEnvVariables: boolean) { +async function getBaseConfig(ctx: FolderContext, expandEnvVariables: boolean) { const { folder, nameSuffix } = getFolderAndNameSuffix(ctx, expandEnvVariables); + const packageName = await ctx.swiftPackage.name; return { type: SWIFT_LAUNCH_CONFIG_TYPE, request: "launch", sourceLanguages: ["swift"], - name: `Test ${ctx.swiftPackage.name}`, + name: `Test ${packageName}`, cwd: folder, args: [], preLaunchTask: `swift: Build All${nameSuffix}`, diff --git a/src/debugger/launch.ts b/src/debugger/launch.ts index b91836828..cf4cf3b80 100644 --- a/src/debugger/launch.ts +++ b/src/debugger/launch.ts @@ -51,7 +51,7 @@ export async function makeDebugConfigurations( ]; const configUpdates: { index: number; config: vscode.DebugConfiguration }[] = []; - const configs = createExecutableConfigurations(ctx); + const configs = await createExecutableConfigurations(ctx); let edited = false; for (const config of configs) { const index = launchConfigs.findIndex(c => c.name === config.name); @@ -126,8 +126,10 @@ export function getLaunchConfiguration( } // Return array of DebugConfigurations for executables based on what is in Package.swift -function createExecutableConfigurations(ctx: FolderContext): vscode.DebugConfiguration[] { - const executableProducts = ctx.swiftPackage.executableProducts; +async function createExecutableConfigurations( + ctx: FolderContext +): Promise { + const executableProducts = await ctx.swiftPackage.executableProducts; // Windows understand the forward slashes, so make the configuration unified as posix path // to make it easier for users switching between platforms. diff --git a/src/extension.ts b/src/extension.ts index 15e45be46..4b28304c3 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -215,7 +215,7 @@ export async function activate(context: vscode.ExtensionContext): Promise { case FolderOperation.add: // Create launch.json files based on package description. debug.makeDebugConfigurations(folder); - if (folder.swiftPackage.foundPackage) { + if (await folder.swiftPackage.foundPackage) { // do not await for this, let packages resolve in parallel folderAdded(folder, workspace); } @@ -225,7 +225,7 @@ export async function activate(context: vscode.ExtensionContext): Promise { // Create launch.json files based on package description. debug.makeDebugConfigurations(folder); if ( - folder.swiftPackage.foundPackage && + (await folder.swiftPackage.foundPackage) && !configuration.folder(folder.workspaceFolder).disableAutoResolve ) { await resolveFolderDependencies(folder, true); @@ -234,7 +234,7 @@ export async function activate(context: vscode.ExtensionContext): Promise { case FolderOperation.resolvedUpdated: if ( - folder.swiftPackage.foundPackage && + (await folder.swiftPackage.foundPackage) && !configuration.folder(folder.workspaceFolder).disableAutoResolve ) { await resolveFolderDependencies(folder, true); diff --git a/src/tasks/SwiftTaskProvider.ts b/src/tasks/SwiftTaskProvider.ts index 40ac5179f..c5137ba12 100644 --- a/src/tasks/SwiftTaskProvider.ts +++ b/src/tasks/SwiftTaskProvider.ts @@ -134,11 +134,11 @@ function buildAllTaskName(folderContext: FolderContext, release: boolean): strin /** * Creates a {@link vscode.Task Task} to build all targets in this package. */ -export function createBuildAllTask( +export async function createBuildAllTask( folderContext: FolderContext, release: boolean = false -): SwiftTask { - const args = BuildConfigurationFactory.buildAll(folderContext, false, release).args; +): Promise { + const args = (await BuildConfigurationFactory.buildAll(folderContext, false, release)).args; const buildTaskName = buildAllTaskName(folderContext, release); const task = createSwiftTask( args, @@ -206,7 +206,7 @@ export async function getBuildAllTask( task.source === "swift" ); if (!task) { - task = createBuildAllTask(folderContext, release); + task = await createBuildAllTask(folderContext, release); } return task; @@ -362,7 +362,7 @@ export class SwiftTaskProvider implements vscode.TaskProvider { const tasks = []; for (const folderContext of this.workspaceContext.folders) { - if (!folderContext.swiftPackage.foundPackage) { + if (!(await folderContext.swiftPackage.foundPackage)) { continue; } const activeOperation = folderContext.taskQueue.activeOperation; @@ -404,9 +404,9 @@ export class SwiftTaskProvider implements vscode.TaskProvider { } // Create debug Build All task. - tasks.push(createBuildAllTask(folderContext, false)); + tasks.push(await createBuildAllTask(folderContext, false)); - const executables = folderContext.swiftPackage.executableProducts; + const executables = await folderContext.swiftPackage.executableProducts; for (const executable of executables) { tasks.push(...createBuildTasks(executable, folderContext)); } diff --git a/src/toolchain/SelectedXcodeWatcher.ts b/src/toolchain/SelectedXcodeWatcher.ts index 30778edf6..d7954e810 100644 --- a/src/toolchain/SelectedXcodeWatcher.ts +++ b/src/toolchain/SelectedXcodeWatcher.ts @@ -76,10 +76,10 @@ export class SelectedXcodeWatcher implements vscode.Disposable { this.outputChannel.appendLine( `Selected Xcode changed from ${this.xcodePath} to ${newXcodePath}` ); - showReloadExtensionNotification( + this.xcodePath = newXcodePath; + await showReloadExtensionNotification( "The Swift Extension has detected a change in the selected Xcode. Please reload the extension to apply the changes." ); - this.xcodePath = newXcodePath; } }, this.checkIntervalMs); } diff --git a/src/ui/LanguageStatusItems.ts b/src/ui/LanguageStatusItems.ts index 66ae187fe..7a21ab52e 100644 --- a/src/ui/LanguageStatusItems.ts +++ b/src/ui/LanguageStatusItems.ts @@ -43,7 +43,7 @@ export class LanguageStatusItems implements vscode.Disposable { const onFocus = workspaceContext.onDidChangeFolders(async ({ folder, operation }) => { switch (operation) { case FolderOperation.focus: - if (folder && folder.swiftPackage.foundPackage) { + if (folder && (await folder.swiftPackage.foundPackage)) { this.packageSwiftItem.text = "Package.swift"; this.packageSwiftItem.command = Command.create( "Open Package", diff --git a/src/ui/ProjectPanelProvider.ts b/src/ui/ProjectPanelProvider.ts index 793bebe1f..9761a880f 100644 --- a/src/ui/ProjectPanelProvider.ts +++ b/src/ui/ProjectPanelProvider.ts @@ -428,8 +428,8 @@ export class ProjectPanelProvider implements vscode.TreeDataProvider { return element.getChildren(); } - const dependencies = this.dependencies(); - const snippets = this.snippets(); + const dependencies = await this.dependencies(); + const snippets = await this.snippets(); const commands = await this.commands(); // TODO: Control ordering @@ -440,11 +440,11 @@ export class ProjectPanelProvider implements vscode.TreeDataProvider { "dependencies", "Dependencies", "circuit-board", - this.wrapInAsync(this.dependencies.bind(this)) + this.dependencies.bind(this) ), ] : []), - new HeaderNode("targets", "Targets", "book", this.wrapInAsync(this.targets.bind(this))), + new HeaderNode("targets", "Targets", "book", this.targets.bind(this)), new HeaderNode("tasks", "Tasks", "debug-continue-small", this.tasks.bind(this)), ...(snippets.length > 0 ? [ @@ -463,12 +463,13 @@ export class ProjectPanelProvider implements vscode.TreeDataProvider { ]; } - private dependencies(): TreeNode[] { + private async dependencies(): Promise { const folderContext = this.workspaceContext.currentFolder; if (!folderContext) { return []; } const pkg = folderContext.swiftPackage; + const rootDeps = await pkg.rootDependencies; if (contextKeys.flatDependenciesList) { const existenceMap = new Map(); const gatherChildren = (dependencies: ResolvedDependency[]): ResolvedDependency[] => { @@ -484,28 +485,26 @@ export class ProjectPanelProvider implements vscode.TreeDataProvider { return result; }; - const rootDeps = pkg.rootDependencies(); const allDeps = gatherChildren(rootDeps); return allDeps.map(dependency => new PackageNode(dependency, () => [])); } else { const childDeps = pkg.childDependencies.bind(pkg); - return pkg.rootDependencies().map(dep => new PackageNode(dep, childDeps)); + return rootDeps.map(dep => new PackageNode(dep, childDeps)); } } - private targets(): TreeNode[] { + private async targets(): Promise { const folderContext = this.workspaceContext.currentFolder; if (!folderContext) { return []; } const targetSort = (node: TargetNode) => `${node.target.type}-${node.name}`; - return ( - folderContext.swiftPackage.targets - // Snipepts are shown under the Snippets header - .filter(target => target.type !== "snippet") - .map(target => new TargetNode(target, this.activeTasks)) - .sort((a, b) => targetSort(a).localeCompare(targetSort(b))) - ); + const targets = await folderContext.swiftPackage.targets; + // Snipepts are shown under the Snippets header + return targets + .filter(target => target.type !== "snippet") + .map(target => new TargetNode(target, this.activeTasks)) + .sort((a, b) => targetSort(a).localeCompare(targetSort(b))); } private async tasks(): Promise { @@ -541,18 +540,15 @@ export class ProjectPanelProvider implements vscode.TreeDataProvider { .sort((a, b) => a.name.localeCompare(b.name)); } - private snippets(): TreeNode[] { + private async snippets(): Promise { const folderContext = this.workspaceContext.currentFolder; if (!folderContext) { return []; } - return folderContext.swiftPackage.targets + const targets = await folderContext.swiftPackage.targets; + return targets .filter(target => target.type === "snippet") .flatMap(target => new TargetNode(target, this.activeTasks)) .sort((a, b) => a.name.localeCompare(b.name)); } - - private wrapInAsync(fn: () => T): () => Promise { - return async () => fn(); - } } diff --git a/test/integration-tests/DiagnosticsManager.test.ts b/test/integration-tests/DiagnosticsManager.test.ts index b0a783090..0b8f1a69d 100644 --- a/test/integration-tests/DiagnosticsManager.test.ts +++ b/test/integration-tests/DiagnosticsManager.test.ts @@ -57,7 +57,7 @@ function assertWithoutDiagnostic(uri: vscode.Uri, expected: vscode.Diagnostic) { ); } -suite("DiagnosticsManager Test Suite", async function () { +suite("DiagnosticsManager Test Suite", function () { // Was hitting a timeout in suiteSetup during CI build once in a while this.timeout(5000); @@ -163,10 +163,10 @@ suite("DiagnosticsManager Test Suite", async function () { } }); - suite("Parse diagnostics", async function () { + suite("Parse diagnostics", function () { this.timeout(60000 * 2); - suite("Parse from task output", async () => { + suite("Parse from task output", () => { const expectedWarningDiagnostic = new vscode.Diagnostic( new vscode.Range(new vscode.Position(1, 8), new vscode.Position(1, 8)), "Initialization of variable 'unused' was never used; consider replacing with assignment to '_' or removing it", @@ -217,7 +217,7 @@ suite("DiagnosticsManager Test Suite", async function () { // failure if `swiftc` diagnostic is fixed suiteSetup(async function () { this.timeout(3 * 60 * 1000); // Allow 3 minutes to build - const task = createBuildAllTask(folderContext); + const task = await createBuildAllTask(folderContext); // This return exit code and output for the task but we will omit it here // because the failures are expected and we just want the task to build await executeTaskAndWaitForResult(task); @@ -254,7 +254,7 @@ suite("DiagnosticsManager Test Suite", async function () { ], // Should have parsed correct severity [funcUri.fsPath]: [expectedFuncErrorDiagnostic], // Check parsed for other file }), - executeTaskAndWaitForResult(createBuildAllTask(folderContext)), + executeTaskAndWaitForResult(await createBuildAllTask(folderContext)), ]); await waitForNoRunningTasks(); @@ -284,7 +284,7 @@ suite("DiagnosticsManager Test Suite", async function () { ], // Should have parsed correct severity [funcUri.fsPath]: [expectedFuncErrorDiagnostic], // Check parsed for other file }), - executeTaskAndWaitForResult(createBuildAllTask(folderContext)), + executeTaskAndWaitForResult(await createBuildAllTask(folderContext)), ]); await waitForNoRunningTasks(); }); @@ -301,7 +301,7 @@ suite("DiagnosticsManager Test Suite", async function () { ], // Should have parsed correct severity [funcUri.fsPath]: [expectedFuncErrorDiagnostic], // Check parsed for other file }), - executeTaskAndWaitForResult(createBuildAllTask(folderContext)), + executeTaskAndWaitForResult(await createBuildAllTask(folderContext)), ]); await waitForNoRunningTasks(); @@ -350,7 +350,7 @@ suite("DiagnosticsManager Test Suite", async function () { waitForDiagnostics({ [cUri.fsPath]: [expectedDiagnostic1, expectedDiagnostic2], }), - executeTaskAndWaitForResult(createBuildAllTask(cFolderContext)), + executeTaskAndWaitForResult(await createBuildAllTask(cFolderContext)), ]); await waitForNoRunningTasks(); }); @@ -398,7 +398,7 @@ suite("DiagnosticsManager Test Suite", async function () { expectedDiagnostic3, ], }), - executeTaskAndWaitForResult(createBuildAllTask(cppFolderContext)), + executeTaskAndWaitForResult(await createBuildAllTask(cppFolderContext)), ]); await waitForNoRunningTasks(); @@ -1025,7 +1025,7 @@ suite("DiagnosticsManager Test Suite", async function () { test("Provides swift diagnostics", async () => { // Build for indexing - const task = createBuildAllTask(folderContext); + const task = await createBuildAllTask(folderContext); await executeTaskAndWaitForResult(task); const lspSource = toolchain.swiftVersion.isGreaterThanOrEqual(new Version(6, 0, 0)) @@ -1066,7 +1066,7 @@ suite("DiagnosticsManager Test Suite", async function () { test("Provides clang diagnostics", async () => { // Build for indexing - const task = createBuildAllTask(cFolderContext); + const task = await createBuildAllTask(cFolderContext); await executeTaskAndWaitForResult(task); // No string manipulation diff --git a/test/integration-tests/SwiftPackage.test.ts b/test/integration-tests/SwiftPackage.test.ts index 7e29cf209..ee998e164 100644 --- a/test/integration-tests/SwiftPackage.test.ts +++ b/test/integration-tests/SwiftPackage.test.ts @@ -27,22 +27,22 @@ suite("SwiftPackage Test Suite", () => { test("No package", async () => { const spmPackage = await SwiftPackage.create(testAssetUri("empty-folder"), toolchain); - assert.strictEqual(spmPackage.foundPackage, false); + assert.strictEqual(await spmPackage.foundPackage, false); }).timeout(10000); test("Invalid package", async () => { const spmPackage = await SwiftPackage.create(testAssetUri("invalid-package"), toolchain); - assert.strictEqual(spmPackage.foundPackage, true); - assert.strictEqual(spmPackage.isValid, false); + assert.strictEqual(await spmPackage.foundPackage, true); + assert.strictEqual(await spmPackage.isValid, false); }).timeout(10000); test("Library package", async () => { const spmPackage = await SwiftPackage.create(testAssetUri("package2"), toolchain); - assert.strictEqual(spmPackage.isValid, true); - assert.strictEqual(spmPackage.libraryProducts.length, 1); - assert.strictEqual(spmPackage.libraryProducts[0].name, "package2"); - assert.strictEqual(spmPackage.dependencies.length, 0); - assert.strictEqual(spmPackage.targets.length, 2); + assert.strictEqual(await spmPackage.isValid, true); + assert.strictEqual((await spmPackage.libraryProducts).length, 1); + assert.strictEqual((await spmPackage.libraryProducts)[0].name, "package2"); + assert.strictEqual((await spmPackage.dependencies).length, 0); + assert.strictEqual((await spmPackage.targets).length, 2); }).timeout(10000); test("Package resolve v2", async function () { @@ -57,14 +57,14 @@ suite("SwiftPackage Test Suite", () => { this.skip(); } const spmPackage = await SwiftPackage.create(testAssetUri("package5.6"), toolchain); - assert.strictEqual(spmPackage.isValid, true); + assert.strictEqual(await spmPackage.isValid, true); assert(spmPackage.resolved !== undefined); }).timeout(20000); test("Identity case-insensitivity", async () => { const spmPackage = await SwiftPackage.create(testAssetUri("identity-case"), toolchain); - assert.strictEqual(spmPackage.isValid, true); - assert.strictEqual(spmPackage.dependencies.length, 1); + assert.strictEqual(await spmPackage.isValid, true); + assert.strictEqual((await spmPackage.dependencies).length, 1); assert(spmPackage.resolved !== undefined); assert.strictEqual(spmPackage.resolved.pins.length, 1); assert.strictEqual(spmPackage.resolved.pins[0].identity, "yams"); @@ -72,8 +72,8 @@ suite("SwiftPackage Test Suite", () => { test("Identity different from name", async () => { const spmPackage = await SwiftPackage.create(testAssetUri("identity-different"), toolchain); - assert.strictEqual(spmPackage.isValid, true); - assert.strictEqual(spmPackage.dependencies.length, 1); + assert.strictEqual(await spmPackage.isValid, true); + assert.strictEqual((await spmPackage.dependencies).length, 1); assert(spmPackage.resolved !== undefined); assert.strictEqual(spmPackage.resolved.pins.length, 1); assert.strictEqual(spmPackage.resolved.pins[0].identity, "swift-log"); diff --git a/test/integration-tests/WorkspaceContext.test.ts b/test/integration-tests/WorkspaceContext.test.ts index afd14f630..56ef40653 100644 --- a/test/integration-tests/WorkspaceContext.test.ts +++ b/test/integration-tests/WorkspaceContext.test.ts @@ -65,7 +65,10 @@ suite("WorkspaceContext Test Suite", () => { await workspaceContext.addPackageFolder(testAssetUri("package2"), workspaceFolder); - const foldersNames = recordedFolders.map(({ folder }) => folder?.swiftPackage.name); + const foldersNamePromises = recordedFolders + .map(({ folder }) => folder?.swiftPackage.name) + .filter(f => !!f); + const foldersNames = await Promise.all(foldersNamePromises); assertContains(foldersNames, "package2"); const addedCount = recordedFolders.filter( @@ -82,7 +85,7 @@ suite("WorkspaceContext Test Suite", () => { }).timeout(60000 * 2); }); - suite("Tasks", async function () { + suite("Tasks", function () { activateExtensionForSuite({ async setup(ctx) { workspaceContext = ctx; @@ -107,7 +110,7 @@ suite("WorkspaceContext Test Suite", () => { ); assert(folder); await swiftConfig.update("diagnosticsStyle", undefined); - const buildAllTask = createBuildAllTask(folder); + const buildAllTask = await createBuildAllTask(folder); const execution = buildAllTask.execution; assert.strictEqual(buildAllTask.definition.type, "swift"); assert.strictEqual(buildAllTask.name, "Build All (defaultPackage)"); @@ -124,7 +127,7 @@ suite("WorkspaceContext Test Suite", () => { ); assert(folder); await swiftConfig.update("diagnosticsStyle", "default"); - const buildAllTask = createBuildAllTask(folder); + const buildAllTask = await createBuildAllTask(folder); const execution = buildAllTask.execution; assert.strictEqual(buildAllTask.definition.type, "swift"); assert.strictEqual(buildAllTask.name, "Build All (defaultPackage)"); @@ -140,7 +143,7 @@ suite("WorkspaceContext Test Suite", () => { ); assert(folder); await swiftConfig.update("diagnosticsStyle", "swift"); - const buildAllTask = createBuildAllTask(folder); + const buildAllTask = await createBuildAllTask(folder); const execution = buildAllTask.execution; assert.strictEqual(buildAllTask.definition.type, "swift"); assert.strictEqual(buildAllTask.name, "Build All (defaultPackage)"); @@ -158,7 +161,7 @@ suite("WorkspaceContext Test Suite", () => { assert(folder); await swiftConfig.update("diagnosticsStyle", undefined); await swiftConfig.update("buildArguments", ["--sanitize=thread"]); - const buildAllTask = createBuildAllTask(folder); + const buildAllTask = await createBuildAllTask(folder); const execution = buildAllTask.execution as SwiftExecution; assertContainsArg(execution, "--sanitize=thread"); await swiftConfig.update("buildArguments", []); @@ -171,7 +174,7 @@ suite("WorkspaceContext Test Suite", () => { assert(folder); await swiftConfig.update("diagnosticsStyle", undefined); await swiftConfig.update("packageArguments", ["--replace-scm-with-registry"]); - const buildAllTask = createBuildAllTask(folder); + const buildAllTask = await createBuildAllTask(folder); const execution = buildAllTask.execution as SwiftExecution; assertContainsArg(execution, "--replace-scm-with-registry"); await swiftConfig.update("packageArguments", []); diff --git a/test/integration-tests/tasks/SwiftPluginTaskProvider.test.ts b/test/integration-tests/tasks/SwiftPluginTaskProvider.test.ts index 85b17112a..4dc9395c6 100644 --- a/test/integration-tests/tasks/SwiftPluginTaskProvider.test.ts +++ b/test/integration-tests/tasks/SwiftPluginTaskProvider.test.ts @@ -128,7 +128,7 @@ suite("SwiftPluginTaskProvider Test Suite", function () { }); suite("provideTasks", () => { - suite("includes command plugin provided by the extension", async () => { + suite("includes command plugin provided by the extension", () => { let task: SwiftTask | undefined; setup(async () => { @@ -154,7 +154,7 @@ suite("SwiftPluginTaskProvider Test Suite", function () { }); }); - suite("includes command plugin provided by tasks.json", async () => { + suite("includes command plugin provided by tasks.json", () => { let task: vscode.Task | undefined; setup(async () => { diff --git a/test/integration-tests/tasks/SwiftTaskProvider.test.ts b/test/integration-tests/tasks/SwiftTaskProvider.test.ts index d28657fac..bbce1d457 100644 --- a/test/integration-tests/tasks/SwiftTaskProvider.test.ts +++ b/test/integration-tests/tasks/SwiftTaskProvider.test.ts @@ -171,12 +171,14 @@ suite("SwiftTaskProvider Test Suite", () => { suite("createBuildAllTask", () => { test("should return same task instance", async () => { - expect(createBuildAllTask(folderContext)).to.equal(createBuildAllTask(folderContext)); + expect(await createBuildAllTask(folderContext)).to.equal( + await createBuildAllTask(folderContext) + ); }); test("different task returned for release mode", async () => { - expect(createBuildAllTask(folderContext)).to.not.equal( - createBuildAllTask(folderContext, true) + expect(await createBuildAllTask(folderContext)).to.not.equal( + await createBuildAllTask(folderContext, true) ); }); }); @@ -187,7 +189,7 @@ suite("SwiftTaskProvider Test Suite", () => { test("creates build all task when it cannot find one", async () => { tasksMock.fetchTasks.resolves([]); await expect(getBuildAllTask(folderContext)).to.eventually.equal( - createBuildAllTask(folderContext) + await createBuildAllTask(folderContext) ); }); }); diff --git a/test/integration-tests/testexplorer/LSPTestDiscovery.test.ts b/test/integration-tests/testexplorer/LSPTestDiscovery.test.ts index 7e109d6d9..e34f0e71e 100644 --- a/test/integration-tests/testexplorer/LSPTestDiscovery.test.ts +++ b/test/integration-tests/testexplorer/LSPTestDiscovery.test.ts @@ -180,12 +180,29 @@ suite("LSPTestDiscovery Suite", () => { })); }); + function assertEqual(items: TestClass[], expected: TestClass[]) { + // There is an issue comparing vscode.Uris directly. + // The internal `_fsPath` is not initialized immediately, and so + // could be undefined, or maybe not. + const convertedItems = items.map(item => ({ + ...item, + location: item.location?.uri.path, + range: item.location?.range, + })); + const convertedExpected = expected.map(item => ({ + ...item, + location: item.location?.uri.path, + range: item.location?.range, + })); + assert.deepStrictEqual(convertedItems, convertedExpected); + } + test(TextDocumentTestsRequest.method, async () => { client.setResponse(TextDocumentTestsRequest.type, items); const testClasses = await discoverer.getDocumentTests(pkg, file); - assert.deepStrictEqual(testClasses, expected); + assertEqual(testClasses, expected); }); test(WorkspaceTestsRequest.method, async () => { @@ -193,7 +210,7 @@ suite("LSPTestDiscovery Suite", () => { const testClasses = await discoverer.getWorkspaceTests(pkg); - assert.deepStrictEqual(testClasses, expected); + assertEqual(testClasses, expected); }); test("converts LSP XCTest IDs", async () => { @@ -207,8 +224,7 @@ suite("LSPTestDiscovery Suite", () => { client.setResponse(WorkspaceTestsRequest.type, items); const testClasses = await discoverer.getWorkspaceTests(pkg); - - assert.deepStrictEqual(testClasses, expected); + assertEqual(testClasses, expected); }); test("Prepends test target to ID", async () => { @@ -227,15 +243,12 @@ suite("LSPTestDiscovery Suite", () => { type: TargetType.test, sources: [], }; - pkg.getTargets = () => [target]; - pkg.getTarget = () => target; + pkg.getTargets = () => Promise.resolve([target]); + pkg.getTarget = () => Promise.resolve(target); const testClasses = await discoverer.getWorkspaceTests(pkg); - assert.deepStrictEqual( - testClasses.map(({ id }) => id), - expected.map(({ id }) => id) - ); + assertEqual(testClasses, expected); }); }); }); diff --git a/test/integration-tests/testexplorer/TestDiscovery.test.ts b/test/integration-tests/testexplorer/TestDiscovery.test.ts index b7fae9cf4..513202f84 100644 --- a/test/integration-tests/testexplorer/TestDiscovery.test.ts +++ b/test/integration-tests/testexplorer/TestDiscovery.test.ts @@ -193,25 +193,25 @@ suite("TestDiscovery Suite", () => { }); test("updates tests from classes within a swift package", async () => { - const file = vscode.Uri.file("file:///some/file.swift"); - const swiftPackage = await SwiftPackage.create(file, await SwiftToolchain.create()); + const targetFolder = vscode.Uri.file("file:///some/"); + const swiftPackage = await SwiftPackage.create(targetFolder, await SwiftToolchain.create()); const testTargetName = "TestTarget"; const target: Target = { c99name: testTargetName, name: testTargetName, - path: file.fsPath, + path: targetFolder.fsPath, type: TargetType.test, sources: [], }; - swiftPackage.getTargets = () => [target]; - swiftPackage.getTarget = () => target; + swiftPackage.getTargets = () => Promise.resolve([target]); + swiftPackage.getTarget = () => Promise.resolve(target); const item = testItem("bar"); item.location = new vscode.Location( - vscode.Uri.file("file:///another/file.swift"), + vscode.Uri.file("file:///some/file.swift"), new vscode.Range(new vscode.Position(1, 0), new vscode.Position(2, 0)) ); - updateTestsFromClasses(testController, swiftPackage, [item]); + await updateTestsFromClasses(testController, swiftPackage, [item]); assert.deepStrictEqual(testControllerChildren(testController.items), [ { diff --git a/test/integration-tests/utilities/testutilities.ts b/test/integration-tests/utilities/testutilities.ts index 23a7530cc..1567c6876 100644 --- a/test/integration-tests/utilities/testutilities.ts +++ b/test/integration-tests/utilities/testutilities.ts @@ -208,7 +208,7 @@ const extensionBootstrapper = (() => { await waitForNoRunningTasks({ timeout: 10000 }); // Close all editors before deactivating the extension. - closeAllEditors(); + await closeAllEditors(); await activatedAPI.workspaceContext?.removeWorkspaceFolder(getRootWorkspaceFolder()); await activatedAPI.deactivate(); diff --git a/test/unit-tests/tasks/SwiftTaskProvider.test.ts b/test/unit-tests/tasks/SwiftTaskProvider.test.ts index f5523e79f..a0f340346 100644 --- a/test/unit-tests/tasks/SwiftTaskProvider.test.ts +++ b/test/unit-tests/tasks/SwiftTaskProvider.test.ts @@ -47,7 +47,7 @@ suite("SwiftTaskProvider Unit Test Suite", () => { const platformMock = mockGlobalValue(process, "platform"); - setup(async () => { + setup(() => { buildFlags = mockObject({ withAdditionalFlags: mockFn(s => s.callsFake(arr => arr)), }); @@ -74,7 +74,7 @@ suite("SwiftTaskProvider Unit Test Suite", () => { }); suite("platformDebugBuildOptions", () => { - test("windows, before 5.9", async () => { + test("windows, before 5.9", () => { platformMock.setValue("win32"); toolchain.swiftVersion = new Version(5, 8, 1); @@ -88,7 +88,7 @@ suite("SwiftTaskProvider Unit Test Suite", () => { ]); }); - test("windows, after 5.9", async () => { + test("windows, after 5.9", () => { platformMock.setValue("win32"); const expected = ["-Xlinker", "-debug:dwarf"]; @@ -99,13 +99,13 @@ suite("SwiftTaskProvider Unit Test Suite", () => { assert.deepEqual(platformDebugBuildOptions(instance(toolchain)), expected); }); - test("linux", async () => { + test("linux", () => { platformMock.setValue("linux"); assert.deepEqual(platformDebugBuildOptions(instance(toolchain)), []); }); - test("macOS", async () => { + test("macOS", () => { platformMock.setValue("darwin"); assert.deepEqual(platformDebugBuildOptions(instance(toolchain)), []); @@ -123,17 +123,17 @@ suite("SwiftTaskProvider Unit Test Suite", () => { diagnosticsStyle.setValue("default"); }); - test("include debug options", async () => { + test("include debug options", () => { platformMock.setValue("win32"); assert.deepEqual(buildOptions(instance(toolchain), true), ["-Xlinker", "-debug:dwarf"]); }); - test("don't include debug options", async () => { + test("don't include debug options", () => { platformMock.setValue("win32"); assert.deepEqual(buildOptions(instance(toolchain), false), []); }); - test("include diagnostic style", async () => { + test("include diagnostic style", () => { diagnosticsStyle.setValue("llvm"); assert.deepEqual(buildOptions(instance(toolchain), false), [ "-Xswiftc", @@ -141,7 +141,7 @@ suite("SwiftTaskProvider Unit Test Suite", () => { ]); }); - test("include sanitizer flags", async () => { + test("include sanitizer flags", () => { const sanitizer = mockObject({ buildFlags: ["--sanitize=thread"], }); @@ -151,7 +151,7 @@ suite("SwiftTaskProvider Unit Test Suite", () => { assert.deepEqual(buildOptions(instance(toolchain), false), ["--sanitize=thread"]); }); - test("include build flags", async () => { + test("include build flags", () => { buildArgs.setValue(["-DFOO"]); assert.deepEqual(buildOptions(instance(toolchain), false), ["-DFOO"]); @@ -161,7 +161,7 @@ suite("SwiftTaskProvider Unit Test Suite", () => { suite("createSwiftTask", () => { const envConfig = mockGlobalValue(configuration, "swiftEnvironmentVariables"); - test("uses SwiftExecution", async () => { + test("uses SwiftExecution", () => { const task = createSwiftTask( ["--help"], "help", @@ -171,15 +171,14 @@ suite("SwiftTaskProvider Unit Test Suite", () => { assert.equal(task.execution instanceof SwiftExecution, true); }); - test("uses toolchain swift path", async () => { + test("uses toolchain swift path", () => { const task = createSwiftTask( ["--help"], "help", { cwd: workspaceFolder.uri, scope: vscode.TaskScope.Workspace }, instance(toolchain) ); - const execution = task.execution as SwiftExecution; - assert.equal(execution.command, "/path/to/bin/swift"); + assert.equal(task.execution.command, "/path/to/bin/swift"); }); test("include sdk flags", () => { @@ -192,8 +191,7 @@ suite("SwiftTaskProvider Unit Test Suite", () => { { cwd: workspaceFolder.uri, scope: vscode.TaskScope.Workspace }, instance(toolchain) ); - const execution = task.execution as SwiftExecution; - assert.deepEqual(execution.args, [ + assert.deepEqual(task.execution.args, [ "build", "--sdk", "/path/to/sdk", @@ -210,8 +208,7 @@ suite("SwiftTaskProvider Unit Test Suite", () => { instance(toolchain), { BAZ: "2" } ); - const execution = task.execution as SwiftExecution; - assert.deepEqual(execution.options.env, { FOO: "1", BAZ: "2" }); + assert.deepEqual(task.execution.options.env, { FOO: "1", BAZ: "2" }); }); test("include presentation", () => { @@ -296,7 +293,7 @@ suite("SwiftTaskProvider Unit Test Suite", () => { }); suite("resolveTask", () => { - test("uses SwiftExecution", async () => { + test("uses SwiftExecution", () => { const taskProvider = new SwiftTaskProvider(instance(workspaceContext)); const task = new vscode.Task( { @@ -314,7 +311,7 @@ suite("SwiftTaskProvider Unit Test Suite", () => { assert.equal(resolvedTask.execution instanceof SwiftExecution, true); }); - test("uses toolchain swift path", async () => { + test("uses toolchain swift path", () => { const taskProvider = new SwiftTaskProvider(instance(workspaceContext)); const task = new vscode.Task( { @@ -334,7 +331,7 @@ suite("SwiftTaskProvider Unit Test Suite", () => { }); suite("Platform cwd", () => { - test("includes macos cwd", async () => { + test("includes macos cwd", () => { platformMock.setValue("darwin"); const taskProvider = new SwiftTaskProvider(instance(workspaceContext)); const task = new vscode.Task( @@ -358,7 +355,7 @@ suite("SwiftTaskProvider Unit Test Suite", () => { assert.equal(swiftExecution.options.cwd, `${workspaceFolder.uri.fsPath}/macos`); }); - test("includes linux cwd", async () => { + test("includes linux cwd", () => { platformMock.setValue("linux"); const taskProvider = new SwiftTaskProvider(instance(workspaceContext)); const task = new vscode.Task( @@ -382,7 +379,7 @@ suite("SwiftTaskProvider Unit Test Suite", () => { assert.equal(swiftExecution.options.cwd, `${workspaceFolder.uri.fsPath}/linux`); }); - test("includes windows cwd", async () => { + test("includes windows cwd", () => { platformMock.setValue("win32"); const taskProvider = new SwiftTaskProvider(instance(workspaceContext)); const task = new vscode.Task( @@ -406,7 +403,7 @@ suite("SwiftTaskProvider Unit Test Suite", () => { assert.equal(swiftExecution.options.cwd, `${workspaceFolder.uri.fsPath}/windows`); }); - test("fallback default cwd", async () => { + test("fallback default cwd", () => { platformMock.setValue("darwin"); const taskProvider = new SwiftTaskProvider(instance(workspaceContext)); const task = new vscode.Task( @@ -432,7 +429,7 @@ suite("SwiftTaskProvider Unit Test Suite", () => { }); suite("Platform env", () => { - test("includes macos env", async () => { + test("includes macos env", () => { platformMock.setValue("darwin"); const taskProvider = new SwiftTaskProvider(instance(workspaceContext)); const task = new vscode.Task( @@ -460,7 +457,7 @@ suite("SwiftTaskProvider Unit Test Suite", () => { assert.equal(swiftExecution.options.env?.FOO, "baz"); }); - test("includes linux env", async () => { + test("includes linux env", () => { platformMock.setValue("linux"); const taskProvider = new SwiftTaskProvider(instance(workspaceContext)); const task = new vscode.Task( @@ -488,7 +485,7 @@ suite("SwiftTaskProvider Unit Test Suite", () => { assert.equal(swiftExecution.options.env?.FOO, "baz"); }); - test("includes windows env", async () => { + test("includes windows env", () => { platformMock.setValue("win32"); const taskProvider = new SwiftTaskProvider(instance(workspaceContext)); const task = new vscode.Task( @@ -516,7 +513,7 @@ suite("SwiftTaskProvider Unit Test Suite", () => { assert.equal(swiftExecution.options.env?.FOO, "baz"); }); - test("fallback default env", async () => { + test("fallback default env", () => { platformMock.setValue("darwin"); const taskProvider = new SwiftTaskProvider(instance(workspaceContext)); const task = new vscode.Task( @@ -546,7 +543,7 @@ suite("SwiftTaskProvider Unit Test Suite", () => { }); suite("Platform args", () => { - test("includes macos args", async () => { + test("includes macos args", () => { platformMock.setValue("darwin"); const taskProvider = new SwiftTaskProvider(instance(workspaceContext)); const task = new vscode.Task( @@ -569,7 +566,7 @@ suite("SwiftTaskProvider Unit Test Suite", () => { assert.deepEqual(swiftExecution.args, ["run", "MacosPackageExe"]); }); - test("includes linux args", async () => { + test("includes linux args", () => { platformMock.setValue("linux"); const taskProvider = new SwiftTaskProvider(instance(workspaceContext)); const task = new vscode.Task( @@ -592,7 +589,7 @@ suite("SwiftTaskProvider Unit Test Suite", () => { assert.deepEqual(swiftExecution.args, ["run", "LinuxPackageExe"]); }); - test("includes windows args", async () => { + test("includes windows args", () => { platformMock.setValue("win32"); const taskProvider = new SwiftTaskProvider(instance(workspaceContext)); const task = new vscode.Task( @@ -615,7 +612,7 @@ suite("SwiftTaskProvider Unit Test Suite", () => { assert.deepEqual(swiftExecution.args, ["run", "WinPackageExe"]); }); - test("fallback default args", async () => { + test("fallback default args", () => { platformMock.setValue("darwin"); const taskProvider = new SwiftTaskProvider(instance(workspaceContext)); const task = new vscode.Task( diff --git a/test/unit-tests/toolchain/BuildFlags.test.ts b/test/unit-tests/toolchain/BuildFlags.test.ts index 0d57cade7..82853a188 100644 --- a/test/unit-tests/toolchain/BuildFlags.test.ts +++ b/test/unit-tests/toolchain/BuildFlags.test.ts @@ -26,7 +26,7 @@ suite("BuildFlags Test Suite", () => { const sandboxConfig = mockGlobalValue(configuration, "disableSandbox"); - suiteSetup(async () => { + suiteSetup(() => { mockedToolchain = mockObject({ swiftVersion: new Version(6, 0, 0), }); @@ -83,7 +83,7 @@ suite("BuildFlags Test Suite", () => { const sdkConfig = mockGlobalValue(configuration, "sdk"); const swiftSDKConfig = mockGlobalValue(configuration, "swiftSDK"); - test("no configuration provided", async () => { + test("no configuration provided", () => { sdkConfig.setValue(""); swiftSDKConfig.setValue(""); expect(buildFlags.swiftpmSDKFlags()).to.be.an("array").that.is.empty; @@ -173,7 +173,7 @@ suite("BuildFlags Test Suite", () => { suite("buildPathFlags", () => { const buildPathConfig = mockGlobalValue(configuration, "buildPath"); - test("no configuration provided", async () => { + test("no configuration provided", () => { buildPathConfig.setValue(""); expect(buildFlags.buildPathFlags()).to.be.an("array").that.is.empty; }); @@ -196,7 +196,7 @@ suite("BuildFlags Test Suite", () => { }); }); - suite("buildDirectoryFromWorkspacePath", async () => { + suite("buildDirectoryFromWorkspacePath", () => { const buildPathConfig = mockGlobalValue(configuration, "buildPath"); test("no configuration provided", () => { diff --git a/test/unit-tests/ui/ReloadExtension.test.ts b/test/unit-tests/ui/ReloadExtension.test.ts index 422bfce23..fe17b48ae 100644 --- a/test/unit-tests/ui/ReloadExtension.test.ts +++ b/test/unit-tests/ui/ReloadExtension.test.ts @@ -17,7 +17,7 @@ import * as vscode from "vscode"; import { showReloadExtensionNotification } from "../../../src/ui/ReloadExtension"; import { Workbench } from "../../../src/utilities/commands"; -suite("showReloadExtensionNotification()", async function () { +suite("showReloadExtensionNotification()", function () { const mockedVSCodeWindow = mockGlobalObject(vscode, "window"); const mockedVSCodeCommands = mockGlobalObject(vscode, "commands"); diff --git a/test/unit-tests/ui/SwiftBuildStatus.test.ts b/test/unit-tests/ui/SwiftBuildStatus.test.ts index 36c5e3b57..050a14910 100644 --- a/test/unit-tests/ui/SwiftBuildStatus.test.ts +++ b/test/unit-tests/ui/SwiftBuildStatus.test.ts @@ -28,7 +28,7 @@ import { TestSwiftProcess } from "../../fixtures"; import { StatusItem } from "../../../src/ui/StatusItem"; import { SwiftBuildStatus } from "../../../src/ui/SwiftBuildStatus"; -suite("SwiftBuildStatus Unit Test Suite", async function () { +suite("SwiftBuildStatus Unit Test Suite", function () { const windowMock = mockGlobalObject(vscode, "window"); const didStartTaskMock = mockGlobalEvent(vscode.tasks, "onDidStartTask"); const configurationMock = mockGlobalValue(configuration, "showBuildStatus");