From cefa8dd67448ff692c4f6da096fd270c5f16e081 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Tue, 1 May 2018 14:16:43 -0700 Subject: [PATCH 1/4] Add/update 'omnisharp.useGlobalMono' option This change updates the name of the 'omnisharp.useMono' option to 'omnisharp.useGlobalMono', and makes it a tri-state value rather than a boolean. It now has three possible values: * "auto": Launch OmniSharp on the globally-installed Mono if it's available. * "always": Always try to launch OmniSharp on the globally-installed Mono and error if it's not available. * "never": Never launch OmniSharp on the globall-installed Mono. --- package.json | 18 +++++++-- src/omnisharp/launcher.ts | 8 ++-- src/omnisharp/options.ts | 80 ++++++++++++++++++++++++++++----------- 3 files changed, 77 insertions(+), 29 deletions(-) diff --git a/package.json b/package.json index e48fa957d..f15dd2230 100644 --- a/package.json +++ b/package.json @@ -521,10 +521,20 @@ "default": null, "description": "Specifies the path to OmniSharp. This can be the absolute path to an OmniSharp executable, a specific version number, or \"latest\". If a version number or \"latest\" is specified, the appropriate version of OmniSharp will be downloaded on your behalf." }, - "omnisharp.useMono": { - "type": "boolean", - "default": false, - "description": "Launch OmniSharp with Mono." + "omnisharp.useGlobalMono": { + "type": "string", + "default": "auto", + "enum": [ + "auto", + "always", + "never" + ], + "enumDescriptions": [ + "Automatically launch OmniSharp with \"mono\" if version 5.2.0 or greater is available on the PATH.", + "Always launch OmniSharp with \"mono\". If version 5.2.0 or greater is not available on the PATH, an error will be printed.", + "Never launch OmniSHarp on a globally-installed Mono." + ], + "description": "Launch OmniSharp with the globally-installed Mono. If set to \"always\", \"mono\" version 5.2.0 or greater must be available on the PATH. If set to \"auto\", OmniSharp will be launched with \"mono\" if version 5.2.0 or greater is available on the PATH." }, "omnisharp.waitForDebugger": { "type": "boolean", diff --git a/src/omnisharp/launcher.ts b/src/omnisharp/launcher.ts index 88f3379e2..85a475b65 100644 --- a/src/omnisharp/launcher.ts +++ b/src/omnisharp/launcher.ts @@ -242,16 +242,18 @@ async function launch(cwd: string, args: string[], launchInfo: LaunchInfo, platf let isValidMonoAvailable = await satisfies(monoVersion, '>=5.2.0'); // If the user specifically said that they wanted to launch on Mono, respect their wishes. - if (options.useMono) { + if (options.useGlobalMono === "always") { if (!isValidMonoAvailable) { throw new Error('Cannot start OmniSharp because Mono version >=5.2.0 is required.'); } - return launchNixMono(launchInfo.LaunchPath, monoVersion, cwd, args); + const launchPath = launchInfo.MonoLaunchPath || launchInfo.LaunchPath; + + return launchNixMono(launchPath, monoVersion, cwd, args); } // If we can launch on the global Mono, do so; otherwise, launch directly; - if (isValidMonoAvailable && launchInfo.MonoLaunchPath) { + if (options.useGlobalMono === "auto" && isValidMonoAvailable && launchInfo.MonoLaunchPath) { return launchNixMono(launchInfo.MonoLaunchPath, monoVersion, cwd, args); } else { diff --git a/src/omnisharp/options.ts b/src/omnisharp/options.ts index cf8c5da8e..7a8567d06 100644 --- a/src/omnisharp/options.ts +++ b/src/omnisharp/options.ts @@ -7,19 +7,19 @@ import * as vscode from 'vscode'; export class Options { constructor( - public path?: string, - public useMono?: boolean, - public waitForDebugger?: boolean, - public loggingLevel?: string, - public autoStart?: boolean, - public projectLoadTimeout?: number, - public maxProjectResults?: number, - public useEditorFormattingSettings?: boolean, - public useFormatting?: boolean, - public showReferencesCodeLens?: boolean, - public showTestsCodeLens?: boolean, - public disableCodeActions?: boolean, - public disableMSBuildDiagnosticWarning?: boolean) { } + public path: string, + public useGlobalMono: string, + public waitForDebugger: boolean, + public loggingLevel: string, + public autoStart: boolean, + public projectLoadTimeout: number, + public maxProjectResults: number, + public useEditorFormattingSettings: boolean, + public useFormatting: boolean, + public showReferencesCodeLens: boolean, + public showTestsCodeLens: boolean, + public disableCodeActions: boolean, + public disableMSBuildDiagnosticWarning: boolean) { } public static Read(): Options { // Extra effort is taken below to ensure that legacy versions of options @@ -27,17 +27,13 @@ export class Options { // // - "csharp.omnisharp" -> "omnisharp.path" // - "csharp.omnisharpUsesMono" -> "omnisharp.useMono" + // - "omnisharp.useMono" -> "omnisharp.useGlobalMono" const omnisharpConfig = vscode.workspace.getConfiguration('omnisharp'); const csharpConfig = vscode.workspace.getConfiguration('csharp'); - const path = csharpConfig.has('omnisharp') - ? csharpConfig.get('omnisharp') - : omnisharpConfig.get('path'); - - const useMono = csharpConfig.has('omnisharpUsesMono') - ? csharpConfig.get('omnisharpUsesMono') - : omnisharpConfig.get('useMono'); + const path = Options.readPathOption(csharpConfig, omnisharpConfig); + const useGlobalMono = Options.readUseGlobalMonoOption(omnisharpConfig, csharpConfig); const waitForDebugger = omnisharpConfig.get('waitForDebugger', false); @@ -62,8 +58,9 @@ export class Options { const disableMSBuildDiagnosticWarning = omnisharpConfig.get('disableMSBuildDiagnosticWarning'); - return new Options(path, - useMono, + return new Options( + path, + useGlobalMono, waitForDebugger, loggingLevel, autoStart, @@ -76,4 +73,43 @@ export class Options { disableCodeActions, disableMSBuildDiagnosticWarning); } + + private static readPathOption(csharpConfig: vscode.WorkspaceConfiguration, omnisharpConfig: vscode.WorkspaceConfiguration): string | null { + if (omnisharpConfig.has('path')) { + // If 'omnisharp.path' setting was found, use it. + return omnisharpConfig.get('path'); + } + else if (csharpConfig.has('omnisharp')) { + // BACKCOMPAT: If 'csharp.omnisharp' setting was found, use it. + return csharpConfig.get('path'); + } + else { + // Otherwise, null. + return null; + } + } + + private static readUseGlobalMonoOption(omnisharpConfig: vscode.WorkspaceConfiguration, csharpConfig: vscode.WorkspaceConfiguration): string { + function toUseGlobalMonoValue(value: boolean): string { + // True means 'always' and false means 'auto'. + return value ? "always" : "auto"; + } + + if (omnisharpConfig.has('useGlobalMono')) { + // If 'omnisharp.useGlobalMono' setting was found, just use it. + return omnisharpConfig.get('useGlobalMono'); + } + else if (omnisharpConfig.has('useMono')) { + // BACKCOMPAT: If 'omnisharp.useMono' setting was found, true maps to "always" and false maps to "auto" + return toUseGlobalMonoValue(omnisharpConfig.get('useMono')); + } + else if (csharpConfig.has('omnisharpUsesMono')) { + // BACKCOMPAT: If 'csharp.omnisharpUsesMono' setting was found, true maps to "always" and false maps to "auto" + return toUseGlobalMonoValue(csharpConfig.get('omnisharpUsesMono')); + } + else { + // Otherwise, the default value is "auto". + return "auto"; + } + } } \ No newline at end of file From 7eac7843c2ceda8de8526368a11dfd9ccc483a6e Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Tue, 1 May 2018 14:49:05 -0700 Subject: [PATCH 2/4] Break dependency of Options.Read() on vscode --- src/features/codeActionProvider.ts | 2 +- src/features/codeLensProvider.ts | 2 +- src/main.ts | 2 +- src/omnisharp/extension.ts | 2 +- src/omnisharp/launcher.ts | 10 ++++------ src/omnisharp/options.ts | 8 ++++---- src/omnisharp/server.ts | 23 ++++++++++++----------- 7 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/features/codeActionProvider.ts b/src/features/codeActionProvider.ts index 6af898c61..8ce1885c2 100644 --- a/src/features/codeActionProvider.ts +++ b/src/features/codeActionProvider.ts @@ -32,7 +32,7 @@ export default class CodeActionProvider extends AbstractProvider implements vsco } private _resetCachedOptions(): void { - this._options = Options.Read(); + this._options = Options.Read(vscode); } public async provideCodeActions(document: vscode.TextDocument, range: vscode.Range, context: vscode.CodeActionContext, token: vscode.CancellationToken): Promise { diff --git a/src/features/codeLensProvider.ts b/src/features/codeLensProvider.ts index e2d633d5e..f369bc46f 100644 --- a/src/features/codeLensProvider.ts +++ b/src/features/codeLensProvider.ts @@ -39,7 +39,7 @@ export default class OmniSharpCodeLensProvider extends AbstractProvider implemen } private _resetCachedOptions(): void { - this._options = Options.Read(); + this._options = Options.Read(vscode); } private static filteredSymbolNames: { [name: string]: boolean } = { diff --git a/src/main.ts b/src/main.ts index 5f9154369..d5d3c8cfc 100644 --- a/src/main.ts +++ b/src/main.ts @@ -61,7 +61,7 @@ export async function activate(context: vscode.ExtensionContext): Promise Options.Read().disableMSBuildDiagnosticWarning || false); + let warningMessageObserver = new WarningMessageObserver(vscode, () => Options.Read(vscode).disableMSBuildDiagnosticWarning || false); eventStream.subscribe(warningMessageObserver.post); let informationMessageObserver = new InformationMessageObserver(vscode); diff --git a/src/omnisharp/extension.ts b/src/omnisharp/extension.ts index 60f7266f6..5c0fa15d5 100644 --- a/src/omnisharp/extension.ts +++ b/src/omnisharp/extension.ts @@ -43,7 +43,7 @@ export async function activate(context: vscode.ExtensionContext, eventStream: Ev scheme: 'file' // only files from disk }; - const options = Options.Read(); + const options = Options.Read(vscode); const server = new OmniSharpServer(vscode, provider, eventStream, packageJSON, platformInfo); omnisharp = server; const advisor = new Advisor(server); // create before server is started diff --git a/src/omnisharp/launcher.ts b/src/omnisharp/launcher.ts index 85a475b65..dfa93d422 100644 --- a/src/omnisharp/launcher.ts +++ b/src/omnisharp/launcher.ts @@ -41,7 +41,7 @@ export function findLaunchTargets(): Thenable { return Promise.resolve([]); } - const options = Options.Read(); + const options = Options.Read(vscode); return vscode.workspace.findFiles( /*include*/ '{**/*.sln,**/*.csproj,**/project.json,**/*.csx,**/*.cake}', @@ -204,9 +204,9 @@ export interface LaunchResult { monoVersion?: string; } -export async function launchOmniSharp(cwd: string, args: string[], launchInfo: LaunchInfo, platformInfo: PlatformInformation): Promise { +export async function launchOmniSharp(cwd: string, args: string[], launchInfo: LaunchInfo, platformInfo: PlatformInformation, options: Options): Promise { return new Promise((resolve, reject) => { - launch(cwd, args, launchInfo, platformInfo) + launch(cwd, args, launchInfo, platformInfo, options) .then(result => { // async error - when target not not ENEOT result.process.on('error', err => { @@ -222,9 +222,7 @@ export async function launchOmniSharp(cwd: string, args: string[], launchInfo: L }); } -async function launch(cwd: string, args: string[], launchInfo: LaunchInfo, platformInfo: PlatformInformation): Promise { - const options = Options.Read(); - +async function launch(cwd: string, args: string[], launchInfo: LaunchInfo, platformInfo: PlatformInformation, options: Options): Promise { if (options.useEditorFormattingSettings) { let globalConfig = vscode.workspace.getConfiguration(); let csharpConfig = vscode.workspace.getConfiguration('[csharp]'); diff --git a/src/omnisharp/options.ts b/src/omnisharp/options.ts index 7a8567d06..8a4d06f23 100644 --- a/src/omnisharp/options.ts +++ b/src/omnisharp/options.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as vscode from 'vscode'; +import { vscode, WorkspaceConfiguration } from '../vscodeAdapter'; export class Options { constructor( @@ -21,7 +21,7 @@ export class Options { public disableCodeActions: boolean, public disableMSBuildDiagnosticWarning: boolean) { } - public static Read(): Options { + public static Read(vscode: vscode): Options { // Extra effort is taken below to ensure that legacy versions of options // are supported below. In particular, these are: // @@ -74,7 +74,7 @@ export class Options { disableMSBuildDiagnosticWarning); } - private static readPathOption(csharpConfig: vscode.WorkspaceConfiguration, omnisharpConfig: vscode.WorkspaceConfiguration): string | null { + private static readPathOption(csharpConfig: WorkspaceConfiguration, omnisharpConfig: WorkspaceConfiguration): string | null { if (omnisharpConfig.has('path')) { // If 'omnisharp.path' setting was found, use it. return omnisharpConfig.get('path'); @@ -89,7 +89,7 @@ export class Options { } } - private static readUseGlobalMonoOption(omnisharpConfig: vscode.WorkspaceConfiguration, csharpConfig: vscode.WorkspaceConfiguration): string { + private static readUseGlobalMonoOption(omnisharpConfig: WorkspaceConfiguration, csharpConfig: WorkspaceConfiguration): string { function toUseGlobalMonoValue(value: boolean): string { // True means 'always' and false means 'auto'. return value ? "always" : "auto"; diff --git a/src/omnisharp/server.ts b/src/omnisharp/server.ts index c51146786..bf0f3301a 100644 --- a/src/omnisharp/server.ts +++ b/src/omnisharp/server.ts @@ -85,7 +85,6 @@ export class OmniSharpServer { private _launchTarget: LaunchTarget; private _requestQueue: RequestQueueCollection; private _serverProcess: ChildProcess; - private _options: Options; private _omnisharpManager: OmnisharpManager; private updateProjectDebouncer = new Subject(); @@ -237,7 +236,7 @@ export class OmniSharpServer { // --- start, stop, and connect - private async _start(launchTarget: LaunchTarget): Promise { + private async _start(launchTarget: LaunchTarget, options: Options): Promise { let disposables = new CompositeDisposable(); @@ -292,7 +291,6 @@ export class OmniSharpServer { const solutionPath = launchTarget.target; const cwd = path.dirname(solutionPath); - this._options = Options.Read(); let args = [ '-s', solutionPath, @@ -300,17 +298,17 @@ export class OmniSharpServer { '--stdio', 'DotNet:enablePackageRestore=false', '--encoding', 'utf-8', - '--loglevel', this._options.loggingLevel + '--loglevel', options.loggingLevel ]; - if (this._options.waitForDebugger === true) { + if (options.waitForDebugger === true) { args.push('--debug'); } let launchInfo: LaunchInfo; try { let extensionPath = utils.getExtensionPath(); - launchInfo = await this._omnisharpManager.GetOmniSharpLaunchInfo(this.packageJSON.defaults.omniSharp, this._options.path, serverUrl, latestVersionFileServerPath, installPath, extensionPath); + launchInfo = await this._omnisharpManager.GetOmniSharpLaunchInfo(this.packageJSON.defaults.omniSharp, options.path, serverUrl, latestVersionFileServerPath, installPath, extensionPath); } catch (error) { this.eventStream.post(new ObservableEvents.OmnisharpFailure(`Error occured in loading omnisharp from omnisharp.path\nCould not start the server due to ${error.toString()}`, error)); @@ -321,7 +319,7 @@ export class OmniSharpServer { this._fireEvent(Events.BeforeServerStart, solutionPath); try { - let launchResult = await launchOmniSharp(cwd, args, launchInfo, this.platformInfo); + let launchResult = await launchOmniSharp(cwd, args, launchInfo, this.platformInfo, options); this.eventStream.post(new ObservableEvents.OmnisharpLaunch(launchResult.monoVersion, launchResult.command, launchResult.process.pid)); this._serverProcess = launchResult.process; @@ -329,7 +327,7 @@ export class OmniSharpServer { this._setState(ServerState.Started); this._fireEvent(Events.ServerStart, solutionPath); - await this._doConnect(); + await this._doConnect(options); this._telemetryIntervalId = setInterval(() => this._reportTelemetry(), TelemetryReportingDelay); this._requestQueue.drain(); @@ -417,7 +415,10 @@ export class OmniSharpServer { public async restart(launchTarget: LaunchTarget = this._launchTarget): Promise { if (launchTarget) { await this.stop(); - await this._start(launchTarget); + + const options = Options.Read(this.vscode); + + await this._start(launchTarget, options); } } @@ -503,7 +504,7 @@ export class OmniSharpServer { }); } - private async _doConnect(): Promise { + private async _doConnect(options: Options): Promise { this._serverProcess.stderr.on('data', (data: any) => { this._fireEvent('stderr', String(data)); @@ -519,7 +520,7 @@ export class OmniSharpServer { let listener: Disposable; // Convert the timeout from the seconds to milliseconds, which is required by setTimeout(). - const timeoutDuration = this._options.projectLoadTimeout * 1000; + const timeoutDuration = options.projectLoadTimeout * 1000; // timeout logic const handle = setTimeout(() => { From 510b7cdfefe8bfbd33cd0cca5a398994e0e72845 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Tue, 1 May 2018 15:51:42 -0700 Subject: [PATCH 3/4] Add test that reads options and verifies default values --- src/omnisharp/options.ts | 8 ++--- test/unitTests/options.test.ts | 56 ++++++++++++++++++++++++++++++ test/unitTests/testAssets/Fakes.ts | 32 ++++++++++++++--- 3 files changed, 88 insertions(+), 8 deletions(-) create mode 100644 test/unitTests/options.test.ts diff --git a/src/omnisharp/options.ts b/src/omnisharp/options.ts index 8a4d06f23..4b1568d3f 100644 --- a/src/omnisharp/options.ts +++ b/src/omnisharp/options.ts @@ -38,8 +38,8 @@ export class Options { const waitForDebugger = omnisharpConfig.get('waitForDebugger', false); // support the legacy "verbose" level as "debug" - let loggingLevel = omnisharpConfig.get('loggingLevel'); - if (loggingLevel.toLowerCase() === 'verbose') { + let loggingLevel = omnisharpConfig.get('loggingLevel', 'information'); + if (loggingLevel && loggingLevel.toLowerCase() === 'verbose') { loggingLevel = 'debug'; } @@ -56,7 +56,7 @@ export class Options { const disableCodeActions = csharpConfig.get('disableCodeActions', false); - const disableMSBuildDiagnosticWarning = omnisharpConfig.get('disableMSBuildDiagnosticWarning'); + const disableMSBuildDiagnosticWarning = omnisharpConfig.get('disableMSBuildDiagnosticWarning', false); return new Options( path, @@ -97,7 +97,7 @@ export class Options { if (omnisharpConfig.has('useGlobalMono')) { // If 'omnisharp.useGlobalMono' setting was found, just use it. - return omnisharpConfig.get('useGlobalMono'); + return omnisharpConfig.get('useGlobalMono', "auto"); } else if (omnisharpConfig.has('useMono')) { // BACKCOMPAT: If 'omnisharp.useMono' setting was found, true maps to "always" and false maps to "auto" diff --git a/test/unitTests/options.test.ts b/test/unitTests/options.test.ts new file mode 100644 index 000000000..55656de7e --- /dev/null +++ b/test/unitTests/options.test.ts @@ -0,0 +1,56 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { should, expect } from 'chai'; +import { Options } from '../../src/omnisharp/options'; +import { getFakeVsCode, getWorkspaceConfiguration } from './testAssets/Fakes'; + +function getVSCode() { + const vscode = getFakeVsCode(); + + const omnisharpConfig = getWorkspaceConfiguration(); + const csharpConfig = getWorkspaceConfiguration(); + + vscode.workspace.getConfiguration = (section?, resource?) => + { + if (section === 'omnisharp') + { + return omnisharpConfig; + } + + if (section === 'csharp') + { + return csharpConfig; + } + + return undefined; + }; + + return vscode; +} + +suite("Options tests", () => { + suiteSetup(() => should()); + + test('Construct options and verify defaults', () => + { + const vscode = getVSCode(); + const options = Options.Read(vscode); + + expect(options.path).to.be.null; + options.useGlobalMono.should.equal("auto"); + options.waitForDebugger.should.equal(false); + options.loggingLevel.should.equal("information"); + options.autoStart.should.equal(true); + options.projectLoadTimeout.should.equal(60); + options.maxProjectResults.should.equal(250); + options.useEditorFormattingSettings.should.equal(true); + options.useFormatting.should.equal(true); + options.showReferencesCodeLens.should.equal(true); + options.showTestsCodeLens.should.equal(true); + options.disableCodeActions.should.equal(false); + options.disableCodeActions.should.equal(false); + }); +}); diff --git a/test/unitTests/testAssets/Fakes.ts b/test/unitTests/testAssets/Fakes.ts index 1a83637e3..ba644c478 100644 --- a/test/unitTests/testAssets/Fakes.ts +++ b/test/unitTests/testAssets/Fakes.ts @@ -32,8 +32,8 @@ export const getNullTelemetryReporter = (): ITelemetryReporter => { }; export const getNullWorkspaceConfiguration = (): vscode.WorkspaceConfiguration => { - let workspace: vscode.WorkspaceConfiguration = { - get: (section: string): T| undefined => { + let configuration: vscode.WorkspaceConfiguration = { + get: (section: string): T | undefined => { return undefined; }, has: (section: string) => { return undefined; }, @@ -42,9 +42,33 @@ export const getNullWorkspaceConfiguration = (): vscode.WorkspaceConfiguration = key: undefined }; }, - update: async () => { return Promise.resolve(); }, + update: async () => { return Promise.resolve(); } }; - return workspace; + + return configuration; +}; + +export const getWorkspaceConfiguration = (): vscode.WorkspaceConfiguration => { + let values: { [key: string]: any } = {}; + + let configuration: vscode.WorkspaceConfiguration = { + get(section: string, defaultValue?: T): T | undefined { + let result = values[section]; + return result === undefined && defaultValue !== undefined + ? defaultValue + : result; + }, + has: (section: string) => { + return values[section] !== undefined; + }, + inspect: () => { throw new Error("Not Implemented"); }, + update: async (section: string, value: any, configurationTarget?: vscode.ConfigurationTarget | boolean) => { + values[section] = value; + return Promise.resolve(); + } + }; + + return configuration; }; export function getOmnisharpMSBuildProjectDiagnosticsEvent(fileName: string, warnings: MSBuildDiagnosticsMessage[], errors: MSBuildDiagnosticsMessage[]): OmnisharpServerMsBuildProjectDiagnostics { From dce7747478b2b7077da381faa7dc063fd153ace3 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Tue, 1 May 2018 16:09:31 -0700 Subject: [PATCH 4/4] Improve code coverage by adding tests for BACK-COMPAT options scenarios --- src/omnisharp/options.ts | 2 +- test/unitTests/options.test.ts | 92 +++++++++++++++++++++++++++++++--- 2 files changed, 87 insertions(+), 7 deletions(-) diff --git a/src/omnisharp/options.ts b/src/omnisharp/options.ts index 4b1568d3f..845084f4d 100644 --- a/src/omnisharp/options.ts +++ b/src/omnisharp/options.ts @@ -81,7 +81,7 @@ export class Options { } else if (csharpConfig.has('omnisharp')) { // BACKCOMPAT: If 'csharp.omnisharp' setting was found, use it. - return csharpConfig.get('path'); + return csharpConfig.get('omnisharp'); } else { // Otherwise, null. diff --git a/test/unitTests/options.test.ts b/test/unitTests/options.test.ts index 55656de7e..d9303acb5 100644 --- a/test/unitTests/options.test.ts +++ b/test/unitTests/options.test.ts @@ -6,23 +6,24 @@ import { should, expect } from 'chai'; import { Options } from '../../src/omnisharp/options'; import { getFakeVsCode, getWorkspaceConfiguration } from './testAssets/Fakes'; +import { WorkspaceConfiguration } from '../../src/vscodeAdapter'; -function getVSCode() { +function getVSCode(omnisharpConfig?: WorkspaceConfiguration, csharpConfig?: WorkspaceConfiguration) { const vscode = getFakeVsCode(); - const omnisharpConfig = getWorkspaceConfiguration(); - const csharpConfig = getWorkspaceConfiguration(); + const _omnisharpConfig = omnisharpConfig || getWorkspaceConfiguration(); + const _csharpConfig = csharpConfig || getWorkspaceConfiguration(); vscode.workspace.getConfiguration = (section?, resource?) => { if (section === 'omnisharp') { - return omnisharpConfig; + return _omnisharpConfig; } if (section === 'csharp') { - return csharpConfig; + return _csharpConfig; } return undefined; @@ -34,7 +35,7 @@ function getVSCode() { suite("Options tests", () => { suiteSetup(() => should()); - test('Construct options and verify defaults', () => + test('Verify defaults', () => { const vscode = getVSCode(); const options = Options.Read(vscode); @@ -53,4 +54,83 @@ suite("Options tests", () => { options.disableCodeActions.should.equal(false); options.disableCodeActions.should.equal(false); }); + + test('BACK-COMPAT: "omnisharp.loggingLevel": "verbose" == "omnisharp.loggingLevel": "debug"', () => + { + const omnisharpConfig = getWorkspaceConfiguration(); + omnisharpConfig.update('loggingLevel', "verbose"); + const vscode = getVSCode(omnisharpConfig); + + const options = Options.Read(vscode); + + options.loggingLevel.should.equal("debug"); + }); + + test('BACK-COMPAT: "omnisharp.useMono": true == "omnisharp.useGlobalMono": "always"', () => + { + const omnisharpConfig = getWorkspaceConfiguration(); + omnisharpConfig.update('useMono', true); + const vscode = getVSCode(omnisharpConfig); + + const options = Options.Read(vscode); + + options.useGlobalMono.should.equal("always"); + }); + + test('BACK-COMPAT: "omnisharp.useMono": false == "omnisharp.useGlobalMono": "auto"', () => + { + const omnisharpConfig = getWorkspaceConfiguration(); + omnisharpConfig.update('useMono', false); + const vscode = getVSCode(omnisharpConfig); + + const options = Options.Read(vscode); + + options.useGlobalMono.should.equal("auto"); + }); + + test('BACK-COMPAT: "csharp.omnisharpUsesMono": true == "omnisharp.useGlobalMono": "always"', () => + { + const csharpConfig = getWorkspaceConfiguration(); + csharpConfig.update('omnisharpUsesMono', true); + const vscode = getVSCode(undefined, csharpConfig); + + const options = Options.Read(vscode); + + options.useGlobalMono.should.equal("always"); + }); + + test('BACK-COMPAT: "csharp.omnisharpUsesMono": false == "omnisharp.useGlobalMono": "auto"', () => + { + const csharpConfig = getWorkspaceConfiguration(); + csharpConfig.update('omnisharpUsesMono', false); + const vscode = getVSCode(undefined, csharpConfig); + + const options = Options.Read(vscode); + + options.useGlobalMono.should.equal("auto"); + }); + + test('BACK-COMPAT: "csharp.omnisharp" is used if it is set and "omnisharp.path" is not', () => + { + const csharpConfig = getWorkspaceConfiguration(); + csharpConfig.update('omnisharp', 'OldPath'); + const vscode = getVSCode(undefined, csharpConfig); + + const options = Options.Read(vscode); + + options.path.should.equal("OldPath"); + }); + + test('BACK-COMPAT: "csharp.omnisharp" is not used if "omnisharp.path" is set', () => + { + const omnisharpConfig = getWorkspaceConfiguration(); + omnisharpConfig.update('path', 'NewPath'); + const csharpConfig = getWorkspaceConfiguration(); + csharpConfig.update('omnisharp', 'OldPath'); + const vscode = getVSCode(omnisharpConfig, csharpConfig); + + const options = Options.Read(vscode); + + options.path.should.equal("NewPath"); + }); });