@@ -598,38 +598,6 @@ namespace FourSlash {
598
598
}
599
599
}
600
600
601
- public verifyImportModuleCompletionListItemsCountIsGreaterThan ( count : number , negative : boolean ) {
602
- const completions = this . getImportModuleCompletionListAtCaret ( ) ;
603
- const itemsCount = completions . entries . length ;
604
-
605
- if ( negative ) {
606
- if ( itemsCount > count ) {
607
- this . raiseError ( `Expected import module completion list items count to not be greater than ${ count } , but is actually ${ itemsCount } ` ) ;
608
- }
609
- }
610
- else {
611
- if ( itemsCount <= count ) {
612
- this . raiseError ( `Expected import module completion list items count to be greater than ${ count } , but is actually ${ itemsCount } ` ) ;
613
- }
614
- }
615
- }
616
-
617
- public verifyImportModuleCompletionListIsEmpty ( negative : boolean ) {
618
- const completions = this . getImportModuleCompletionListAtCaret ( ) ;
619
- if ( ( ! completions || completions . entries . length === 0 ) && negative ) {
620
- this . raiseError ( "Completion list is empty at caret at position " + this . activeFile . fileName + " " + this . currentCaretPosition ) ;
621
- }
622
- else if ( completions && completions . entries . length !== 0 && ! negative ) {
623
- let errorMsg = "\n" + "Completion List contains: [" + completions . entries [ 0 ] . name ;
624
- for ( let i = 1 ; i < completions . entries . length ; i ++ ) {
625
- errorMsg += ", " + completions . entries [ i ] . name ;
626
- }
627
- errorMsg += "]\n" ;
628
-
629
- this . raiseError ( "Completion list is not empty at caret at position " + this . activeFile . fileName + " " + this . currentCaretPosition + errorMsg ) ;
630
- }
631
- }
632
-
633
601
public verifyCompletionListStartsWithItemsInOrder ( items : string [ ] ) : void {
634
602
if ( items . length === 0 ) {
635
603
return ;
@@ -701,10 +669,10 @@ namespace FourSlash {
701
669
}
702
670
}
703
671
704
- public verifyCompletionListContains ( symbol : string , text ?: string , documentation ?: string , kind ?: string ) {
672
+ public verifyCompletionListContains ( symbol : string , text ?: string , documentation ?: string , kind ?: string , spanIndex ?: number ) {
705
673
const completions = this . getCompletionListAtCaret ( ) ;
706
674
if ( completions ) {
707
- this . assertItemInCompletionList ( completions . entries , symbol , text , documentation , kind ) ;
675
+ this . assertItemInCompletionList ( completions . entries , symbol , text , documentation , kind , spanIndex ) ;
708
676
}
709
677
else {
710
678
this . raiseError ( `No completions at position '${ this . currentCaretPosition } ' when looking for '${ symbol } '.` ) ;
@@ -720,25 +688,32 @@ namespace FourSlash {
720
688
* @param expectedText the text associated with the symbol
721
689
* @param expectedDocumentation the documentation text associated with the symbol
722
690
* @param expectedKind the kind of symbol (see ScriptElementKind)
691
+ * @param spanIndex the index of the range that the completion item's replacement text span should match
723
692
*/
724
- public verifyCompletionListDoesNotContain ( symbol : string , expectedText ?: string , expectedDocumentation ?: string , expectedKind ?: string ) {
693
+ public verifyCompletionListDoesNotContain ( symbol : string , expectedText ?: string , expectedDocumentation ?: string , expectedKind ?: string , spanIndex ?: number ) {
725
694
const that = this ;
695
+ let replacementSpan : ts . TextSpan ;
696
+ if ( spanIndex !== undefined ) {
697
+ replacementSpan = this . getTextSpanForRangeAtIndex ( spanIndex ) ;
698
+ }
699
+
726
700
function filterByTextOrDocumentation ( entry : ts . CompletionEntry ) {
727
701
const details = that . getCompletionEntryDetails ( entry . name ) ;
728
702
const documentation = ts . displayPartsToString ( details . documentation ) ;
729
703
const text = ts . displayPartsToString ( details . displayParts ) ;
730
- if ( expectedText && expectedDocumentation ) {
731
- return ( documentation === expectedDocumentation && text === expectedText ) ? true : false ;
704
+
705
+ // If any of the expected values are undefined, assume that users don't
706
+ // care about them.
707
+ if ( replacementSpan && ! TestState . textSpansEqual ( replacementSpan , entry . replacementSpan ) ) {
708
+ return false ;
732
709
}
733
- else if ( expectedText && ! expectedDocumentation ) {
734
- return text === expectedText ? true : false ;
710
+ else if ( expectedText && text !== expectedText ) {
711
+ return false ;
735
712
}
736
- else if ( expectedDocumentation && ! expectedText ) {
737
- return documentation === expectedDocumentation ? true : false ;
713
+ else if ( expectedDocumentation && documentation !== expectedDocumentation ) {
714
+ return false ;
738
715
}
739
- // Because expectedText and expectedDocumentation are undefined, we assume that
740
- // users don"t care to compare them so we will treat that entry as if the entry has matching text and documentation
741
- // and keep it in the list of filtered entry.
716
+
742
717
return true ;
743
718
}
744
719
@@ -762,45 +737,11 @@ namespace FourSlash {
762
737
if ( expectedKind ) {
763
738
error += "Expected kind: " + expectedKind + " to equal: " + filterCompletions [ 0 ] . kind + "." ;
764
739
}
765
- this . raiseError ( error ) ;
766
- }
767
- }
768
- }
769
-
770
- public verifyImportModuleCompletionListContains ( symbol : string , rangeIndex ?: number ) {
771
- const completions = this . getImportModuleCompletionListAtCaret ( ) ;
772
- if ( completions ) {
773
- const completion = ts . forEach ( completions . entries , completion => completion . name === symbol ? completion : undefined ) ;
774
- if ( ! completion ) {
775
- const itemsString = completions . entries . map ( item => item . name ) . join ( ",\n" ) ;
776
- this . raiseError ( `Expected "${ symbol } " to be in list [${ itemsString } ]` ) ;
777
- }
778
- else if ( rangeIndex !== undefined ) {
779
- const ranges = this . getRanges ( ) ;
780
- if ( ranges && ranges . length > rangeIndex ) {
781
- const range = ranges [ rangeIndex ] ;
782
-
783
- const start = completion . replacementSpan . start ;
784
- const end = start + completion . replacementSpan . length ;
785
- if ( range . start !== start || range . end !== end ) {
786
- this . raiseError ( `Expected completion span for '${ symbol } ', ${ stringify ( completion . replacementSpan ) } , to cover range ${ stringify ( range ) } ` ) ;
787
- }
740
+ if ( replacementSpan ) {
741
+ const spanText = filterCompletions [ 0 ] . replacementSpan ? stringify ( filterCompletions [ 0 ] . replacementSpan ) : undefined ;
742
+ error += "Expected replacement span: " + stringify ( replacementSpan ) + " to equal: " + spanText + "." ;
788
743
}
789
- else {
790
- this . raiseError ( `Expected completion span for '${ symbol } ' to cover range at index ${ rangeIndex } , but no range was found at that index` ) ;
791
- }
792
- }
793
- }
794
- else {
795
- this . raiseError ( `No import module completions at position '${ this . currentCaretPosition } ' when looking for '${ symbol } '.` ) ;
796
- }
797
- }
798
-
799
- public verifyImportModuleCompletionListDoesNotContain ( symbol : string ) {
800
- const completions = this . getImportModuleCompletionListAtCaret ( ) ;
801
- if ( completions ) {
802
- if ( ts . forEach ( completions . entries , completion => completion . name === symbol ) ) {
803
- this . raiseError ( `Import module completion list did contain ${ symbol } ` ) ;
744
+ this . raiseError ( error ) ;
804
745
}
805
746
}
806
747
}
@@ -891,10 +832,6 @@ namespace FourSlash {
891
832
return this . languageService . getCompletionsAtPosition ( this . activeFile . fileName , this . currentCaretPosition ) ;
892
833
}
893
834
894
- private getImportModuleCompletionListAtCaret ( ) {
895
- return this . languageService . getCompletionsAtPosition ( this . activeFile . fileName , this . currentCaretPosition ) ;
896
- }
897
-
898
835
private getCompletionEntryDetails ( entryName : string ) {
899
836
return this . languageService . getCompletionEntryDetails ( this . activeFile . fileName , this . currentCaretPosition , entryName ) ;
900
837
}
@@ -2241,7 +2178,7 @@ namespace FourSlash {
2241
2178
return text . substring ( startPos , endPos ) ;
2242
2179
}
2243
2180
2244
- private assertItemInCompletionList ( items : ts . CompletionEntry [ ] , name : string , text ?: string , documentation ?: string , kind ?: string ) {
2181
+ private assertItemInCompletionList ( items : ts . CompletionEntry [ ] , name : string , text ?: string , documentation ?: string , kind ?: string , spanIndex ?: number ) {
2245
2182
for ( let i = 0 ; i < items . length ; i ++ ) {
2246
2183
const item = items [ i ] ;
2247
2184
if ( item . name === name ) {
@@ -2260,6 +2197,11 @@ namespace FourSlash {
2260
2197
assert . equal ( item . kind , kind , this . assertionMessageAtLastKnownMarker ( "completion item kind for " + name ) ) ;
2261
2198
}
2262
2199
2200
+ if ( spanIndex !== undefined ) {
2201
+ const span = this . getTextSpanForRangeAtIndex ( spanIndex ) ;
2202
+ assert . isTrue ( TestState . textSpansEqual ( span , item . replacementSpan ) , this . assertionMessageAtLastKnownMarker ( stringify ( span ) + " does not equal " + stringify ( item . replacementSpan ) + " replacement span for " + name ) ) ;
2203
+ }
2204
+
2263
2205
return ;
2264
2206
}
2265
2207
}
@@ -2316,6 +2258,17 @@ namespace FourSlash {
2316
2258
return `line ${ ( pos . line + 1 ) } , col ${ pos . character } ` ;
2317
2259
}
2318
2260
2261
+ private getTextSpanForRangeAtIndex ( index : number ) : ts . TextSpan {
2262
+ const ranges = this . getRanges ( ) ;
2263
+ if ( ranges && ranges . length > index ) {
2264
+ const range = ranges [ index ] ;
2265
+ return { start : range . start , length : range . end - range . start } ;
2266
+ }
2267
+ else {
2268
+ this . raiseError ( "Supplied span index: " + index + " does not exist in range list of size: " + ( ranges ? 0 : ranges . length ) ) ;
2269
+ }
2270
+ }
2271
+
2319
2272
public getMarkerByName ( markerName : string ) {
2320
2273
const markerPos = this . testData . markerPositions [ markerName ] ;
2321
2274
if ( markerPos === undefined ) {
@@ -2339,6 +2292,10 @@ namespace FourSlash {
2339
2292
public resetCancelled ( ) : void {
2340
2293
this . cancellationToken . resetCancelled ( ) ;
2341
2294
}
2295
+
2296
+ private static textSpansEqual ( a : ts . TextSpan , b : ts . TextSpan ) {
2297
+ return a && b && a . start === b . start && a . length === b . length ;
2298
+ }
2342
2299
}
2343
2300
2344
2301
export function runFourSlashTest ( basePath : string , testType : FourSlashTestType , fileName : string ) {
@@ -2909,12 +2866,12 @@ namespace FourSlashInterface {
2909
2866
2910
2867
// Verifies the completion list contains the specified symbol. The
2911
2868
// completion list is brought up if necessary
2912
- public completionListContains ( symbol : string , text ?: string , documentation ?: string , kind ?: string ) {
2869
+ public completionListContains ( symbol : string , text ?: string , documentation ?: string , kind ?: string , spanIndex ?: number ) {
2913
2870
if ( this . negative ) {
2914
- this . state . verifyCompletionListDoesNotContain ( symbol , text , documentation , kind ) ;
2871
+ this . state . verifyCompletionListDoesNotContain ( symbol , text , documentation , kind , spanIndex ) ;
2915
2872
}
2916
2873
else {
2917
- this . state . verifyCompletionListContains ( symbol , text , documentation , kind ) ;
2874
+ this . state . verifyCompletionListContains ( symbol , text , documentation , kind , spanIndex ) ;
2918
2875
}
2919
2876
}
2920
2877
@@ -2924,23 +2881,6 @@ namespace FourSlashInterface {
2924
2881
this . state . verifyCompletionListItemsCountIsGreaterThan ( count , this . negative ) ;
2925
2882
}
2926
2883
2927
- public importModuleCompletionListContains ( symbol : string , rangeIndex ?: number ) : void {
2928
- if ( this . negative ) {
2929
- this . state . verifyImportModuleCompletionListDoesNotContain ( symbol ) ;
2930
- }
2931
- else {
2932
- this . state . verifyImportModuleCompletionListContains ( symbol , rangeIndex ) ;
2933
- }
2934
- }
2935
-
2936
- public importModuleCompletionListItemsCountIsGreaterThan ( count : number ) : void {
2937
- this . state . verifyImportModuleCompletionListItemsCountIsGreaterThan ( count , this . negative ) ;
2938
- }
2939
-
2940
- public importModuleCompletionListIsEmpty ( ) : void {
2941
- this . state . verifyImportModuleCompletionListIsEmpty ( this . negative ) ;
2942
- }
2943
-
2944
2884
public assertHasRanges ( ranges : FourSlash . Range [ ] ) {
2945
2885
assert ( ranges . length !== 0 , "Array of ranges is expected to be non-empty" ) ;
2946
2886
}
0 commit comments