@@ -3005,9 +3005,7 @@ Actual: ${stringify(fullActual)}`);
3005
3005
}
3006
3006
3007
3007
public verifyApplicableRefactorAvailableAtMarker ( negative : boolean , markerName : string ) {
3008
- const marker = this . getMarkerByName ( markerName ) ;
3009
- const applicableRefactors = this . languageService . getApplicableRefactors ( this . activeFile . fileName , marker . position , ts . defaultPreferences ) ;
3010
- const isAvailable = applicableRefactors && applicableRefactors . length > 0 ;
3008
+ const isAvailable = this . getApplicableRefactors ( this . getMarkerByName ( markerName ) . position ) . length > 0 ;
3011
3009
if ( negative && isAvailable ) {
3012
3010
this . raiseError ( `verifyApplicableRefactorAvailableAtMarker failed - expected no refactor at marker ${ markerName } but found some.` ) ;
3013
3011
}
@@ -3024,9 +3022,7 @@ Actual: ${stringify(fullActual)}`);
3024
3022
}
3025
3023
3026
3024
public verifyRefactorAvailable ( negative : boolean , name : string , actionName ?: string ) {
3027
- const selection = this . getSelection ( ) ;
3028
-
3029
- let refactors = this . languageService . getApplicableRefactors ( this . activeFile . fileName , selection , ts . defaultPreferences ) || [ ] ;
3025
+ let refactors = this . getApplicableRefactors ( this . getSelection ( ) ) ;
3030
3026
refactors = refactors . filter ( r => r . name === name && ( actionName === undefined || r . actions . some ( a => a . name === actionName ) ) ) ;
3031
3027
const isAvailable = refactors . length > 0 ;
3032
3028
@@ -3046,10 +3042,7 @@ Actual: ${stringify(fullActual)}`);
3046
3042
}
3047
3043
3048
3044
public verifyRefactor ( { name, actionName, refactors } : FourSlashInterface . VerifyRefactorOptions ) {
3049
- const selection = this . getSelection ( ) ;
3050
-
3051
- const actualRefactors = ( this . languageService . getApplicableRefactors ( this . activeFile . fileName , selection , ts . defaultPreferences ) || ts . emptyArray )
3052
- . filter ( r => r . name === name && r . actions . some ( a => a . name === actionName ) ) ;
3045
+ const actualRefactors = this . getApplicableRefactors ( this . getSelection ( ) ) . filter ( r => r . name === name && r . actions . some ( a => a . name === actionName ) ) ;
3053
3046
this . assertObjectsEqual ( actualRefactors , refactors ) ;
3054
3047
}
3055
3048
@@ -3059,8 +3052,7 @@ Actual: ${stringify(fullActual)}`);
3059
3052
throw new Error ( "Exactly one refactor range is allowed per test." ) ;
3060
3053
}
3061
3054
3062
- const applicableRefactors = this . languageService . getApplicableRefactors ( this . activeFile . fileName , ts . first ( ranges ) , ts . defaultPreferences ) ;
3063
- const isAvailable = applicableRefactors && applicableRefactors . length > 0 ;
3055
+ const isAvailable = this . getApplicableRefactors ( ts . first ( ranges ) ) . length > 0 ;
3064
3056
if ( negative && isAvailable ) {
3065
3057
this . raiseError ( `verifyApplicableRefactorAvailableForRange failed - expected no refactor but found some.` ) ;
3066
3058
}
@@ -3071,7 +3063,7 @@ Actual: ${stringify(fullActual)}`);
3071
3063
3072
3064
public applyRefactor ( { refactorName, actionName, actionDescription, newContent : newContentWithRenameMarker } : FourSlashInterface . ApplyRefactorOptions ) {
3073
3065
const range = this . getSelection ( ) ;
3074
- const refactors = this . languageService . getApplicableRefactors ( this . activeFile . fileName , range , ts . defaultPreferences ) ;
3066
+ const refactors = this . getApplicableRefactors ( range ) ;
3075
3067
const refactorsWithName = refactors . filter ( r => r . name === refactorName ) ;
3076
3068
if ( refactorsWithName . length === 0 ) {
3077
3069
this . raiseError ( `The expected refactor: ${ refactorName } is not available at the marker location.\nAvailable refactors: ${ refactors . map ( r => r . name ) } ` ) ;
@@ -3117,7 +3109,48 @@ Actual: ${stringify(fullActual)}`);
3117
3109
return { renamePosition, newContent } ;
3118
3110
}
3119
3111
}
3112
+ }
3120
3113
3114
+ public noMoveToNewFile ( ) {
3115
+ for ( const range of this . getRanges ( ) ) {
3116
+ for ( const refactor of this . getApplicableRefactors ( range , { allowTextChangesInNewFiles : true } ) ) {
3117
+ if ( refactor . name === "Move to a new file" ) {
3118
+ ts . Debug . fail ( "Did not expect to get 'move to a new file' refactor" ) ;
3119
+ }
3120
+ }
3121
+ }
3122
+ }
3123
+
3124
+ public moveToNewFile ( options : FourSlashInterface . MoveToNewFileOptions ) : void {
3125
+ assert ( this . getRanges ( ) . length === 1 ) ;
3126
+ const range = this . getRanges ( ) [ 0 ] ;
3127
+ const refactor = ts . find ( this . getApplicableRefactors ( range , { allowTextChangesInNewFiles : true } ) , r => r . name === "Move to a new file" ) ;
3128
+ assert ( refactor . actions . length === 1 ) ;
3129
+ const action = ts . first ( refactor . actions ) ;
3130
+ assert ( action . name === "Move to a new file" && action . description === "Move to a new file" ) ;
3131
+
3132
+ const editInfo = this . languageService . getEditsForRefactor ( this . activeFile . fileName , this . formatCodeSettings , range , refactor . name , action . name , ts . defaultPreferences ) ;
3133
+ for ( const edit of editInfo . edits ) {
3134
+ const newContent = options . newFileContents [ edit . fileName ] ;
3135
+ if ( newContent === undefined ) {
3136
+ this . raiseError ( `There was an edit in ${ edit . fileName } but new content was not specified.` ) ;
3137
+ }
3138
+ if ( this . testData . files . some ( f => f . fileName === edit . fileName ) ) {
3139
+ this . applyEdits ( edit . fileName , edit . textChanges , /*isFormattingEdit*/ false ) ;
3140
+ this . openFile ( edit . fileName ) ;
3141
+ this . verifyCurrentFileContent ( newContent ) ;
3142
+ }
3143
+ else {
3144
+ assert ( edit . textChanges . length === 1 ) ;
3145
+ const change = ts . first ( edit . textChanges ) ;
3146
+ assert . deepEqual ( change . span , ts . createTextSpan ( 0 , 0 ) ) ;
3147
+ assert . equal ( change . newText , newContent , `Content for ${ edit . fileName } ` ) ;
3148
+ }
3149
+ }
3150
+
3151
+ for ( const fileName in options . newFileContents ) {
3152
+ assert ( editInfo . edits . some ( e => e . fileName === fileName ) ) ;
3153
+ }
3121
3154
}
3122
3155
3123
3156
public verifyFileAfterApplyingRefactorAtMarker (
@@ -3333,6 +3366,10 @@ Actual: ${stringify(fullActual)}`);
3333
3366
this . verifyCurrentFileContent ( options . newFileContents [ fileName ] ) ;
3334
3367
}
3335
3368
}
3369
+
3370
+ private getApplicableRefactors ( positionOrRange : number | ts . TextRange , preferences = ts . defaultPreferences ) : ReadonlyArray < ts . ApplicableRefactorInfo > {
3371
+ return this . languageService . getApplicableRefactors ( this . activeFile . fileName , positionOrRange , preferences ) || ts . emptyArray ;
3372
+ }
3336
3373
}
3337
3374
3338
3375
export function runFourSlashTest ( basePath : string , testType : FourSlashTestType , fileName : string ) {
@@ -4430,6 +4467,13 @@ namespace FourSlashInterface {
4430
4467
public getEditsForFileRename ( options : GetEditsForFileRenameOptions ) {
4431
4468
this . state . getEditsForFileRename ( options ) ;
4432
4469
}
4470
+
4471
+ public moveToNewFile ( options : MoveToNewFileOptions ) : void {
4472
+ this . state . moveToNewFile ( options ) ;
4473
+ }
4474
+ public noMoveToNewFile ( ) : void {
4475
+ this . state . noMoveToNewFile ( ) ;
4476
+ }
4433
4477
}
4434
4478
4435
4479
export class Edit {
@@ -4803,4 +4847,8 @@ namespace FourSlashInterface {
4803
4847
readonly newPath : string ;
4804
4848
readonly newFileContents : { readonly [ fileName : string ] : string } ;
4805
4849
}
4850
+
4851
+ export interface MoveToNewFileOptions {
4852
+ readonly newFileContents : { readonly [ fileName : string ] : string } ;
4853
+ }
4806
4854
}
0 commit comments