@@ -452,7 +452,8 @@ namespace FourSlash {
452452 }
453453
454454 private messageAtLastKnownMarker ( message : string ) {
455- return "Marker: " + this . lastKnownMarker + "\n" + message ;
455+ const locationDescription = this . lastKnownMarker ? this . lastKnownMarker : this . getLineColStringAtPosition ( this . currentCaretPosition ) ;
456+ return `At ${ locationDescription } : ${ message } ` ;
456457 }
457458
458459 private assertionMessageAtLastKnownMarker ( msg : string ) {
@@ -562,7 +563,7 @@ namespace FourSlash {
562563 }
563564
564565 public verifyGoToDefinitionIs ( endMarker : string | string [ ] ) {
565- this . verifyGoToXWorker ( endMarker instanceof Array ? endMarker : [ endMarker ] , ( ) => this . getGoToDefinition ( ) ) ;
566+ this . verifyGoToXWorker ( toArray ( endMarker ) , ( ) => this . getGoToDefinition ( ) ) ;
566567 }
567568
568569 public verifyGoToDefinition ( arg0 : any , endMarkerNames ?: string | string [ ] ) {
@@ -582,7 +583,7 @@ namespace FourSlash {
582583 if ( endMarkerNames ) {
583584 this . verifyGoToXPlain ( arg0 , endMarkerNames , getDefs ) ;
584585 }
585- else if ( arg0 instanceof Array ) {
586+ else if ( ts . isArray ( arg0 ) ) {
586587 const pairs : [ string | string [ ] , string | string [ ] ] [ ] = arg0 ;
587588 for ( const [ start , end ] of pairs ) {
588589 this . verifyGoToXPlain ( start , end , getDefs ) ;
@@ -599,13 +600,8 @@ namespace FourSlash {
599600 }
600601
601602 private verifyGoToXPlain ( startMarkerNames : string | string [ ] , endMarkerNames : string | string [ ] , getDefs : ( ) => ts . DefinitionInfo [ ] | undefined ) {
602- if ( startMarkerNames instanceof Array ) {
603- for ( const start of startMarkerNames ) {
604- this . verifyGoToXSingle ( start , endMarkerNames , getDefs ) ;
605- }
606- }
607- else {
608- this . verifyGoToXSingle ( startMarkerNames , endMarkerNames , getDefs ) ;
603+ for ( const start of toArray ( startMarkerNames ) ) {
604+ this . verifyGoToXSingle ( start , endMarkerNames , getDefs ) ;
609605 }
610606 }
611607
@@ -617,7 +613,7 @@ namespace FourSlash {
617613
618614 private verifyGoToXSingle ( startMarkerName : string , endMarkerNames : string | string [ ] , getDefs : ( ) => ts . DefinitionInfo [ ] | undefined ) {
619615 this . goToMarker ( startMarkerName ) ;
620- this . verifyGoToXWorker ( endMarkerNames instanceof Array ? endMarkerNames : [ endMarkerNames ] , getDefs ) ;
616+ this . verifyGoToXWorker ( toArray ( endMarkerNames ) , getDefs ) ;
621617 }
622618
623619 private verifyGoToXWorker ( endMarkers : string [ ] , getDefs : ( ) => ts . DefinitionInfo [ ] | undefined ) {
@@ -899,8 +895,74 @@ namespace FourSlash {
899895 }
900896 }
901897
902- public verifyRangesWithSameTextReferenceEachOther ( ) {
903- this . rangesByText ( ) . forEach ( ranges => this . verifyRangesReferenceEachOther ( ranges ) ) ;
898+ public verifyReferenceGroups ( startRanges : Range | Range [ ] , parts : Array < { definition : string , ranges : Range [ ] } > ) : void {
899+ interface ReferenceJson { definition : string ; ranges : ts . ReferenceEntry [ ] ; }
900+ type ReferencesJson = ReferenceJson [ ] ;
901+ const fullExpected = parts . map < ReferenceJson > ( ( { definition, ranges } ) => ( { definition, ranges : ranges . map ( rangeToReferenceEntry ) } ) ) ;
902+
903+ for ( const startRange of toArray ( startRanges ) ) {
904+ this . goToRangeStart ( startRange ) ;
905+ const fullActual = this . findReferencesAtCaret ( ) . map < ReferenceJson > ( ( { definition, references } ) => ( {
906+ definition : definition . displayParts . map ( d => d . text ) . join ( "" ) ,
907+ ranges : references
908+ } ) ) ;
909+ this . assertObjectsEqual < ReferencesJson > ( fullActual , fullExpected ) ;
910+ }
911+
912+ function rangeToReferenceEntry ( r : Range ) {
913+ let { isWriteAccess, isDefinition } = ( r . marker && r . marker . data ) || { isWriteAccess : false , isDefinition : false } ;
914+ isWriteAccess = isWriteAccess || false ; isDefinition = isDefinition || false ;
915+ return { fileName : r . fileName , textSpan : { start : r . start , length : r . end - r . start } , isWriteAccess, isDefinition }
916+ }
917+ }
918+
919+ public verifyNoReferences ( markerNameOrRange ?: string | Range ) {
920+ if ( markerNameOrRange ) {
921+ if ( typeof markerNameOrRange === "string" ) {
922+ this . goToMarker ( markerNameOrRange ) ;
923+ }
924+ else {
925+ this . goToRangeStart ( markerNameOrRange ) ;
926+ }
927+ }
928+
929+ const refs = this . getReferencesAtCaret ( ) ;
930+ if ( refs && refs . length ) {
931+ console . log ( refs ) ;
932+ this . raiseError ( "Expected getReferences to fail" ) ;
933+ }
934+ }
935+
936+ public verifySingleReferenceGroup ( definition : string , ranges ?: Range [ ] ) {
937+ ranges = ranges || this . getRanges ( ) ;
938+ this . verifyReferenceGroups ( ranges , [ { definition, ranges } ] ) ;
939+ }
940+
941+ private assertObjectsEqual < T > ( fullActual : T , fullExpected : T , msgPrefix = "" ) : void {
942+ const recur = < U > ( actual : U , expected : U , path : string ) => {
943+ const fail = ( msg : string ) => {
944+ console . log ( "Expected:" , stringify ( fullExpected ) ) ;
945+ console . log ( "Actual: " , stringify ( fullActual ) ) ;
946+ this . raiseError ( `${ msgPrefix } At ${ path } : ${ msg } ` ) ;
947+ } ;
948+
949+ for ( const key in actual ) if ( ts . hasProperty ( actual as any , key ) ) {
950+ const ak = actual [ key ] , ek = expected [ key ] ;
951+ if ( typeof ak === "object" && typeof ek === "object" ) {
952+ recur ( ak , ek , path ? path + "." + key : key ) ;
953+ }
954+ else if ( ak !== ek ) {
955+ fail ( `Expected '${ key } ' to be '${ ek } ', got '${ ak } '` ) ;
956+ }
957+ }
958+ for ( const key in expected ) if ( ts . hasProperty ( expected as any , key ) ) {
959+ if ( ! ts . hasProperty ( actual as any , key ) ) {
960+ fail ( `${ msgPrefix } Missing property '${ key } '` ) ;
961+ }
962+ }
963+ } ;
964+ recur ( fullActual , fullExpected , "" ) ;
965+
904966 }
905967
906968 public verifyDisplayPartsOfReferencedSymbol ( expected : ts . SymbolDisplayPart [ ] ) {
@@ -974,7 +1036,7 @@ namespace FourSlash {
9741036 public verifyQuickInfos ( namesAndTexts : { [ name : string ] : string | [ string , string ] } ) {
9751037 for ( const name in namesAndTexts ) if ( ts . hasProperty ( namesAndTexts , name ) ) {
9761038 const text = namesAndTexts [ name ] ;
977- if ( text instanceof Array ) {
1039+ if ( ts . isArray ( text ) ) {
9781040 assert ( text . length === 2 ) ;
9791041 const [ expectedText , expectedDocumentation ] = text ;
9801042 this . verifyQuickInfoAt ( name , expectedText , expectedDocumentation ) ;
@@ -1411,13 +1473,6 @@ namespace FourSlash {
14111473 Harness . IO . log ( membersString ) ;
14121474 }
14131475
1414- public printReferences ( ) {
1415- const references = this . getReferencesAtCaret ( ) ;
1416- ts . forEach ( references , entry => {
1417- Harness . IO . log ( stringify ( entry ) ) ;
1418- } ) ;
1419- }
1420-
14211476 public printContext ( ) {
14221477 ts . forEach ( this . languageServiceAdapterHost . getFilenames ( ) , Harness . IO . log ) ;
14231478 }
@@ -3082,6 +3137,10 @@ ${code}
30823137 }
30833138 return ts . arrayFrom ( set . keys ( ) ) ;
30843139 }
3140+
3141+ function toArray < T > ( x : T | T [ ] ) : T [ ] {
3142+ return ts . isArray ( x ) ? x : [ x ] ;
3143+ }
30853144}
30863145
30873146namespace FourSlashInterface {
@@ -3346,6 +3405,18 @@ namespace FourSlashInterface {
33463405 this . state . verifyReferencesOf ( start , references ) ;
33473406 }
33483407
3408+ public referenceGroups ( startRanges : FourSlash . Range [ ] , parts : Array < { definition : string , ranges : FourSlash . Range [ ] } > ) {
3409+ this . state . verifyReferenceGroups ( startRanges , parts ) ;
3410+ }
3411+
3412+ public noReferences ( markerNameOrRange ?: string | FourSlash . Range ) {
3413+ this . state . verifyNoReferences ( markerNameOrRange ) ;
3414+ }
3415+
3416+ public singleReferenceGroup ( definition : string , ranges ?: FourSlash . Range [ ] ) {
3417+ this . state . verifySingleReferenceGroup ( definition , ranges ) ;
3418+ }
3419+
33493420 public rangesReferenceEachOther ( ranges ?: FourSlash . Range [ ] ) {
33503421 this . state . verifyRangesReferenceEachOther ( ranges ) ;
33513422 }
@@ -3354,10 +3425,6 @@ namespace FourSlashInterface {
33543425 this . state . verifyDisplayPartsOfReferencedSymbol ( expected ) ;
33553426 }
33563427
3357- public rangesWithSameTextReferenceEachOther ( ) {
3358- this . state . verifyRangesWithSameTextReferenceEachOther ( ) ;
3359- }
3360-
33613428 public currentParameterHelpArgumentNameIs ( name : string ) {
33623429 this . state . verifyCurrentParameterHelpName ( name ) ;
33633430 }
@@ -3660,10 +3727,6 @@ namespace FourSlashInterface {
36603727 this . state . printNavigationBar ( ) ;
36613728 }
36623729
3663- public printReferences ( ) {
3664- this . state . printReferences ( ) ;
3665- }
3666-
36673730 public printContext ( ) {
36683731 this . state . printContext ( ) ;
36693732 }
0 commit comments