@@ -492,6 +492,136 @@ function testDiffDelta() {
492
492
// Convert delta string into a diff.
493
493
assertEquivalent ( diffs , dmp . diff_fromDelta ( text1 , delta ) ) ;
494
494
495
+ diffs = [ [ DIFF_EQUAL , '\ud83d\ude4b\ud83d' ] , [ DIFF_INSERT , '\ude4c\ud83d' ] , [ DIFF_EQUAL , '\ude4b' ] ] ;
496
+ try {
497
+ delta = dmp . diff_toDelta ( diffs ) ;
498
+ assertEquals ( '=2\t+%F0%9F%99%8C\t=2' , delta ) ;
499
+ } catch ( e ) {
500
+ assertEquals ( false , true ) ;
501
+ }
502
+
503
+ ( function ( ) {
504
+ const originalText = `U+1F17x 🅰️ 🅱️ 🅾️ 🅿️ safhawifhkw
505
+ U+1F18x 🆎
506
+ 0 1 2 3 4 5 6 7 8 9 A B C D E F
507
+ U+1F19x 🆑 🆒 🆓 🆔 🆕 🆖 🆗 🆘 🆙 🆚
508
+ U+1F20x 🈁 🈂️ sfss.,_||saavvvbbds
509
+ U+1F21x 🈚
510
+ U+1F22x 🈯
511
+ U+1F23x 🈲 🈳 🈴 🈵 🈶 🈷️ 🈸 🈹 🈺
512
+ U+1F25x 🉐 🉑
513
+ U+1F30x 🌀 🌁 🌂 🌃 🌄 🌅 🌆 🌇 🌈 🌉 🌊 🌋 🌌 🌍 🌎 🌏
514
+ U+1F31x 🌐 🌑 🌒 🌓 🌔 🌕 🌖 🌗 🌘 🌙 🌚 🌛 🌜 🌝 🌞 ` ;
515
+
516
+ // applies some random edits to string and returns new, edited string
517
+ function applyRandomTextEdit ( text ) {
518
+ let textArr = [ ...text ] ;
519
+ let r = Math . random ( ) ;
520
+ if ( r < 1 / 3 ) { // swap
521
+ let swapCount = Math . floor ( Math . random ( ) * 5 ) ;
522
+ for ( let i = 0 ; i < swapCount ; i ++ ) {
523
+ let swapPos1 = Math . floor ( Math . random ( ) * textArr . length ) ;
524
+ let swapPos2 = Math . floor ( Math . random ( ) * textArr . length ) ;
525
+ let char1 = textArr [ swapPos1 ] ;
526
+ let char2 = textArr [ swapPos2 ] ;
527
+ textArr [ swapPos1 ] = char2 ;
528
+ textArr [ swapPos2 ] = char1 ;
529
+ }
530
+ } else if ( r < 2 / 3 ) { // remove
531
+ let removeCount = Math . floor ( Math . random ( ) * 5 ) ;
532
+ for ( let i = 0 ; i < removeCount ; i ++ ) {
533
+ let removePos = Math . floor ( Math . random ( ) * textArr . length ) ;
534
+ textArr [ removePos ] = "" ;
535
+ }
536
+ } else { // add
537
+ let addCount = Math . floor ( Math . random ( ) * 5 ) ;
538
+ for ( let i = 0 ; i < addCount ; i ++ ) {
539
+ let addPos = Math . floor ( Math . random ( ) * textArr . length ) ;
540
+ let addFromPos = Math . floor ( Math . random ( ) * textArr . length ) ;
541
+ textArr [ addPos ] = textArr [ addPos ] + textArr [ addFromPos ] ;
542
+ }
543
+ }
544
+ return textArr . join ( "" ) ;
545
+ }
546
+
547
+ for ( let i = 0 ; i < 1000 ; i ++ ) {
548
+ newText = applyRandomTextEdit ( originalText ) ;
549
+ dmp . diff_toDelta ( dmp . diff_main ( originalText , newText ) ) ;
550
+ }
551
+ } ) ( ) ;
552
+
553
+ // Unicode - splitting surrogates
554
+ try {
555
+ assertEquivalent (
556
+ dmp . diff_toDelta ( [ [ DIFF_INSERT , '\ud83c\udd71' ] , [ DIFF_EQUAL , '\ud83c\udd70\ud83c\udd71' ] ] ) ,
557
+ dmp . diff_toDelta ( dmp . diff_main ( '\ud83c\udd70\ud83c\udd71' , '\ud83c\udd71\ud83c\udd70\ud83c\udd71' ) )
558
+ ) ;
559
+ } catch ( e ) {
560
+ assertEquals ( 'Inserting similar surrogate pair at beginning' , 'crashed' ) ;
561
+ }
562
+
563
+ try {
564
+ assertEquivalent (
565
+ dmp . diff_toDelta ( [ [ DIFF_EQUAL , '\ud83c\udd70' ] , [ DIFF_INSERT , '\ud83c\udd70' ] , [ DIFF_EQUAL , '\ud83c\udd71' ] ] ) ,
566
+ dmp . diff_toDelta ( dmp . diff_main ( '\ud83c\udd70\ud83c\udd71' , '\ud83c\udd70\ud83c\udd70\ud83c\udd71' ) )
567
+ ) ;
568
+ } catch ( e ) {
569
+ assertEquals ( 'Inserting similar surrogate pair in the middle' , 'crashed' ) ;
570
+ }
571
+
572
+ try {
573
+ assertEquivalent (
574
+ dmp . diff_toDelta ( [ [ DIFF_DELETE , '\ud83c\udd71' ] , [ DIFF_EQUAL , '\ud83c\udd70\ud83c\udd71' ] ] ) ,
575
+ dmp . diff_toDelta ( dmp . diff_main ( '\ud83c\udd71\ud83c\udd70\ud83c\udd71' , '\ud83c\udd70\ud83c\udd71' ) )
576
+ ) ;
577
+ } catch ( e ) {
578
+ assertEquals ( 'Deleting similar surrogate pair at the beginning' , 'crashed' ) ;
579
+ }
580
+
581
+ try {
582
+ assertEquivalent (
583
+ dmp . diff_toDelta ( [ [ DIFF_EQUAL , '\ud83c\udd70' ] , [ DIFF_DELETE , '\ud83c\udd72' ] , [ DIFF_EQUAL , '\ud83c\udd71' ] ] ) ,
584
+ dmp . diff_toDelta ( dmp . diff_main ( '\ud83c\udd70\ud83c\udd72\ud83c\udd71' , '\ud83c\udd70\ud83c\udd71' ) )
585
+ ) ;
586
+ } catch ( e ) {
587
+ assertEquals ( 'Deleting similar surrogate pair in the middle' , 'crashed' ) ;
588
+ }
589
+
590
+ try {
591
+ assertEquivalent (
592
+ dmp . diff_toDelta ( [ [ DIFF_DELETE , '\ud83c\udd70' ] , [ DIFF_INSERT , '\ud83c\udd71' ] ] ) ,
593
+ dmp . diff_toDelta ( [ [ DIFF_EQUAL , '\ud83c' ] , [ DIFF_DELETE , '\udd70' ] , [ DIFF_INSERT , '\udd71' ] ] ) ,
594
+ ) ;
595
+ } catch ( e ) {
596
+ assertEquals ( 'Swap surrogate pair' , 'crashed' ) ;
597
+ }
598
+
599
+ try {
600
+ assertEquivalent (
601
+ dmp . diff_toDelta ( [ [ DIFF_INSERT , '\ud83c\udd70' ] , [ DIFF_DELETE , '\ud83c\udd71' ] ] ) ,
602
+ dmp . diff_toDelta ( [ [ DIFF_EQUAL , '\ud83c' ] , [ DIFF_INSERT , '\udd70' ] , [ DIFF_DELETE , '\udd71' ] ] ) ,
603
+ ) ;
604
+ } catch ( e ) {
605
+ assertEquals ( 'Swap surrogate pair' , 'crashed' ) ;
606
+ }
607
+
608
+ // Empty diff groups
609
+ assertEquivalent (
610
+ dmp . diff_toDelta ( [ [ DIFF_EQUAL , 'abcdef' ] , [ DIFF_DELETE , '' ] , [ DIFF_INSERT , 'ghijk' ] ] ) ,
611
+ dmp . diff_toDelta ( [ [ DIFF_EQUAL , 'abcdef' ] , [ DIFF_INSERT , 'ghijk' ] ] ) ,
612
+ ) ;
613
+
614
+ // Different versions of the library may have created deltas with
615
+ // half of a surrogate pair encoded as if it were valid UTF-8
616
+ try {
617
+ assertEquivalent (
618
+ dmp . diff_toDelta ( dmp . diff_fromDelta ( '\ud83c\udd70' , '-2\t+%F0%9F%85%B1' ) ) ,
619
+ dmp . diff_toDelta ( dmp . diff_fromDelta ( '\ud83c\udd70' , '=1\t-1\t+%ED%B5%B1' ) )
620
+ ) ;
621
+ } catch ( e ) {
622
+ assertEquals ( 'Decode UTF8-encoded surrogate half' , 'crashed' ) ;
623
+ }
624
+
495
625
// Verify pool of unchanged characters.
496
626
diffs = [ [ DIFF_INSERT , 'A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + $ , # ' ] ] ;
497
627
var text2 = dmp . diff_text2 ( diffs ) ;
@@ -963,4 +1093,4 @@ function testPatchApply() {
963
1093
patches = dmp . patch_make ( 'y' , 'y123' ) ;
964
1094
results = dmp . patch_apply ( patches , 'x' ) ;
965
1095
assertEquivalent ( [ 'x123' , [ true ] ] , results ) ;
966
- }
1096
+ }
0 commit comments