11import * as chai from 'chai' ;
22import * as sinon from 'sinon' ;
33import * 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' ;
55import { Command , Diagnostic , Hover , Location , SignatureHelp , SymbolInformation , SymbolKind } from 'vscode-languageserver-types' ;
66import { LanguageClient , RemoteLanguageClient } from '../lang-handler' ;
77import { DependencyReference , PackageInformation , ReferenceInformation , TextDocumentContentParams , WorkspaceFilesParams } from '../request-type' ;
8- import { SymbolLocationInformation } from '../request-type' ;
8+ import { ClientCapabilities , SymbolLocationInformation } from '../request-type' ;
99import { TypeScriptService , TypeScriptServiceFactory } from '../typescript-service' ;
1010import { observableFromIterable , toUnixPath , uri2path } from '../util' ;
1111import chaiAsPromised = require( 'chai-as-promised' ) ;
@@ -16,6 +16,11 @@ import { IBeforeAndAfterContext, ISuiteCallbackContext, ITestCallbackContext } f
1616chai . use ( chaiAsPromised ) ;
1717const assert = chai . assert ;
1818
19+ const DEFAULT_CAPABILITIES : ClientCapabilities = {
20+ xcontentProvider : true ,
21+ xfilesProvider : true
22+ } ;
23+
1924export interface TestContext {
2025
2126 /** TypeScript service under test */
@@ -31,7 +36,7 @@ export interface TestContext {
3136 * @param createService A factory that creates the TypeScript service. Allows to test subclasses of TypeScriptService
3237 * @param files A Map from URI to file content of files that should be available in the workspace
3338 */
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 > {
3540
3641 // Stub client
3742 this . client = sinon . createStubInstance ( RemoteLanguageClient ) ;
@@ -56,10 +61,7 @@ export const initializeTypeScriptService = (createService: TypeScriptServiceFact
5661 await this . service . initialize ( {
5762 processId : process . pid ,
5863 rootUri,
59- capabilities : {
60- xcontentProvider : true ,
61- xfilesProvider : true
62- }
64+ capabilities : clientCapabilities || DEFAULT_CAPABILITIES
6365 } ) . toPromise ( ) ;
6466} ;
6567
@@ -2123,6 +2125,91 @@ export function describeTypeScriptService(createService: TypeScriptServiceFactor
21232125
21242126 } ) ;
21252127
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+
21262213 describe ( 'textDocumentCompletion()' , function ( this : TestContext & ISuiteCallbackContext ) {
21272214 beforeEach ( initializeTypeScriptService ( createService , rootUri , new Map ( [
21282215 [ rootUri + 'a.ts' , [
@@ -2175,32 +2262,41 @@ export function describeTypeScriptService(createService: TypeScriptServiceFactor
21752262 label : 'bar' ,
21762263 kind : CompletionItemKind . Method ,
21772264 documentation : 'bar doc' ,
2265+ insertText : 'bar' ,
2266+ insertTextFormat : InsertTextFormat . PlainText ,
21782267 sortText : '0' ,
21792268 detail : '(method) A.bar(): number'
21802269 } ,
21812270 {
21822271 label : 'baz' ,
21832272 kind : CompletionItemKind . Method ,
21842273 documentation : 'baz doc' ,
2274+ insertText : 'baz' ,
2275+ insertTextFormat : InsertTextFormat . PlainText ,
21852276 sortText : '0' ,
21862277 detail : '(method) A.baz(): string'
21872278 } ,
21882279 {
21892280 label : 'foo' ,
21902281 kind : CompletionItemKind . Method ,
21912282 documentation : 'foo doc' ,
2283+ insertText : 'foo' ,
2284+ insertTextFormat : InsertTextFormat . PlainText ,
21922285 sortText : '0' ,
21932286 detail : '(method) A.foo(): void'
21942287 } ,
21952288 {
21962289 label : 'qux' ,
21972290 kind : CompletionItemKind . Property ,
21982291 documentation : 'qux doc' ,
2292+ insertText : 'qux' ,
2293+ insertTextFormat : InsertTextFormat . PlainText ,
21992294 sortText : '0' ,
22002295 detail : '(property) A.qux: number'
22012296 }
22022297 ] ) ;
22032298 } ) ;
2299+
22042300 it ( 'produces completions for imported symbols' , async function ( this : TestContext & ITestCallbackContext ) {
22052301 const result : CompletionList = await this . service . textDocumentCompletion ( {
22062302 textDocument : {
@@ -2217,6 +2313,8 @@ export function describeTypeScriptService(createService: TypeScriptServiceFactor
22172313 label : 'd' ,
22182314 kind : CompletionItemKind . Function ,
22192315 documentation : 'd doc' ,
2316+ insertText : 'd' ,
2317+ insertTextFormat : InsertTextFormat . PlainText ,
22202318 detail : 'function d(): void' ,
22212319 sortText : '0'
22222320 } ]
@@ -2238,6 +2336,8 @@ export function describeTypeScriptService(createService: TypeScriptServiceFactor
22382336 label : 'bar' ,
22392337 kind : CompletionItemKind . Interface ,
22402338 documentation : 'bar doc' ,
2339+ insertText : 'bar' ,
2340+ insertTextFormat : InsertTextFormat . PlainText ,
22412341 sortText : '0' ,
22422342 detail : 'interface foo.bar'
22432343 } ]
0 commit comments