DavidSchuldenfrei/gtest-adapter

Support of multi root workspaces

Opened this issue · 3 comments

It seems like the extension doesn't support multi root workspaces. I added the "gtest-adapter.debugConfig": setting with an existing debug config as value to the .code-workspace file but the extension is unable to find it. If i try to switch the configuration i get a popup saing "You first need to define a debug configuration, for your tests".

Is it correct that the gtest-adapter extension doesn't support multi root workspaces or is just my configuration wrong?

Edit: I now added a launch config to the .code-workspace file instead of the launch.json. Now it detects the configuration but it's nevertheless unable to parse any tests.

The issue seems to be here:

const debugConfigs = workspace.getConfiguration("launch", null).get("configurations") as Array<CppDebugConfig>;
return debugConfigs.filter(config => namesSet.has(config.name));

Note that the scope passed to getConfiguration is null. This method can be passed a WorkspaceFolder as a ConfigurationScope.

So presumably it just needs a little extra work getting the WorkspaceFolders and searching through them. It might be a little hairy, because it sounds like things get messy when there's both workspace files and launch.json.

Unfortunately, Javascript is not my jam, and I'm not sure I have the mental bandwidth to put together a properly tested PR.

So I did a dive into this, and here's what's actually going on.

In a multi root workspace, there are times when you need to scope a substitution variable, esp. ${workspaceFolder}, to a specific folder. For example, ${workspaceFolder:MyProject} substitutes the workspace path for your MyProject folder.

GoogleTestAdapter tries to parse your configuration manually, and it does not support such scoping:

public static expandEnv(path: string, workspaceFolder: string): string {
path = path.replace("${workspaceFolder}", workspaceFolder);
path = path.replace("${workspaceRoot}", workspaceFolder); //Deprecated but might still be used.
return path;
}

The easy remedy as a user is to get rid of such variables in your task configuration and hard code the values in, i.e. replace ${workspaceFolder:MyProject} wtih /path/to/MyProject. For me, this is making my test show up in the GoogleTests panel.

There's also another catch I found: GoogleTestAdapter will only read the folder that's specified first in your workspace file:

private getWorkspaceFolder(): string {
const folders = workspace.workspaceFolders;
if (!folders || folders.length == 0)
return '';
const uri = folders[0].uri;
return uri.fsPath;
}