refactor: Decouple the codelens provider and test file watchers (#1178)
This commit is contained in:
Родитель
e78bb34729
Коммит
e0de9672cc
|
@ -10,3 +10,4 @@ export * from './src/protocols';
|
|||
export * from './src/utils/commandUtils';
|
||||
export * from './src/testFileWatcher';
|
||||
export * from './src/runners/runnerScheduler';
|
||||
export * from './src/provider/testSourceProvider';
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
|
||||
package com.microsoft.java.test.plugin.util;
|
||||
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.jdt.core.IClasspathAttribute;
|
||||
|
@ -27,12 +26,11 @@ import java.net.URISyntaxException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.eclipse.jdt.ls.core.internal.ProjectUtils.WORKSPACE_LINK;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public final class ProjectTestUtils {
|
||||
|
||||
|
@ -49,24 +47,46 @@ public final class ProjectTestUtils {
|
|||
* @throws JavaModelException
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static String[] listTestSourcePaths(List<Object> arguments, IProgressMonitor monitor)
|
||||
public static List<TestSourcePath> listTestSourcePaths(List<Object> arguments, IProgressMonitor monitor)
|
||||
throws JavaModelException {
|
||||
final List<String> resultList = new ArrayList<>();
|
||||
final List<TestSourcePath> resultList = new ArrayList<>();
|
||||
if (arguments == null || arguments.size() == 0) {
|
||||
return new String[0];
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final ArrayList<String> uriArray = ((ArrayList<String>) arguments.get(0));
|
||||
for (final String uri : uriArray) {
|
||||
final Set<IJavaProject> projectSet = parseProjects(uri);
|
||||
for (final IJavaProject project : projectSet) {
|
||||
for (final IPath path : getTestPath(project)) {
|
||||
final IPath relativePath = path.makeRelativeTo(project.getPath());
|
||||
resultList.add(project.getProject().getFolder(relativePath).getLocation().toOSString());
|
||||
}
|
||||
resultList.addAll(getTestSourcePaths(project));
|
||||
}
|
||||
}
|
||||
return resultList.toArray(new String[resultList.size()]);
|
||||
return resultList;
|
||||
}
|
||||
|
||||
public static List<TestSourcePath> getTestSourcePaths(IJavaProject project) throws JavaModelException {
|
||||
final List<TestSourcePath> paths = new LinkedList<>();
|
||||
for (final IClasspathEntry entry : project.getRawClasspath()) {
|
||||
// Ignore default project
|
||||
if (ProjectsManager.DEFAULT_PROJECT_NAME.equals(project.getProject().getName())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry.getEntryKind() != ClasspathEntry.CPE_SOURCE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isTestEntry(entry)) {
|
||||
paths.add(new TestSourcePath(parseTestSourcePathString(entry, project), true));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Always return true Eclipse & invisible project
|
||||
if (ProjectUtils.isGeneralJavaProject(project.getProject())) {
|
||||
paths.add(new TestSourcePath(parseTestSourcePathString(entry, project), false));
|
||||
}
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
|
||||
public static Set<IJavaProject> parseProjects(String uriStr) {
|
||||
|
@ -75,31 +95,29 @@ public final class ProjectTestUtils {
|
|||
return Collections.emptySet();
|
||||
}
|
||||
return Arrays.stream(ProjectUtils.getJavaProjects())
|
||||
.filter(p -> isProjectBelongToPath(p.getProject(), parentPath))
|
||||
.filter(p -> ResourceUtils.isContainedIn(ProjectUtils.getProjectRealFolder(p.getProject()),
|
||||
Arrays.asList(parentPath)))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public static List<IPath> getTestPath(IJavaProject project) throws JavaModelException {
|
||||
final IClasspathEntry[] entries = project.getRawClasspath();
|
||||
return Arrays.stream(entries)
|
||||
.filter(entry -> isTest(project, entry))
|
||||
.map(entry -> entry.getPath())
|
||||
.collect(Collectors.toList());
|
||||
private static String parseTestSourcePathString(IClasspathEntry entry, IJavaProject project) {
|
||||
final IPath relativePath = entry.getPath().makeRelativeTo(project.getPath());
|
||||
return project.getProject().getFolder(relativePath).getLocation().toOSString();
|
||||
}
|
||||
|
||||
public static boolean isTest(IJavaProject project, IPath path) {
|
||||
public static boolean isTest(IJavaProject project, IPath path, boolean containsGeneral) {
|
||||
try {
|
||||
final IClasspathEntry entry = project.getClasspathEntryFor(path);
|
||||
if (entry == null) {
|
||||
return false;
|
||||
}
|
||||
return isTest(project, entry);
|
||||
return isTest(project, entry, containsGeneral);
|
||||
} catch (final JavaModelException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isTest(IJavaProject project, IClasspathEntry entry) {
|
||||
public static boolean isTest(IJavaProject project, IClasspathEntry entry, boolean containsGeneral) {
|
||||
// Ignore default project
|
||||
if (ProjectsManager.DEFAULT_PROJECT_NAME.equals(project.getProject().getName())) {
|
||||
return false;
|
||||
|
@ -109,12 +127,12 @@ public final class ProjectTestUtils {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Always return true Eclipse & invisible project
|
||||
if (ProjectUtils.isGeneralJavaProject(project.getProject())) {
|
||||
if (isTestEntry(entry)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return isTestEntry(entry);
|
||||
// Always return true Eclipse & invisible project
|
||||
return containsGeneral && ProjectUtils.isGeneralJavaProject(project.getProject());
|
||||
}
|
||||
|
||||
public static boolean isTestEntry(IClasspathEntry entry) {
|
||||
|
@ -133,19 +151,17 @@ public final class ProjectTestUtils {
|
|||
return false;
|
||||
}
|
||||
|
||||
public static boolean isProjectBelongToPath(IProject project, IPath path) {
|
||||
// Check for visible project
|
||||
if (project.getLocation() != null && path.isPrefixOf(project.getLocation())) {
|
||||
return true;
|
||||
static class TestSourcePath {
|
||||
public String testSourcePath;
|
||||
/**
|
||||
* All the source paths from eclipse and invisible project will be treated as test source
|
||||
* even they are not marked as test in the classpath entry, in that case, this field will be false.
|
||||
*/
|
||||
public boolean isStrict;
|
||||
|
||||
public TestSourcePath(String testSourcePath, boolean isStrict) {
|
||||
this.testSourcePath = testSourcePath;
|
||||
this.isStrict = isStrict;
|
||||
}
|
||||
|
||||
|
||||
// Check for invisible project
|
||||
final IPath linkedLocation = project.getFolder(WORKSPACE_LINK).getLocation();
|
||||
if (linkedLocation != null && path.isPrefixOf(linkedLocation)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -290,7 +290,7 @@ public class TestSearchUtils {
|
|||
private static boolean isInTestScope(IJavaElement element) throws JavaModelException {
|
||||
final IJavaProject project = element.getJavaProject();
|
||||
for (final IPath sourcePath : ProjectUtils.listSourcePaths(project)) {
|
||||
if (!ProjectTestUtils.isTest(project, sourcePath)) {
|
||||
if (!ProjectTestUtils.isTest(project, sourcePath, true /*containsGeneralProject*/)) {
|
||||
continue;
|
||||
}
|
||||
if (sourcePath.isPrefixOf(element.getPath())) {
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
// Licensed under the MIT license.
|
||||
|
||||
import { ConfigurationChangeEvent, Disposable, DocumentSelector, languages, RelativePattern, workspace } from 'vscode';
|
||||
import { testSourceProvider } from '../../extension.bundle';
|
||||
import { ENABLE_EDITOR_SHORTCUTS_KEY } from '../constants/configs';
|
||||
import { parseDocumentSelector } from '../utils/uiUtils';
|
||||
import { TestCodeLensProvider } from './TestCodeLensProvider';
|
||||
|
||||
class TestCodeLensController implements Disposable {
|
||||
|
@ -22,18 +24,14 @@ class TestCodeLensController implements Disposable {
|
|||
this.setCodeLensVisibility();
|
||||
}
|
||||
|
||||
public registerCodeLensProvider(patterns: RelativePattern[]): void {
|
||||
public async registerCodeLensProvider(): Promise<void> {
|
||||
if (this.registeredProvider) {
|
||||
this.registeredProvider.dispose();
|
||||
}
|
||||
|
||||
const documentSelector: DocumentSelector = patterns.map((p: RelativePattern) => {
|
||||
return {
|
||||
language: 'java',
|
||||
scheme: 'file',
|
||||
pattern: p,
|
||||
};
|
||||
});
|
||||
const patterns: RelativePattern[] = await testSourceProvider.getTestSourcePattern();
|
||||
|
||||
const documentSelector: DocumentSelector = parseDocumentSelector(patterns);
|
||||
|
||||
this.registeredProvider = languages.registerCodeLensProvider(documentSelector, this.internalProvider);
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ export namespace JavaTestRunnerDelegateCommands {
|
|||
export const SEARCH_TEST_CODE_LENS: string = 'vscode.java.test.search.codelens';
|
||||
export const SEARCH_TEST_LOCATION: string = 'vscode.java.test.search.location';
|
||||
export const RESOLVE_JUNIT_ARGUMENT: string = 'vscode.java.test.junit.argument';
|
||||
export const GENERATE_TESTS: string = 'vscode.java.test.generateTests';
|
||||
}
|
||||
|
||||
export namespace JavaTestRunnerCommands {
|
||||
|
|
|
@ -7,6 +7,7 @@ import * as path from 'path';
|
|||
import { CodeActionKind, commands, DebugConfiguration, Event, Extension, ExtensionContext, extensions, languages, Range, TreeView, TreeViewExpansionEvent, TreeViewSelectionChangeEvent, Uri, window, workspace } from 'vscode';
|
||||
import { dispose as disposeTelemetryWrapper, initializeFromJsonFile, instrumentOperation, instrumentOperationAsVsCodeCommand } from 'vscode-extension-telemetry-wrapper';
|
||||
import { sendInfo } from 'vscode-extension-telemetry-wrapper';
|
||||
import { testSourceProvider } from '../extension.bundle';
|
||||
import { TestCodeActionProvider } from './codeActionProvider';
|
||||
import { testCodeLensController } from './codelens/TestCodeLensController';
|
||||
import { debugTestsFromExplorer, openTextDocument, runTestsFromExplorer, runTestsFromJavaProjectExplorer } from './commands/explorerCommands';
|
||||
|
@ -62,23 +63,35 @@ async function doActivate(_operationId: string, context: ExtensionContext): Prom
|
|||
if (extensionApi.onDidClasspathUpdate) {
|
||||
const onDidClasspathUpdate: Event<Uri> = extensionApi.onDidClasspathUpdate;
|
||||
context.subscriptions.push(onDidClasspathUpdate(async () => {
|
||||
await testSourceProvider.initialize();
|
||||
await testFileWatcher.registerListeners(true /*enableDebounce*/);
|
||||
await testCodeLensController.registerCodeLensProvider();
|
||||
}));
|
||||
}
|
||||
|
||||
if (extensionApi.onDidServerModeChange) {
|
||||
const onDidServerModeChange: Event<string> = extensionApi.onDidServerModeChange;
|
||||
context.subscriptions.push(onDidServerModeChange(async (mode: string) => {
|
||||
if (serverMode === mode) {
|
||||
return;
|
||||
}
|
||||
// Only re-initialize the component when its lightweight -> standard
|
||||
if (serverMode !== LanguageServerMode.Hybrid) {
|
||||
testExplorer.refresh();
|
||||
await testSourceProvider.initialize();
|
||||
await testFileWatcher.registerListeners();
|
||||
await testCodeLensController.registerCodeLensProvider();
|
||||
}
|
||||
serverMode = mode;
|
||||
testExplorer.refresh();
|
||||
await testFileWatcher.registerListeners();
|
||||
}));
|
||||
}
|
||||
|
||||
if (extensionApi.onDidProjectsImport) {
|
||||
const onDidProjectsImport: Event<Uri[]> = extensionApi.onDidProjectsImport;
|
||||
context.subscriptions.push(onDidProjectsImport(async () => {
|
||||
await testSourceProvider.initialize();
|
||||
await testFileWatcher.registerListeners(true /*enableDebounce*/);
|
||||
await testCodeLensController.registerCodeLensProvider();
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -90,7 +103,9 @@ async function doActivate(_operationId: string, context: ExtensionContext): Prom
|
|||
progressProvider = javaDebugger.exports?.progressProvider;
|
||||
}
|
||||
|
||||
await testSourceProvider.initialize();
|
||||
await testFileWatcher.registerListeners();
|
||||
await testCodeLensController.registerCodeLensProvider();
|
||||
testExplorer.initialize(context);
|
||||
const testTreeView: TreeView<ITestItem> = window.createTreeView(testExplorer.testExplorerViewId, { treeDataProvider: testExplorer, showCollapseAll: true });
|
||||
runnerScheduler.initialize(context);
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import { RelativePattern, Uri, workspace, WorkspaceFolder } from 'vscode';
|
||||
import { getTestSourcePaths } from '../utils/commandUtils';
|
||||
|
||||
class TestSourcePathProvider {
|
||||
private testSource: ITestSourcePath[];
|
||||
|
||||
public async initialize(): Promise<void> {
|
||||
this.testSource = [];
|
||||
if (!workspace.workspaceFolders) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.testSource = await getTestSourcePaths(workspace.workspaceFolders.map((workspaceFolder: WorkspaceFolder) => workspaceFolder.uri.toString()));
|
||||
}
|
||||
|
||||
public async getTestSourcePattern(containsGeneral: boolean = true): Promise<RelativePattern[]> {
|
||||
const patterns: RelativePattern[] = [];
|
||||
const sourcePaths: string[] = await testSourceProvider.getTestSourcePath(containsGeneral);
|
||||
for (const sourcePath of sourcePaths) {
|
||||
const normalizedPath: string = Uri.file(sourcePath).fsPath;
|
||||
const pattern: RelativePattern = new RelativePattern(normalizedPath, '**/*.java');
|
||||
patterns.push(pattern);
|
||||
}
|
||||
return patterns;
|
||||
}
|
||||
|
||||
public async getTestSourcePath(containsGeneral: boolean = true): Promise<string[]> {
|
||||
if (this.testSource === undefined) {
|
||||
await this.initialize();
|
||||
}
|
||||
|
||||
if (containsGeneral) {
|
||||
return this.testSource.map((s: ITestSourcePath) => s.testSourcePath);
|
||||
}
|
||||
|
||||
return this.testSource.filter((s: ITestSourcePath) => s.isStrict)
|
||||
.map((s: ITestSourcePath) => s.testSourcePath);
|
||||
}
|
||||
}
|
||||
|
||||
export interface ITestSourcePath {
|
||||
testSourcePath: string;
|
||||
/**
|
||||
* All the source paths from eclipse and invisible project will be treated as test source
|
||||
* even they are not marked as test in the classpath entry, in that case, this field will be false.
|
||||
*/
|
||||
isStrict: boolean;
|
||||
}
|
||||
|
||||
export const testSourceProvider: TestSourcePathProvider = new TestSourcePathProvider();
|
|
@ -2,19 +2,17 @@
|
|||
// Licensed under the MIT license.
|
||||
|
||||
import * as _ from 'lodash';
|
||||
import { Disposable, FileSystemWatcher, RelativePattern, Uri, workspace, WorkspaceFolder } from 'vscode';
|
||||
import { testCodeLensController } from './codelens/TestCodeLensController';
|
||||
import { Disposable, FileSystemWatcher, RelativePattern, Uri, workspace } from 'vscode';
|
||||
import { testSourceProvider } from '../extension.bundle';
|
||||
import { testExplorer } from './explorer/testExplorer';
|
||||
import { isStandardServerReady } from './extension';
|
||||
import { logger } from './logger/logger';
|
||||
import { ITestItem, TestLevel } from './protocols';
|
||||
import { testItemModel } from './testItemModel';
|
||||
import { testResultManager } from './testResultManager';
|
||||
import { getTestSourcePaths } from './utils/commandUtils';
|
||||
|
||||
class TestFileWatcher implements Disposable {
|
||||
|
||||
private patterns: RelativePattern[] = [];
|
||||
private disposables: Disposable[] = [];
|
||||
private registerListenersDebounce: _.DebouncedFunc<() => Promise<void>> = _.debounce(this.registerListenersInternal, 2 * 1000 /*ms*/);
|
||||
|
||||
|
@ -33,7 +31,6 @@ class TestFileWatcher implements Disposable {
|
|||
}
|
||||
}
|
||||
this.disposables = [];
|
||||
this.patterns = [];
|
||||
}
|
||||
|
||||
protected async registerListenersInternal(): Promise<void> {
|
||||
|
@ -41,24 +38,18 @@ class TestFileWatcher implements Disposable {
|
|||
return;
|
||||
}
|
||||
this.dispose();
|
||||
if (workspace.workspaceFolders) {
|
||||
try {
|
||||
const sourcePaths: string[] = await getTestSourcePaths(workspace.workspaceFolders.map((workspaceFolder: WorkspaceFolder) => workspaceFolder.uri.toString()));
|
||||
for (const sourcePath of sourcePaths) {
|
||||
const normalizedPath: string = Uri.file(sourcePath).fsPath;
|
||||
const pattern: RelativePattern = new RelativePattern(normalizedPath, '**/*.java');
|
||||
this.patterns.push(pattern);
|
||||
const watcher: FileSystemWatcher = workspace.createFileSystemWatcher(pattern, true /* ignoreCreateEvents */);
|
||||
this.registerWatcherListeners(watcher);
|
||||
this.disposables.push(watcher);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('Failed to get the test paths', error);
|
||||
const watcher: FileSystemWatcher = workspace.createFileSystemWatcher('**/*.java');
|
||||
try {
|
||||
const patterns: RelativePattern[] = await testSourceProvider.getTestSourcePattern();
|
||||
for (const pattern of patterns) {
|
||||
const watcher: FileSystemWatcher = workspace.createFileSystemWatcher(pattern, true /* ignoreCreateEvents */);
|
||||
this.registerWatcherListeners(watcher);
|
||||
this.disposables.push(watcher);
|
||||
}
|
||||
testCodeLensController.registerCodeLensProvider(this.patterns);
|
||||
} catch (error) {
|
||||
logger.error('Failed to get the test paths', error);
|
||||
const watcher: FileSystemWatcher = workspace.createFileSystemWatcher('**/*.java');
|
||||
this.registerWatcherListeners(watcher);
|
||||
this.disposables.push(watcher);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,13 +2,14 @@
|
|||
// Licensed under the MIT license.
|
||||
|
||||
import { CancellationToken, commands, Position, Uri } from 'vscode';
|
||||
import { ITestSourcePath } from '../../extension.bundle';
|
||||
import { JavaLanguageServerCommands, JavaTestRunnerDelegateCommands } from '../constants/commands';
|
||||
import { logger } from '../logger/logger';
|
||||
import { ILocation, ISearchTestItemParams, ITestItem, TestKind, TestLevel } from '../protocols';
|
||||
import { IJUnitLaunchArguments } from '../runners/baseRunner/BaseRunner';
|
||||
|
||||
export async function getTestSourcePaths(uri: string[]): Promise<string[]> {
|
||||
return await executeJavaLanguageServerCommand<string[]>(
|
||||
export async function getTestSourcePaths(uri: string[]): Promise<ITestSourcePath[]> {
|
||||
return await executeJavaLanguageServerCommand<ITestSourcePath[]>(
|
||||
JavaTestRunnerDelegateCommands.GET_TEST_SOURCE_PATH, uri) || [];
|
||||
}
|
||||
|
||||
|
@ -41,16 +42,8 @@ export async function resolveStackTraceLocation(trace: string, projectNames: str
|
|||
JavaLanguageServerCommands.RESOLVE_STACKTRACE_LOCATION, trace, projectNames) || '';
|
||||
}
|
||||
|
||||
export async function getSourcePaths(): Promise<any> {
|
||||
const result: any = await executeJavaLanguageServerCommand<any>('java.project.listSourcePaths');
|
||||
if (result?.data) {
|
||||
return result.data;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
export async function generateTests(uri: Uri, startPosition: number): Promise<any> {
|
||||
return await executeJavaLanguageServerCommand<any>('vscode.java.test.generateTests', uri.toString(), startPosition);
|
||||
return await executeJavaLanguageServerCommand<any>(JavaTestRunnerDelegateCommands.GENERATE_TESTS, uri.toString(), startPosition);
|
||||
}
|
||||
|
||||
export async function resolveJUnitLaunchArguments(uri: string, fullName: string, testName: string, project: string,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import { window } from 'vscode';
|
||||
import { DocumentSelector, RelativePattern, window } from 'vscode';
|
||||
import { showOutputChannel } from '../commands/logCommands';
|
||||
import { OPEN_OUTPUT_CHANNEL } from '../constants/dialogOptions';
|
||||
import { testStatusBarProvider } from '../testStatusBarProvider';
|
||||
|
@ -14,3 +14,15 @@ export function showError(error: Error): void {
|
|||
});
|
||||
testStatusBarProvider.showFailure();
|
||||
}
|
||||
|
||||
export function parseDocumentSelector(patterns: RelativePattern[]): DocumentSelector {
|
||||
const documentSelector: DocumentSelector = patterns.map((p: RelativePattern) => {
|
||||
return {
|
||||
language: 'java',
|
||||
scheme: 'file',
|
||||
pattern: p,
|
||||
};
|
||||
});
|
||||
|
||||
return documentSelector;
|
||||
}
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import { commands, RelativePattern } from 'vscode';
|
||||
import { testCodeLensController, testFileWatcher } from '../../extension.bundle';
|
||||
import * as assert from 'assert';
|
||||
import * as sinon from 'sinon';
|
||||
import * as path from "path";
|
||||
import { setupTestEnv, Uris } from '../shared';
|
||||
|
||||
suite('Test File Watcher Tests', function() {
|
||||
|
||||
const sandbox = sinon.createSandbox();
|
||||
|
||||
suiteSetup(async function() {
|
||||
setupTestEnv();
|
||||
});
|
||||
|
||||
test("Should correctly setup code lens provider", async function() {
|
||||
let spy: sinon.SinonSpy = sandbox.spy(testCodeLensController, 'registerCodeLensProvider');
|
||||
await testFileWatcher.registerListeners();
|
||||
const args: RelativePattern[] = spy.getCall(0).args[0];
|
||||
assert.ok(args.length === 3);
|
||||
assert.ok(path.relative(args[0].base, path.join(Uris.JUNIT4_TEST_PACKAGE, '..')));
|
||||
spy.restore();
|
||||
});
|
||||
|
||||
teardown(async function() {
|
||||
await commands.executeCommand('workbench.action.closeActiveEditor');
|
||||
});
|
||||
});
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
import { RelativePattern } from 'vscode';
|
||||
import { testSourceProvider } from '../../extension.bundle';
|
||||
import * as assert from 'assert';
|
||||
import { setupTestEnv } from '../shared';
|
||||
|
||||
suite('Test File Watcher Tests', function() {
|
||||
|
||||
suiteSetup(async function() {
|
||||
setupTestEnv();
|
||||
});
|
||||
|
||||
test("Should correctly get the test source paths", async function() {
|
||||
const patterns: RelativePattern[] = await testSourceProvider.getTestSourcePattern();
|
||||
assert.strictEqual(patterns.length, 3);
|
||||
});
|
||||
});
|
Загрузка…
Ссылка в новой задаче