Skip to content

Commit 8b0aa39

Browse files
authored
Merge pull request #6391 from dibarbet/merge_main
Snap main to release
2 parents 464949f + 5363302 commit 8b0aa39

File tree

83 files changed

+1363
-1824
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+1363
-1824
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@
88
- Debug from .csproj and .sln [#5876](https://github.com/dotnet/vscode-csharp/issues/5876)
99

1010
## Latest
11+
* Update Roslyn version (PR: [#6389](https://github.com/dotnet/vscode-csharp/pull/6389))
12+
* Remove diagnostic source name (PR: [#69939](https://github.com/dotnet/roslyn/pull/69939))
13+
* Fix fold all regions (PR: [#69817](https://github.com/dotnet/roslyn/pull/69817))
14+
* Fix escaping and wrapping in hover (PR: [#69893](https://github.com/dotnet/roslyn/pull/69893))
15+
* Fix error in override completion when containing type does not exist (PR: [#69855](https://github.com/dotnet/roslyn/pull/69855))
16+
* Fix issues generating assets in Omnisharp (PR: [#6380](https://github.com/dotnet/vscode-csharp/pull/6380))
17+
* Allow Razor to format new documents via Roslyn (PR: [#6329](https://github.com/dotnet/vscode-csharp/pull/6329))
18+
* Switch to named pipes for client <-> server communication (PR: [#6351](https://github.com/dotnet/vscode-csharp/pull/6351))
19+
* Only show clr debugger if on Windows (PR: [#6359](https://github.com/dotnet/vscode-csharp/pull/6359))
1120
* Update Razor version to 7.0.0-preview.23456.2 (PR: [#6304](https://github.com/dotnet/vscode-csharp/pull/6304))
1221
* Fixes regression where semantic colors for razor components appear as red
1322
* Make completion complex text edits more robust (PR: [#6325](https://github.com/dotnet/vscode-csharp/pull/6325))

gulpfile.ts

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,9 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import * as gulp from 'gulp';
7-
import * as optionsSchemaGenerator from './src/tools/generateOptionsSchema';
8-
import * as packageDependencyUpdater from './src/tools/updatePackageDependencies';
9-
106
require('./tasks/testTasks');
117
require('./tasks/offlinePackagingTasks');
128
require('./tasks/backcompatTasks');
139
require('./tasks/localizationTasks');
1410
require('./tasks/createTagsTasks');
15-
16-
// Disable warning about wanting an async function
17-
// tslint:disable-next-line
18-
gulp.task('generateOptionsSchema', async (): Promise<void> => {
19-
optionsSchemaGenerator.GenerateOptionsSchema();
20-
return Promise.resolve();
21-
});
22-
23-
// Disable warning about wanting an async function
24-
// tslint:disable-next-line
25-
gulp.task('updatePackageDependencies', async (): Promise<void> => {
26-
return packageDependencyUpdater.updatePackageDependencies();
27-
});
11+
require('./tasks/debuggerTasks');

omnisharptest/omnisharpUnitTests/common.test.ts renamed to omnisharptest/omnisharpJestTests/common.test.ts

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

6+
import { describe, test, expect } from '@jest/globals';
67
import * as path from 'path';
78

89
import { isSubfolderOf, safeLength, sum } from '../../src/common';
910

10-
import { should, expect } from 'chai';
11-
12-
suite('Common', () => {
13-
suiteSetup(() => should());
14-
15-
suite('safeLength', () => {
11+
describe('Common', () => {
12+
describe('safeLength', () => {
1613
test('return 0 for empty array', () => {
1714
const array: any[] = [];
1815
const result = safeLength(array);
19-
result.should.equal(0);
16+
expect(result).toBe(0);
2017
});
2118

2219
test('returns 5 for array of 5 elements', () => {
2320
const array = [1, 2, 3, 4, 5];
2421
const result = safeLength(array);
25-
result.should.equal(5);
22+
expect(result).toBe(5);
2623
});
2724

2825
test('returns 0 for undefined', () => {
2926
const array = undefined;
3027
const result = safeLength(array);
31-
result.should.equal(0);
28+
expect(result).toBe(0);
3229
});
3330
});
3431

35-
suite('sum', () => {
32+
describe('sum', () => {
3633
test('produce total from numbers', () => {
3734
const array = [1, 2, 3, 4, 5];
3835
const result = sum(array, (i) => i);
39-
result.should.equal(15);
36+
expect(result).toBe(15);
4037
});
4138

4239
test('produce total from lengths of arrays', () => {
4340
const array = [[1, 2], [3], [], [4, 5, 6]];
4441
const result = sum(array, (i) => i.length);
45-
result.should.equal(6);
42+
expect(result).toBe(6);
4643
});
4744

4845
test('produce total of true values from array of booleans', () => {
4946
const array = [true, false, false, true, true, true, false, true];
5047
const result = sum(array, (b) => (b ? 1 : 0));
51-
result.should.equal(5);
48+
expect(result).toBe(5);
5249
});
5350
});
5451

55-
suite('isSubfolderOf', () => {
52+
describe('isSubfolderOf', () => {
5653
test('same paths', () => {
5754
const subfolder: string = ['C:', 'temp', 'VS', 'dotnetProject'].join(path.sep);
5855
const folder: string = ['C:', 'temp', 'VS', 'dotnetProject'].join(path.sep);
5956

60-
expect(isSubfolderOf(subfolder, folder)).to.be.true;
57+
expect(isSubfolderOf(subfolder, folder)).toBe(true);
6158
});
6259

6360
test('correct subfolder', () => {
64-
const subfolder: string = ['C:', 'temp', 'VS'].join(path.sep);
65-
const folder: string = ['C:', 'temp', 'VS', 'dotnetProject'].join(path.sep);
61+
const folder: string = ['C:', 'temp', 'VS'].join(path.sep);
62+
const subfolder: string = ['C:', 'temp', 'VS', 'dotnetProject'].join(path.sep);
6663

67-
expect(isSubfolderOf(subfolder, folder)).to.be.true;
64+
expect(isSubfolderOf(subfolder, folder)).toBe(true);
6865
});
6966

70-
test('longer subfolder', () => {
71-
const subfolder: string = ['C:', 'temp', 'VS', 'a', 'b', 'c'].join(path.sep);
72-
const folder: string = ['C:', 'temp', 'VS'].join(path.sep);
67+
test('longer folder', () => {
68+
const folder: string = ['C:', 'temp', 'VS', 'a', 'b', 'c'].join(path.sep);
69+
const subfolder: string = ['C:', 'temp', 'VS'].join(path.sep);
7370

74-
expect(isSubfolderOf(subfolder, folder)).to.be.false;
71+
expect(isSubfolderOf(subfolder, folder)).toBe(false);
7572
});
7673

7774
test('Different drive', () => {
7875
const subfolder: string = ['C:', 'temp', 'VS'].join(path.sep);
7976
const folder: string = ['E:', 'temp', 'VS'].join(path.sep);
8077

81-
expect(isSubfolderOf(subfolder, folder)).to.be.false;
78+
expect(isSubfolderOf(subfolder, folder)).toBe(false);
8279
});
8380
});
8481
});
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
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 * as vscode from 'vscode';
7+
import reportIssue from '../../../src/shared/reportIssue';
8+
import { FakeMonoResolver, fakeMonoInfo } from '../../omnisharpUnitTests/fakes/fakeMonoResolver';
9+
import { FakeDotnetResolver } from '../../omnisharpUnitTests/fakes/fakeDotnetResolver';
10+
import { DotnetInfo } from '../../../src/shared/utils/dotnetInfo';
11+
import { jest, describe, test, expect, beforeEach } from '@jest/globals';
12+
13+
describe(`${reportIssue.name}`, () => {
14+
const vscodeVersion = 'myVersion';
15+
const csharpExtVersion = 'csharpExtVersion';
16+
const isValidForMono = true;
17+
const extension1 = {
18+
packageJSON: {
19+
name: 'name1',
20+
publisher: 'publisher1',
21+
version: 'version1',
22+
isBuiltin: true,
23+
},
24+
id: 'id1',
25+
extensionPath: 'c:/extensions/abc-x64',
26+
} as vscode.Extension<any>;
27+
28+
const extension2 = {
29+
packageJSON: {
30+
name: 'name2',
31+
publisher: 'publisher2',
32+
version: 'version2',
33+
isBuiltin: false,
34+
},
35+
id: 'id2',
36+
extensionPath: 'c:/extensions/xyz-x64',
37+
} as vscode.Extension<any>;
38+
39+
const fakeDotnetInfo: DotnetInfo = {
40+
FullInfo: 'myDotnetInfo',
41+
Version: '1.0.x',
42+
RuntimeId: 'win10-x64',
43+
Runtimes: {},
44+
};
45+
46+
let fakeMonoResolver: FakeMonoResolver;
47+
let fakeDotnetResolver: FakeDotnetResolver;
48+
const getDotnetInfo = async () => Promise.resolve(fakeDotnetInfo);
49+
let issueBody: string;
50+
51+
beforeEach(() => {
52+
jest.spyOn(vscode.workspace, 'getConfiguration').mockReturnValue({
53+
get: jest.fn((_config: string) => {
54+
return undefined;
55+
}),
56+
has: jest.fn(),
57+
inspect: jest.fn(),
58+
update: jest.fn(),
59+
} as vscode.WorkspaceConfiguration);
60+
61+
jest.spyOn(vscode.commands, 'executeCommand').mockImplementation(async (command: string, ...rest: any[]) => {
62+
issueBody = rest[0].issueBody;
63+
return {} as any;
64+
});
65+
jest.replaceProperty(vscode, 'extensions', {
66+
all: [extension1, extension2],
67+
getExtension: jest.fn(),
68+
onDidChange: jest.fn(),
69+
} as typeof vscode.extensions);
70+
71+
fakeMonoResolver = new FakeMonoResolver();
72+
fakeDotnetResolver = new FakeDotnetResolver();
73+
});
74+
75+
describe('The body is passed to the vscode clipboard and', () => {
76+
test('it contains the vscode version', async () => {
77+
await reportIssue(csharpExtVersion, getDotnetInfo, isValidForMono, fakeDotnetResolver, fakeMonoResolver);
78+
expect(issueBody).toContain(`**VSCode version**: ${vscodeVersion}`);
79+
});
80+
81+
test('it contains the csharp extension version', async () => {
82+
await reportIssue(csharpExtVersion, getDotnetInfo, isValidForMono, fakeDotnetResolver, fakeMonoResolver);
83+
expect(issueBody).toContain(`**C# Extension**: ${csharpExtVersion}`);
84+
});
85+
86+
test('it contains dotnet info', async () => {
87+
await reportIssue(csharpExtVersion, getDotnetInfo, isValidForMono, fakeDotnetResolver, fakeMonoResolver);
88+
expect(issueBody).toContain(fakeDotnetInfo.FullInfo);
89+
});
90+
91+
test('mono information is obtained when it is a valid mono platform', async () => {
92+
await reportIssue(csharpExtVersion, getDotnetInfo, isValidForMono, fakeDotnetResolver, fakeMonoResolver);
93+
expect(fakeMonoResolver.getMonoCalled).toEqual(true);
94+
});
95+
96+
test('mono version is put in the body when it is a valid mono platform', async () => {
97+
await reportIssue(csharpExtVersion, getDotnetInfo, isValidForMono, fakeDotnetResolver, fakeMonoResolver);
98+
expect(fakeMonoResolver.getMonoCalled).toEqual(true);
99+
expect(issueBody).toContain(fakeMonoInfo.version);
100+
});
101+
102+
test('mono information is not obtained when it is not a valid mono platform', async () => {
103+
await reportIssue(csharpExtVersion, getDotnetInfo, false, fakeDotnetResolver, fakeMonoResolver);
104+
expect(fakeMonoResolver.getMonoCalled).toEqual(false);
105+
});
106+
107+
test('The url contains the name, publisher and version for all the extensions that are not builtin', async () => {
108+
await reportIssue(csharpExtVersion, getDotnetInfo, isValidForMono, fakeDotnetResolver, fakeMonoResolver);
109+
expect(issueBody).toContain(extension2.packageJSON.name);
110+
expect(issueBody).toContain(extension2.packageJSON.publisher);
111+
expect(issueBody).toContain(extension2.packageJSON.version);
112+
expect(issueBody).not.toContain(extension1.packageJSON.name);
113+
expect(issueBody).not.toContain(extension1.packageJSON.publisher);
114+
expect(issueBody).not.toContain(extension1.packageJSON.version);
115+
});
116+
});
117+
});
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
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 * as vscode from 'vscode';
7+
import { jest, describe, test, expect, beforeEach } from '@jest/globals';
8+
import { InformationMessageObserver } from '../../src/observers/informationMessageObserver';
9+
import { getUnresolvedDependenices, getWorkspaceConfiguration } from '../../test/unitTests/fakes';
10+
import { Subject, from as observableFrom } from 'rxjs';
11+
import { timeout } from 'rxjs/operators';
12+
13+
describe('InformationMessageObserver', () => {
14+
let doClickOk: () => void;
15+
let doClickCancel: () => void;
16+
let signalCommandDone: () => void;
17+
let commandDone: Promise<void> | undefined;
18+
const optionObservable = new Subject<void>();
19+
let infoMessage: string | undefined;
20+
let invokedCommand: string | undefined;
21+
const observer: InformationMessageObserver = new InformationMessageObserver(vscode);
22+
23+
beforeEach(() => {
24+
infoMessage = undefined;
25+
invokedCommand = undefined;
26+
commandDone = new Promise<void>((resolve) => {
27+
signalCommandDone = () => {
28+
resolve();
29+
};
30+
});
31+
32+
jest.spyOn(vscode.workspace, 'getConfiguration').mockReturnValue(getWorkspaceConfiguration());
33+
jest.spyOn(vscode.window, 'showInformationMessage').mockImplementation(
34+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
35+
//@ts-ignore
36+
async <T>(message: string, ...items: T[]) => {
37+
infoMessage = message;
38+
return new Promise<T | undefined>((resolve) => {
39+
doClickCancel = () => {
40+
resolve(undefined);
41+
};
42+
43+
doClickOk = () => {
44+
resolve(items[0]);
45+
};
46+
47+
return undefined;
48+
});
49+
}
50+
);
51+
jest.spyOn(vscode.commands, 'executeCommand').mockImplementation(async (command: string, ..._: any[]) => {
52+
invokedCommand = command;
53+
signalCommandDone();
54+
return undefined;
55+
});
56+
});
57+
58+
[
59+
{
60+
event: getUnresolvedDependenices('someFile'),
61+
expectedCommand: 'dotnet.restore.all',
62+
},
63+
].forEach((elem) => {
64+
describe(elem.event.constructor.name, () => {
65+
describe('Suppress Dotnet Restore Notification is true', () => {
66+
beforeEach(() => {
67+
vscode.workspace.getConfiguration().update('csharp.suppressDotnetRestoreNotification', true);
68+
optionObservable.next();
69+
});
70+
71+
test('The information message is not shown', () => {
72+
observer.post(elem.event);
73+
expect(infoMessage).toBeUndefined();
74+
});
75+
});
76+
77+
describe('Suppress Dotnet Restore Notification is false', () => {
78+
beforeEach(() => {
79+
vscode.workspace.getConfiguration().update('csharp.suppressDotnetRestoreNotification', false);
80+
optionObservable.next();
81+
});
82+
83+
test('The information message is shown', async () => {
84+
observer.post(elem.event);
85+
expect(infoMessage?.length).toBeGreaterThan(0);
86+
doClickOk();
87+
await commandDone;
88+
expect(invokedCommand).toEqual(elem.expectedCommand);
89+
});
90+
91+
test('Given an information message if the user clicks Restore, the command is executed', async () => {
92+
observer.post(elem.event);
93+
doClickOk();
94+
await commandDone;
95+
expect(invokedCommand).toEqual(elem.expectedCommand);
96+
});
97+
98+
test('Given an information message if the user clicks cancel, the command is not executed', async () => {
99+
observer.post(elem.event);
100+
doClickCancel();
101+
await expect(observableFrom(commandDone!).pipe(timeout(1)).toPromise()).rejects.toThrow();
102+
expect(invokedCommand).toBeUndefined();
103+
});
104+
});
105+
});
106+
});
107+
108+
afterEach(() => {
109+
commandDone = undefined;
110+
});
111+
});

0 commit comments

Comments
 (0)