Skip to content

Commit 5765286

Browse files
authored
Ensure tests in root directory are displayed (#5329)
1 parent 1799d75 commit 5765286

5 files changed

Lines changed: 811 additions & 622 deletions

File tree

src/client/testing/common/services/discoveredTestParser.ts

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,14 @@ import * as path from 'path';
88
import { Uri } from 'vscode';
99
import { IWorkspaceService } from '../../../common/application/types';
1010
import { traceError } from '../../../common/logger';
11-
import { IFileSystem } from '../../../common/platform/types';
1211
import { TestDataItem } from '../../types';
1312
import { getParentFile, getParentSuite, getTestType } from '../testUtils';
1413
import { FlattenedTestFunction, FlattenedTestSuite, SubtestParent, TestFile, TestFolder, TestFunction, Tests, TestSuite, TestType } from '../types';
1514
import { DiscoveredTests, ITestDiscoveredTestParser, TestContainer, TestItem } from './types';
1615

1716
@injectable()
1817
export class TestDiscoveredTestParser implements ITestDiscoveredTestParser {
19-
constructor(@inject(IFileSystem) private readonly fs: IFileSystem,
20-
@inject(IWorkspaceService) private readonly workspaceService: IWorkspaceService) { }
18+
constructor(@inject(IWorkspaceService) private readonly workspaceService: IWorkspaceService) { }
2119
public parse(resource: Uri, discoveredTests: DiscoveredTests[]): Tests {
2220
const tests: Tests = {
2321
rootTestFolders: [],
@@ -43,30 +41,10 @@ export class TestDiscoveredTestParser implements ITestDiscoveredTestParser {
4341
tests.rootTestFolders.push(rootFolder);
4442
tests.testFolders.push(rootFolder);
4543
this.buildChildren(rootFolder, rootFolder, data, tests);
46-
this.fixRootFolders(workspace.uri, data, tests);
4744
}
4845

4946
return tests;
5047
}
51-
/**
52-
* Users workspace folder is not to be treated as the root.
53-
* All root folders are relative to the worspace folder.
54-
* @protected
55-
* @param {Uri} workspaceFolder
56-
* @param {DiscoveredTests} discoveredTests
57-
* @param {Tests} tests
58-
* @returns {void}
59-
* @memberof TestDiscoveredTestParser
60-
*/
61-
protected fixRootFolders(workspaceFolder: Uri, discoveredTests: DiscoveredTests, tests: Tests): void {
62-
const isWorkspaceFolderTheRoot = this.fs.arePathsSame(discoveredTests.root, workspaceFolder.fsPath);
63-
if (!isWorkspaceFolderTheRoot) {
64-
return;
65-
}
66-
const indexToRemove = tests.rootTestFolders.findIndex(folder => folder.name === discoveredTests.root);
67-
const rootFolder = tests.rootTestFolders.splice(indexToRemove, 1)[0];
68-
tests.rootTestFolders.push(...rootFolder.folders);
69-
}
7048
/**
7149
* Not the best solution to use `case statements`, but it keeps the code simple and easy to read in one place.
7250
* Could go with separate classes for each type and use stratergies, but that just ends up a class for

src/client/testing/explorer/testTreeViewProvider.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,17 @@
44
'use strict';
55

66
import { inject, injectable } from 'inversify';
7+
import * as path from 'path';
78
import { Event, EventEmitter, TreeItem, TreeItemCollapsibleState, Uri } from 'vscode';
89
import { ICommandManager, IWorkspaceService } from '../../common/application/types';
910
import { Commands } from '../../common/constants';
11+
import { IFileSystem } from '../../common/platform/types';
1012
import { IDisposable, IDisposableRegistry } from '../../common/types';
1113
import { sendTelemetryEvent } from '../../telemetry';
1214
import { EventName } from '../../telemetry/constants';
1315
import { CommandSource } from '../common/constants';
1416
import { getChildren, getParent, getTestType } from '../common/testUtils';
15-
import { ITestCollectionStorageService, TestStatus, TestType } from '../common/types';
17+
import { ITestCollectionStorageService, Tests, TestStatus, TestType } from '../common/types';
1618
import { ITestDataItemResource, ITestManagementService, ITestTreeViewProvider, TestDataItem, TestWorkspaceFolder, WorkspaceTestStatus } from '../types';
1719
import { TestTreeItem } from './testTreeViewItem';
1820

@@ -30,6 +32,7 @@ export class TestTreeViewProvider implements ITestTreeViewProvider, ITestDataIte
3032
@inject(ITestManagementService) private testService: ITestManagementService,
3133
@inject(IWorkspaceService) private readonly workspace: IWorkspaceService,
3234
@inject(ICommandManager) private readonly commandManager: ICommandManager,
35+
@inject(IFileSystem) private readonly fs: IFileSystem,
3336
@inject(IDisposableRegistry) disposableRegistry: IDisposableRegistry
3437
) {
3538
this.onDidChangeTreeData = this._onDidChangeTreeData.event;
@@ -92,7 +95,7 @@ export class TestTreeViewProvider implements ITestTreeViewProvider, ITestDataIte
9295
await this.commandManager.executeCommand(Commands.Tests_Discover, element, CommandSource.testExplorer, undefined);
9396
tests = this.testStore.getTests(element.workspaceFolder.uri);
9497
}
95-
return tests ? tests.rootTestFolders : [];
98+
return this.getRootNodes(tests);
9699
}
97100
return getChildren(element!);
98101
}
@@ -106,7 +109,7 @@ export class TestTreeViewProvider implements ITestTreeViewProvider, ITestDataIte
106109
// If we are in a single workspace
107110
if (this.workspace.workspaceFolders.length === 1) {
108111
const tests = this.testStore.getTests(this.workspace.workspaceFolders[0].uri);
109-
return tests ? tests.rootTestFolders : [];
112+
return this.getRootNodes(tests);
110113
}
111114

112115
// If we are in a mult-root workspace, then nest the test data within a
@@ -131,7 +134,23 @@ export class TestTreeViewProvider implements ITestTreeViewProvider, ITestDataIte
131134
const tests = this.testStore.getTests(element.resource);
132135
return tests ? getParent(tests, element) : undefined;
133136
}
134-
137+
/**
138+
* If we have test files directly in root directory, return those.
139+
* If we have test folders and no test files under the root directory, then just return the test directories.
140+
* The goal is not avoid returning an empty root node, when all it contains are child nodes for folders.
141+
*
142+
* @param {Tests} [tests]
143+
* @returns
144+
* @memberof TestTreeViewProvider
145+
*/
146+
public getRootNodes(tests?: Tests) {
147+
if (tests && tests.rootTestFolders && tests.rootTestFolders.length === 1) {
148+
const rootFolder = tests.rootTestFolders[0].name;
149+
const testFiles = tests.testFiles.filter(file => this.fs.arePathsSame(path.dirname(file.fullPath), rootFolder));
150+
return [...testFiles, ...tests.rootTestFolders[0].folders];
151+
}
152+
return tests ? tests.rootTestFolders : [];
153+
}
135154
/**
136155
* Refresh the view by rebuilding the model and signaling the tree view to update itself.
137156
*

src/test/testing/explorer/explorerTestData.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { CommandManager } from '../../../client/common/application/commandManage
1515
import {
1616
IApplicationShell, ICommandManager, IWorkspaceService
1717
} from '../../../client/common/application/types';
18+
import { FileSystem } from '../../../client/common/platform/fileSystem';
1819
import {
1920
IDisposable, IDisposableRegistry
2021
} from '../../../client/common/types';
@@ -255,6 +256,7 @@ export function createMockTestExplorer(
255256
dispRegMoq.setup(d => d.push(typemoq.It.isAny()));
256257

257258
return new TestTreeViewProvider(
258-
testStore, unitTestMgmtService, workspaceService, commandManager, dispRegMoq.object
259+
testStore, unitTestMgmtService, workspaceService, commandManager,
260+
tsmockito.instance(tsmockito.mock(FileSystem)), dispRegMoq.object
259261
);
260262
}

0 commit comments

Comments
 (0)