@@ -859,9 +859,8 @@ namespace FourSlash {
859
859
}
860
860
}
861
861
862
- public verifyReferencesOf ( { fileName, start} : Range , references : Range [ ] ) {
863
- this . openFile ( fileName ) ;
864
- this . goToPosition ( start ) ;
862
+ public verifyReferencesOf ( range : Range , references : Range [ ] ) {
863
+ this . goToRangeStart ( range ) ;
865
864
this . verifyReferencesAre ( references ) ;
866
865
}
867
866
@@ -1669,6 +1668,11 @@ namespace FourSlash {
1669
1668
this . goToPosition ( len ) ;
1670
1669
}
1671
1670
1671
+ private goToRangeStart ( { fileName, start} : Range ) {
1672
+ this . openFile ( fileName ) ;
1673
+ this . goToPosition ( start ) ;
1674
+ }
1675
+
1672
1676
public goToTypeDefinition ( definitionIndex : number ) {
1673
1677
const definitions = this . languageService . getTypeDefinitionAtPosition ( this . activeFile . fileName , this . currentCaretPosition ) ;
1674
1678
if ( ! definitions || ! definitions . length ) {
@@ -2361,40 +2365,45 @@ namespace FourSlash {
2361
2365
return this . languageService . getDocumentHighlights ( this . activeFile . fileName , this . currentCaretPosition , filesToSearch ) ;
2362
2366
}
2363
2367
2364
- public verifyDocumentHighlightsAtPositionListContains ( fileName : string , start : number , end : number , fileNamesToSearch : string [ ] , kind ?: string ) {
2365
- const documentHighlights = this . getDocumentHighlightsAtCurrentPosition ( fileNamesToSearch ) ;
2368
+ public verifyRangesWithSameTextAreDocumentHighlights ( ) {
2369
+ this . rangesByText ( ) . forEach ( ranges => this . verifyRangesAreDocumentHighlights ( ranges ) ) ;
2370
+ }
2366
2371
2367
- if ( ! documentHighlights || documentHighlights . length === 0 ) {
2368
- this . raiseError ( "verifyDocumentHighlightsAtPositionListContains failed - found 0 highlights, expected at least one." ) ;
2372
+ public verifyRangesAreDocumentHighlights ( ranges ?: Range [ ] ) {
2373
+ ranges = ranges || this . getRanges ( ) ;
2374
+ const fileNames = unique ( ranges , range => range . fileName ) ;
2375
+ for ( const range of ranges ) {
2376
+ this . goToRangeStart ( range ) ;
2377
+ this . verifyDocumentHighlights ( ranges , fileNames ) ;
2369
2378
}
2379
+ }
2370
2380
2371
- for ( const documentHighlight of documentHighlights ) {
2372
- if ( documentHighlight . fileName === fileName ) {
2373
- const { highlightSpans } = documentHighlight ;
2381
+ private verifyDocumentHighlights ( expectedRanges : Range [ ] , fileNames : string [ ] = [ this . activeFile . fileName ] ) {
2382
+ const documentHighlights = this . getDocumentHighlightsAtCurrentPosition ( fileNames ) || [ ] ;
2374
2383
2375
- for ( const highlight of highlightSpans ) {
2376
- if ( highlight && highlight . textSpan . start === start && ts . textSpanEnd ( highlight . textSpan ) === end ) {
2377
- if ( typeof kind !== "undefined" && highlight . kind !== kind ) {
2378
- this . raiseError ( `verifyDocumentHighlightsAtPositionListContains failed - item "kind" value does not match, actual: ${ highlight . kind } , expected: ${ kind } .` ) ;
2379
- }
2380
- return ;
2381
- }
2382
- }
2384
+ for ( const dh of documentHighlights ) {
2385
+ if ( fileNames . indexOf ( dh . fileName ) === - 1 ) {
2386
+ this . raiseError ( `verifyDocumentHighlights failed - got highlights in unexpected file name ${ dh . fileName } ` ) ;
2383
2387
}
2384
2388
}
2385
2389
2386
- const missingItem = { fileName : fileName , start : start , end : end , kind : kind } ;
2387
- this . raiseError ( `verifyDocumentHighlightsAtPositionListContains failed - could not find the item: ${ stringify ( missingItem ) } in the returned list: (${ stringify ( documentHighlights ) } )` ) ;
2388
- }
2390
+ for ( const fileName of fileNames ) {
2391
+ const expectedRangesInFile = expectedRanges . filter ( r => r . fileName === fileName ) ;
2392
+ const highlights = ts . find ( documentHighlights , dh => dh . fileName === fileName ) ;
2393
+ if ( ! highlights ) {
2394
+ this . raiseError ( `verifyDocumentHighlights failed - found no highlights in ${ fileName } ` ) ;
2395
+ }
2396
+ const spansInFile = highlights . highlightSpans . sort ( ( s1 , s2 ) => s1 . textSpan . start - s2 . textSpan . start ) ;
2389
2397
2390
- public verifyDocumentHighlightsAtPositionListCount ( expectedCount : number , fileNamesToSearch : string [ ] ) {
2391
- const documentHighlights = this . getDocumentHighlightsAtCurrentPosition ( fileNamesToSearch ) ;
2392
- const actualCount = documentHighlights
2393
- ? documentHighlights . reduce ( ( currentCount , { highlightSpans } ) => currentCount + highlightSpans . length , 0 )
2394
- : 0 ;
2398
+ if ( expectedRangesInFile . length !== spansInFile . length ) {
2399
+ this . raiseError ( `verifyDocumentHighlights failed - In ${ fileName } , expected ${ expectedRangesInFile . length } highlights, got ${ spansInFile . length } ` ) ;
2400
+ }
2395
2401
2396
- if ( expectedCount !== actualCount ) {
2397
- this . raiseError ( "verifyDocumentHighlightsAtPositionListCount failed - actual: " + actualCount + ", expected:" + expectedCount ) ;
2402
+ ts . zipWith ( expectedRangesInFile , spansInFile , ( expectedRange , span ) => {
2403
+ if ( span . textSpan . start !== expectedRange . start || ts . textSpanEnd ( span . textSpan ) !== expectedRange . end ) {
2404
+ this . raiseError ( `verifyDocumentHighlights failed - span does not match, actual: ${ JSON . stringify ( span . textSpan ) } , expected: ${ expectedRange . start } --${ expectedRange . end } ` ) ;
2405
+ }
2406
+ } ) ;
2398
2407
}
2399
2408
}
2400
2409
@@ -3021,6 +3030,16 @@ ${code}
3021
3030
function stringify ( data : any , replacer ?: ( key : string , value : any ) => any ) : string {
3022
3031
return JSON . stringify ( data , replacer , 2 ) ;
3023
3032
}
3033
+
3034
+ /** Collects an array of unique outputs. */
3035
+ function unique < T > ( inputs : T [ ] , getOutput : ( t : T ) => string ) : string [ ] {
3036
+ const set = ts . createMap < true > ( ) ;
3037
+ for ( const input of inputs ) {
3038
+ const out = getOutput ( input ) ;
3039
+ set . set ( out , true ) ;
3040
+ }
3041
+ return ts . arrayFrom ( set . keys ( ) ) ;
3042
+ }
3024
3043
}
3025
3044
3026
3045
namespace FourSlashInterface {
@@ -3413,12 +3432,12 @@ namespace FourSlashInterface {
3413
3432
this . state . verifyOccurrencesAtPositionListCount ( expectedCount ) ;
3414
3433
}
3415
3434
3416
- public documentHighlightsAtPositionContains ( range : FourSlash . Range , fileNamesToSearch : string [ ] , kind ?: string ) {
3417
- this . state . verifyDocumentHighlightsAtPositionListContains ( range . fileName , range . start , range . end , fileNamesToSearch , kind ) ;
3435
+ public rangesAreDocumentHighlights ( ranges ? : FourSlash . Range [ ] ) {
3436
+ this . state . verifyRangesAreDocumentHighlights ( ranges ) ;
3418
3437
}
3419
3438
3420
- public documentHighlightsAtPositionCount ( expectedCount : number , fileNamesToSearch : string [ ] ) {
3421
- this . state . verifyDocumentHighlightsAtPositionListCount ( expectedCount , fileNamesToSearch ) ;
3439
+ public rangesWithSameTextAreDocumentHighlights ( ) {
3440
+ this . state . verifyRangesWithSameTextAreDocumentHighlights ( ) ;
3422
3441
}
3423
3442
3424
3443
public completionEntryDetailIs ( entryName : string , text : string , documentation ?: string , kind ?: string ) {
0 commit comments