1
1
import * as chai from 'chai' ;
2
2
import * as sinon from 'sinon' ;
3
3
import * as ts from 'typescript' ;
4
- import { CompletionItemKind , CompletionList , DiagnosticSeverity , TextDocumentIdentifier , TextDocumentItem , WorkspaceEdit } from 'vscode-languageserver' ;
4
+ import { CompletionItemKind , CompletionList , DiagnosticSeverity , InsertTextFormat , TextDocumentIdentifier , TextDocumentItem , WorkspaceEdit } from 'vscode-languageserver' ;
5
5
import { Command , Diagnostic , Hover , Location , SignatureHelp , SymbolInformation , SymbolKind } from 'vscode-languageserver-types' ;
6
6
import { LanguageClient , RemoteLanguageClient } from '../lang-handler' ;
7
7
import { DependencyReference , PackageInformation , ReferenceInformation , TextDocumentContentParams , WorkspaceFilesParams } from '../request-type' ;
8
- import { SymbolLocationInformation } from '../request-type' ;
8
+ import { ClientCapabilities , SymbolLocationInformation } from '../request-type' ;
9
9
import { TypeScriptService , TypeScriptServiceFactory } from '../typescript-service' ;
10
10
import { observableFromIterable , toUnixPath , uri2path } from '../util' ;
11
11
import chaiAsPromised = require( 'chai-as-promised' ) ;
@@ -16,6 +16,11 @@ import { IBeforeAndAfterContext, ISuiteCallbackContext, ITestCallbackContext } f
16
16
chai . use ( chaiAsPromised ) ;
17
17
const assert = chai . assert ;
18
18
19
+ const DEFAULT_CAPABILITIES : ClientCapabilities = {
20
+ xcontentProvider : true ,
21
+ xfilesProvider : true
22
+ } ;
23
+
19
24
export interface TestContext {
20
25
21
26
/** TypeScript service under test */
@@ -31,7 +36,7 @@ export interface TestContext {
31
36
* @param createService A factory that creates the TypeScript service. Allows to test subclasses of TypeScriptService
32
37
* @param files A Map from URI to file content of files that should be available in the workspace
33
38
*/
34
- export const initializeTypeScriptService = ( createService : TypeScriptServiceFactory , rootUri : string , files : Map < string , string > ) => async function ( this : TestContext & IBeforeAndAfterContext ) : Promise < void > {
39
+ export const initializeTypeScriptService = ( createService : TypeScriptServiceFactory , rootUri : string , files : Map < string , string > , clientCapabilities : ClientCapabilities = DEFAULT_CAPABILITIES ) => async function ( this : TestContext & IBeforeAndAfterContext ) : Promise < void > {
35
40
36
41
// Stub client
37
42
this . client = sinon . createStubInstance ( RemoteLanguageClient ) ;
@@ -56,10 +61,7 @@ export const initializeTypeScriptService = (createService: TypeScriptServiceFact
56
61
await this . service . initialize ( {
57
62
processId : process . pid ,
58
63
rootUri,
59
- capabilities : {
60
- xcontentProvider : true ,
61
- xfilesProvider : true
62
- }
64
+ capabilities : clientCapabilities || DEFAULT_CAPABILITIES
63
65
} ) . toPromise ( ) ;
64
66
} ;
65
67
@@ -2123,6 +2125,91 @@ export function describeTypeScriptService(createService: TypeScriptServiceFactor
2123
2125
2124
2126
} ) ;
2125
2127
2128
+ describe ( 'textDocumentCompletion() with snippets' , function ( this : TestContext & ISuiteCallbackContext ) {
2129
+ beforeEach ( initializeTypeScriptService ( createService , rootUri , new Map ( [
2130
+ [ rootUri + 'a.ts' , [
2131
+ 'class A {' ,
2132
+ ' /** foo doc*/' ,
2133
+ ' foo() {}' ,
2134
+ ' /** bar doc*/' ,
2135
+ ' bar(num: number): number { return 1; }' ,
2136
+ ' /** baz doc*/' ,
2137
+ ' baz(num: number): string { return ""; }' ,
2138
+ ' /** qux doc*/' ,
2139
+ ' qux: number;' ,
2140
+ '}' ,
2141
+ 'const a = new A();' ,
2142
+ 'a.'
2143
+ ] . join ( '\n' ) ]
2144
+ ] ) , {
2145
+ textDocument : {
2146
+ completion : {
2147
+ completionItem : {
2148
+ snippetSupport : true
2149
+ }
2150
+ }
2151
+ } ,
2152
+ ...DEFAULT_CAPABILITIES
2153
+ } ) ) ;
2154
+
2155
+ afterEach ( shutdownService ) ;
2156
+
2157
+ it ( 'should produce completions with snippets if supported' , async function ( this : TestContext & ITestCallbackContext ) {
2158
+ const result : CompletionList = await this . service . textDocumentCompletion ( {
2159
+ textDocument : {
2160
+ uri : rootUri + 'a.ts'
2161
+ } ,
2162
+ position : {
2163
+ line : 11 ,
2164
+ character : 2
2165
+ }
2166
+ } ) . reduce < Operation , CompletionList > ( applyReducer , null as any ) . toPromise ( ) ;
2167
+ // * A snippet can define tab stops and placeholders with `$1`, `$2`
2168
+ // * and `${3:foo}`. `$0` defines the final tab stop, it defaults to
2169
+ // * the end of the snippet. Placeholders with equal identifiers are linked,
2170
+ // * that is typing in one will update others too.
2171
+ assert . equal ( result . isIncomplete , false ) ;
2172
+ assert . sameDeepMembers ( result . items , [
2173
+ {
2174
+ label : 'bar' ,
2175
+ kind : CompletionItemKind . Method ,
2176
+ documentation : 'bar doc' ,
2177
+ sortText : '0' ,
2178
+ insertTextFormat : InsertTextFormat . Snippet ,
2179
+ insertText : 'bar(${1:num})' ,
2180
+ detail : '(method) A.bar(num: number): number'
2181
+ } ,
2182
+ {
2183
+ label : 'baz' ,
2184
+ kind : CompletionItemKind . Method ,
2185
+ documentation : 'baz doc' ,
2186
+ sortText : '0' ,
2187
+ insertTextFormat : InsertTextFormat . Snippet ,
2188
+ insertText : 'baz(${1:num})' ,
2189
+ detail : '(method) A.baz(num: number): string'
2190
+ } ,
2191
+ {
2192
+ label : 'foo' ,
2193
+ kind : CompletionItemKind . Method ,
2194
+ documentation : 'foo doc' ,
2195
+ sortText : '0' ,
2196
+ insertTextFormat : InsertTextFormat . Snippet ,
2197
+ insertText : 'foo()' ,
2198
+ detail : '(method) A.foo(): void'
2199
+ } ,
2200
+ {
2201
+ label : 'qux' ,
2202
+ kind : CompletionItemKind . Property ,
2203
+ documentation : 'qux doc' ,
2204
+ sortText : '0' ,
2205
+ insertTextFormat : InsertTextFormat . Snippet ,
2206
+ insertText : 'qux' ,
2207
+ detail : '(property) A.qux: number'
2208
+ }
2209
+ ] ) ;
2210
+ } ) ;
2211
+ } ) ;
2212
+
2126
2213
describe ( 'textDocumentCompletion()' , function ( this : TestContext & ISuiteCallbackContext ) {
2127
2214
beforeEach ( initializeTypeScriptService ( createService , rootUri , new Map ( [
2128
2215
[ rootUri + 'a.ts' , [
@@ -2175,32 +2262,41 @@ export function describeTypeScriptService(createService: TypeScriptServiceFactor
2175
2262
label : 'bar' ,
2176
2263
kind : CompletionItemKind . Method ,
2177
2264
documentation : 'bar doc' ,
2265
+ insertText : 'bar' ,
2266
+ insertTextFormat : InsertTextFormat . PlainText ,
2178
2267
sortText : '0' ,
2179
2268
detail : '(method) A.bar(): number'
2180
2269
} ,
2181
2270
{
2182
2271
label : 'baz' ,
2183
2272
kind : CompletionItemKind . Method ,
2184
2273
documentation : 'baz doc' ,
2274
+ insertText : 'baz' ,
2275
+ insertTextFormat : InsertTextFormat . PlainText ,
2185
2276
sortText : '0' ,
2186
2277
detail : '(method) A.baz(): string'
2187
2278
} ,
2188
2279
{
2189
2280
label : 'foo' ,
2190
2281
kind : CompletionItemKind . Method ,
2191
2282
documentation : 'foo doc' ,
2283
+ insertText : 'foo' ,
2284
+ insertTextFormat : InsertTextFormat . PlainText ,
2192
2285
sortText : '0' ,
2193
2286
detail : '(method) A.foo(): void'
2194
2287
} ,
2195
2288
{
2196
2289
label : 'qux' ,
2197
2290
kind : CompletionItemKind . Property ,
2198
2291
documentation : 'qux doc' ,
2292
+ insertText : 'qux' ,
2293
+ insertTextFormat : InsertTextFormat . PlainText ,
2199
2294
sortText : '0' ,
2200
2295
detail : '(property) A.qux: number'
2201
2296
}
2202
2297
] ) ;
2203
2298
} ) ;
2299
+
2204
2300
it ( 'produces completions for imported symbols' , async function ( this : TestContext & ITestCallbackContext ) {
2205
2301
const result : CompletionList = await this . service . textDocumentCompletion ( {
2206
2302
textDocument : {
@@ -2217,6 +2313,8 @@ export function describeTypeScriptService(createService: TypeScriptServiceFactor
2217
2313
label : 'd' ,
2218
2314
kind : CompletionItemKind . Function ,
2219
2315
documentation : 'd doc' ,
2316
+ insertText : 'd' ,
2317
+ insertTextFormat : InsertTextFormat . PlainText ,
2220
2318
detail : 'function d(): void' ,
2221
2319
sortText : '0'
2222
2320
} ]
@@ -2238,6 +2336,8 @@ export function describeTypeScriptService(createService: TypeScriptServiceFactor
2238
2336
label : 'bar' ,
2239
2337
kind : CompletionItemKind . Interface ,
2240
2338
documentation : 'bar doc' ,
2339
+ insertText : 'bar' ,
2340
+ insertTextFormat : InsertTextFormat . PlainText ,
2241
2341
sortText : '0' ,
2242
2342
detail : 'interface foo.bar'
2243
2343
} ]
0 commit comments