@@ -36,6 +36,7 @@ import {
3636 DidChangeWorkspaceFoldersNotification ,
3737 DidChangeWorkspaceFoldersParams ,
3838 LanguageClient ,
39+ Middleware ,
3940 State ,
4041 StateChangeEvent ,
4142} from "vscode-languageclient/node" ;
@@ -597,6 +598,213 @@ suite("LanguageClientManager Suite", () => {
597598 ] ) ;
598599 } ) ;
599600
601+ suite ( "provideCompletionItem middleware" , ( ) => {
602+ const mockParameterHintsEnabled = mockGlobalValue ( configuration , "parameterHintsEnabled" ) ;
603+ let document : MockedObject < vscode . TextDocument > ;
604+ let middleware : Middleware ;
605+
606+ setup ( async ( ) => {
607+ mockParameterHintsEnabled . setValue ( ( ) => true ) ;
608+
609+ document = mockObject < vscode . TextDocument > ( {
610+ uri : vscode . Uri . file ( "/test/file.swift" ) ,
611+ } ) ;
612+
613+ new LanguageClientToolchainCoordinator (
614+ instance ( mockedWorkspace ) ,
615+ { } ,
616+ languageClientFactoryMock
617+ ) ;
618+
619+ await waitForReturnedPromises ( languageClientMock . start ) ;
620+
621+ middleware = languageClientFactoryMock . createLanguageClient . args [ 0 ] [ 3 ] . middleware ! ;
622+ } ) ;
623+
624+ test ( "adds parameter hints command to function completion items when enabled" , async ( ) => {
625+ const completionItemsFromLSP = async ( ) : Promise < vscode . CompletionItem [ ] > => {
626+ return [
627+ {
628+ label : "post(endpoint: String, body: [String : Any]?)" ,
629+ detail : "NetworkRequest" ,
630+ kind : vscode . CompletionItemKind . EnumMember ,
631+ } ,
632+ {
633+ label : "defaultHeaders" ,
634+ detail : "[String : String]" ,
635+ kind : vscode . CompletionItemKind . Property ,
636+ } ,
637+ {
638+ label : "makeRequest(for: NetworkRequest)" ,
639+ detail : "String" ,
640+ kind : vscode . CompletionItemKind . Function ,
641+ } ,
642+ {
643+ label : "[endpoint: String]" ,
644+ detail : "NetworkRequest" ,
645+ kind : vscode . CompletionItemKind . Method ,
646+ } ,
647+ {
648+ label : "(endpoint: String, method: String)" ,
649+ detail : "NetworkRequest" ,
650+ kind : vscode . CompletionItemKind . Constructor ,
651+ } ,
652+ ] ;
653+ } ;
654+
655+ expect ( middleware ) . to . have . property ( "provideCompletionItem" ) ;
656+
657+ const result = await middleware . provideCompletionItem ! (
658+ instance ( document ) ,
659+ new vscode . Position ( 0 , 0 ) ,
660+ { } as any ,
661+ { } as any ,
662+ completionItemsFromLSP
663+ ) ;
664+
665+ expect ( result ) . to . deep . equal ( [
666+ {
667+ label : "post(endpoint: String, body: [String : Any]?)" ,
668+ detail : "NetworkRequest" ,
669+ kind : vscode . CompletionItemKind . EnumMember ,
670+ command : {
671+ title : "Trigger Parameter Hints" ,
672+ command : "editor.action.triggerParameterHints" ,
673+ } ,
674+ } ,
675+ {
676+ label : "defaultHeaders" ,
677+ detail : "[String : String]" ,
678+ kind : vscode . CompletionItemKind . Property ,
679+ } ,
680+ {
681+ label : "makeRequest(for: NetworkRequest)" ,
682+ detail : "String" ,
683+ kind : vscode . CompletionItemKind . Function ,
684+ command : {
685+ title : "Trigger Parameter Hints" ,
686+ command : "editor.action.triggerParameterHints" ,
687+ } ,
688+ } ,
689+ {
690+ label : "[endpoint: String]" ,
691+ detail : "NetworkRequest" ,
692+ kind : vscode . CompletionItemKind . Method ,
693+ command : {
694+ title : "Trigger Parameter Hints" ,
695+ command : "editor.action.triggerParameterHints" ,
696+ } ,
697+ } ,
698+ {
699+ label : "(endpoint: String, method: String)" ,
700+ detail : "NetworkRequest" ,
701+ kind : vscode . CompletionItemKind . Constructor ,
702+ command : {
703+ title : "Trigger Parameter Hints" ,
704+ command : "editor.action.triggerParameterHints" ,
705+ } ,
706+ } ,
707+ ] ) ;
708+ } ) ;
709+
710+ test ( "does not add parameter hints command when disabled" , async ( ) => {
711+ mockParameterHintsEnabled . setValue ( ( ) => false ) ;
712+
713+ const completionItems = [
714+ {
715+ label : "makeRequest(for: NetworkRequest)" ,
716+ detail : "String" ,
717+ kind : vscode . CompletionItemKind . Function ,
718+ } ,
719+ {
720+ label : "[endpoint: String]" ,
721+ detail : "NetworkRequest" ,
722+ kind : vscode . CompletionItemKind . Method ,
723+ } ,
724+ ] ;
725+
726+ const completionItemsFromLSP = async ( ) : Promise < vscode . CompletionItem [ ] > => {
727+ return completionItems ;
728+ } ;
729+
730+ const result = await middleware . provideCompletionItem ! (
731+ instance ( document ) ,
732+ new vscode . Position ( 0 , 0 ) ,
733+ { } as any ,
734+ { } as any ,
735+ completionItemsFromLSP
736+ ) ;
737+
738+ expect ( result ) . to . deep . equal ( completionItems ) ;
739+ } ) ;
740+
741+ test ( "handles CompletionList result format" , async ( ) => {
742+ const completionListFromLSP = async ( ) : Promise < vscode . CompletionList > => {
743+ return {
744+ isIncomplete : false ,
745+ items : [
746+ {
747+ label : "defaultHeaders" ,
748+ detail : "[String : String]" ,
749+ kind : vscode . CompletionItemKind . Property ,
750+ } ,
751+ {
752+ label : "makeRequest(for: NetworkRequest)" ,
753+ detail : "String" ,
754+ kind : vscode . CompletionItemKind . Function ,
755+ } ,
756+ ] ,
757+ } ;
758+ } ;
759+
760+ const result = await middleware . provideCompletionItem ! (
761+ instance ( document ) ,
762+ new vscode . Position ( 0 , 0 ) ,
763+ { } as any ,
764+ { } as any ,
765+ completionListFromLSP
766+ ) ;
767+
768+ expect ( result ) . to . deep . equal ( {
769+ isIncomplete : false ,
770+ items : [
771+ {
772+ label : "defaultHeaders" ,
773+ detail : "[String : String]" ,
774+ kind : vscode . CompletionItemKind . Property ,
775+ } ,
776+ {
777+ label : "makeRequest(for: NetworkRequest)" ,
778+ detail : "String" ,
779+ kind : vscode . CompletionItemKind . Function ,
780+ command : {
781+ title : "Trigger Parameter Hints" ,
782+ command : "editor.action.triggerParameterHints" ,
783+ } ,
784+ } ,
785+ ] ,
786+ } ) ;
787+ } ) ;
788+
789+ test ( "handles null/undefined result from next middleware" , async ( ) => {
790+ mockParameterHintsEnabled . setValue ( ( ) => true ) ;
791+
792+ const nullCompletionResult = async ( ) : Promise < null > => {
793+ return null ;
794+ } ;
795+
796+ const result = await middleware . provideCompletionItem ! (
797+ instance ( document ) ,
798+ new vscode . Position ( 0 , 0 ) ,
799+ { } as any ,
800+ { } as any ,
801+ nullCompletionResult
802+ ) ;
803+
804+ expect ( result ) . to . be . null ;
805+ } ) ;
806+ } ) ;
807+
600808 suite ( "active document changes" , ( ) => {
601809 const mockWindow = mockGlobalObject ( vscode , "window" ) ;
602810
0 commit comments