@@ -308,18 +308,16 @@ func TestDiffLinesToChars(t *testing.T) {
308
308
309
309
ExpectedChars1 string
310
310
ExpectedChars2 string
311
- ExpectedLines [] string
311
+ ExpectedLines LineMap
312
312
}
313
313
314
314
dmp := New ()
315
315
316
316
for i , tc := range []TestCase {
317
- {"" , "alpha\r \n beta\r \n \r \n \r \n " , "" , "1,2,3,3 " , [ ]string {"" , "alpha\r \n " , "beta\r \n " , "\r \n " }},
318
- {"a" , "b" , "1 " , "2 " , [ ]string {"" , "a" , "b" }},
317
+ {"" , "alpha\r \n beta\r \n \r \n \r \n " , "" , "\u0001 \u0002 \u0003 \u0003 " , map [ rune ]string {1 : "alpha\r \n " , 2 : "beta\r \n " , 3 : "\r \n " }},
318
+ {"a" , "b" , "\u0001 " , "\u0002 " , map [ rune ]string {1 : "a" , 2 : "b" }},
319
319
// Omit final newline.
320
- {"alpha\n beta\n alpha" , "" , "1,2,3" , "" , []string {"" , "alpha\n " , "beta\n " , "alpha" }},
321
- // Same lines in Text1 and Text2
322
- {"abc\n defg\n 12345\n " , "abc\n def\n 12345\n 678" , "1,2,3" , "1,4,3,5" , []string {"" , "abc\n " , "defg\n " , "12345\n " , "def\n " , "678" }},
320
+ {"alpha\n beta\n alpha" , "" , "\u0001 \u0002 \u0003 " , "" , map [rune ]string {1 : "alpha\n " , 2 : "beta\n " , 3 : "alpha" }},
323
321
} {
324
322
actualChars1 , actualChars2 , actualLines := dmp .DiffLinesToChars (tc .Text1 , tc .Text2 )
325
323
assert .Equal (t , tc .ExpectedChars1 , actualChars1 , fmt .Sprintf ("Test case #%d, %#v" , i , tc ))
@@ -329,28 +327,28 @@ func TestDiffLinesToChars(t *testing.T) {
329
327
330
328
// More than 256 to reveal any 8-bit limitations.
331
329
n := 300
332
- lineList := []string {
333
- "" , // Account for the initial empty element of the lines array.
334
- }
335
- var charList []string
330
+ var lines []string
331
+ lineMap := LineMap {}
332
+ var charList []rune
336
333
for x := 1 ; x < n + 1 ; x ++ {
337
- lineList = append (lineList , strconv .Itoa (x )+ "\n " )
338
- charList = append (charList , strconv .Itoa (x ))
334
+ line := strconv .Itoa (x ) + "\n "
335
+ lines = append (lines , line )
336
+ lineMap [rune (x )] = line
337
+ charList = append (charList , rune (x ))
339
338
}
340
- lines := strings .Join (lineList , "" )
341
- chars := strings .Join (charList [:], "," )
342
- assert .Equal (t , n , len (strings .Split (chars , "," )))
339
+ chars := string (charList )
340
+ assert .Equal (t , n , utf8 .RuneCountInString (chars ))
343
341
344
- actualChars1 , actualChars2 , actualLines := dmp .DiffLinesToChars (lines , "" )
342
+ actualChars1 , actualChars2 , actualLines := dmp .DiffLinesToChars (strings . Join ( lines , "" ) , "" )
345
343
assert .Equal (t , chars , actualChars1 )
346
344
assert .Equal (t , "" , actualChars2 )
347
- assert .Equal (t , lineList , actualLines )
345
+ assert .Equal (t , lineMap , actualLines )
348
346
}
349
347
350
348
func TestDiffCharsToLines (t * testing.T ) {
351
349
type TestCase struct {
352
350
Diffs []Diff
353
- Lines [ ]string
351
+ Lines map [ rune ]string
354
352
355
353
Expected []Diff
356
354
}
@@ -360,10 +358,10 @@ func TestDiffCharsToLines(t *testing.T) {
360
358
for i , tc := range []TestCase {
361
359
{
362
360
Diffs : []Diff {
363
- {DiffEqual , "1,2,1 " },
364
- {DiffInsert , "2,1,2 " },
361
+ {DiffEqual , "\u0001 \u0002 \u0001 " },
362
+ {DiffInsert , "\u0002 \u0001 \u0002 " },
365
363
},
366
- Lines : [ ]string {"" , "alpha\n " , "beta\n " },
364
+ Lines : map [ rune ]string {1 : "alpha\n " , 2 : "beta\n " },
367
365
368
366
Expected : []Diff {
369
367
{DiffEqual , "alpha\n beta\n alpha\n " },
@@ -377,19 +375,19 @@ func TestDiffCharsToLines(t *testing.T) {
377
375
378
376
// More than 256 to reveal any 8-bit limitations.
379
377
n := 300
380
- lineList := []string {
381
- "" , // Account for the initial empty element of the lines array.
382
- }
383
- charList := []string {}
378
+ var lines []string
379
+ lineMap := LineMap {}
380
+ charList := []rune {}
384
381
for x := 1 ; x <= n ; x ++ {
385
- lineList = append (lineList , strconv .Itoa (x )+ "\n " )
386
- charList = append (charList , strconv .Itoa (x ))
382
+ line := strconv .Itoa (x ) + "\n "
383
+ lines = append (lines , line )
384
+ lineMap [rune (x )] = line
385
+ charList = append (charList , rune (x ))
387
386
}
388
387
assert .Equal (t , n , len (charList ))
389
- chars := strings .Join (charList [:], "," )
390
388
391
- actual := dmp .DiffCharsToLines ([]Diff {Diff {DiffDelete , chars }}, lineList )
392
- assert .Equal (t , []Diff {Diff {DiffDelete , strings .Join (lineList , "" )}}, actual )
389
+ actual := dmp .DiffCharsToLines ([]Diff {Diff {DiffDelete , string ( charList ) }}, lineMap )
390
+ assert .Equal (t , []Diff {Diff {DiffDelete , strings .Join (lines , "" )}}, actual )
393
391
}
394
392
395
393
func TestDiffCleanupMerge (t * testing.T ) {
@@ -826,43 +824,6 @@ func TestDiffCleanupSemantic(t *testing.T) {
826
824
{DiffDelete , " deal" },
827
825
},
828
826
},
829
- {
830
- "Taken from python / CPP library" ,
831
- []Diff {
832
- {DiffInsert , "星球大戰:新的希望 " },
833
- {DiffEqual , "star wars: " },
834
- {DiffDelete , "episodio iv - un" },
835
- {DiffEqual , "a n" },
836
- {DiffDelete , "u" },
837
- {DiffEqual , "e" },
838
- {DiffDelete , "va" },
839
- {DiffInsert , "w" },
840
- {DiffEqual , " " },
841
- {DiffDelete , "es" },
842
- {DiffInsert , "ho" },
843
- {DiffEqual , "pe" },
844
- {DiffDelete , "ranza" },
845
- },
846
- []Diff {
847
- {DiffInsert , "星球大戰:新的希望 " },
848
- {DiffEqual , "star wars: " },
849
- {DiffDelete , "episodio iv - una nueva esperanza" },
850
- {DiffInsert , "a new hope" },
851
- },
852
- },
853
- {
854
- "panic" ,
855
- []Diff {
856
- {DiffInsert , "킬러 인 " },
857
- {DiffEqual , "리커버리" },
858
- {DiffDelete , " 보이즈" },
859
- },
860
- []Diff {
861
- {DiffInsert , "킬러 인 " },
862
- {DiffEqual , "리커버리" },
863
- {DiffDelete , " 보이즈" },
864
- },
865
- },
866
827
} {
867
828
actual := dmp .DiffCleanupSemantic (tc .Diffs )
868
829
assert .Equal (t , tc .Expected , actual , fmt .Sprintf ("Test case #%d, %s" , i , tc .Name ))
@@ -1531,3 +1492,86 @@ func BenchmarkDiffMainRunesLargeDiffLines(b *testing.B) {
1531
1492
diffs = dmp .DiffCharsToLines (diffs , linearray )
1532
1493
}
1533
1494
}
1495
+
1496
+ func TestLineDiff (t * testing.T ) {
1497
+ t .Run ("VeryLarge" , func (t * testing.T ) {
1498
+ var beforeBuf , afterBuf bytes.Buffer
1499
+
1500
+ for i := 0 ; i <= surrogateMax + 1 ; i ++ {
1501
+ beforeBuf .WriteString (fmt .Sprintf ("%d\n " , i ))
1502
+ afterBuf .WriteString (fmt .Sprintf ("%d\n " , i / 2 ))
1503
+ }
1504
+
1505
+ before , after := beforeBuf .String (), afterBuf .String ()
1506
+
1507
+ diff := New ().DiffMain (before , after , true )
1508
+ checkDiffText (t , before , after , diff )
1509
+ })
1510
+
1511
+ t .Run ("Chars" , func (t * testing.T ) {
1512
+ before := `1
1513
+ 2
1514
+ 3
1515
+ 4
1516
+ 5
1517
+ 6
1518
+ 7
1519
+ 8
1520
+ 9
1521
+ `
1522
+ after := `10
1523
+ `
1524
+
1525
+ dmp := New ()
1526
+ txt1 , txt2 , lines := dmp .DiffLinesToChars (string (before ), string (after ))
1527
+ diff := dmp .DiffMain (txt1 , txt2 , false )
1528
+ diff = dmp .DiffCharsToLines (diff , lines )
1529
+
1530
+ checkDiffText (t , before , after , diff )
1531
+ })
1532
+
1533
+ t .Run ("Runes" , func (t * testing.T ) {
1534
+ before := `1
1535
+ 2
1536
+ 3
1537
+ 4
1538
+ 5
1539
+ 6
1540
+ 7
1541
+ 8
1542
+ 9
1543
+ `
1544
+ after := `10
1545
+ `
1546
+
1547
+ dmp := New ()
1548
+ txt1 , txt2 , lines := dmp .DiffLinesToRunes (string (before ), string (after ))
1549
+ diff := dmp .DiffMainRunes (txt1 , txt2 , false )
1550
+ diff = dmp .DiffCharsToLines (diff , lines )
1551
+
1552
+ checkDiffText (t , before , after , diff )
1553
+ })
1554
+ }
1555
+
1556
+ func checkDiffText (t * testing.T , before , after string , diff []Diff ) {
1557
+ t .Helper ()
1558
+ var foundBefore , foundAfter string
1559
+ for _ , d := range diff {
1560
+ switch d .Type {
1561
+ case DiffEqual :
1562
+ foundBefore += d .Text
1563
+ foundAfter += d .Text
1564
+ case DiffDelete :
1565
+ foundBefore += d .Text
1566
+ case DiffInsert :
1567
+ foundAfter += d .Text
1568
+ }
1569
+ }
1570
+
1571
+ if foundBefore != before {
1572
+ t .Errorf ("Expected before %q; found %q" , before , foundBefore )
1573
+ }
1574
+ if foundAfter != after {
1575
+ t .Errorf ("Expected after %q; found %q" , after , foundAfter )
1576
+ }
1577
+ }
0 commit comments