Skip to content

Commit fa55876

Browse files
authored
Joh/spatial-pig (microsoft#203535)
* more `ensureNoDisposablesAreLeakedInTestSuite` * adopt `ensureNoDisposablesAreLeakedInTestSuite` for api command tests
1 parent 6eb3213 commit fa55876

File tree

4 files changed

+104
-82
lines changed

4 files changed

+104
-82
lines changed

.eslintrc.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,6 @@
153153
"src/vs/base/test/browser/ui/scrollbar/scrollbarState.test.ts",
154154
"src/vs/editor/contrib/codeAction/test/browser/codeActionKeybindingResolver.test.ts",
155155
"src/vs/editor/contrib/codeAction/test/browser/codeActionModel.test.ts",
156-
"src/vs/editor/contrib/gotoSymbol/test/browser/referencesModel.test.ts",
157156
"src/vs/editor/test/common/services/languageService.test.ts",
158157
"src/vs/editor/test/node/classification/typescript.test.ts",
159158
"src/vs/editor/test/node/diffing/defaultLinesDiffComputer.test.ts",
@@ -172,9 +171,7 @@
172171
"src/vs/platform/telemetry/test/browser/1dsAppender.test.ts",
173172
"src/vs/platform/workspace/test/common/workspace.test.ts",
174173
"src/vs/platform/workspaces/test/electron-main/workspaces.test.ts",
175-
"src/vs/workbench/api/test/browser/extHostWorkspace.test.ts",
176174
"src/vs/workbench/api/test/browser/mainThreadConfiguration.test.ts",
177-
"src/vs/workbench/api/test/browser/mainThreadDocuments.test.ts",
178175
"src/vs/workbench/api/test/common/extHostExtensionActivator.test.ts",
179176
"src/vs/workbench/api/test/node/extHostTunnelService.test.ts",
180177
"src/vs/workbench/contrib/bulkEdit/test/browser/bulkCellEdits.test.ts",

src/vs/editor/contrib/gotoSymbol/test/browser/referencesModel.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@
55

66
import * as assert from 'assert';
77
import { URI } from 'vs/base/common/uri';
8+
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
89
import { Position } from 'vs/editor/common/core/position';
910
import { Range } from 'vs/editor/common/core/range';
1011
import { ReferencesModel } from 'vs/editor/contrib/gotoSymbol/browser/referencesModel';
1112

1213
suite('references', function () {
1314

15+
ensureNoDisposablesAreLeakedInTestSuite();
16+
1417
test('nearestReference', () => {
1518
const model = new ReferencesModel([{
1619
uri: URI.file('/out/obj/can'),

src/vs/workbench/api/test/browser/extHostApiCommands.test.ts

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

6+
import 'vs/editor/contrib/codeAction/browser/codeAction';
7+
import 'vs/editor/contrib/codelens/browser/codelens';
8+
import 'vs/editor/contrib/colorPicker/browser/color';
9+
import 'vs/editor/contrib/format/browser/format';
10+
import 'vs/editor/contrib/gotoSymbol/browser/goToCommands';
11+
import 'vs/editor/contrib/documentSymbols/browser/documentSymbols';
12+
import 'vs/editor/contrib/hover/browser/getHover';
13+
import 'vs/editor/contrib/links/browser/getLinks';
14+
import 'vs/editor/contrib/parameterHints/browser/provideSignatureHelp';
15+
import 'vs/editor/contrib/smartSelect/browser/smartSelect';
16+
import 'vs/editor/contrib/suggest/browser/suggest';
17+
import 'vs/editor/contrib/rename/browser/rename';
18+
import 'vs/editor/contrib/inlayHints/browser/inlayHintsController';
19+
620
import * as assert from 'assert';
721
import { setUnexpectedErrorHandler, errorHandler } from 'vs/base/common/errors';
822
import { URI } from 'vs/base/common/uri';
@@ -39,20 +53,6 @@ import { IExtHostFileSystemInfo } from 'vs/workbench/api/common/extHostFileSyste
3953
import { URITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService';
4054
import { IOutlineModelService, OutlineModelService } from 'vs/editor/contrib/documentSymbols/browser/outlineModel';
4155
import { ILanguageFeatureDebounceService, LanguageFeatureDebounceService } from 'vs/editor/common/services/languageFeatureDebounce';
42-
43-
import 'vs/editor/contrib/codeAction/browser/codeAction';
44-
import 'vs/editor/contrib/codelens/browser/codelens';
45-
import 'vs/editor/contrib/colorPicker/browser/color';
46-
import 'vs/editor/contrib/format/browser/format';
47-
import 'vs/editor/contrib/gotoSymbol/browser/goToCommands';
48-
import 'vs/editor/contrib/documentSymbols/browser/documentSymbols';
49-
import 'vs/editor/contrib/hover/browser/getHover';
50-
import 'vs/editor/contrib/links/browser/getLinks';
51-
import 'vs/editor/contrib/parameterHints/browser/provideSignatureHelp';
52-
import 'vs/editor/contrib/smartSelect/browser/smartSelect';
53-
import 'vs/editor/contrib/suggest/browser/suggest';
54-
import 'vs/editor/contrib/rename/browser/rename';
55-
import 'vs/editor/contrib/inlayHints/browser/inlayHintsController';
5656
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
5757
import { LanguageFeaturesService } from 'vs/editor/common/services/languageFeaturesService';
5858
import { assertType } from 'vs/base/common/types';
@@ -62,6 +62,9 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
6262
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
6363
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
6464
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
65+
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
66+
import { runWithFakedTimers } from 'vs/base/test/common/timeTravelScheduler';
67+
import { timeout } from 'vs/base/common/async';
6568

6669
function assertRejects(fn: () => Promise<any>, message: string = 'Expected rejection') {
6770
return fn().then(() => assert.ok(false, message), _err => assert.ok(true));
@@ -190,6 +193,9 @@ suite('ExtHostLanguageFeatureCommands', function () {
190193

191194
mainThread = rpcProtocol.set(MainContext.MainThreadLanguageFeatures, insta.createInstance(MainThreadLanguageFeatures, rpcProtocol));
192195

196+
// forcefully create the outline service so that `ensureNoDisposablesAreLeakedInTestSuite` doesn't bark
197+
insta.get(IOutlineModelService);
198+
193199
return rpcProtocol.sync();
194200
});
195201

@@ -207,10 +213,21 @@ suite('ExtHostLanguageFeatureCommands', function () {
207213
return rpcProtocol.sync();
208214
});
209215

210-
// ensureNoDisposablesAreLeakedInTestSuite();
216+
ensureNoDisposablesAreLeakedInTestSuite();
211217

212218
// --- workspace symbols
213219

220+
function testApiCmd(name: string, fn: () => Promise<any>) {
221+
test(name, async function () {
222+
await runWithFakedTimers({}, async () => {
223+
await fn();
224+
await timeout(10000); // API commands for things that allow commands dispose their result delay. This is to be nice
225+
// because otherwise properties like command are disposed too early
226+
});
227+
});
228+
229+
}
230+
214231
test('WorkspaceSymbols, invalid arguments', function () {
215232
const promises = [
216233
assertRejects(() => commands.executeCommand('vscode.executeWorkspaceSymbolProvider')),
@@ -767,7 +784,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
767784

768785
// --- suggest
769786

770-
test('triggerCharacter is null when completion provider is called programmatically #159914', async function () {
787+
testApiCmd('triggerCharacter is null when completion provider is called programmatically #159914', async function () {
771788

772789
let actualContext: vscode.CompletionContext | undefined;
773790

@@ -784,9 +801,11 @@ suite('ExtHostLanguageFeatureCommands', function () {
784801

785802
assert.ok(actualContext);
786803
assert.deepStrictEqual(actualContext, { triggerKind: types.CompletionTriggerKind.Invoke, triggerCharacter: undefined });
804+
787805
});
788806

789-
test('Suggest, back and forth', function () {
807+
testApiCmd('Suggest, back and forth', async function () {
808+
790809
disposables.push(extHost.registerCompletionItemProvider(nullExtensionDescription, defaultSelector, <vscode.CompletionItemProvider>{
791810
provideCompletionItems(): any {
792811
const a = new types.CompletionItem('item1');
@@ -804,49 +823,45 @@ suite('ExtHostLanguageFeatureCommands', function () {
804823
}
805824
}, []));
806825

807-
return rpcProtocol.sync().then(() => {
808-
return commands.executeCommand<vscode.CompletionList>('vscode.executeCompletionItemProvider', model.uri, new types.Position(0, 4)).then(list => {
826+
await rpcProtocol.sync();
827+
828+
const list = await commands.executeCommand<vscode.CompletionList>('vscode.executeCompletionItemProvider', model.uri, new types.Position(0, 4));
829+
assert.ok(list instanceof types.CompletionList);
830+
const values = list.items;
831+
assert.ok(Array.isArray(values));
832+
assert.strictEqual(values.length, 4);
833+
const [first, second, third, fourth] = values;
834+
assert.strictEqual(first.label, 'item1');
835+
assert.strictEqual(first.textEdit, undefined); // no text edit, default ranges
836+
assert.ok(!types.Range.isRange(first.range));
837+
assert.strictEqual((<types.MarkdownString>first.documentation).value, 'hello_md_string');
838+
assert.strictEqual(second.label, 'item2');
839+
assert.strictEqual(second.textEdit!.newText, 'foo');
840+
assert.strictEqual(second.textEdit!.range.start.line, 0);
841+
assert.strictEqual(second.textEdit!.range.start.character, 4);
842+
assert.strictEqual(second.textEdit!.range.end.line, 0);
843+
assert.strictEqual(second.textEdit!.range.end.character, 8);
844+
assert.strictEqual(third.label, 'item3');
845+
assert.strictEqual(third.textEdit!.newText, 'foobar');
846+
assert.strictEqual(third.textEdit!.range.start.line, 0);
847+
assert.strictEqual(third.textEdit!.range.start.character, 1);
848+
assert.strictEqual(third.textEdit!.range.end.line, 0);
849+
assert.strictEqual(third.textEdit!.range.end.character, 6);
850+
assert.strictEqual(fourth.label, 'item4');
851+
assert.strictEqual(fourth.textEdit, undefined);
852+
const range: any = fourth.range!;
853+
assert.ok(types.Range.isRange(range));
854+
assert.strictEqual(range.start.line, 0);
855+
assert.strictEqual(range.start.character, 1);
856+
assert.strictEqual(range.end.line, 0);
857+
assert.strictEqual(range.end.character, 4);
858+
assert.ok(fourth.insertText instanceof types.SnippetString);
859+
assert.strictEqual((<types.SnippetString>fourth.insertText).value, 'foo$0bar');
809860

810-
assert.ok(list instanceof types.CompletionList);
811-
const values = list.items;
812-
assert.ok(Array.isArray(values));
813-
assert.strictEqual(values.length, 4);
814-
const [first, second, third, fourth] = values;
815-
assert.strictEqual(first.label, 'item1');
816-
assert.strictEqual(first.textEdit, undefined);// no text edit, default ranges
817-
assert.ok(!types.Range.isRange(first.range));
818-
assert.strictEqual((<types.MarkdownString>first.documentation).value, 'hello_md_string');
819-
820-
assert.strictEqual(second.label, 'item2');
821-
assert.strictEqual(second.textEdit!.newText, 'foo');
822-
assert.strictEqual(second.textEdit!.range.start.line, 0);
823-
assert.strictEqual(second.textEdit!.range.start.character, 4);
824-
assert.strictEqual(second.textEdit!.range.end.line, 0);
825-
assert.strictEqual(second.textEdit!.range.end.character, 8);
826-
827-
assert.strictEqual(third.label, 'item3');
828-
assert.strictEqual(third.textEdit!.newText, 'foobar');
829-
assert.strictEqual(third.textEdit!.range.start.line, 0);
830-
assert.strictEqual(third.textEdit!.range.start.character, 1);
831-
assert.strictEqual(third.textEdit!.range.end.line, 0);
832-
assert.strictEqual(third.textEdit!.range.end.character, 6);
833-
834-
assert.strictEqual(fourth.label, 'item4');
835-
assert.strictEqual(fourth.textEdit, undefined);
836-
837-
const range: any = fourth.range!;
838-
assert.ok(types.Range.isRange(range));
839-
assert.strictEqual(range.start.line, 0);
840-
assert.strictEqual(range.start.character, 1);
841-
assert.strictEqual(range.end.line, 0);
842-
assert.strictEqual(range.end.character, 4);
843-
assert.ok(fourth.insertText instanceof types.SnippetString);
844-
assert.strictEqual((<types.SnippetString>fourth.insertText).value, 'foo$0bar');
845-
});
846-
});
847861
});
848862

849-
test('Suggest, return CompletionList !array', function () {
863+
testApiCmd('Suggest, return CompletionList !array', async function () {
864+
850865
disposables.push(extHost.registerCompletionItemProvider(nullExtensionDescription, defaultSelector, <vscode.CompletionItemProvider>{
851866
provideCompletionItems(): any {
852867
const a = new types.CompletionItem('item1');
@@ -855,15 +870,16 @@ suite('ExtHostLanguageFeatureCommands', function () {
855870
}
856871
}, []));
857872

858-
return rpcProtocol.sync().then(() => {
859-
return commands.executeCommand<vscode.CompletionList>('vscode.executeCompletionItemProvider', model.uri, new types.Position(0, 4)).then(list => {
860-
assert.ok(list instanceof types.CompletionList);
861-
assert.strictEqual(list.isIncomplete, true);
862-
});
863-
});
873+
await rpcProtocol.sync();
874+
875+
const list = await commands.executeCommand<vscode.CompletionList>('vscode.executeCompletionItemProvider', model.uri, new types.Position(0, 4));
876+
877+
assert.ok(list instanceof types.CompletionList);
878+
assert.strictEqual(list.isIncomplete, true);
864879
});
865880

866-
test('Suggest, resolve completion items', async function () {
881+
testApiCmd('Suggest, resolve completion items', async function () {
882+
867883

868884
let resolveCount = 0;
869885

@@ -896,7 +912,10 @@ suite('ExtHostLanguageFeatureCommands', function () {
896912

897913
});
898914

899-
test('"vscode.executeCompletionItemProvider" doesnot return a preselect field #53749', async function () {
915+
testApiCmd('"vscode.executeCompletionItemProvider" doesnot return a preselect field #53749', async function () {
916+
917+
918+
900919
disposables.push(extHost.registerCompletionItemProvider(nullExtensionDescription, defaultSelector, <vscode.CompletionItemProvider>{
901920
provideCompletionItems(): any {
902921
const a = new types.CompletionItem('item1');
@@ -928,7 +947,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
928947
assert.strictEqual(d.preselect, undefined);
929948
});
930949

931-
test('executeCompletionItemProvider doesn\'t capture commitCharacters #58228', async function () {
950+
testApiCmd('executeCompletionItemProvider doesn\'t capture commitCharacters #58228', async function () {
932951
disposables.push(extHost.registerCompletionItemProvider(nullExtensionDescription, defaultSelector, <vscode.CompletionItemProvider>{
933952
provideCompletionItems(): any {
934953
const a = new types.CompletionItem('item1');
@@ -955,7 +974,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
955974
assert.strictEqual(b.commitCharacters, undefined);
956975
});
957976

958-
test('vscode.executeCompletionItemProvider returns the wrong CompletionItemKinds in insiders #95715', async function () {
977+
testApiCmd('vscode.executeCompletionItemProvider returns the wrong CompletionItemKinds in insiders #95715', async function () {
959978
disposables.push(extHost.registerCompletionItemProvider(nullExtensionDescription, defaultSelector, <vscode.CompletionItemProvider>{
960979
provideCompletionItems(): any {
961980
return [
@@ -1013,7 +1032,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
10131032

10141033
// --- quickfix
10151034

1016-
test('QuickFix, back and forth', function () {
1035+
testApiCmd('QuickFix, back and forth', function () {
10171036
disposables.push(extHost.registerCodeActionProvider(nullExtensionDescription, defaultSelector, {
10181037
provideCodeActions(): vscode.Command[] {
10191038
return [{ command: 'testing', title: 'Title', arguments: [1, 2, true] }];
@@ -1031,7 +1050,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
10311050
});
10321051
});
10331052

1034-
test('vscode.executeCodeActionProvider results seem to be missing their `command` property #45124', function () {
1053+
testApiCmd('vscode.executeCodeActionProvider results seem to be missing their `command` property #45124', function () {
10351054
disposables.push(extHost.registerCodeActionProvider(nullExtensionDescription, defaultSelector, {
10361055
provideCodeActions(document, range): vscode.CodeAction[] {
10371056
return [{
@@ -1060,7 +1079,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
10601079
});
10611080
});
10621081

1063-
test('vscode.executeCodeActionProvider passes Range to provider although Selection is passed in #77997', function () {
1082+
testApiCmd('vscode.executeCodeActionProvider passes Range to provider although Selection is passed in #77997', function () {
10641083
disposables.push(extHost.registerCodeActionProvider(nullExtensionDescription, defaultSelector, {
10651084
provideCodeActions(document, rangeOrSelection): vscode.CodeAction[] {
10661085
return [{
@@ -1088,7 +1107,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
10881107
});
10891108
});
10901109

1091-
test('vscode.executeCodeActionProvider results seem to be missing their `isPreferred` property #78098', function () {
1110+
testApiCmd('vscode.executeCodeActionProvider results seem to be missing their `isPreferred` property #78098', function () {
10921111
disposables.push(extHost.registerCodeActionProvider(nullExtensionDescription, defaultSelector, {
10931112
provideCodeActions(document, rangeOrSelection): vscode.CodeAction[] {
10941113
return [{
@@ -1115,7 +1134,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
11151134
});
11161135
});
11171136

1118-
test('resolving code action', async function () {
1137+
testApiCmd('resolving code action', async function () {
11191138

11201139
let didCallResolve = 0;
11211140
class MyAction extends types.CodeAction { }
@@ -1149,7 +1168,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
11491168

11501169
// --- code lens
11511170

1152-
test('CodeLens, back and forth', function () {
1171+
testApiCmd('CodeLens, back and forth', function () {
11531172

11541173
const complexArg = {
11551174
foo() { },
@@ -1177,7 +1196,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
11771196
});
11781197
});
11791198

1180-
test('CodeLens, resolve', async function () {
1199+
testApiCmd('CodeLens, resolve', async function () {
11811200

11821201
let resolveCount = 0;
11831202

@@ -1211,7 +1230,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
12111230
assert.strictEqual(resolveCount, 0);
12121231
});
12131232

1214-
test('Links, back and forth', function () {
1233+
testApiCmd('Links, back and forth', function () {
12151234

12161235
disposables.push(extHost.registerDocumentLinkProvider(nullExtensionDescription, defaultSelector, <vscode.DocumentLinkProvider>{
12171236
provideDocumentLinks(): any {
@@ -1233,7 +1252,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
12331252
});
12341253
});
12351254

1236-
test('What\'s the condition for DocumentLink target to be undefined? #106308', async function () {
1255+
testApiCmd('What\'s the condition for DocumentLink target to be undefined? #106308', async function () {
12371256
disposables.push(extHost.registerDocumentLinkProvider(nullExtensionDescription, defaultSelector, <vscode.DocumentLinkProvider>{
12381257
provideDocumentLinks(): any {
12391258
return [new types.DocumentLink(new types.Range(0, 0, 0, 20), undefined)];
@@ -1325,7 +1344,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
13251344

13261345
// --- inline hints
13271346

1328-
test('Inlay Hints, back and forth', async function () {
1347+
testApiCmd('Inlay Hints, back and forth', async function () {
13291348
disposables.push(extHost.registerInlayHintsProvider(nullExtensionDescription, defaultSelector, <vscode.InlayHintsProvider>{
13301349
provideInlayHints() {
13311350
return [new types.InlayHint(new types.Position(0, 1), 'Foo')];
@@ -1343,7 +1362,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
13431362
assert.strictEqual(first.position.character, 1);
13441363
});
13451364

1346-
test('Inline Hints, merge', async function () {
1365+
testApiCmd('Inline Hints, merge', async function () {
13471366
disposables.push(extHost.registerInlayHintsProvider(nullExtensionDescription, defaultSelector, <vscode.InlayHintsProvider>{
13481367
provideInlayHints() {
13491368
const part = new types.InlayHintLabelPart('Bar');
@@ -1391,7 +1410,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
13911410
assert.strictEqual(label.command?.title, 'part');
13921411
});
13931412

1394-
test('Inline Hints, bad provider', async function () {
1413+
testApiCmd('Inline Hints, bad provider', async function () {
13951414
disposables.push(extHost.registerInlayHintsProvider(nullExtensionDescription, defaultSelector, <vscode.InlayHintsProvider>{
13961415
provideInlayHints() {
13971416
return [new types.InlayHint(new types.Position(0, 1), 'Foo')];

0 commit comments

Comments
 (0)