3
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
4
*--------------------------------------------------------------------------------------------*/
5
5
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
+
6
20
import * as assert from 'assert' ;
7
21
import { setUnexpectedErrorHandler , errorHandler } from 'vs/base/common/errors' ;
8
22
import { URI } from 'vs/base/common/uri' ;
@@ -39,20 +53,6 @@ import { IExtHostFileSystemInfo } from 'vs/workbench/api/common/extHostFileSyste
39
53
import { URITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService' ;
40
54
import { IOutlineModelService , OutlineModelService } from 'vs/editor/contrib/documentSymbols/browser/outlineModel' ;
41
55
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' ;
56
56
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures' ;
57
57
import { LanguageFeaturesService } from 'vs/editor/common/services/languageFeaturesService' ;
58
58
import { assertType } from 'vs/base/common/types' ;
@@ -62,6 +62,9 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
62
62
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService' ;
63
63
import { IEnvironmentService } from 'vs/platform/environment/common/environment' ;
64
64
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' ;
65
68
66
69
function assertRejects ( fn : ( ) => Promise < any > , message : string = 'Expected rejection' ) {
67
70
return fn ( ) . then ( ( ) => assert . ok ( false , message ) , _err => assert . ok ( true ) ) ;
@@ -190,6 +193,9 @@ suite('ExtHostLanguageFeatureCommands', function () {
190
193
191
194
mainThread = rpcProtocol . set ( MainContext . MainThreadLanguageFeatures , insta . createInstance ( MainThreadLanguageFeatures , rpcProtocol ) ) ;
192
195
196
+ // forcefully create the outline service so that `ensureNoDisposablesAreLeakedInTestSuite` doesn't bark
197
+ insta . get ( IOutlineModelService ) ;
198
+
193
199
return rpcProtocol . sync ( ) ;
194
200
} ) ;
195
201
@@ -207,10 +213,21 @@ suite('ExtHostLanguageFeatureCommands', function () {
207
213
return rpcProtocol . sync ( ) ;
208
214
} ) ;
209
215
210
- // ensureNoDisposablesAreLeakedInTestSuite();
216
+ ensureNoDisposablesAreLeakedInTestSuite ( ) ;
211
217
212
218
// --- workspace symbols
213
219
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
+
214
231
test ( 'WorkspaceSymbols, invalid arguments' , function ( ) {
215
232
const promises = [
216
233
assertRejects ( ( ) => commands . executeCommand ( 'vscode.executeWorkspaceSymbolProvider' ) ) ,
@@ -767,7 +784,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
767
784
768
785
// --- suggest
769
786
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 ( ) {
771
788
772
789
let actualContext : vscode . CompletionContext | undefined ;
773
790
@@ -784,9 +801,11 @@ suite('ExtHostLanguageFeatureCommands', function () {
784
801
785
802
assert . ok ( actualContext ) ;
786
803
assert . deepStrictEqual ( actualContext , { triggerKind : types . CompletionTriggerKind . Invoke , triggerCharacter : undefined } ) ;
804
+
787
805
} ) ;
788
806
789
- test ( 'Suggest, back and forth' , function ( ) {
807
+ testApiCmd ( 'Suggest, back and forth' , async function ( ) {
808
+
790
809
disposables . push ( extHost . registerCompletionItemProvider ( nullExtensionDescription , defaultSelector , < vscode . CompletionItemProvider > {
791
810
provideCompletionItems ( ) : any {
792
811
const a = new types . CompletionItem ( 'item1' ) ;
@@ -804,49 +823,45 @@ suite('ExtHostLanguageFeatureCommands', function () {
804
823
}
805
824
} , [ ] ) ) ;
806
825
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' ) ;
809
860
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
- } ) ;
847
861
} ) ;
848
862
849
- test ( 'Suggest, return CompletionList !array' , function ( ) {
863
+ testApiCmd ( 'Suggest, return CompletionList !array' , async function ( ) {
864
+
850
865
disposables . push ( extHost . registerCompletionItemProvider ( nullExtensionDescription , defaultSelector , < vscode . CompletionItemProvider > {
851
866
provideCompletionItems ( ) : any {
852
867
const a = new types . CompletionItem ( 'item1' ) ;
@@ -855,15 +870,16 @@ suite('ExtHostLanguageFeatureCommands', function () {
855
870
}
856
871
} , [ ] ) ) ;
857
872
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 ) ;
864
879
} ) ;
865
880
866
- test ( 'Suggest, resolve completion items' , async function ( ) {
881
+ testApiCmd ( 'Suggest, resolve completion items' , async function ( ) {
882
+
867
883
868
884
let resolveCount = 0 ;
869
885
@@ -896,7 +912,10 @@ suite('ExtHostLanguageFeatureCommands', function () {
896
912
897
913
} ) ;
898
914
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
+
900
919
disposables . push ( extHost . registerCompletionItemProvider ( nullExtensionDescription , defaultSelector , < vscode . CompletionItemProvider > {
901
920
provideCompletionItems ( ) : any {
902
921
const a = new types . CompletionItem ( 'item1' ) ;
@@ -928,7 +947,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
928
947
assert . strictEqual ( d . preselect , undefined ) ;
929
948
} ) ;
930
949
931
- test ( 'executeCompletionItemProvider doesn\'t capture commitCharacters #58228' , async function ( ) {
950
+ testApiCmd ( 'executeCompletionItemProvider doesn\'t capture commitCharacters #58228' , async function ( ) {
932
951
disposables . push ( extHost . registerCompletionItemProvider ( nullExtensionDescription , defaultSelector , < vscode . CompletionItemProvider > {
933
952
provideCompletionItems ( ) : any {
934
953
const a = new types . CompletionItem ( 'item1' ) ;
@@ -955,7 +974,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
955
974
assert . strictEqual ( b . commitCharacters , undefined ) ;
956
975
} ) ;
957
976
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 ( ) {
959
978
disposables . push ( extHost . registerCompletionItemProvider ( nullExtensionDescription , defaultSelector , < vscode . CompletionItemProvider > {
960
979
provideCompletionItems ( ) : any {
961
980
return [
@@ -1013,7 +1032,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
1013
1032
1014
1033
// --- quickfix
1015
1034
1016
- test ( 'QuickFix, back and forth' , function ( ) {
1035
+ testApiCmd ( 'QuickFix, back and forth' , function ( ) {
1017
1036
disposables . push ( extHost . registerCodeActionProvider ( nullExtensionDescription , defaultSelector , {
1018
1037
provideCodeActions ( ) : vscode . Command [ ] {
1019
1038
return [ { command : 'testing' , title : 'Title' , arguments : [ 1 , 2 , true ] } ] ;
@@ -1031,7 +1050,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
1031
1050
} ) ;
1032
1051
} ) ;
1033
1052
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 ( ) {
1035
1054
disposables . push ( extHost . registerCodeActionProvider ( nullExtensionDescription , defaultSelector , {
1036
1055
provideCodeActions ( document , range ) : vscode . CodeAction [ ] {
1037
1056
return [ {
@@ -1060,7 +1079,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
1060
1079
} ) ;
1061
1080
} ) ;
1062
1081
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 ( ) {
1064
1083
disposables . push ( extHost . registerCodeActionProvider ( nullExtensionDescription , defaultSelector , {
1065
1084
provideCodeActions ( document , rangeOrSelection ) : vscode . CodeAction [ ] {
1066
1085
return [ {
@@ -1088,7 +1107,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
1088
1107
} ) ;
1089
1108
} ) ;
1090
1109
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 ( ) {
1092
1111
disposables . push ( extHost . registerCodeActionProvider ( nullExtensionDescription , defaultSelector , {
1093
1112
provideCodeActions ( document , rangeOrSelection ) : vscode . CodeAction [ ] {
1094
1113
return [ {
@@ -1115,7 +1134,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
1115
1134
} ) ;
1116
1135
} ) ;
1117
1136
1118
- test ( 'resolving code action' , async function ( ) {
1137
+ testApiCmd ( 'resolving code action' , async function ( ) {
1119
1138
1120
1139
let didCallResolve = 0 ;
1121
1140
class MyAction extends types . CodeAction { }
@@ -1149,7 +1168,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
1149
1168
1150
1169
// --- code lens
1151
1170
1152
- test ( 'CodeLens, back and forth' , function ( ) {
1171
+ testApiCmd ( 'CodeLens, back and forth' , function ( ) {
1153
1172
1154
1173
const complexArg = {
1155
1174
foo ( ) { } ,
@@ -1177,7 +1196,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
1177
1196
} ) ;
1178
1197
} ) ;
1179
1198
1180
- test ( 'CodeLens, resolve' , async function ( ) {
1199
+ testApiCmd ( 'CodeLens, resolve' , async function ( ) {
1181
1200
1182
1201
let resolveCount = 0 ;
1183
1202
@@ -1211,7 +1230,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
1211
1230
assert . strictEqual ( resolveCount , 0 ) ;
1212
1231
} ) ;
1213
1232
1214
- test ( 'Links, back and forth' , function ( ) {
1233
+ testApiCmd ( 'Links, back and forth' , function ( ) {
1215
1234
1216
1235
disposables . push ( extHost . registerDocumentLinkProvider ( nullExtensionDescription , defaultSelector , < vscode . DocumentLinkProvider > {
1217
1236
provideDocumentLinks ( ) : any {
@@ -1233,7 +1252,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
1233
1252
} ) ;
1234
1253
} ) ;
1235
1254
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 ( ) {
1237
1256
disposables . push ( extHost . registerDocumentLinkProvider ( nullExtensionDescription , defaultSelector , < vscode . DocumentLinkProvider > {
1238
1257
provideDocumentLinks ( ) : any {
1239
1258
return [ new types . DocumentLink ( new types . Range ( 0 , 0 , 0 , 20 ) , undefined ) ] ;
@@ -1325,7 +1344,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
1325
1344
1326
1345
// --- inline hints
1327
1346
1328
- test ( 'Inlay Hints, back and forth' , async function ( ) {
1347
+ testApiCmd ( 'Inlay Hints, back and forth' , async function ( ) {
1329
1348
disposables . push ( extHost . registerInlayHintsProvider ( nullExtensionDescription , defaultSelector , < vscode . InlayHintsProvider > {
1330
1349
provideInlayHints ( ) {
1331
1350
return [ new types . InlayHint ( new types . Position ( 0 , 1 ) , 'Foo' ) ] ;
@@ -1343,7 +1362,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
1343
1362
assert . strictEqual ( first . position . character , 1 ) ;
1344
1363
} ) ;
1345
1364
1346
- test ( 'Inline Hints, merge' , async function ( ) {
1365
+ testApiCmd ( 'Inline Hints, merge' , async function ( ) {
1347
1366
disposables . push ( extHost . registerInlayHintsProvider ( nullExtensionDescription , defaultSelector , < vscode . InlayHintsProvider > {
1348
1367
provideInlayHints ( ) {
1349
1368
const part = new types . InlayHintLabelPart ( 'Bar' ) ;
@@ -1391,7 +1410,7 @@ suite('ExtHostLanguageFeatureCommands', function () {
1391
1410
assert . strictEqual ( label . command ?. title , 'part' ) ;
1392
1411
} ) ;
1393
1412
1394
- test ( 'Inline Hints, bad provider' , async function ( ) {
1413
+ testApiCmd ( 'Inline Hints, bad provider' , async function ( ) {
1395
1414
disposables . push ( extHost . registerInlayHintsProvider ( nullExtensionDescription , defaultSelector , < vscode . InlayHintsProvider > {
1396
1415
provideInlayHints ( ) {
1397
1416
return [ new types . InlayHint ( new types . Position ( 0 , 1 ) , 'Foo' ) ] ;
0 commit comments