@@ -36,6 +36,7 @@ import {
36
36
DidChangeWorkspaceFoldersNotification ,
37
37
DidChangeWorkspaceFoldersParams ,
38
38
LanguageClient ,
39
+ Middleware ,
39
40
State ,
40
41
StateChangeEvent ,
41
42
} from "vscode-languageclient/node" ;
@@ -597,6 +598,213 @@ suite("LanguageClientManager Suite", () => {
597
598
] ) ;
598
599
} ) ;
599
600
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
+
600
808
suite ( "active document changes" , ( ) => {
601
809
const mockWindow = mockGlobalObject ( vscode , "window" ) ;
602
810
0 commit comments