Skip to content

Commit 7876468

Browse files
committed
refactoring for testing
1 parent 42fa329 commit 7876468

File tree

9 files changed

+136
-32
lines changed

9 files changed

+136
-32
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,7 @@
645645
"category": "CSharp"
646646
},
647647
{
648-
"command": "csharp.fileBugReport",
648+
"command": "csharp.reportIssue",
649649
"title": "Upload bug report to github",
650650
"category": "CSharp"
651651
}

src/constants/CSharpExtensionId.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
export const CSharpExtensionId = 'ms-vscode.csharp';

src/features/commands.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { PlatformInformation } from '../platform';
2020
import CompositeDisposable from '../CompositeDisposable';
2121
import OptionProvider from '../observers/OptionProvider';
2222
import generateBugReport from './generateBugReport';
23+
import { execChildProcess } from '../common';
2324

2425
export default function registerCommands(server: OmniSharpServer, platformInfo: PlatformInformation, eventStream: EventStream, optionProvider: OptionProvider): CompositeDisposable {
2526
let disposable = new CompositeDisposable();
@@ -47,7 +48,7 @@ export default function registerCommands(server: OmniSharpServer, platformInfo:
4748
// Register command for adapter executable command.
4849
disposable.add(vscode.commands.registerCommand('csharp.coreclrAdapterExecutableCommand', async (args) => getAdapterExecutionCommand(platformInfo, eventStream)));
4950
disposable.add(vscode.commands.registerCommand('csharp.clrAdapterExecutableCommand', async (args) => getAdapterExecutionCommand(platformInfo, eventStream)));
50-
disposable.add(vscode.commands.registerCommand('csharp.fileBugReport', async () => generateBugReport(platformInfo.isValidPlatformForMono())));
51+
disposable.add(vscode.commands.registerCommand('csharp.reportIssue', async () => generateBugReport(vscode, eventStream, execChildProcess, platformInfo.isValidPlatformForMono())));
5152

5253
return new CompositeDisposable(disposable);
5354
}

src/features/generateBugReport.ts

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,21 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import * as vscode from "vscode";
7-
import { execChildProcess } from "../common";
6+
import { vscode } from "../vscodeAdapter";
7+
import { Extension } from "../vscodeAdapter";
8+
import { CSharpExtensionId } from "../constants/CSharpExtensionId";
9+
import { EventStream } from "../EventStream";
10+
import { ReportIssue } from "../omnisharp/loggingEvents";
811

9-
const extensionId = 'ms-vscode.csharp';
10-
const extension = vscode.extensions.getExtension(extensionId);
11-
const extensionVersion = extension.packageJSON.version;
1212
const issuesUrl = "https://github.com/OmniSharp/omnisharp-vscode/issues/new";
13-
const queryStringPrefix: string = "?";
1413

15-
let extensions = vscode.extensions.all
16-
.filter(extension => extension.packageJSON.isBuiltin === false);
17-
18-
extensions.sort(sortExtensions);
14+
export default async function generateBugReport(vscode: vscode, eventStream: EventStream, execChildProcess:(command: string, workingDirectory?: string) => Promise<string>, isValidPlatformForMono: boolean) {
15+
const dotnetInfo = await getDotnetInfo(execChildProcess);
16+
const monoInfo = await getMonoIfPlatformValid(execChildProcess, isValidPlatformForMono);
17+
let extensions = getInstalledExtensions(vscode);
18+
let csharpExtVersion = getCsharpExtensionVersion(vscode);
1919

20-
export default async function generateBugReport(isValidPlatformForMono: boolean) {
21-
const dotnetInfo = await getDotnetInfo();
22-
23-
const body = encodeURIComponent(`## Issue Description ##
20+
const body = `## Issue Description ##
2421
## Steps to Reproduce ##
2522
2623
## Expected Behavior ##
@@ -30,8 +27,8 @@ export default async function generateBugReport(isValidPlatformForMono: boolean)
3027
## Environment Information ##
3128
3229
VSCode version: ${vscode.version}
33-
C# Extension: ${extensionVersion}
34-
${getMonoIfPlatformValid(isValidPlatformForMono)}
30+
C# Extension: ${csharpExtVersion}
31+
${monoInfo}
3532
3633
<details><summary>Dotnet Info</summary>
3734
${dotnetInfo}</details>
@@ -46,14 +43,12 @@ Post the output from Output-->C# here
4643
<details><summary>Visual Studio Code Extensions</summary>
4744
${generateExtensionTable(extensions)}
4845
</details>
49-
`);
46+
`;
5047

51-
const encodedBody = encodeURIComponent(body);
52-
const fullUrl = `${issuesUrl}${queryStringPrefix}body=${encodedBody}`;
53-
vscode.commands.executeCommand("vscode.open", vscode.Uri.parse(fullUrl));
48+
eventStream.post(new ReportIssue(issuesUrl, body));
5449
}
5550

56-
function sortExtensions(a: vscode.Extension<any>, b: vscode.Extension<any>): number {
51+
function sortExtensions(a: Extension<any>, b: Extension<any>): number {
5752

5853
if (a.packageJSON.name.toLowerCase() < b.packageJSON.name.toLowerCase()) {
5954
return -1;
@@ -64,7 +59,7 @@ function sortExtensions(a: vscode.Extension<any>, b: vscode.Extension<any>): num
6459
return 0;
6560
}
6661

67-
function generateExtensionTable(extensions: vscode.Extension<any>[]) {
62+
function generateExtensionTable(extensions: Extension<any>[]) {
6863
if (extensions.length <= 0) {
6964
return "none";
7065
}
@@ -83,18 +78,30 @@ ${tableHeader}\n${table};
8378
return extensionTable;
8479
}
8580

86-
function getMonoIfPlatformValid(isValidPlatformForMono: boolean): string{
81+
async function getMonoIfPlatformValid(execChildProcess:(command: string, workingDirectory?: string) =>Promise<string>, isValidPlatformForMono: boolean): Promise<string>{
8782
if (isValidPlatformForMono) {
88-
return `Mono: ${getMonoVersion()}`;
83+
return `Mono: ${await getMonoVersion(execChildProcess)}`;
8984
}
9085

9186
return "";
9287
}
9388

94-
async function getDotnetInfo(): Promise<string> {
89+
async function getDotnetInfo(execChildProcess:(command: string, workingDirectory?: string) =>Promise<string>): Promise<string> {
9590
return execChildProcess("dotnet --info", process.cwd());
9691
}
9792

98-
async function getMonoVersion(): Promise<string>{
99-
return execChildProcess("dotnet --info", process.cwd());
93+
async function getMonoVersion(execChildProcess:(command: string, workingDirectory?: string) =>Promise<string>): Promise<string>{
94+
return execChildProcess("mono --version", process.cwd());
10095
}
96+
97+
function getInstalledExtensions(vscode: vscode) {
98+
let extensions = vscode.extensions.all
99+
.filter(extension => extension.packageJSON.isBuiltin === false);
100+
101+
return extensions.sort(sortExtensions);
102+
}
103+
104+
function getCsharpExtensionVersion(vscode: vscode): string{
105+
const extension = vscode.extensions.getExtension(CSharpExtensionId);
106+
return extension.packageJSON.version;
107+
}

src/main.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,12 @@ import DotNetTestChannelObserver from './observers/DotnetTestChannelObserver';
3535
import DotNetTestLoggerObserver from './observers/DotnetTestLoggerObserver';
3636
import { ShowOmniSharpConfigChangePrompt } from './observers/OptionChangeObserver';
3737
import createOptionStream from './observables/CreateOptionStream';
38+
import { CSharpExtensionId } from './constants/CSharpExtensionId';
39+
import { ReportIssueObserver } from './observers/ReportIssueObserver';
3840

3941
export async function activate(context: vscode.ExtensionContext): Promise<CSharpExtensionExports> {
4042

41-
const extensionId = 'ms-vscode.csharp';
43+
const extensionId = CSharpExtensionId;
4244
const extension = vscode.extensions.getExtension<CSharpExtensionExports>(extensionId);
4345
const extensionVersion = extension.packageJSON.version;
4446
const aiKey = extension.packageJSON.contributes.debuggers[0].aiKey;
@@ -91,6 +93,9 @@ export async function activate(context: vscode.ExtensionContext): Promise<CSharp
9193
let projectStatusBarObserver = new ProjectStatusBarObserver(projectStatusBar);
9294
eventStream.subscribe(projectStatusBarObserver.post);
9395

96+
let reportIssueObserver = new ReportIssueObserver(vscode);
97+
eventStream.subscribe(reportIssueObserver.post);
98+
9499
const debugMode = false;
95100
if (debugMode) {
96101
let omnisharpDebugModeLoggerObserver = new OmnisharpDebugModeLoggerObserver(omnisharpChannel);
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { vscode } from "../vscodeAdapter";
7+
import { BaseEvent, ReportIssue } from "../omnisharp/loggingEvents";
8+
9+
export class ReportIssueObserver {
10+
11+
constructor(private vscode: vscode) {
12+
}
13+
14+
public post = (event: BaseEvent) => {
15+
switch (event.constructor.name) {
16+
case ReportIssue.name:
17+
let issue = <ReportIssue>event;
18+
let encodedBody = encodeURIComponent(issue.body);
19+
const queryStringPrefix: string = "?";
20+
const fullUrl = `${issue.url}${queryStringPrefix}body=${encodedBody}`;
21+
this.vscode.commands.executeCommand("vscode.open", this.vscode.Uri.parse(fullUrl));
22+
break;
23+
}
24+
}
25+
}

src/omnisharp/loggingEvents.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,6 @@ export class DotNetTestDebugProcessStart implements BaseEvent {
138138
constructor(public targetProcessId: number) { }
139139
}
140140

141-
142141
export class DotNetTestsInClassRunStart implements BaseEvent {
143142
constructor(public className: string) { }
144143
}
@@ -151,6 +150,10 @@ export class DocumentSynchronizationFailure implements BaseEvent {
151150
constructor(public documentPath: string, public errorMessage: string) { }
152151
}
153152

153+
export class ReportIssue {
154+
constructor(public url: string, public body: string) { }
155+
}
156+
154157
export class DebuggerPrerequisiteFailure extends EventWithMessage { }
155158
export class DebuggerPrerequisiteWarning extends EventWithMessage { }
156159
export class CommandDotNetRestoreProgress extends EventWithMessage { }

src/vscodeAdapter.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,42 @@ interface Thenable<T> {
902902
then<TResult>(onfulfilled?: (value: T) => TResult | Thenable<TResult>, onrejected?: (reason: any) => void): Thenable<TResult>;
903903
}
904904

905+
export interface Extension<T> {
906+
907+
/**
908+
* The canonical extension identifier in the form of: `publisher.name`.
909+
*/
910+
readonly id: string;
911+
912+
/**
913+
* The absolute file path of the directory containing this extension.
914+
*/
915+
readonly extensionPath: string;
916+
917+
/**
918+
* `true` if the extension has been activated.
919+
*/
920+
readonly isActive: boolean;
921+
922+
/**
923+
* The parsed contents of the extension's package.json.
924+
*/
925+
readonly packageJSON: any;
926+
927+
/**
928+
* The public API exported by this extension. It is an invalid action
929+
* to access this field before this extension has been activated.
930+
*/
931+
readonly exports: T;
932+
933+
/**
934+
* Activates this extension and returns its public API.
935+
*
936+
* @return A promise that will resolve when this extension has been activated.
937+
*/
938+
activate(): Thenable<T>;
939+
}
940+
905941
export interface vscode {
906942
commands: {
907943
executeCommand: <T>(command: string, ...rest: any[]) => Thenable<T | undefined>;
@@ -921,4 +957,13 @@ export interface vscode {
921957
createFileSystemWatcher(globPattern: GlobPattern, ignoreCreateEvents?: boolean, ignoreChangeEvents?: boolean, ignoreDeleteEvents?: boolean): FileSystemWatcher;
922958
onDidChangeConfiguration: Event<ConfigurationChangeEvent>;
923959
};
960+
extensions: {
961+
getExtension(extensionId: string): Extension<any> | undefined;
962+
all: Extension<any>[];
963+
};
964+
Uri: {
965+
parse(value: string): Uri;
966+
};
967+
968+
version: string;
924969
}

test/unitTests/testAssets/Fakes.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,19 @@ export function getFakeVsCode(): vscode.vscode {
133133
onDidChangeConfiguration: (listener: (e: ConfigurationChangeEvent) => any, thisArgs?: any, disposables?: Disposable[]): Disposable => {
134134
throw new Error("Not Implemented");
135135
}
136-
}
136+
},
137+
extensions: {
138+
getExtension: () => {
139+
throw new Error("Not Implemented");
140+
},
141+
all: []
142+
},
143+
Uri: {
144+
parse: () => {
145+
throw new Error("Not Implemented");
146+
}
147+
},
148+
version: ""
137149
};
138150
}
139151

0 commit comments

Comments
 (0)