Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Support relative paths with omnisharp.testRunSettings #4860

Merged
merged 3 commits into from
Nov 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,14 @@
"default": false,
"description": "(EXPERIMENTAL) Enables support for resolving completion edits asynchronously. This can speed up time to show the completion list, particularly override and partial method completion lists, at the cost of slight delays after inserting a completion item. Most completion items will have no noticeable impact with this feature, but typing immediately after inserting an override or partial method completion, before the insert is completed, can have unpredictable results."
},
"omnisharp.testRunSettings": {
"type": [
"string",
"null"
],
"default": null,
"description": "Path to the .runsettings file which should be used when running unit tests."
},
"razor.plugin.path": {
"type": [
"string",
Expand Down
31 changes: 22 additions & 9 deletions src/features/dotnetTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ export default class TestManager extends AbstractProvider {
public async discoverTests(fileName: string, testFrameworkName: string, noBuild: boolean): Promise<protocol.V2.TestInfo[]> {

let targetFrameworkVersion = await this._recordRunAndGetFrameworkVersion(fileName, testFrameworkName);
let runSettings = vscode.workspace.getConfiguration('omnisharp').get<string>('testRunSettings');
let runSettings = this._getRunSettings(fileName);

const request: protocol.V2.DiscoverTestsRequest = {
FileName: fileName,
Expand All @@ -191,8 +191,21 @@ export default class TestManager extends AbstractProvider {
}
}

private _getRunSettings(): string | undefined {
return vscode.workspace.getConfiguration('omnisharp').get<string>('testRunSettings');
private _getRunSettings(filename: string): string | undefined {
const testSettingsPath = vscode.workspace.getConfiguration('omnisharp').get<string>('testRunSettings');
if (!testSettingsPath) {
return undefined;
}

if (path.isAbsolute(testSettingsPath)) {
return testSettingsPath;
}

// Path is relative to the workspace. Create absolute path.
const fileUri = vscode.Uri.file(filename);
const workspaceFolder = vscode.workspace.getWorkspaceFolder(fileUri);

return path.join(workspaceFolder.uri.fsPath, testSettingsPath);
}

public async runDotnetTest(testMethod: string, fileName: string, testFrameworkName: string, noBuild: boolean = false) {
Expand All @@ -204,7 +217,7 @@ export default class TestManager extends AbstractProvider {
});

let targetFrameworkVersion = await this._recordRunAndGetFrameworkVersion(fileName, testFrameworkName);
let runSettings = this._getRunSettings();
let runSettings = this._getRunSettings(fileName);

try {
let results = await this._runTest(fileName, testMethod, runSettings, testFrameworkName, targetFrameworkVersion, noBuild);
Expand All @@ -228,7 +241,7 @@ export default class TestManager extends AbstractProvider {
});

let targetFrameworkVersion = await this._recordRunAndGetFrameworkVersion(fileName, testFrameworkName);
let runSettings = this._getRunSettings();
let runSettings = this._getRunSettings(fileName);

try {
let results = await this._runTestsInClass(fileName, runSettings, testFrameworkName, targetFrameworkVersion, methodsInClass, noBuild);
Expand Down Expand Up @@ -269,7 +282,7 @@ export default class TestManager extends AbstractProvider {
});

let targetFrameworkVersion = await this._recordRunAndGetFrameworkVersion(fileName);
let runSettings = this._getRunSettings();
let runSettings = this._getRunSettings(fileName);

const request: protocol.V2.RunTestsInContextRequest = {
FileName: fileName,
Expand Down Expand Up @@ -395,7 +408,7 @@ export default class TestManager extends AbstractProvider {
this._eventStream.post(new DotNetTestDebugStart(testMethod));

let { debugEventListener, targetFrameworkVersion } = await this._recordDebugAndGetDebugValues(fileName, testFrameworkName);
let runSettings = this._getRunSettings();
let runSettings = this._getRunSettings(fileName);

try {
let config = await this._getLaunchConfigurationForVSTest(fileName, testMethod, runSettings, testFrameworkName, targetFrameworkVersion, debugEventListener, noBuild);
Expand All @@ -415,7 +428,7 @@ export default class TestManager extends AbstractProvider {
this._eventStream.post(new DotNetTestsInClassDebugStart(className));

let { debugEventListener, targetFrameworkVersion } = await this._recordDebugAndGetDebugValues(fileName, testFrameworkName);
let runSettings = this._getRunSettings();
let runSettings = this._getRunSettings(fileName);

try {
let config = await this._getLaunchConfigurationForVSTestClass(fileName, methodsToRun, runSettings, testFrameworkName, targetFrameworkVersion, debugEventListener, noBuild);
Expand All @@ -440,7 +453,7 @@ export default class TestManager extends AbstractProvider {

let { debugEventListener, targetFrameworkVersion } = await this._recordDebugAndGetDebugValues(fileName);

let runSettings = this._getRunSettings();
let runSettings = this._getRunSettings(fileName);

try {
let config = await this._getLaunchConfigurationForVSTestInContext(fileName, active.line, active.character, runSettings, targetFrameworkVersion, debugEventListener);
Expand Down
2 changes: 1 addition & 1 deletion test/featureTests/processPicker.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ suite("Remote Process Picker: Validate quoting arguments.", () => {
const process3: Process = parsedOutput[2];
const process4: Process = parsedOutput[3];

var should = require('chai').should();
const should = require('chai').should();
should.not.exist(process1.commandLine);
process1.name.should.equal('System Idle Process');
process1.pid.should.equal('0');
Expand Down
133 changes: 133 additions & 0 deletions test/integrationTests/dotnetTest.integration.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import * as vscode from 'vscode';
import * as path from 'path';

import { should, expect } from 'chai';
import { activateCSharpExtension, isSlnWithCsproj } from './integrationHelpers';
import testAssetWorkspace from './testAssets/testAssetWorkspace';
import { EventStream } from '../../src/EventStream';
import { EventType } from '../../src/omnisharp/EventType';
import { BaseEvent, OmnisharpRequestMessage } from '../../src/omnisharp/loggingEvents';
import { poll } from './poll';
import { V2 } from '../../src/omnisharp/protocol';

const chai = require('chai');
chai.use(require('chai-arrays'));
chai.use(require('chai-fs'));

async function waitActivityToSettle(stream: EventStream, timeout: number): Promise<void> {
let event: BaseEvent = { type: 0 };

const subscription = stream.subscribe((e: BaseEvent) => event = e);

await poll(() => event, timeout, 500, e => !e || (event = null));

subscription.unsubscribe();
}

async function waitForEvent<T extends BaseEvent>(stream: EventStream, captureType: EventType, stopCondition: (e: T) => boolean, timeout: number): Promise<T> {
let event: T = null;

const subscription = stream.subscribe((e: BaseEvent) => {
if (e.type === captureType) {
const tEvent = <T>e;

if (stopCondition(tEvent)) {
event = tEvent;
subscription.unsubscribe();
}
}
});

await poll(() => event, timeout, 500, e => !!e);

return event;
}

suite(`DotnetTest: ${testAssetWorkspace.description}`, function () {
let fileUri: vscode.Uri;
let eventStream: EventStream;

suiteSetup(async function () {
should();

// These tests only run on the slnWithCsproj solution
if (!isSlnWithCsproj(vscode.workspace)) {
this.skip();
}
else {
const activation = await activateCSharpExtension();
await testAssetWorkspace.restoreAndWait(activation);

eventStream = activation.eventStream;

let fileName = 'UnitTest1.cs';
let projectDirectory = testAssetWorkspace.projects[2].projectDirectoryPath;
let filePath = path.join(projectDirectory, fileName);
fileUri = vscode.Uri.file(filePath);

await vscode.commands.executeCommand("vscode.open", fileUri);

await waitActivityToSettle(eventStream, 90 * 1000);
}
});

suiteTeardown(async () => {
await testAssetWorkspace.cleanupWorkspace();
});

test("Undefined runsettings path is unchanged", async function () {
const omnisharpConfig = vscode.workspace.getConfiguration('omnisharp');
await omnisharpConfig.update('testRunSettings', undefined);

const eventWaiter = waitForEvent<OmnisharpRequestMessage>(eventStream, EventType.OmnisharpRequestMessage, e => e.request.command === V2.Requests.RunTestsInContext, /* timeout */ 10 * 1000);

await vscode.commands.executeCommand('dotnet.test.runTestsInContext');

const event = await eventWaiter;
const runTestsRequest = <V2.RunTestsInContextRequest>event.request.data;

expect(runTestsRequest.RunSettings).to.be.undefined;
});

test("Absolute runsettings path is unchanged", async function () {
const relativeRunSettingsPath = `.\\settings\\TestSettings.runsettings`.replace("\\", path.sep);
const absoluteRunSettingsPath = path.join(process.cwd(), relativeRunSettingsPath);

const omnisharpConfig = vscode.workspace.getConfiguration('omnisharp');
await omnisharpConfig.update('testRunSettings', absoluteRunSettingsPath);

const eventWaiter = waitForEvent<OmnisharpRequestMessage>(eventStream, EventType.OmnisharpRequestMessage, e => e.request.command === V2.Requests.RunTestsInContext, /* timeout */ 10 * 1000);

await vscode.commands.executeCommand('dotnet.test.runTestsInContext');

const event = await eventWaiter;
const runTestsRequest = <V2.RunTestsInContextRequest>event.request.data;

expect(runTestsRequest.RunSettings).to.be.equal(absoluteRunSettingsPath);
});

test("Relative runsettings path is made absolute", async function () {
const endingPath = 'settings\\TestSettings.runsettings'.replace("\\", path.sep);
const relativeRunSettingPath = `.\\${endingPath}`.replace("\\", path.sep);

const omnisharpConfig = vscode.workspace.getConfiguration('omnisharp');
await omnisharpConfig.update('testRunSettings', relativeRunSettingPath);

const eventWaiter = waitForEvent<OmnisharpRequestMessage>(eventStream, EventType.OmnisharpRequestMessage, e => e.request.command === V2.Requests.RunTestsInContext, /* timeout */ 10 * 1000);

await vscode.commands.executeCommand('dotnet.test.runTestsInContext');

const event = await eventWaiter;
const runTestsRequest = <V2.RunTestsInContextRequest>event.request.data;

expect(runTestsRequest.RunSettings).to.be.not.null;
expect(runTestsRequest.RunSettings.endsWith(endingPath), "Path includes relative path").to.be.true;
expect(path.isAbsolute(runTestsRequest.RunSettings), "Path is absolute").to.be.true;
});
});

2 changes: 1 addition & 1 deletion test/releaseTests/offlinePackage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ suite("Offline packaging of VSIX", function () {

test(`Given Platform: ${platformInfo.platform} and Architecture: ${platformInfo.architecture}, the vsix file is created`, () => {
const expectedVsixName = getPackageName(packageJson, packageId);
const vsixFile = vsixFiles.find(file => file.endsWith(expectedVsixName))
const vsixFile = vsixFiles.find(file => file.endsWith(expectedVsixName));
expect(vsixFile, `offline packaging did not build package ${expectedVsixName}`)
.to.not.be.null;
});
Expand Down