1
1
import * as assert from 'assert'
2
2
import path from 'path'
3
- import { CallHierarchyIncomingCall , CallHierarchyItem , CallHierarchyOutgoingCall , CallHierarchyPrepareRequest , CancellationToken , CancellationTokenSource , CodeAction , CodeActionRequest , CodeLensRequest , Color , ColorInformation , ColorPresentation , CompletionItem , CompletionRequest , CompletionTriggerKind , ConfigurationRequest , DeclarationRequest , DefinitionRequest , DidChangeConfigurationNotification , DidChangeTextDocumentNotification , DidChangeWatchedFilesNotification , DidCloseTextDocumentNotification , DidCreateFilesNotification , DidDeleteFilesNotification , DidOpenTextDocumentNotification , DidRenameFilesNotification , DidSaveTextDocumentNotification , Disposable , DocumentColorRequest , DocumentDiagnosticReport , DocumentDiagnosticReportKind , DocumentDiagnosticRequest , DocumentFormattingRequest , DocumentHighlight , DocumentHighlightKind , DocumentHighlightRequest , DocumentLink , DocumentLinkRequest , DocumentOnTypeFormattingRequest , DocumentRangeFormattingRequest , DocumentSelector , DocumentSymbolRequest , FoldingRange , FoldingRangeRequest , FullDocumentDiagnosticReport , Hover , HoverRequest , ImplementationRequest , InlayHintKind , InlayHintLabelPart , InlayHintRequest , InlineValueEvaluatableExpression , InlineValueRequest , InlineValueText , InlineValueVariableLookup , LinkedEditingRangeRequest , Location , NotificationType0 , ParameterInformation , Position , ProgressToken , ProtocolRequestType , Range , ReferencesRequest , RenameRequest , SelectionRange , SelectionRangeRequest , SemanticTokensRegistrationType , SignatureHelpRequest , SignatureHelpTriggerKind , SignatureInformation , TextDocumentEdit , TextDocumentSyncKind , TextEdit , TypeDefinitionRequest , TypeHierarchyPrepareRequest , WillCreateFilesRequest , WillDeleteFilesRequest , WillRenameFilesRequest , WillSaveTextDocumentNotification , WillSaveTextDocumentWaitUntilRequest , WorkDoneProgressBegin , WorkDoneProgressCreateRequest , WorkDoneProgressEnd , WorkDoneProgressReport , WorkspaceEdit , WorkspaceSymbolRequest } from 'vscode-languageserver-protocol'
3
+ import { ApplyWorkspaceEditParams , CallHierarchyIncomingCall , CallHierarchyItem , CallHierarchyOutgoingCall , CallHierarchyPrepareRequest , CancellationToken , CancellationTokenSource , CodeAction , CodeActionRequest , CodeLensRequest , Color , ColorInformation , ColorPresentation , CompletionItem , CompletionRequest , CompletionTriggerKind , ConfigurationRequest , DeclarationRequest , DefinitionRequest , DidChangeConfigurationNotification , DidChangeTextDocumentNotification , DidChangeWatchedFilesNotification , DidCloseTextDocumentNotification , DidCreateFilesNotification , DidDeleteFilesNotification , DidOpenTextDocumentNotification , DidRenameFilesNotification , DidSaveTextDocumentNotification , Disposable , DocumentColorRequest , DocumentDiagnosticReport , DocumentDiagnosticReportKind , DocumentDiagnosticRequest , DocumentFormattingRequest , DocumentHighlight , DocumentHighlightKind , DocumentHighlightRequest , DocumentLink , DocumentLinkRequest , DocumentOnTypeFormattingRequest , DocumentRangeFormattingRequest , DocumentSelector , DocumentSymbolRequest , FoldingRange , FoldingRangeRequest , FullDocumentDiagnosticReport , Hover , HoverRequest , ImplementationRequest , InlayHintKind , InlayHintLabelPart , InlayHintRequest , InlineCompletionItem , InlineCompletionRequest , InlineValueEvaluatableExpression , InlineValueRequest , InlineValueText , InlineValueVariableLookup , LinkedEditingRangeRequest , Location , NotificationType0 , ParameterInformation , Position , ProgressToken , ProtocolRequestType , Range , ReferencesRequest , RenameRequest , SelectionRange , SelectionRangeRequest , SemanticTokensRegistrationType , SignatureHelpRequest , SignatureHelpTriggerKind , SignatureInformation , TextDocumentEdit , TextDocumentSyncKind , TextEdit , TypeDefinitionRequest , TypeHierarchyPrepareRequest , WillCreateFilesRequest , WillDeleteFilesRequest , WillRenameFilesRequest , WillSaveTextDocumentNotification , WillSaveTextDocumentWaitUntilRequest , WorkDoneProgressBegin , WorkDoneProgressCreateRequest , WorkDoneProgressEnd , WorkDoneProgressReport , WorkspaceEdit , WorkspaceSymbolRequest } from 'vscode-languageserver-protocol'
4
4
import { TextDocument } from 'vscode-languageserver-textdocument'
5
5
import { URI } from 'vscode-uri'
6
6
import commands from '../../commands'
@@ -154,6 +154,7 @@ describe('Client integration', () => {
154
154
documentSelector : [ { language : '*' } ]
155
155
} ,
156
156
selectionRangeProvider : true ,
157
+ inlineCompletionProvider : true ,
157
158
inlineValueProvider : { } ,
158
159
inlayHintProvider : {
159
160
resolveProvider : true
@@ -270,6 +271,7 @@ describe('Client integration', () => {
270
271
testFeature ( SemanticTokensRegistrationType . method , 'document' )
271
272
testFeature ( LinkedEditingRangeRequest . method , 'document' )
272
273
testFeature ( TypeHierarchyPrepareRequest . method , 'document' )
274
+ testFeature ( InlineCompletionRequest . method , 'document' )
273
275
testFeature ( InlineValueRequest . method , 'document' )
274
276
testFeature ( InlayHintRequest . method , 'document' )
275
277
testFeature ( WorkspaceSymbolRequest . method , 'workspace' )
@@ -538,6 +540,40 @@ describe('Client integration', () => {
538
540
)
539
541
} )
540
542
543
+ test ( 'Progress percentage is an integer' , async ( ) => {
544
+ const progressToken = 'TEST-PROGRESS-PERCENTAGE'
545
+ const percentages : Array < number | undefined > = [ ]
546
+ let currentProgressResolver : ( value : unknown ) => void | undefined
547
+
548
+ // Set up middleware that calls the current resolve function when it gets its 'end' progress event.
549
+ middleware . handleWorkDoneProgress = ( token : ProgressToken , params : WorkDoneProgressBegin | WorkDoneProgressReport | WorkDoneProgressEnd , next ) => {
550
+ if ( token === progressToken ) {
551
+ const percentage = params . kind === 'report' || params . kind === 'begin' ? params . percentage : undefined
552
+ percentages . push ( percentage )
553
+
554
+ if ( params . kind === 'end' ) {
555
+ setImmediate ( currentProgressResolver )
556
+ }
557
+ }
558
+ return next ( token , params )
559
+ }
560
+
561
+ // Trigger a progress event.
562
+ await new Promise < unknown > ( resolve => {
563
+ currentProgressResolver = resolve
564
+ void client . sendRequest (
565
+ new ProtocolRequestType < any , null , never , any , any > ( 'testing/sendPercentageProgress' ) ,
566
+ { } ,
567
+ tokenSource . token ,
568
+ )
569
+ } )
570
+
571
+ middleware . handleWorkDoneProgress = undefined
572
+
573
+ // Ensure percentages are rounded according to the spec
574
+ assert . deepStrictEqual ( percentages , [ 0 , 50 , undefined ] )
575
+ } )
576
+
541
577
test ( 'Document Formatting' , async ( ) => {
542
578
const provider = client . getFeature ( DocumentFormattingRequest . method ) . getProvider ( document )
543
579
isDefined ( provider )
@@ -1351,6 +1387,27 @@ describe('Client integration', () => {
1351
1387
} , true )
1352
1388
} )
1353
1389
1390
+ test ( 'Inline Completions' , async ( ) => {
1391
+ const provider = client . getFeature ( InlineCompletionRequest . method ) ?. getProvider ( document )
1392
+ isDefined ( provider )
1393
+ const results = ( await provider . provideInlineCompletionItems ( document , position , { triggerKind : 1 , selectedCompletionInfo : { range, text : 'text' } } , tokenSource . token ) ) as InlineCompletionItem [ ]
1394
+
1395
+ isArray ( results , InlineCompletionItem , 1 )
1396
+
1397
+ rangeEqual ( results [ 0 ] . range ! , 1 , 2 , 3 , 4 )
1398
+ assert . strictEqual ( results [ 0 ] . filterText ! , 'te' )
1399
+ assert . strictEqual ( results [ 0 ] . insertText , 'text inline' )
1400
+
1401
+ let middlewareCalled = false
1402
+ middleware . provideInlineCompletionItems = ( d , r , c , t , n ) => {
1403
+ middlewareCalled = true
1404
+ return n ( d , r , c , t )
1405
+ }
1406
+ await provider . provideInlineCompletionItems ( document , position , { triggerKind : 1 , selectedCompletionInfo : undefined } , tokenSource . token )
1407
+ middleware . provideInlineCompletionItems = undefined
1408
+ assert . strictEqual ( middlewareCalled , true )
1409
+ } )
1410
+
1354
1411
test ( 'Workspace symbols' , async ( ) => {
1355
1412
const providers = client . getFeature ( WorkspaceSymbolRequest . method ) . getProviders ( )
1356
1413
isDefined ( providers )
@@ -1365,6 +1422,58 @@ describe('Client integration', () => {
1365
1422
isDefined ( symbol )
1366
1423
rangeEqual ( symbol . location [ 'range' ] , 1 , 2 , 3 , 4 )
1367
1424
} )
1425
+
1426
+ test ( 'General middleware' , async ( ) => {
1427
+ let middlewareCallCount = 0
1428
+ // Add a general middleware for both requests and notifications
1429
+ middleware . sendRequest = ( type , param , token , next ) => {
1430
+ middlewareCallCount ++
1431
+ return next ( type , param , token )
1432
+ }
1433
+ middleware . sendNotification = ( type , next , params ) => {
1434
+ middlewareCallCount ++
1435
+ return next ( type , params )
1436
+ }
1437
+ // Send a request
1438
+ const definitionProvider = client . getFeature ( DefinitionRequest . method ) . getProvider ( document )
1439
+ isDefined ( definitionProvider )
1440
+ await definitionProvider . provideDefinition ( document , position , tokenSource . token )
1441
+ // Send a notification
1442
+ const notificationProvider = client . getFeature ( DidSaveTextDocumentNotification . method ) . getProvider ( document )
1443
+ isDefined ( notificationProvider )
1444
+ await notificationProvider . send ( document )
1445
+ // Verify that both the request and notification went through the middleware
1446
+ middleware . sendRequest = undefined
1447
+ middleware . sendNotification = undefined
1448
+ assert . strictEqual ( middlewareCallCount , 2 )
1449
+ } )
1450
+
1451
+ test ( 'applyEdit middleware' , async ( ) => {
1452
+ const middlewareEvents : Array < ApplyWorkspaceEditParams > = [ ]
1453
+ let currentProgressResolver : ( value : unknown ) => void | undefined
1454
+
1455
+ middleware . workspace = middleware . workspace || { }
1456
+ middleware . workspace . handleApplyEdit = async ( params , next ) => {
1457
+ middlewareEvents . push ( params )
1458
+ setImmediate ( currentProgressResolver )
1459
+ return next ( params , tokenSource . token )
1460
+ }
1461
+
1462
+ // Trigger sample applyEdit event.
1463
+ await new Promise < unknown > ( resolve => {
1464
+ currentProgressResolver = resolve
1465
+ void client . sendRequest (
1466
+ new ProtocolRequestType < any , null , never , any , any > ( 'testing/sendApplyEdit' ) ,
1467
+ { } ,
1468
+ tokenSource . token ,
1469
+ )
1470
+ } )
1471
+
1472
+ middleware . workspace . handleApplyEdit = undefined
1473
+
1474
+ // Ensure event was handled.
1475
+ assert . deepStrictEqual ( middlewareEvents , [ { label : 'Apply Edit' , edit : { } } ] )
1476
+ } )
1368
1477
} )
1369
1478
1370
1479
namespace CrashNotification {
0 commit comments