22
22
namespace FourSlash {
23
23
ts . disableIncrementalParsing = false ;
24
24
25
- function normalizeNewLines ( s : string ) {
26
- return s . replace ( / \r \n / g, "\n" ) ;
27
- }
28
-
29
25
// Represents a parsed source file with metadata
30
26
export interface FourSlashFile {
31
27
// The contents of the file (with markers, etc stripped out)
@@ -364,7 +360,7 @@ namespace FourSlash {
364
360
baseIndentSize : 0 ,
365
361
indentSize : 4 ,
366
362
tabSize : 4 ,
367
- newLineCharacter : Harness . IO . newLine ( ) ,
363
+ newLineCharacter : "\n" ,
368
364
convertTabsToSpaces : true ,
369
365
indentStyle : ts . IndentStyle . Smart ,
370
366
insertSpaceAfterCommaDelimiter : true ,
@@ -1603,16 +1599,16 @@ namespace FourSlash {
1603
1599
}
1604
1600
}
1605
1601
1606
- public printCurrentFileState ( makeWhitespaceVisible : boolean , makeCaretVisible : boolean ) {
1602
+ public printCurrentFileState ( showWhitespace : boolean , makeCaretVisible : boolean ) {
1607
1603
for ( const file of this . testData . files ) {
1608
1604
const active = ( this . activeFile === file ) ;
1609
1605
Harness . IO . log ( `=== Script (${ file . fileName } ) ${ ( active ? "(active, cursor at |)" : "" ) } ===` ) ;
1610
1606
let content = this . getFileContent ( file . fileName ) ;
1611
1607
if ( active ) {
1612
1608
content = content . substr ( 0 , this . currentCaretPosition ) + ( makeCaretVisible ? "|" : "" ) + content . substr ( this . currentCaretPosition ) ;
1613
1609
}
1614
- if ( makeWhitespaceVisible ) {
1615
- content = TestState . makeWhitespaceVisible ( content ) ;
1610
+ if ( showWhitespace ) {
1611
+ content = makeWhitespaceVisible ( content ) ;
1616
1612
}
1617
1613
Harness . IO . log ( content ) ;
1618
1614
}
@@ -2128,10 +2124,8 @@ namespace FourSlash {
2128
2124
2129
2125
public verifyCurrentFileContent ( text : string ) {
2130
2126
const actual = this . getFileContent ( this . activeFile . fileName ) ;
2131
- if ( normalizeNewLines ( actual ) !== normalizeNewLines ( text ) ) {
2132
- throw new Error ( "verifyCurrentFileContent\n" +
2133
- "\tExpected: \"" + TestState . makeWhitespaceVisible ( text ) + "\"\n" +
2134
- "\t Actual: \"" + TestState . makeWhitespaceVisible ( actual ) + "\"" ) ;
2127
+ if ( actual !== text ) {
2128
+ throw new Error ( `verifyCurrentFileContent failed:\n${ showTextDiff ( text , actual ) } ` ) ;
2135
2129
}
2136
2130
}
2137
2131
@@ -2305,11 +2299,11 @@ namespace FourSlash {
2305
2299
const actualText = this . rangeText ( ranges [ 0 ] ) ;
2306
2300
2307
2301
const result = includeWhiteSpace
2308
- ? normalizeNewLines ( actualText ) === normalizeNewLines ( expectedText )
2302
+ ? actualText === expectedText
2309
2303
: this . removeWhitespace ( actualText ) === this . removeWhitespace ( expectedText ) ;
2310
2304
2311
2305
if ( ! result ) {
2312
- this . raiseError ( `Actual text doesn't match expected text. Actual:\n' ${ actualText } '\nExpected:\n' ${ expectedText } ' ` ) ;
2306
+ this . raiseError ( `Actual range text doesn't match expected text.\n ${ showTextDiff ( expectedText , actualText ) } ` ) ;
2313
2307
}
2314
2308
}
2315
2309
@@ -2403,15 +2397,19 @@ namespace FourSlash {
2403
2397
const originalContent = scriptInfo . content ;
2404
2398
for ( const codeFix of codeFixes ) {
2405
2399
this . applyEdits ( codeFix . changes [ 0 ] . fileName , codeFix . changes [ 0 ] . textChanges , /*isFormattingEdit*/ false ) ;
2406
- actualTextArray . push ( this . normalizeNewlines ( this . rangeText ( ranges [ 0 ] ) ) ) ;
2400
+ let text = this . rangeText ( ranges [ 0 ] ) ;
2401
+ // TODO:GH#18445 (remove this line to see errors in many `importNameCodeFix` tests)
2402
+ text = text . replace ( / \r \n / g, "\n" ) ;
2403
+ actualTextArray . push ( text ) ;
2407
2404
scriptInfo . updateContent ( originalContent ) ;
2408
2405
}
2409
- const sortedExpectedArray = ts . map ( expectedTextArray , str => this . normalizeNewlines ( str ) ) . sort ( ) ;
2406
+ const sortedExpectedArray = expectedTextArray . sort ( ) ;
2410
2407
const sortedActualArray = actualTextArray . sort ( ) ;
2411
- if ( ! ts . arrayIsEqualTo ( sortedExpectedArray , sortedActualArray ) ) {
2412
- this . raiseError (
2413
- `Actual text array doesn't match expected text array. \nActual: \n'${ sortedActualArray . join ( "\n\n" ) } '\n---\nExpected: \n'${ sortedExpectedArray . join ( "\n\n" ) } '` ) ;
2414
- }
2408
+ ts . zipWith ( sortedExpectedArray , sortedActualArray , ( expected , actual , index ) => {
2409
+ if ( expected !== actual ) {
2410
+ this . raiseError ( `Import fix at index ${ index } doesn't match.\n${ showTextDiff ( expected , actual ) } ` ) ;
2411
+ }
2412
+ } ) ;
2415
2413
}
2416
2414
2417
2415
public verifyDocCommentTemplate ( expected : ts . TextInsertion | undefined ) {
@@ -2431,7 +2429,7 @@ namespace FourSlash {
2431
2429
}
2432
2430
2433
2431
if ( actual . newText !== expected . newText ) {
2434
- this . raiseError ( `${ name } failed - expected insertion:\n" ${ this . clarifyNewlines ( expected . newText ) } "\nactual insertion:\n" ${ this . clarifyNewlines ( actual . newText ) } " ` ) ;
2432
+ this . raiseError ( `${ name } failed for expected insertion.\n ${ showTextDiff ( expected . newText , actual . newText ) } ` ) ;
2435
2433
}
2436
2434
2437
2435
if ( actual . caretOffset !== expected . caretOffset ) {
@@ -2440,17 +2438,6 @@ namespace FourSlash {
2440
2438
}
2441
2439
}
2442
2440
2443
- private clarifyNewlines ( str : string ) {
2444
- return str . replace ( / \r ? \n / g, lineEnding => {
2445
- const representation = lineEnding === "\r\n" ? "CRLF" : "LF" ;
2446
- return "# - " + representation + lineEnding ;
2447
- } ) ;
2448
- }
2449
-
2450
- private normalizeNewlines ( str : string ) {
2451
- return str . replace ( / \r ? \n / g, "\n" ) ;
2452
- }
2453
-
2454
2441
public verifyBraceCompletionAtPosition ( negative : boolean , openingBrace : string ) {
2455
2442
2456
2443
const openBraceMap = ts . createMapFromTemplate < ts . CharacterCodes > ( {
@@ -2878,8 +2865,8 @@ namespace FourSlash {
2878
2865
}
2879
2866
const actualContent = this . getFileContent ( this . activeFile . fileName ) ;
2880
2867
2881
- if ( this . normalizeNewlines ( actualContent ) !== this . normalizeNewlines ( expectedContent ) ) {
2882
- this . raiseError ( `verifyFileAfterApplyingRefactors failed: expected: \n${ expectedContent } \nactual:\n ${ actualContent } ` ) ;
2868
+ if ( actualContent !== expectedContent ) {
2869
+ this . raiseError ( `verifyFileAfterApplyingRefactors failed:\n${ showTextDiff ( expectedContent , actualContent ) } ` ) ;
2883
2870
}
2884
2871
}
2885
2872
@@ -3014,10 +3001,6 @@ namespace FourSlash {
3014
3001
}
3015
3002
}
3016
3003
3017
- private static makeWhitespaceVisible ( text : string ) {
3018
- return text . replace ( / / g, "\u00B7" ) . replace ( / \r / g, "\u00B6" ) . replace ( / \n / g, "\u2193\n" ) . replace ( / \t / g, "\u2192\ " ) ;
3019
- }
3020
-
3021
3004
public setCancelled ( numberOfCalls : number ) : void {
3022
3005
this . cancellationToken . setCancelled ( numberOfCalls ) ;
3023
3006
}
@@ -3319,12 +3302,7 @@ ${code}
3319
3302
let column = 1 ;
3320
3303
3321
3304
const flush = ( lastSafeCharIndex : number ) => {
3322
- if ( lastSafeCharIndex === undefined ) {
3323
- output = output + content . substr ( lastNormalCharPosition ) ;
3324
- }
3325
- else {
3326
- output = output + content . substr ( lastNormalCharPosition , lastSafeCharIndex - lastNormalCharPosition ) ;
3327
- }
3305
+ output = output + content . substr ( lastNormalCharPosition , lastSafeCharIndex === undefined ? undefined : lastSafeCharIndex - lastNormalCharPosition ) ;
3328
3306
} ;
3329
3307
3330
3308
if ( content . length > 0 ) {
@@ -3511,6 +3489,27 @@ ${code}
3511
3489
function toArray < T > ( x : T | T [ ] ) : T [ ] {
3512
3490
return ts . isArray ( x ) ? x : [ x ] ;
3513
3491
}
3492
+
3493
+ function makeWhitespaceVisible ( text : string ) {
3494
+ return text . replace ( / / g, "\u00B7" ) . replace ( / \r / g, "\u00B6" ) . replace ( / \n / g, "\u2193\n" ) . replace ( / \t / g, "\u2192\ " ) ;
3495
+ }
3496
+
3497
+ function showTextDiff ( expected : string , actual : string ) : string {
3498
+ // Only show whitespace if the difference is whitespace-only.
3499
+ if ( differOnlyByWhitespace ( expected , actual ) ) {
3500
+ expected = makeWhitespaceVisible ( expected ) ;
3501
+ actual = makeWhitespaceVisible ( actual ) ;
3502
+ }
3503
+ return `Expected:\n${ expected } \nActual:${ actual } ` ;
3504
+ }
3505
+
3506
+ function differOnlyByWhitespace ( a : string , b : string ) {
3507
+ return stripWhitespace ( a ) === stripWhitespace ( b ) ;
3508
+ }
3509
+
3510
+ function stripWhitespace ( s : string ) : string {
3511
+ return s . replace ( / \s / g, "" ) ;
3512
+ }
3514
3513
}
3515
3514
3516
3515
namespace FourSlashInterface {
@@ -4143,15 +4142,15 @@ namespace FourSlashInterface {
4143
4142
}
4144
4143
4145
4144
public printCurrentFileState ( ) {
4146
- this . state . printCurrentFileState ( /*makeWhitespaceVisible */ false , /*makeCaretVisible*/ true ) ;
4145
+ this . state . printCurrentFileState ( /*showWhitespace */ false , /*makeCaretVisible*/ true ) ;
4147
4146
}
4148
4147
4149
4148
public printCurrentFileStateWithWhitespace ( ) {
4150
- this . state . printCurrentFileState ( /*makeWhitespaceVisible */ true , /*makeCaretVisible*/ true ) ;
4149
+ this . state . printCurrentFileState ( /*showWhitespace */ true , /*makeCaretVisible*/ true ) ;
4151
4150
}
4152
4151
4153
4152
public printCurrentFileStateWithoutCaret ( ) {
4154
- this . state . printCurrentFileState ( /*makeWhitespaceVisible */ false , /*makeCaretVisible*/ false ) ;
4153
+ this . state . printCurrentFileState ( /*showWhitespace */ false , /*makeCaretVisible*/ false ) ;
4155
4154
}
4156
4155
4157
4156
public printCurrentQuickInfo ( ) {
0 commit comments