19
19
20
20
// If expected and actual are the equivalent, pass the test.
21
21
function assertEquivalent ( msg , expected , actual ) {
22
- if ( typeof actual == 'undefined' ) {
23
- // msg is optional.
24
- actual = expected ;
25
- expected = msg ;
26
- msg = 'Expected: \'' + expected + '\' Actual: \'' + actual + '\'' ;
27
- }
28
- if ( _equivalent ( expected , actual ) ) {
29
- return assertEquals ( msg , String ( expected ) , String ( actual ) ) ;
30
- } else {
31
- return assertEquals ( msg , expected , actual ) ;
32
- }
22
+ if ( typeof actual == 'undefined' ) {
23
+ // msg is optional.
24
+ actual = expected ;
25
+ expected = msg ;
26
+ msg = 'Expected: \'' + expected + '\' Actual: \'' + actual + '\'' ;
27
+ }
28
+ if ( _equivalent ( expected , actual ) ) {
29
+ return assertEquals ( msg , String ( expected ) , String ( actual ) ) ;
30
+ } else {
31
+ return assertEquals ( msg , expected , actual ) ;
32
+ }
33
33
}
34
34
35
35
36
36
// Are a and b the equivalent? -- Recursive.
37
37
function _equivalent ( a , b ) {
38
- if ( a == b ) {
39
- return true ;
40
- }
41
- if ( typeof a == 'object' && typeof b == 'object' && a !== null && b !== null ) {
42
- if ( a . toString ( ) != b . toString ( ) ) {
43
- return false ;
44
- }
45
- for ( var p in a ) {
46
- if ( a . hasOwnProperty ( p ) && ! _equivalent ( a [ p ] , b [ p ] ) ) {
47
- return false ;
48
- }
49
- }
50
- for ( var p in b ) {
51
- if ( a . hasOwnProperty ( p ) && ! _equivalent ( a [ p ] , b [ p ] ) ) {
52
- return false ;
53
- }
54
- }
55
- return true ;
56
- }
57
- return false ;
38
+ if ( a == b ) {
39
+ return true ;
40
+ }
41
+ if ( typeof a == 'object' && typeof b == 'object' && a !== null && b !== null ) {
42
+ if ( a . toString ( ) != b . toString ( ) ) {
43
+ return false ;
44
+ }
45
+ for ( var p in a ) {
46
+ if ( a . hasOwnProperty ( p ) && ! _equivalent ( a [ p ] , b [ p ] ) ) {
47
+ return false ;
48
+ }
49
+ }
50
+ for ( var p in b ) {
51
+ if ( a . hasOwnProperty ( p ) && ! _equivalent ( a [ p ] , b [ p ] ) ) {
52
+ return false ;
53
+ }
54
+ }
55
+ return true ;
56
+ }
57
+ return false ;
58
58
}
59
59
60
60
61
61
function diff_rebuildtexts ( diffs ) {
62
- // Construct the two texts which made up the diff originally.
63
- var text1 = '' ;
64
- var text2 = '' ;
65
- for ( var x = 0 ; x < diffs . length ; x ++ ) {
66
- if ( diffs [ x ] [ 0 ] != DIFF_INSERT ) {
67
- text1 += diffs [ x ] [ 1 ] ;
68
- }
69
- if ( diffs [ x ] [ 0 ] != DIFF_DELETE ) {
70
- text2 += diffs [ x ] [ 1 ] ;
71
- }
72
- }
73
- return [ text1 , text2 ] ;
62
+ // Construct the two texts which made up the diff originally.
63
+ var text1 = '' ;
64
+ var text2 = '' ;
65
+ for ( var x = 0 ; x < diffs . length ; x ++ ) {
66
+ if ( diffs [ x ] [ 0 ] != DIFF_INSERT ) {
67
+ text1 += diffs [ x ] [ 1 ] ;
68
+ }
69
+ if ( diffs [ x ] [ 0 ] != DIFF_DELETE ) {
70
+ text2 += diffs [ x ] [ 1 ] ;
71
+ }
72
+ }
73
+ return [ text1 , text2 ] ;
74
74
}
75
75
76
76
var dmp = new diff_match_patch ( ) ;
@@ -80,428 +80,428 @@ var dmp = new diff_match_patch();
80
80
81
81
82
82
function testDiffCommonPrefix ( ) {
83
- // Detect any common prefix.
84
- // Null case.
85
- assertEquals ( 0 , dmp . diff_commonPrefix ( 'abc' , 'xyz' ) ) ;
86
-
87
- // Non-null case.
88
- assertEquals ( 4 , dmp . diff_commonPrefix ( '1234abcdef' , '1234xyz' ) ) ;
89
-
90
- // Whole case.
91
- assertEquals ( 4 , dmp . diff_commonPrefix ( '1234' , '1234xyz' ) ) ;
83
+ // Detect any common prefix.
84
+ // Null case.
85
+ assertEquals ( 0 , dmp . diff_commonPrefix ( 'abc' , 'xyz' ) ) ;
86
+
87
+ // Non-null case.
88
+ assertEquals ( 4 , dmp . diff_commonPrefix ( '1234abcdef' , '1234xyz' ) ) ;
89
+
90
+ // Whole case.
91
+ assertEquals ( 4 , dmp . diff_commonPrefix ( '1234' , '1234xyz' ) ) ;
92
92
}
93
93
94
94
function testDiffCommonSuffix ( ) {
95
- // Detect any common suffix.
96
- // Null case.
97
- assertEquals ( 0 , dmp . diff_commonSuffix ( 'abc' , 'xyz' ) ) ;
98
-
99
- // Non-null case.
100
- assertEquals ( 4 , dmp . diff_commonSuffix ( 'abcdef1234' , 'xyz1234' ) ) ;
101
-
102
- // Whole case.
103
- assertEquals ( 4 , dmp . diff_commonSuffix ( '1234' , 'xyz1234' ) ) ;
95
+ // Detect any common suffix.
96
+ // Null case.
97
+ assertEquals ( 0 , dmp . diff_commonSuffix ( 'abc' , 'xyz' ) ) ;
98
+
99
+ // Non-null case.
100
+ assertEquals ( 4 , dmp . diff_commonSuffix ( 'abcdef1234' , 'xyz1234' ) ) ;
101
+
102
+ // Whole case.
103
+ assertEquals ( 4 , dmp . diff_commonSuffix ( '1234' , 'xyz1234' ) ) ;
104
104
}
105
105
106
106
function testDiffCommonOverlap ( ) {
107
- // Detect any suffix/prefix overlap.
108
- // Null case.
109
- assertEquals ( 0 , dmp . diff_commonOverlap_ ( '' , 'abcd' ) ) ;
110
-
111
- // Whole case.
112
- assertEquals ( 3 , dmp . diff_commonOverlap_ ( 'abc' , 'abcd' ) ) ;
113
-
114
- // No overlap.
115
- assertEquals ( 0 , dmp . diff_commonOverlap_ ( '123456' , 'abcd' ) ) ;
116
-
117
- // Overlap.
118
- assertEquals ( 3 , dmp . diff_commonOverlap_ ( '123456xxx' , 'xxxabcd' ) ) ;
119
-
120
- // Unicode.
121
- // Some overly clever languages (C#) may treat ligatures as equal to their
122
- // component letters. E.g. U+FB01 == 'fi'
123
- assertEquals ( 0 , dmp . diff_commonOverlap_ ( 'fi' , '\ufb01i' ) ) ;
107
+ // Detect any suffix/prefix overlap.
108
+ // Null case.
109
+ assertEquals ( 0 , dmp . diff_commonOverlap_ ( '' , 'abcd' ) ) ;
110
+
111
+ // Whole case.
112
+ assertEquals ( 3 , dmp . diff_commonOverlap_ ( 'abc' , 'abcd' ) ) ;
113
+
114
+ // No overlap.
115
+ assertEquals ( 0 , dmp . diff_commonOverlap_ ( '123456' , 'abcd' ) ) ;
116
+
117
+ // Overlap.
118
+ assertEquals ( 3 , dmp . diff_commonOverlap_ ( '123456xxx' , 'xxxabcd' ) ) ;
119
+
120
+ // Unicode.
121
+ // Some overly clever languages (C#) may treat ligatures as equal to their
122
+ // component letters. E.g. U+FB01 == 'fi'
123
+ assertEquals ( 0 , dmp . diff_commonOverlap_ ( 'fi' , '\ufb01i' ) ) ;
124
124
}
125
125
126
126
function testDiffHalfMatch ( ) {
127
- // Detect a halfmatch.
128
- dmp . Diff_Timeout = 1 ;
129
- // No match.
130
- assertEquals ( null , dmp . diff_halfMatch_ ( '1234567890' , 'abcdef' ) ) ;
131
-
132
- assertEquals ( null , dmp . diff_halfMatch_ ( '12345' , '23' ) ) ;
133
-
134
- // Single Match.
135
- assertEquivalent ( [ '12' , '90' , 'a' , 'z' , '345678' ] , dmp . diff_halfMatch_ ( '1234567890' , 'a345678z' ) ) ;
136
-
137
- assertEquivalent ( [ 'a' , 'z' , '12' , '90' , '345678' ] , dmp . diff_halfMatch_ ( 'a345678z' , '1234567890' ) ) ;
138
-
139
- assertEquivalent ( [ 'abc' , 'z' , '1234' , '0' , '56789' ] , dmp . diff_halfMatch_ ( 'abc56789z' , '1234567890' ) ) ;
140
-
141
- assertEquivalent ( [ 'a' , 'xyz' , '1' , '7890' , '23456' ] , dmp . diff_halfMatch_ ( 'a23456xyz' , '1234567890' ) ) ;
142
-
143
- // Multiple Matches.
144
- assertEquivalent ( [ '12123' , '123121' , 'a' , 'z' , '1234123451234' ] , dmp . diff_halfMatch_ ( '121231234123451234123121' , 'a1234123451234z' ) ) ;
145
-
146
- assertEquivalent ( [ '' , '-=-=-=-=-=' , 'x' , '' , 'x-=-=-=-=-=-=-=' ] , dmp . diff_halfMatch_ ( 'x-=-=-=-=-=-=-=-=-=-=-=-=' , 'xx-=-=-=-=-=-=-=' ) ) ;
147
-
148
- assertEquivalent ( [ '-=-=-=-=-=' , '' , '' , 'y' , '-=-=-=-=-=-=-=y' ] , dmp . diff_halfMatch_ ( '-=-=-=-=-=-=-=-=-=-=-=-=y' , '-=-=-=-=-=-=-=yy' ) ) ;
149
-
150
- // Non-optimal halfmatch.
151
- // Optimal diff would be -q+x=H-i+e=lloHe+Hu=llo-Hew+y not -qHillo+x=HelloHe-w+Hulloy
152
- assertEquivalent ( [ 'qHillo' , 'w' , 'x' , 'Hulloy' , 'HelloHe' ] , dmp . diff_halfMatch_ ( 'qHilloHelloHew' , 'xHelloHeHulloy' ) ) ;
153
-
154
- // Optimal no halfmatch.
155
- dmp . Diff_Timeout = 0 ;
156
- assertEquals ( null , dmp . diff_halfMatch_ ( 'qHilloHelloHew' , 'xHelloHeHulloy' ) ) ;
127
+ // Detect a halfmatch.
128
+ dmp . Diff_Timeout = 1 ;
129
+ // No match.
130
+ assertEquals ( null , dmp . diff_halfMatch_ ( '1234567890' , 'abcdef' ) ) ;
131
+
132
+ assertEquals ( null , dmp . diff_halfMatch_ ( '12345' , '23' ) ) ;
133
+
134
+ // Single Match.
135
+ assertEquivalent ( [ '12' , '90' , 'a' , 'z' , '345678' ] , dmp . diff_halfMatch_ ( '1234567890' , 'a345678z' ) ) ;
136
+
137
+ assertEquivalent ( [ 'a' , 'z' , '12' , '90' , '345678' ] , dmp . diff_halfMatch_ ( 'a345678z' , '1234567890' ) ) ;
138
+
139
+ assertEquivalent ( [ 'abc' , 'z' , '1234' , '0' , '56789' ] , dmp . diff_halfMatch_ ( 'abc56789z' , '1234567890' ) ) ;
140
+
141
+ assertEquivalent ( [ 'a' , 'xyz' , '1' , '7890' , '23456' ] , dmp . diff_halfMatch_ ( 'a23456xyz' , '1234567890' ) ) ;
142
+
143
+ // Multiple Matches.
144
+ assertEquivalent ( [ '12123' , '123121' , 'a' , 'z' , '1234123451234' ] , dmp . diff_halfMatch_ ( '121231234123451234123121' , 'a1234123451234z' ) ) ;
145
+
146
+ assertEquivalent ( [ '' , '-=-=-=-=-=' , 'x' , '' , 'x-=-=-=-=-=-=-=' ] , dmp . diff_halfMatch_ ( 'x-=-=-=-=-=-=-=-=-=-=-=-=' , 'xx-=-=-=-=-=-=-=' ) ) ;
147
+
148
+ assertEquivalent ( [ '-=-=-=-=-=' , '' , '' , 'y' , '-=-=-=-=-=-=-=y' ] , dmp . diff_halfMatch_ ( '-=-=-=-=-=-=-=-=-=-=-=-=y' , '-=-=-=-=-=-=-=yy' ) ) ;
149
+
150
+ // Non-optimal halfmatch.
151
+ // Optimal diff would be -q+x=H-i+e=lloHe+Hu=llo-Hew+y not -qHillo+x=HelloHe-w+Hulloy
152
+ assertEquivalent ( [ 'qHillo' , 'w' , 'x' , 'Hulloy' , 'HelloHe' ] , dmp . diff_halfMatch_ ( 'qHilloHelloHew' , 'xHelloHeHulloy' ) ) ;
153
+
154
+ // Optimal no halfmatch.
155
+ dmp . Diff_Timeout = 0 ;
156
+ assertEquals ( null , dmp . diff_halfMatch_ ( 'qHilloHelloHew' , 'xHelloHeHulloy' ) ) ;
157
157
}
158
158
159
159
function testDiffLinesToChars ( ) {
160
- function assertLinesToCharsResultEquals ( a , b ) {
161
- assertEquals ( a . chars1 , b . chars1 ) ;
162
- assertEquals ( a . chars2 , b . chars2 ) ;
163
- assertEquivalent ( a . lineArray , b . lineArray ) ;
164
- }
165
-
166
- // Convert lines down to characters.
167
- assertLinesToCharsResultEquals ( { chars1 : '\x01\x02\x01' , chars2 : '\x02\x01\x02' , lineArray : [ '' , 'alpha\n' , 'beta\n' ] } , dmp . diff_linesToChars_ ( 'alpha\nbeta\nalpha\n' , 'beta\nalpha\nbeta\n' ) ) ;
168
-
169
- assertLinesToCharsResultEquals ( { chars1 : '' , chars2 : '\x01\x02\x03\x03' , lineArray : [ '' , 'alpha\r\n' , 'beta\r\n' , '\r\n' ] } , dmp . diff_linesToChars_ ( '' , 'alpha\r\nbeta\r\n\r\n\r\n' ) ) ;
170
-
171
- assertLinesToCharsResultEquals ( { chars1 : '\x01' , chars2 : '\x02' , lineArray : [ '' , 'a' , 'b' ] } , dmp . diff_linesToChars_ ( 'a' , 'b' ) ) ;
172
-
173
- // More than 256 to reveal any 8-bit limitations.
174
- var n = 300 ;
175
- var lineList = [ ] ;
176
- var charList = [ ] ;
177
- for ( var i = 1 ; i < n + 1 ; i ++ ) {
178
- lineList [ i - 1 ] = i + '\n' ;
179
- charList [ i - 1 ] = String . fromCharCode ( i ) ;
180
- }
181
- assertEquals ( n , lineList . length ) ;
182
- var lines = lineList . join ( '' ) ;
183
- var chars = charList . join ( '' ) ;
184
- assertEquals ( n , chars . length ) ;
185
- lineList . unshift ( '' ) ;
186
- assertLinesToCharsResultEquals ( { chars1 : chars , chars2 : '' , lineArray : lineList } , dmp . diff_linesToChars_ ( lines , '' ) ) ;
160
+ function assertLinesToCharsResultEquals ( a , b ) {
161
+ assertEquals ( a . chars1 , b . chars1 ) ;
162
+ assertEquals ( a . chars2 , b . chars2 ) ;
163
+ assertEquivalent ( a . lineArray , b . lineArray ) ;
164
+ }
165
+
166
+ // Convert lines down to characters.
167
+ assertLinesToCharsResultEquals ( { chars1 : '\x01\x02\x01' , chars2 : '\x02\x01\x02' , lineArray : [ '' , 'alpha\n' , 'beta\n' ] } , dmp . diff_linesToChars_ ( 'alpha\nbeta\nalpha\n' , 'beta\nalpha\nbeta\n' ) ) ;
168
+
169
+ assertLinesToCharsResultEquals ( { chars1 : '' , chars2 : '\x01\x02\x03\x03' , lineArray : [ '' , 'alpha\r\n' , 'beta\r\n' , '\r\n' ] } , dmp . diff_linesToChars_ ( '' , 'alpha\r\nbeta\r\n\r\n\r\n' ) ) ;
170
+
171
+ assertLinesToCharsResultEquals ( { chars1 : '\x01' , chars2 : '\x02' , lineArray : [ '' , 'a' , 'b' ] } , dmp . diff_linesToChars_ ( 'a' , 'b' ) ) ;
172
+
173
+ // More than 256 to reveal any 8-bit limitations.
174
+ var n = 300 ;
175
+ var lineList = [ ] ;
176
+ var charList = [ ] ;
177
+ for ( var i = 1 ; i < n + 1 ; i ++ ) {
178
+ lineList [ i - 1 ] = i + '\n' ;
179
+ charList [ i - 1 ] = String . fromCharCode ( i ) ;
180
+ }
181
+ assertEquals ( n , lineList . length ) ;
182
+ var lines = lineList . join ( '' ) ;
183
+ var chars = charList . join ( '' ) ;
184
+ assertEquals ( n , chars . length ) ;
185
+ lineList . unshift ( '' ) ;
186
+ assertLinesToCharsResultEquals ( { chars1 : chars , chars2 : '' , lineArray : lineList } , dmp . diff_linesToChars_ ( lines , '' ) ) ;
187
187
}
188
188
189
189
function testDiffCharsToLines ( ) {
190
- // Convert chars up to lines.
191
- var diffs = [ [ DIFF_EQUAL , '\x01\x02\x01' ] , [ DIFF_INSERT , '\x02\x01\x02' ] ] ;
192
- dmp . diff_charsToLines_ ( diffs , [ '' , 'alpha\n' , 'beta\n' ] ) ;
193
- assertEquivalent ( [ [ DIFF_EQUAL , 'alpha\nbeta\nalpha\n' ] , [ DIFF_INSERT , 'beta\nalpha\nbeta\n' ] ] , diffs ) ;
194
-
195
- // More than 256 to reveal any 8-bit limitations.
196
- var n = 300 ;
197
- var lineList = [ ] ;
198
- var charList = [ ] ;
199
- for ( var i = 1 ; i < n + 1 ; i ++ ) {
200
- lineList [ i - 1 ] = i + '\n' ;
201
- charList [ i - 1 ] = String . fromCharCode ( i ) ;
202
- }
203
- assertEquals ( n , lineList . length ) ;
204
- var lines = lineList . join ( '' ) ;
205
- var chars = charList . join ( '' ) ;
206
- assertEquals ( n , chars . length ) ;
207
- lineList . unshift ( '' ) ;
208
- var diffs = [ [ DIFF_DELETE , chars ] ] ;
209
- dmp . diff_charsToLines_ ( diffs , lineList ) ;
210
- assertEquivalent ( [ [ DIFF_DELETE , lines ] ] , diffs ) ;
211
-
212
- // More than 65536 to verify any 16-bit limitation.
213
- lineList = [ ] ;
214
- for ( var i = 0 ; i < 66000 ; i ++ ) {
215
- lineList [ i ] = i + '\n' ;
216
- }
217
- chars = lineList . join ( '' ) ;
218
- var results = dmp . diff_linesToChars_ ( chars , '' ) ;
219
- diffs = [ [ DIFF_INSERT , results . chars1 ] ] ;
220
- dmp . diff_charsToLines_ ( diffs , results . lineArray ) ;
221
- assertEquals ( chars , diffs [ 0 ] [ 1 ] ) ;
190
+ // Convert chars up to lines.
191
+ var diffs = [ [ DIFF_EQUAL , '\x01\x02\x01' ] , [ DIFF_INSERT , '\x02\x01\x02' ] ] ;
192
+ dmp . diff_charsToLines_ ( diffs , [ '' , 'alpha\n' , 'beta\n' ] ) ;
193
+ assertEquivalent ( [ [ DIFF_EQUAL , 'alpha\nbeta\nalpha\n' ] , [ DIFF_INSERT , 'beta\nalpha\nbeta\n' ] ] , diffs ) ;
194
+
195
+ // More than 256 to reveal any 8-bit limitations.
196
+ var n = 300 ;
197
+ var lineList = [ ] ;
198
+ var charList = [ ] ;
199
+ for ( var i = 1 ; i < n + 1 ; i ++ ) {
200
+ lineList [ i - 1 ] = i + '\n' ;
201
+ charList [ i - 1 ] = String . fromCharCode ( i ) ;
202
+ }
203
+ assertEquals ( n , lineList . length ) ;
204
+ var lines = lineList . join ( '' ) ;
205
+ var chars = charList . join ( '' ) ;
206
+ assertEquals ( n , chars . length ) ;
207
+ lineList . unshift ( '' ) ;
208
+ var diffs = [ [ DIFF_DELETE , chars ] ] ;
209
+ dmp . diff_charsToLines_ ( diffs , lineList ) ;
210
+ assertEquivalent ( [ [ DIFF_DELETE , lines ] ] , diffs ) ;
211
+
212
+ // More than 65536 to verify any 16-bit limitation.
213
+ lineList = [ ] ;
214
+ for ( var i = 0 ; i < 66000 ; i ++ ) {
215
+ lineList [ i ] = i + '\n' ;
216
+ }
217
+ chars = lineList . join ( '' ) ;
218
+ var results = dmp . diff_linesToChars_ ( chars , '' ) ;
219
+ diffs = [ [ DIFF_INSERT , results . chars1 ] ] ;
220
+ dmp . diff_charsToLines_ ( diffs , results . lineArray ) ;
221
+ assertEquals ( chars , diffs [ 0 ] [ 1 ] ) ;
222
222
}
223
223
224
224
function testDiffCleanupMerge ( ) {
225
- // Cleanup a messy diff.
226
- // Null case.
227
- var diffs = [ ] ;
228
- dmp . diff_cleanupMerge ( diffs ) ;
229
- assertEquivalent ( [ ] , diffs ) ;
230
-
231
- // No change case.
232
- diffs = [ [ DIFF_EQUAL , 'a' ] , [ DIFF_DELETE , 'b' ] , [ DIFF_INSERT , 'c' ] ] ;
233
- dmp . diff_cleanupMerge ( diffs ) ;
234
- assertEquivalent ( [ [ DIFF_EQUAL , 'a' ] , [ DIFF_DELETE , 'b' ] , [ DIFF_INSERT , 'c' ] ] , diffs ) ;
235
-
236
- // Merge equalities.
237
- diffs = [ [ DIFF_EQUAL , 'a' ] , [ DIFF_EQUAL , 'b' ] , [ DIFF_EQUAL , 'c' ] ] ;
238
- dmp . diff_cleanupMerge ( diffs ) ;
239
- assertEquivalent ( [ [ DIFF_EQUAL , 'abc' ] ] , diffs ) ;
240
-
241
- // Merge deletions.
242
- diffs = [ [ DIFF_DELETE , 'a' ] , [ DIFF_DELETE , 'b' ] , [ DIFF_DELETE , 'c' ] ] ;
243
- dmp . diff_cleanupMerge ( diffs ) ;
244
- assertEquivalent ( [ [ DIFF_DELETE , 'abc' ] ] , diffs ) ;
245
-
246
- // Merge insertions.
247
- diffs = [ [ DIFF_INSERT , 'a' ] , [ DIFF_INSERT , 'b' ] , [ DIFF_INSERT , 'c' ] ] ;
248
- dmp . diff_cleanupMerge ( diffs ) ;
249
- assertEquivalent ( [ [ DIFF_INSERT , 'abc' ] ] , diffs ) ;
250
-
251
- // Merge interweave.
252
- diffs = [ [ DIFF_DELETE , 'a' ] , [ DIFF_INSERT , 'b' ] , [ DIFF_DELETE , 'c' ] , [ DIFF_INSERT , 'd' ] , [ DIFF_EQUAL , 'e' ] , [ DIFF_EQUAL , 'f' ] ] ;
253
- dmp . diff_cleanupMerge ( diffs ) ;
254
- assertEquivalent ( [ [ DIFF_DELETE , 'ac' ] , [ DIFF_INSERT , 'bd' ] , [ DIFF_EQUAL , 'ef' ] ] , diffs ) ;
255
-
256
- // Prefix and suffix detection.
257
- diffs = [ [ DIFF_DELETE , 'a' ] , [ DIFF_INSERT , 'abc' ] , [ DIFF_DELETE , 'dc' ] ] ;
258
- dmp . diff_cleanupMerge ( diffs ) ;
259
- assertEquivalent ( [ [ DIFF_EQUAL , 'a' ] , [ DIFF_DELETE , 'd' ] , [ DIFF_INSERT , 'b' ] , [ DIFF_EQUAL , 'c' ] ] , diffs ) ;
260
-
261
- // Prefix and suffix detection with equalities.
262
- diffs = [ [ DIFF_EQUAL , 'x' ] , [ DIFF_DELETE , 'a' ] , [ DIFF_INSERT , 'abc' ] , [ DIFF_DELETE , 'dc' ] , [ DIFF_EQUAL , 'y' ] ] ;
263
- dmp . diff_cleanupMerge ( diffs ) ;
264
- assertEquivalent ( [ [ DIFF_EQUAL , 'xa' ] , [ DIFF_DELETE , 'd' ] , [ DIFF_INSERT , 'b' ] , [ DIFF_EQUAL , 'cy' ] ] , diffs ) ;
265
-
266
- // Slide edit left.
267
- diffs = [ [ DIFF_EQUAL , 'a' ] , [ DIFF_INSERT , 'ba' ] , [ DIFF_EQUAL , 'c' ] ] ;
268
- dmp . diff_cleanupMerge ( diffs ) ;
269
- assertEquivalent ( [ [ DIFF_INSERT , 'ab' ] , [ DIFF_EQUAL , 'ac' ] ] , diffs ) ;
270
-
271
- // Slide edit right.
272
- diffs = [ [ DIFF_EQUAL , 'c' ] , [ DIFF_INSERT , 'ab' ] , [ DIFF_EQUAL , 'a' ] ] ;
273
- dmp . diff_cleanupMerge ( diffs ) ;
274
- assertEquivalent ( [ [ DIFF_EQUAL , 'ca' ] , [ DIFF_INSERT , 'ba' ] ] , diffs ) ;
275
-
276
- // Slide edit left recursive.
277
- diffs = [ [ DIFF_EQUAL , 'a' ] , [ DIFF_DELETE , 'b' ] , [ DIFF_EQUAL , 'c' ] , [ DIFF_DELETE , 'ac' ] , [ DIFF_EQUAL , 'x' ] ] ;
278
- dmp . diff_cleanupMerge ( diffs ) ;
279
- assertEquivalent ( [ [ DIFF_DELETE , 'abc' ] , [ DIFF_EQUAL , 'acx' ] ] , diffs ) ;
280
-
281
- // Slide edit right recursive.
282
- diffs = [ [ DIFF_EQUAL , 'x' ] , [ DIFF_DELETE , 'ca' ] , [ DIFF_EQUAL , 'c' ] , [ DIFF_DELETE , 'b' ] , [ DIFF_EQUAL , 'a' ] ] ;
283
- dmp . diff_cleanupMerge ( diffs ) ;
284
- assertEquivalent ( [ [ DIFF_EQUAL , 'xca' ] , [ DIFF_DELETE , 'cba' ] ] , diffs ) ;
285
-
286
- // Empty merge.
287
- diffs = [ [ DIFF_DELETE , 'b' ] , [ DIFF_INSERT , 'ab' ] , [ DIFF_EQUAL , 'c' ] ] ;
288
- dmp . diff_cleanupMerge ( diffs ) ;
289
- assertEquivalent ( [ [ DIFF_INSERT , 'a' ] , [ DIFF_EQUAL , 'bc' ] ] , diffs ) ;
290
-
291
- // Empty equality.
292
- diffs = [ [ DIFF_EQUAL , '' ] , [ DIFF_INSERT , 'a' ] , [ DIFF_EQUAL , 'b' ] ] ;
293
- dmp . diff_cleanupMerge ( diffs ) ;
294
- assertEquivalent ( [ [ DIFF_INSERT , 'a' ] , [ DIFF_EQUAL , 'b' ] ] , diffs ) ;
225
+ // Cleanup a messy diff.
226
+ // Null case.
227
+ var diffs = [ ] ;
228
+ dmp . diff_cleanupMerge ( diffs ) ;
229
+ assertEquivalent ( [ ] , diffs ) ;
230
+
231
+ // No change case.
232
+ diffs = [ [ DIFF_EQUAL , 'a' ] , [ DIFF_DELETE , 'b' ] , [ DIFF_INSERT , 'c' ] ] ;
233
+ dmp . diff_cleanupMerge ( diffs ) ;
234
+ assertEquivalent ( [ [ DIFF_EQUAL , 'a' ] , [ DIFF_DELETE , 'b' ] , [ DIFF_INSERT , 'c' ] ] , diffs ) ;
235
+
236
+ // Merge equalities.
237
+ diffs = [ [ DIFF_EQUAL , 'a' ] , [ DIFF_EQUAL , 'b' ] , [ DIFF_EQUAL , 'c' ] ] ;
238
+ dmp . diff_cleanupMerge ( diffs ) ;
239
+ assertEquivalent ( [ [ DIFF_EQUAL , 'abc' ] ] , diffs ) ;
240
+
241
+ // Merge deletions.
242
+ diffs = [ [ DIFF_DELETE , 'a' ] , [ DIFF_DELETE , 'b' ] , [ DIFF_DELETE , 'c' ] ] ;
243
+ dmp . diff_cleanupMerge ( diffs ) ;
244
+ assertEquivalent ( [ [ DIFF_DELETE , 'abc' ] ] , diffs ) ;
245
+
246
+ // Merge insertions.
247
+ diffs = [ [ DIFF_INSERT , 'a' ] , [ DIFF_INSERT , 'b' ] , [ DIFF_INSERT , 'c' ] ] ;
248
+ dmp . diff_cleanupMerge ( diffs ) ;
249
+ assertEquivalent ( [ [ DIFF_INSERT , 'abc' ] ] , diffs ) ;
250
+
251
+ // Merge interweave.
252
+ diffs = [ [ DIFF_DELETE , 'a' ] , [ DIFF_INSERT , 'b' ] , [ DIFF_DELETE , 'c' ] , [ DIFF_INSERT , 'd' ] , [ DIFF_EQUAL , 'e' ] , [ DIFF_EQUAL , 'f' ] ] ;
253
+ dmp . diff_cleanupMerge ( diffs ) ;
254
+ assertEquivalent ( [ [ DIFF_DELETE , 'ac' ] , [ DIFF_INSERT , 'bd' ] , [ DIFF_EQUAL , 'ef' ] ] , diffs ) ;
255
+
256
+ // Prefix and suffix detection.
257
+ diffs = [ [ DIFF_DELETE , 'a' ] , [ DIFF_INSERT , 'abc' ] , [ DIFF_DELETE , 'dc' ] ] ;
258
+ dmp . diff_cleanupMerge ( diffs ) ;
259
+ assertEquivalent ( [ [ DIFF_EQUAL , 'a' ] , [ DIFF_DELETE , 'd' ] , [ DIFF_INSERT , 'b' ] , [ DIFF_EQUAL , 'c' ] ] , diffs ) ;
260
+
261
+ // Prefix and suffix detection with equalities.
262
+ diffs = [ [ DIFF_EQUAL , 'x' ] , [ DIFF_DELETE , 'a' ] , [ DIFF_INSERT , 'abc' ] , [ DIFF_DELETE , 'dc' ] , [ DIFF_EQUAL , 'y' ] ] ;
263
+ dmp . diff_cleanupMerge ( diffs ) ;
264
+ assertEquivalent ( [ [ DIFF_EQUAL , 'xa' ] , [ DIFF_DELETE , 'd' ] , [ DIFF_INSERT , 'b' ] , [ DIFF_EQUAL , 'cy' ] ] , diffs ) ;
265
+
266
+ // Slide edit left.
267
+ diffs = [ [ DIFF_EQUAL , 'a' ] , [ DIFF_INSERT , 'ba' ] , [ DIFF_EQUAL , 'c' ] ] ;
268
+ dmp . diff_cleanupMerge ( diffs ) ;
269
+ assertEquivalent ( [ [ DIFF_INSERT , 'ab' ] , [ DIFF_EQUAL , 'ac' ] ] , diffs ) ;
270
+
271
+ // Slide edit right.
272
+ diffs = [ [ DIFF_EQUAL , 'c' ] , [ DIFF_INSERT , 'ab' ] , [ DIFF_EQUAL , 'a' ] ] ;
273
+ dmp . diff_cleanupMerge ( diffs ) ;
274
+ assertEquivalent ( [ [ DIFF_EQUAL , 'ca' ] , [ DIFF_INSERT , 'ba' ] ] , diffs ) ;
275
+
276
+ // Slide edit left recursive.
277
+ diffs = [ [ DIFF_EQUAL , 'a' ] , [ DIFF_DELETE , 'b' ] , [ DIFF_EQUAL , 'c' ] , [ DIFF_DELETE , 'ac' ] , [ DIFF_EQUAL , 'x' ] ] ;
278
+ dmp . diff_cleanupMerge ( diffs ) ;
279
+ assertEquivalent ( [ [ DIFF_DELETE , 'abc' ] , [ DIFF_EQUAL , 'acx' ] ] , diffs ) ;
280
+
281
+ // Slide edit right recursive.
282
+ diffs = [ [ DIFF_EQUAL , 'x' ] , [ DIFF_DELETE , 'ca' ] , [ DIFF_EQUAL , 'c' ] , [ DIFF_DELETE , 'b' ] , [ DIFF_EQUAL , 'a' ] ] ;
283
+ dmp . diff_cleanupMerge ( diffs ) ;
284
+ assertEquivalent ( [ [ DIFF_EQUAL , 'xca' ] , [ DIFF_DELETE , 'cba' ] ] , diffs ) ;
285
+
286
+ // Empty merge.
287
+ diffs = [ [ DIFF_DELETE , 'b' ] , [ DIFF_INSERT , 'ab' ] , [ DIFF_EQUAL , 'c' ] ] ;
288
+ dmp . diff_cleanupMerge ( diffs ) ;
289
+ assertEquivalent ( [ [ DIFF_INSERT , 'a' ] , [ DIFF_EQUAL , 'bc' ] ] , diffs ) ;
290
+
291
+ // Empty equality.
292
+ diffs = [ [ DIFF_EQUAL , '' ] , [ DIFF_INSERT , 'a' ] , [ DIFF_EQUAL , 'b' ] ] ;
293
+ dmp . diff_cleanupMerge ( diffs ) ;
294
+ assertEquivalent ( [ [ DIFF_INSERT , 'a' ] , [ DIFF_EQUAL , 'b' ] ] , diffs ) ;
295
295
}
296
296
297
297
function testDiffCleanupSemanticLossless ( ) {
298
- // Slide diffs to match logical boundaries.
299
- // Null case.
300
- var diffs = [ ] ;
301
- dmp . diff_cleanupSemanticLossless ( diffs ) ;
302
- assertEquivalent ( [ ] , diffs ) ;
303
-
304
- // Blank lines.
305
- diffs = [ [ DIFF_EQUAL , 'AAA\r\n\r\nBBB' ] , [ DIFF_INSERT , '\r\nDDD\r\n\r\nBBB' ] , [ DIFF_EQUAL , '\r\nEEE' ] ] ;
306
- dmp . diff_cleanupSemanticLossless ( diffs ) ;
307
- assertEquivalent ( [ [ DIFF_EQUAL , 'AAA\r\n\r\n' ] , [ DIFF_INSERT , 'BBB\r\nDDD\r\n\r\n' ] , [ DIFF_EQUAL , 'BBB\r\nEEE' ] ] , diffs ) ;
308
-
309
- // Line boundaries.
310
- diffs = [ [ DIFF_EQUAL , 'AAA\r\nBBB' ] , [ DIFF_INSERT , ' DDD\r\nBBB' ] , [ DIFF_EQUAL , ' EEE' ] ] ;
311
- dmp . diff_cleanupSemanticLossless ( diffs ) ;
312
- assertEquivalent ( [ [ DIFF_EQUAL , 'AAA\r\n' ] , [ DIFF_INSERT , 'BBB DDD\r\n' ] , [ DIFF_EQUAL , 'BBB EEE' ] ] , diffs ) ;
313
-
314
- // Word boundaries.
315
- diffs = [ [ DIFF_EQUAL , 'The c' ] , [ DIFF_INSERT , 'ow and the c' ] , [ DIFF_EQUAL , 'at.' ] ] ;
316
- dmp . diff_cleanupSemanticLossless ( diffs ) ;
317
- assertEquivalent ( [ [ DIFF_EQUAL , 'The ' ] , [ DIFF_INSERT , 'cow and the ' ] , [ DIFF_EQUAL , 'cat.' ] ] , diffs ) ;
318
-
319
- // Alphanumeric boundaries.
320
- diffs = [ [ DIFF_EQUAL , 'The-c' ] , [ DIFF_INSERT , 'ow-and-the-c' ] , [ DIFF_EQUAL , 'at.' ] ] ;
321
- dmp . diff_cleanupSemanticLossless ( diffs ) ;
322
- assertEquivalent ( [ [ DIFF_EQUAL , 'The-' ] , [ DIFF_INSERT , 'cow-and-the-' ] , [ DIFF_EQUAL , 'cat.' ] ] , diffs ) ;
323
-
324
- // Hitting the start.
325
- diffs = [ [ DIFF_EQUAL , 'a' ] , [ DIFF_DELETE , 'a' ] , [ DIFF_EQUAL , 'ax' ] ] ;
326
- dmp . diff_cleanupSemanticLossless ( diffs ) ;
327
- assertEquivalent ( [ [ DIFF_DELETE , 'a' ] , [ DIFF_EQUAL , 'aax' ] ] , diffs ) ;
328
-
329
- // Hitting the end.
330
- diffs = [ [ DIFF_EQUAL , 'xa' ] , [ DIFF_DELETE , 'a' ] , [ DIFF_EQUAL , 'a' ] ] ;
331
- dmp . diff_cleanupSemanticLossless ( diffs ) ;
332
- assertEquivalent ( [ [ DIFF_EQUAL , 'xaa' ] , [ DIFF_DELETE , 'a' ] ] , diffs ) ;
333
-
334
- // Sentence boundaries.
335
- diffs = [ [ DIFF_EQUAL , 'The xxx. The ' ] , [ DIFF_INSERT , 'zzz. The ' ] , [ DIFF_EQUAL , 'yyy.' ] ] ;
336
- dmp . diff_cleanupSemanticLossless ( diffs ) ;
337
- assertEquivalent ( [ [ DIFF_EQUAL , 'The xxx.' ] , [ DIFF_INSERT , ' The zzz.' ] , [ DIFF_EQUAL , ' The yyy.' ] ] , diffs ) ;
298
+ // Slide diffs to match logical boundaries.
299
+ // Null case.
300
+ var diffs = [ ] ;
301
+ dmp . diff_cleanupSemanticLossless ( diffs ) ;
302
+ assertEquivalent ( [ ] , diffs ) ;
303
+
304
+ // Blank lines.
305
+ diffs = [ [ DIFF_EQUAL , 'AAA\r\n\r\nBBB' ] , [ DIFF_INSERT , '\r\nDDD\r\n\r\nBBB' ] , [ DIFF_EQUAL , '\r\nEEE' ] ] ;
306
+ dmp . diff_cleanupSemanticLossless ( diffs ) ;
307
+ assertEquivalent ( [ [ DIFF_EQUAL , 'AAA\r\n\r\n' ] , [ DIFF_INSERT , 'BBB\r\nDDD\r\n\r\n' ] , [ DIFF_EQUAL , 'BBB\r\nEEE' ] ] , diffs ) ;
308
+
309
+ // Line boundaries.
310
+ diffs = [ [ DIFF_EQUAL , 'AAA\r\nBBB' ] , [ DIFF_INSERT , ' DDD\r\nBBB' ] , [ DIFF_EQUAL , ' EEE' ] ] ;
311
+ dmp . diff_cleanupSemanticLossless ( diffs ) ;
312
+ assertEquivalent ( [ [ DIFF_EQUAL , 'AAA\r\n' ] , [ DIFF_INSERT , 'BBB DDD\r\n' ] , [ DIFF_EQUAL , 'BBB EEE' ] ] , diffs ) ;
313
+
314
+ // Word boundaries.
315
+ diffs = [ [ DIFF_EQUAL , 'The c' ] , [ DIFF_INSERT , 'ow and the c' ] , [ DIFF_EQUAL , 'at.' ] ] ;
316
+ dmp . diff_cleanupSemanticLossless ( diffs ) ;
317
+ assertEquivalent ( [ [ DIFF_EQUAL , 'The ' ] , [ DIFF_INSERT , 'cow and the ' ] , [ DIFF_EQUAL , 'cat.' ] ] , diffs ) ;
318
+
319
+ // Alphanumeric boundaries.
320
+ diffs = [ [ DIFF_EQUAL , 'The-c' ] , [ DIFF_INSERT , 'ow-and-the-c' ] , [ DIFF_EQUAL , 'at.' ] ] ;
321
+ dmp . diff_cleanupSemanticLossless ( diffs ) ;
322
+ assertEquivalent ( [ [ DIFF_EQUAL , 'The-' ] , [ DIFF_INSERT , 'cow-and-the-' ] , [ DIFF_EQUAL , 'cat.' ] ] , diffs ) ;
323
+
324
+ // Hitting the start.
325
+ diffs = [ [ DIFF_EQUAL , 'a' ] , [ DIFF_DELETE , 'a' ] , [ DIFF_EQUAL , 'ax' ] ] ;
326
+ dmp . diff_cleanupSemanticLossless ( diffs ) ;
327
+ assertEquivalent ( [ [ DIFF_DELETE , 'a' ] , [ DIFF_EQUAL , 'aax' ] ] , diffs ) ;
328
+
329
+ // Hitting the end.
330
+ diffs = [ [ DIFF_EQUAL , 'xa' ] , [ DIFF_DELETE , 'a' ] , [ DIFF_EQUAL , 'a' ] ] ;
331
+ dmp . diff_cleanupSemanticLossless ( diffs ) ;
332
+ assertEquivalent ( [ [ DIFF_EQUAL , 'xaa' ] , [ DIFF_DELETE , 'a' ] ] , diffs ) ;
333
+
334
+ // Sentence boundaries.
335
+ diffs = [ [ DIFF_EQUAL , 'The xxx. The ' ] , [ DIFF_INSERT , 'zzz. The ' ] , [ DIFF_EQUAL , 'yyy.' ] ] ;
336
+ dmp . diff_cleanupSemanticLossless ( diffs ) ;
337
+ assertEquivalent ( [ [ DIFF_EQUAL , 'The xxx.' ] , [ DIFF_INSERT , ' The zzz.' ] , [ DIFF_EQUAL , ' The yyy.' ] ] , diffs ) ;
338
338
}
339
339
340
340
function testDiffCleanupSemantic ( ) {
341
- // Cleanup semantically trivial equalities.
342
- // Null case.
343
- var diffs = [ ] ;
344
- dmp . diff_cleanupSemantic ( diffs ) ;
345
- assertEquivalent ( [ ] , diffs ) ;
346
-
347
- // No elimination #1.
348
- diffs = [ [ DIFF_DELETE , 'ab' ] , [ DIFF_INSERT , 'cd' ] , [ DIFF_EQUAL , '12' ] , [ DIFF_DELETE , 'e' ] ] ;
349
- dmp . diff_cleanupSemantic ( diffs ) ;
350
- assertEquivalent ( [ [ DIFF_DELETE , 'ab' ] , [ DIFF_INSERT , 'cd' ] , [ DIFF_EQUAL , '12' ] , [ DIFF_DELETE , 'e' ] ] , diffs ) ;
351
-
352
- // No elimination #2.
353
- diffs = [ [ DIFF_DELETE , 'abc' ] , [ DIFF_INSERT , 'ABC' ] , [ DIFF_EQUAL , '1234' ] , [ DIFF_DELETE , 'wxyz' ] ] ;
354
- dmp . diff_cleanupSemantic ( diffs ) ;
355
- assertEquivalent ( [ [ DIFF_DELETE , 'abc' ] , [ DIFF_INSERT , 'ABC' ] , [ DIFF_EQUAL , '1234' ] , [ DIFF_DELETE , 'wxyz' ] ] , diffs ) ;
356
-
357
- // Simple elimination.
358
- diffs = [ [ DIFF_DELETE , 'a' ] , [ DIFF_EQUAL , 'b' ] , [ DIFF_DELETE , 'c' ] ] ;
359
- dmp . diff_cleanupSemantic ( diffs ) ;
360
- assertEquivalent ( [ [ DIFF_DELETE , 'abc' ] , [ DIFF_INSERT , 'b' ] ] , diffs ) ;
361
-
362
- // Backpass elimination.
363
- diffs = [ [ DIFF_DELETE , 'ab' ] , [ DIFF_EQUAL , 'cd' ] , [ DIFF_DELETE , 'e' ] , [ DIFF_EQUAL , 'f' ] , [ DIFF_INSERT , 'g' ] ] ;
364
- dmp . diff_cleanupSemantic ( diffs ) ;
365
- assertEquivalent ( [ [ DIFF_DELETE , 'abcdef' ] , [ DIFF_INSERT , 'cdfg' ] ] , diffs ) ;
366
-
367
- // Multiple eliminations.
368
- diffs = [ [ DIFF_INSERT , '1' ] , [ DIFF_EQUAL , 'A' ] , [ DIFF_DELETE , 'B' ] , [ DIFF_INSERT , '2' ] , [ DIFF_EQUAL , '_' ] , [ DIFF_INSERT , '1' ] , [ DIFF_EQUAL , 'A' ] , [ DIFF_DELETE , 'B' ] , [ DIFF_INSERT , '2' ] ] ;
369
- dmp . diff_cleanupSemantic ( diffs ) ;
370
- assertEquivalent ( [ [ DIFF_DELETE , 'AB_AB' ] , [ DIFF_INSERT , '1A2_1A2' ] ] , diffs ) ;
371
-
372
- // Word boundaries.
373
- diffs = [ [ DIFF_EQUAL , 'The c' ] , [ DIFF_DELETE , 'ow and the c' ] , [ DIFF_EQUAL , 'at.' ] ] ;
374
- dmp . diff_cleanupSemantic ( diffs ) ;
375
- assertEquivalent ( [ [ DIFF_EQUAL , 'The ' ] , [ DIFF_DELETE , 'cow and the ' ] , [ DIFF_EQUAL , 'cat.' ] ] , diffs ) ;
376
-
377
- // No overlap elimination.
378
- diffs = [ [ DIFF_DELETE , 'abcxx' ] , [ DIFF_INSERT , 'xxdef' ] ] ;
379
- dmp . diff_cleanupSemantic ( diffs ) ;
380
- assertEquivalent ( [ [ DIFF_DELETE , 'abcxx' ] , [ DIFF_INSERT , 'xxdef' ] ] , diffs ) ;
381
-
382
- // Overlap elimination.
383
- diffs = [ [ DIFF_DELETE , 'abcxxx' ] , [ DIFF_INSERT , 'xxxdef' ] ] ;
384
- dmp . diff_cleanupSemantic ( diffs ) ;
385
- assertEquivalent ( [ [ DIFF_DELETE , 'abc' ] , [ DIFF_EQUAL , 'xxx' ] , [ DIFF_INSERT , 'def' ] ] , diffs ) ;
386
-
387
- // Reverse overlap elimination.
388
- diffs = [ [ DIFF_DELETE , 'xxxabc' ] , [ DIFF_INSERT , 'defxxx' ] ] ;
389
- dmp . diff_cleanupSemantic ( diffs ) ;
390
- assertEquivalent ( [ [ DIFF_INSERT , 'def' ] , [ DIFF_EQUAL , 'xxx' ] , [ DIFF_DELETE , 'abc' ] ] , diffs ) ;
391
-
392
- // Two overlap eliminations.
393
- diffs = [ [ DIFF_DELETE , 'abcd1212' ] , [ DIFF_INSERT , '1212efghi' ] , [ DIFF_EQUAL , '----' ] , [ DIFF_DELETE , 'A3' ] , [ DIFF_INSERT , '3BC' ] ] ;
394
- dmp . diff_cleanupSemantic ( diffs ) ;
395
- assertEquivalent ( [ [ DIFF_DELETE , 'abcd' ] , [ DIFF_EQUAL , '1212' ] , [ DIFF_INSERT , 'efghi' ] , [ DIFF_EQUAL , '----' ] , [ DIFF_DELETE , 'A' ] , [ DIFF_EQUAL , '3' ] , [ DIFF_INSERT , 'BC' ] ] , diffs ) ;
341
+ // Cleanup semantically trivial equalities.
342
+ // Null case.
343
+ var diffs = [ ] ;
344
+ dmp . diff_cleanupSemantic ( diffs ) ;
345
+ assertEquivalent ( [ ] , diffs ) ;
346
+
347
+ // No elimination #1.
348
+ diffs = [ [ DIFF_DELETE , 'ab' ] , [ DIFF_INSERT , 'cd' ] , [ DIFF_EQUAL , '12' ] , [ DIFF_DELETE , 'e' ] ] ;
349
+ dmp . diff_cleanupSemantic ( diffs ) ;
350
+ assertEquivalent ( [ [ DIFF_DELETE , 'ab' ] , [ DIFF_INSERT , 'cd' ] , [ DIFF_EQUAL , '12' ] , [ DIFF_DELETE , 'e' ] ] , diffs ) ;
351
+
352
+ // No elimination #2.
353
+ diffs = [ [ DIFF_DELETE , 'abc' ] , [ DIFF_INSERT , 'ABC' ] , [ DIFF_EQUAL , '1234' ] , [ DIFF_DELETE , 'wxyz' ] ] ;
354
+ dmp . diff_cleanupSemantic ( diffs ) ;
355
+ assertEquivalent ( [ [ DIFF_DELETE , 'abc' ] , [ DIFF_INSERT , 'ABC' ] , [ DIFF_EQUAL , '1234' ] , [ DIFF_DELETE , 'wxyz' ] ] , diffs ) ;
356
+
357
+ // Simple elimination.
358
+ diffs = [ [ DIFF_DELETE , 'a' ] , [ DIFF_EQUAL , 'b' ] , [ DIFF_DELETE , 'c' ] ] ;
359
+ dmp . diff_cleanupSemantic ( diffs ) ;
360
+ assertEquivalent ( [ [ DIFF_DELETE , 'abc' ] , [ DIFF_INSERT , 'b' ] ] , diffs ) ;
361
+
362
+ // Backpass elimination.
363
+ diffs = [ [ DIFF_DELETE , 'ab' ] , [ DIFF_EQUAL , 'cd' ] , [ DIFF_DELETE , 'e' ] , [ DIFF_EQUAL , 'f' ] , [ DIFF_INSERT , 'g' ] ] ;
364
+ dmp . diff_cleanupSemantic ( diffs ) ;
365
+ assertEquivalent ( [ [ DIFF_DELETE , 'abcdef' ] , [ DIFF_INSERT , 'cdfg' ] ] , diffs ) ;
366
+
367
+ // Multiple eliminations.
368
+ diffs = [ [ DIFF_INSERT , '1' ] , [ DIFF_EQUAL , 'A' ] , [ DIFF_DELETE , 'B' ] , [ DIFF_INSERT , '2' ] , [ DIFF_EQUAL , '_' ] , [ DIFF_INSERT , '1' ] , [ DIFF_EQUAL , 'A' ] , [ DIFF_DELETE , 'B' ] , [ DIFF_INSERT , '2' ] ] ;
369
+ dmp . diff_cleanupSemantic ( diffs ) ;
370
+ assertEquivalent ( [ [ DIFF_DELETE , 'AB_AB' ] , [ DIFF_INSERT , '1A2_1A2' ] ] , diffs ) ;
371
+
372
+ // Word boundaries.
373
+ diffs = [ [ DIFF_EQUAL , 'The c' ] , [ DIFF_DELETE , 'ow and the c' ] , [ DIFF_EQUAL , 'at.' ] ] ;
374
+ dmp . diff_cleanupSemantic ( diffs ) ;
375
+ assertEquivalent ( [ [ DIFF_EQUAL , 'The ' ] , [ DIFF_DELETE , 'cow and the ' ] , [ DIFF_EQUAL , 'cat.' ] ] , diffs ) ;
376
+
377
+ // No overlap elimination.
378
+ diffs = [ [ DIFF_DELETE , 'abcxx' ] , [ DIFF_INSERT , 'xxdef' ] ] ;
379
+ dmp . diff_cleanupSemantic ( diffs ) ;
380
+ assertEquivalent ( [ [ DIFF_DELETE , 'abcxx' ] , [ DIFF_INSERT , 'xxdef' ] ] , diffs ) ;
381
+
382
+ // Overlap elimination.
383
+ diffs = [ [ DIFF_DELETE , 'abcxxx' ] , [ DIFF_INSERT , 'xxxdef' ] ] ;
384
+ dmp . diff_cleanupSemantic ( diffs ) ;
385
+ assertEquivalent ( [ [ DIFF_DELETE , 'abc' ] , [ DIFF_EQUAL , 'xxx' ] , [ DIFF_INSERT , 'def' ] ] , diffs ) ;
386
+
387
+ // Reverse overlap elimination.
388
+ diffs = [ [ DIFF_DELETE , 'xxxabc' ] , [ DIFF_INSERT , 'defxxx' ] ] ;
389
+ dmp . diff_cleanupSemantic ( diffs ) ;
390
+ assertEquivalent ( [ [ DIFF_INSERT , 'def' ] , [ DIFF_EQUAL , 'xxx' ] , [ DIFF_DELETE , 'abc' ] ] , diffs ) ;
391
+
392
+ // Two overlap eliminations.
393
+ diffs = [ [ DIFF_DELETE , 'abcd1212' ] , [ DIFF_INSERT , '1212efghi' ] , [ DIFF_EQUAL , '----' ] , [ DIFF_DELETE , 'A3' ] , [ DIFF_INSERT , '3BC' ] ] ;
394
+ dmp . diff_cleanupSemantic ( diffs ) ;
395
+ assertEquivalent ( [ [ DIFF_DELETE , 'abcd' ] , [ DIFF_EQUAL , '1212' ] , [ DIFF_INSERT , 'efghi' ] , [ DIFF_EQUAL , '----' ] , [ DIFF_DELETE , 'A' ] , [ DIFF_EQUAL , '3' ] , [ DIFF_INSERT , 'BC' ] ] , diffs ) ;
396
396
}
397
397
398
398
function testDiffCleanupEfficiency ( ) {
399
- // Cleanup operationally trivial equalities.
400
- dmp . Diff_EditCost = 4 ;
401
- // Null case.
402
- var diffs = [ ] ;
403
- dmp . diff_cleanupEfficiency ( diffs ) ;
404
- assertEquivalent ( [ ] , diffs ) ;
405
-
406
- // No elimination.
407
- diffs = [ [ DIFF_DELETE , 'ab' ] , [ DIFF_INSERT , '12' ] , [ DIFF_EQUAL , 'wxyz' ] , [ DIFF_DELETE , 'cd' ] , [ DIFF_INSERT , '34' ] ] ;
408
- dmp . diff_cleanupEfficiency ( diffs ) ;
409
- assertEquivalent ( [ [ DIFF_DELETE , 'ab' ] , [ DIFF_INSERT , '12' ] , [ DIFF_EQUAL , 'wxyz' ] , [ DIFF_DELETE , 'cd' ] , [ DIFF_INSERT , '34' ] ] , diffs ) ;
410
-
411
- // Four-edit elimination.
412
- diffs = [ [ DIFF_DELETE , 'ab' ] , [ DIFF_INSERT , '12' ] , [ DIFF_EQUAL , 'xyz' ] , [ DIFF_DELETE , 'cd' ] , [ DIFF_INSERT , '34' ] ] ;
413
- dmp . diff_cleanupEfficiency ( diffs ) ;
414
- assertEquivalent ( [ [ DIFF_DELETE , 'abxyzcd' ] , [ DIFF_INSERT , '12xyz34' ] ] , diffs ) ;
415
-
416
- // Three-edit elimination.
417
- diffs = [ [ DIFF_INSERT , '12' ] , [ DIFF_EQUAL , 'x' ] , [ DIFF_DELETE , 'cd' ] , [ DIFF_INSERT , '34' ] ] ;
418
- dmp . diff_cleanupEfficiency ( diffs ) ;
419
- assertEquivalent ( [ [ DIFF_DELETE , 'xcd' ] , [ DIFF_INSERT , '12x34' ] ] , diffs ) ;
420
-
421
- // Backpass elimination.
422
- diffs = [ [ DIFF_DELETE , 'ab' ] , [ DIFF_INSERT , '12' ] , [ DIFF_EQUAL , 'xy' ] , [ DIFF_INSERT , '34' ] , [ DIFF_EQUAL , 'z' ] , [ DIFF_DELETE , 'cd' ] , [ DIFF_INSERT , '56' ] ] ;
423
- dmp . diff_cleanupEfficiency ( diffs ) ;
424
- assertEquivalent ( [ [ DIFF_DELETE , 'abxyzcd' ] , [ DIFF_INSERT , '12xy34z56' ] ] , diffs ) ;
425
-
426
- // High cost elimination.
427
- dmp . Diff_EditCost = 5 ;
428
- diffs = [ [ DIFF_DELETE , 'ab' ] , [ DIFF_INSERT , '12' ] , [ DIFF_EQUAL , 'wxyz' ] , [ DIFF_DELETE , 'cd' ] , [ DIFF_INSERT , '34' ] ] ;
429
- dmp . diff_cleanupEfficiency ( diffs ) ;
430
- assertEquivalent ( [ [ DIFF_DELETE , 'abwxyzcd' ] , [ DIFF_INSERT , '12wxyz34' ] ] , diffs ) ;
431
- dmp . Diff_EditCost = 4 ;
399
+ // Cleanup operationally trivial equalities.
400
+ dmp . Diff_EditCost = 4 ;
401
+ // Null case.
402
+ var diffs = [ ] ;
403
+ dmp . diff_cleanupEfficiency ( diffs ) ;
404
+ assertEquivalent ( [ ] , diffs ) ;
405
+
406
+ // No elimination.
407
+ diffs = [ [ DIFF_DELETE , 'ab' ] , [ DIFF_INSERT , '12' ] , [ DIFF_EQUAL , 'wxyz' ] , [ DIFF_DELETE , 'cd' ] , [ DIFF_INSERT , '34' ] ] ;
408
+ dmp . diff_cleanupEfficiency ( diffs ) ;
409
+ assertEquivalent ( [ [ DIFF_DELETE , 'ab' ] , [ DIFF_INSERT , '12' ] , [ DIFF_EQUAL , 'wxyz' ] , [ DIFF_DELETE , 'cd' ] , [ DIFF_INSERT , '34' ] ] , diffs ) ;
410
+
411
+ // Four-edit elimination.
412
+ diffs = [ [ DIFF_DELETE , 'ab' ] , [ DIFF_INSERT , '12' ] , [ DIFF_EQUAL , 'xyz' ] , [ DIFF_DELETE , 'cd' ] , [ DIFF_INSERT , '34' ] ] ;
413
+ dmp . diff_cleanupEfficiency ( diffs ) ;
414
+ assertEquivalent ( [ [ DIFF_DELETE , 'abxyzcd' ] , [ DIFF_INSERT , '12xyz34' ] ] , diffs ) ;
415
+
416
+ // Three-edit elimination.
417
+ diffs = [ [ DIFF_INSERT , '12' ] , [ DIFF_EQUAL , 'x' ] , [ DIFF_DELETE , 'cd' ] , [ DIFF_INSERT , '34' ] ] ;
418
+ dmp . diff_cleanupEfficiency ( diffs ) ;
419
+ assertEquivalent ( [ [ DIFF_DELETE , 'xcd' ] , [ DIFF_INSERT , '12x34' ] ] , diffs ) ;
420
+
421
+ // Backpass elimination.
422
+ diffs = [ [ DIFF_DELETE , 'ab' ] , [ DIFF_INSERT , '12' ] , [ DIFF_EQUAL , 'xy' ] , [ DIFF_INSERT , '34' ] , [ DIFF_EQUAL , 'z' ] , [ DIFF_DELETE , 'cd' ] , [ DIFF_INSERT , '56' ] ] ;
423
+ dmp . diff_cleanupEfficiency ( diffs ) ;
424
+ assertEquivalent ( [ [ DIFF_DELETE , 'abxyzcd' ] , [ DIFF_INSERT , '12xy34z56' ] ] , diffs ) ;
425
+
426
+ // High cost elimination.
427
+ dmp . Diff_EditCost = 5 ;
428
+ diffs = [ [ DIFF_DELETE , 'ab' ] , [ DIFF_INSERT , '12' ] , [ DIFF_EQUAL , 'wxyz' ] , [ DIFF_DELETE , 'cd' ] , [ DIFF_INSERT , '34' ] ] ;
429
+ dmp . diff_cleanupEfficiency ( diffs ) ;
430
+ assertEquivalent ( [ [ DIFF_DELETE , 'abwxyzcd' ] , [ DIFF_INSERT , '12wxyz34' ] ] , diffs ) ;
431
+ dmp . Diff_EditCost = 4 ;
432
432
}
433
433
434
434
function testDiffPrettyHtml ( ) {
435
- // Pretty print.
436
- var diffs = [ [ DIFF_EQUAL , 'a\n' ] , [ DIFF_DELETE , '<B>b</B>' ] , [ DIFF_INSERT , 'c&d' ] ] ;
437
- assertEquals ( '<span>a¶<br></span><del style="background:#ffe6e6;"><B>b</B></del><ins style="background:#e6ffe6;">c&d</ins>' , dmp . diff_prettyHtml ( diffs ) ) ;
435
+ // Pretty print.
436
+ var diffs = [ [ DIFF_EQUAL , 'a\n' ] , [ DIFF_DELETE , '<B>b</B>' ] , [ DIFF_INSERT , 'c&d' ] ] ;
437
+ assertEquals ( '<span>a¶<br></span><del style="background:#ffe6e6;"><B>b</B></del><ins style="background:#e6ffe6;">c&d</ins>' , dmp . diff_prettyHtml ( diffs ) ) ;
438
438
}
439
439
440
440
function testDiffText ( ) {
441
- // Compute the source and destination texts.
442
- var diffs = [ [ DIFF_EQUAL , 'jump' ] , [ DIFF_DELETE , 's' ] , [ DIFF_INSERT , 'ed' ] , [ DIFF_EQUAL , ' over ' ] , [ DIFF_DELETE , 'the' ] , [ DIFF_INSERT , 'a' ] , [ DIFF_EQUAL , ' lazy' ] ] ;
443
- assertEquals ( 'jumps over the lazy' , dmp . diff_text1 ( diffs ) ) ;
444
-
445
- assertEquals ( 'jumped over a lazy' , dmp . diff_text2 ( diffs ) ) ;
441
+ // Compute the source and destination texts.
442
+ var diffs = [ [ DIFF_EQUAL , 'jump' ] , [ DIFF_DELETE , 's' ] , [ DIFF_INSERT , 'ed' ] , [ DIFF_EQUAL , ' over ' ] , [ DIFF_DELETE , 'the' ] , [ DIFF_INSERT , 'a' ] , [ DIFF_EQUAL , ' lazy' ] ] ;
443
+ assertEquals ( 'jumps over the lazy' , dmp . diff_text1 ( diffs ) ) ;
444
+
445
+ assertEquals ( 'jumped over a lazy' , dmp . diff_text2 ( diffs ) ) ;
446
446
}
447
447
448
448
function testDiffDelta ( ) {
449
- // Convert a diff into delta string.
450
- var diffs = [ [ DIFF_EQUAL , 'jump' ] , [ DIFF_DELETE , 's' ] , [ DIFF_INSERT , 'ed' ] , [ DIFF_EQUAL , ' over ' ] , [ DIFF_DELETE , 'the' ] , [ DIFF_INSERT , 'a' ] , [ DIFF_EQUAL , ' lazy' ] , [ DIFF_INSERT , 'old dog' ] ] ;
451
- var text1 = dmp . diff_text1 ( diffs ) ;
452
- assertEquals ( 'jumps over the lazy' , text1 ) ;
453
-
454
- var delta = dmp . diff_toDelta ( diffs ) ;
455
- assertEquals ( '=4\t-1\t+ed\t=6\t-3\t+a\t=5\t+old dog' , delta ) ;
456
-
457
- // Convert delta string into a diff.
458
- assertEquivalent ( diffs , dmp . diff_fromDelta ( text1 , delta ) ) ;
459
-
460
- // Generates error (19 != 20).
461
- try {
462
- dmp . diff_fromDelta ( text1 + 'x' , delta ) ;
463
- assertEquals ( Error , null ) ;
464
- } catch ( e ) {
465
- // Exception expected.
466
- }
467
-
468
- // Generates error (19 != 18).
469
- try {
470
- dmp . diff_fromDelta ( text1 . substring ( 1 ) , delta ) ;
471
- assertEquals ( Error , null ) ;
472
- } catch ( e ) {
473
- // Exception expected.
474
- }
475
-
476
- // Generates error (%c3%xy invalid Unicode).
477
- try {
478
- dmp . diff_fromDelta ( '' , '+%c3%xy' ) ;
479
- assertEquals ( Error , null ) ;
480
- } catch ( e ) {
481
- // Exception expected.
482
- }
483
-
484
- // Test deltas with special characters.
485
- diffs = [ [ DIFF_EQUAL , '\u0680 \x00 \t %' ] , [ DIFF_DELETE , '\u0681 \x01 \n ^' ] , [ DIFF_INSERT , '\u0682 \x02 \\ |' ] ] ;
486
- text1 = dmp . diff_text1 ( diffs ) ;
487
- assertEquals ( '\u0680 \x00 \t %\u0681 \x01 \n ^' , text1 ) ;
488
-
489
- delta = dmp . diff_toDelta ( diffs ) ;
490
- assertEquals ( '=7\t-7\t+%DA%82 %02 %5C %7C' , delta ) ;
491
-
492
- // Convert delta string into a diff.
493
- assertEquivalent ( diffs , dmp . diff_fromDelta ( text1 , delta ) ) ;
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
449
+ // Convert a diff into delta string.
450
+ var diffs = [ [ DIFF_EQUAL , 'jump' ] , [ DIFF_DELETE , 's' ] , [ DIFF_INSERT , 'ed' ] , [ DIFF_EQUAL , ' over ' ] , [ DIFF_DELETE , 'the' ] , [ DIFF_INSERT , 'a' ] , [ DIFF_EQUAL , ' lazy' ] , [ DIFF_INSERT , 'old dog' ] ] ;
451
+ var text1 = dmp . diff_text1 ( diffs ) ;
452
+ assertEquals ( 'jumps over the lazy' , text1 ) ;
453
+
454
+ var delta = dmp . diff_toDelta ( diffs ) ;
455
+ assertEquals ( '=4\t-1\t+ed\t=6\t-3\t+a\t=5\t+old dog' , delta ) ;
456
+
457
+ // Convert delta string into a diff.
458
+ assertEquivalent ( diffs , dmp . diff_fromDelta ( text1 , delta ) ) ;
459
+
460
+ // Generates error (19 != 20).
461
+ try {
462
+ dmp . diff_fromDelta ( text1 + 'x' , delta ) ;
463
+ assertEquals ( Error , null ) ;
464
+ } catch ( e ) {
465
+ // Exception expected.
466
+ }
467
+
468
+ // Generates error (19 != 18).
469
+ try {
470
+ dmp . diff_fromDelta ( text1 . substring ( 1 ) , delta ) ;
471
+ assertEquals ( Error , null ) ;
472
+ } catch ( e ) {
473
+ // Exception expected.
474
+ }
475
+
476
+ // Generates error (%c3%xy invalid Unicode).
477
+ try {
478
+ dmp . diff_fromDelta ( '' , '+%c3%xy' ) ;
479
+ assertEquals ( Error , null ) ;
480
+ } catch ( e ) {
481
+ // Exception expected.
482
+ }
483
+
484
+ // Test deltas with special characters.
485
+ diffs = [ [ DIFF_EQUAL , '\u0680 \x00 \t %' ] , [ DIFF_DELETE , '\u0681 \x01 \n ^' ] , [ DIFF_INSERT , '\u0682 \x02 \\ |' ] ] ;
486
+ text1 = dmp . diff_text1 ( diffs ) ;
487
+ assertEquals ( '\u0680 \x00 \t %\u0681 \x01 \n ^' , text1 ) ;
488
+
489
+ delta = dmp . diff_toDelta ( diffs ) ;
490
+ assertEquals ( '=7\t-7\t+%DA%82 %02 %5C %7C' , delta ) ;
491
+
492
+ // Convert delta string into a diff.
493
+ assertEquivalent ( diffs , dmp . diff_fromDelta ( text1 , delta ) ) ;
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
505
U+1F18x 🆎
506
506
0 1 2 3 4 5 6 7 8 9 A B C D E F
507
507
U+1F19x 🆑 🆒 🆓 🆔 🆕 🆖 🆗 🆘 🆙 🆚
@@ -512,585 +512,585 @@ function testDiffDelta() {
512
512
U+1F25x 🉐 🉑
513
513
U+1F30x 🌀 🌁 🌂 🌃 🌄 🌅 🌆 🌇 🌈 🌉 🌊 🌋 🌌 🌍 🌎 🌏
514
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
-
625
- // Verify pool of unchanged characters.
626
- diffs = [ [ DIFF_INSERT , 'A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + $ , # ' ] ] ;
627
- var text2 = dmp . diff_text2 ( diffs ) ;
628
- assertEquals ( 'A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + $ , # ' , text2 ) ;
629
-
630
- delta = dmp . diff_toDelta ( diffs ) ;
631
- assertEquals ( '+A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + $ , # ' , delta ) ;
632
-
633
- // Convert delta string into a diff.
634
- assertEquivalent ( diffs , dmp . diff_fromDelta ( '' , delta ) ) ;
635
-
636
- // 160 kb string.
637
- var a = 'abcdefghij' ;
638
- for ( var i = 0 ; i < 14 ; i ++ ) {
639
- a += a ;
640
- }
641
- diffs = [ [ DIFF_INSERT , a ] ] ;
642
- delta = dmp . diff_toDelta ( diffs ) ;
643
- assertEquals ( '+' + a , delta ) ;
644
-
645
- // Convert delta string into a diff.
646
- assertEquivalent ( diffs , dmp . diff_fromDelta ( '' , delta ) ) ;
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
+
625
+ // Verify pool of unchanged characters.
626
+ diffs = [ [ DIFF_INSERT , 'A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + $ , # ' ] ] ;
627
+ var text2 = dmp . diff_text2 ( diffs ) ;
628
+ assertEquals ( 'A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + $ , # ' , text2 ) ;
629
+
630
+ delta = dmp . diff_toDelta ( diffs ) ;
631
+ assertEquals ( '+A-Z a-z 0-9 - _ . ! ~ * \' ( ) ; / ? : @ & = + $ , # ' , delta ) ;
632
+
633
+ // Convert delta string into a diff.
634
+ assertEquivalent ( diffs , dmp . diff_fromDelta ( '' , delta ) ) ;
635
+
636
+ // 160 kb string.
637
+ var a = 'abcdefghij' ;
638
+ for ( var i = 0 ; i < 14 ; i ++ ) {
639
+ a += a ;
640
+ }
641
+ diffs = [ [ DIFF_INSERT , a ] ] ;
642
+ delta = dmp . diff_toDelta ( diffs ) ;
643
+ assertEquals ( '+' + a , delta ) ;
644
+
645
+ // Convert delta string into a diff.
646
+ assertEquivalent ( diffs , dmp . diff_fromDelta ( '' , delta ) ) ;
647
647
}
648
648
649
649
function testDiffXIndex ( ) {
650
- // Translate a location in text1 to text2.
651
- // Translation on equality.
652
- assertEquals ( 5 , dmp . diff_xIndex ( [ [ DIFF_DELETE , 'a' ] , [ DIFF_INSERT , '1234' ] , [ DIFF_EQUAL , 'xyz' ] ] , 2 ) ) ;
653
-
654
- // Translation on deletion.
655
- assertEquals ( 1 , dmp . diff_xIndex ( [ [ DIFF_EQUAL , 'a' ] , [ DIFF_DELETE , '1234' ] , [ DIFF_EQUAL , 'xyz' ] ] , 3 ) ) ;
650
+ // Translate a location in text1 to text2.
651
+ // Translation on equality.
652
+ assertEquals ( 5 , dmp . diff_xIndex ( [ [ DIFF_DELETE , 'a' ] , [ DIFF_INSERT , '1234' ] , [ DIFF_EQUAL , 'xyz' ] ] , 2 ) ) ;
653
+
654
+ // Translation on deletion.
655
+ assertEquals ( 1 , dmp . diff_xIndex ( [ [ DIFF_EQUAL , 'a' ] , [ DIFF_DELETE , '1234' ] , [ DIFF_EQUAL , 'xyz' ] ] , 3 ) ) ;
656
656
}
657
657
658
658
function testDiffLevenshtein ( ) {
659
- // Levenshtein with trailing equality.
660
- assertEquals ( 4 , dmp . diff_levenshtein ( [ [ DIFF_DELETE , 'abc' ] , [ DIFF_INSERT , '1234' ] , [ DIFF_EQUAL , 'xyz' ] ] ) ) ;
661
- // Levenshtein with leading equality.
662
- assertEquals ( 4 , dmp . diff_levenshtein ( [ [ DIFF_EQUAL , 'xyz' ] , [ DIFF_DELETE , 'abc' ] , [ DIFF_INSERT , '1234' ] ] ) ) ;
663
- // Levenshtein with middle equality.
664
- assertEquals ( 7 , dmp . diff_levenshtein ( [ [ DIFF_DELETE , 'abc' ] , [ DIFF_EQUAL , 'xyz' ] , [ DIFF_INSERT , '1234' ] ] ) ) ;
659
+ // Levenshtein with trailing equality.
660
+ assertEquals ( 4 , dmp . diff_levenshtein ( [ [ DIFF_DELETE , 'abc' ] , [ DIFF_INSERT , '1234' ] , [ DIFF_EQUAL , 'xyz' ] ] ) ) ;
661
+ // Levenshtein with leading equality.
662
+ assertEquals ( 4 , dmp . diff_levenshtein ( [ [ DIFF_EQUAL , 'xyz' ] , [ DIFF_DELETE , 'abc' ] , [ DIFF_INSERT , '1234' ] ] ) ) ;
663
+ // Levenshtein with middle equality.
664
+ assertEquals ( 7 , dmp . diff_levenshtein ( [ [ DIFF_DELETE , 'abc' ] , [ DIFF_EQUAL , 'xyz' ] , [ DIFF_INSERT , '1234' ] ] ) ) ;
665
665
}
666
666
667
667
function testDiffBisect ( ) {
668
- // Normal.
669
- var a = 'cat' ;
670
- var b = 'map' ;
671
- // Since the resulting diff hasn't been normalized, it would be ok if
672
- // the insertion and deletion pairs are swapped.
673
- // If the order changes, tweak this test as required.
674
- assertEquivalent ( [ [ DIFF_DELETE , 'c' ] , [ DIFF_INSERT , 'm' ] , [ DIFF_EQUAL , 'a' ] , [ DIFF_DELETE , 't' ] , [ DIFF_INSERT , 'p' ] ] , dmp . diff_bisect_ ( a , b , Number . MAX_VALUE ) ) ;
675
-
676
- // Timeout.
677
- assertEquivalent ( [ [ DIFF_DELETE , 'cat' ] , [ DIFF_INSERT , 'map' ] ] , dmp . diff_bisect_ ( a , b , 0 ) ) ;
668
+ // Normal.
669
+ var a = 'cat' ;
670
+ var b = 'map' ;
671
+ // Since the resulting diff hasn't been normalized, it would be ok if
672
+ // the insertion and deletion pairs are swapped.
673
+ // If the order changes, tweak this test as required.
674
+ assertEquivalent ( [ [ DIFF_DELETE , 'c' ] , [ DIFF_INSERT , 'm' ] , [ DIFF_EQUAL , 'a' ] , [ DIFF_DELETE , 't' ] , [ DIFF_INSERT , 'p' ] ] , dmp . diff_bisect_ ( a , b , Number . MAX_VALUE ) ) ;
675
+
676
+ // Timeout.
677
+ assertEquivalent ( [ [ DIFF_DELETE , 'cat' ] , [ DIFF_INSERT , 'map' ] ] , dmp . diff_bisect_ ( a , b , 0 ) ) ;
678
678
}
679
679
680
680
function testDiffMain ( ) {
681
- // Perform a trivial diff.
682
- // Null case.
683
- assertEquivalent ( [ ] , dmp . diff_main ( '' , '' , false ) ) ;
684
-
685
- // Equality.
686
- assertEquivalent ( [ [ DIFF_EQUAL , 'abc' ] ] , dmp . diff_main ( 'abc' , 'abc' , false ) ) ;
687
-
688
- // Simple insertion.
689
- assertEquivalent ( [ [ DIFF_EQUAL , 'ab' ] , [ DIFF_INSERT , '123' ] , [ DIFF_EQUAL , 'c' ] ] , dmp . diff_main ( 'abc' , 'ab123c' , false ) ) ;
690
-
691
- // Simple deletion.
692
- assertEquivalent ( [ [ DIFF_EQUAL , 'a' ] , [ DIFF_DELETE , '123' ] , [ DIFF_EQUAL , 'bc' ] ] , dmp . diff_main ( 'a123bc' , 'abc' , false ) ) ;
693
-
694
- // Two insertions.
695
- assertEquivalent ( [ [ DIFF_EQUAL , 'a' ] , [ DIFF_INSERT , '123' ] , [ DIFF_EQUAL , 'b' ] , [ DIFF_INSERT , '456' ] , [ DIFF_EQUAL , 'c' ] ] , dmp . diff_main ( 'abc' , 'a123b456c' , false ) ) ;
696
-
697
- // Two deletions.
698
- assertEquivalent ( [ [ DIFF_EQUAL , 'a' ] , [ DIFF_DELETE , '123' ] , [ DIFF_EQUAL , 'b' ] , [ DIFF_DELETE , '456' ] , [ DIFF_EQUAL , 'c' ] ] , dmp . diff_main ( 'a123b456c' , 'abc' , false ) ) ;
699
-
700
- // Perform a real diff.
701
- // Switch off the timeout.
702
- dmp . Diff_Timeout = 0 ;
703
- // Simple cases.
704
- assertEquivalent ( [ [ DIFF_DELETE , 'a' ] , [ DIFF_INSERT , 'b' ] ] , dmp . diff_main ( 'a' , 'b' , false ) ) ;
705
-
706
- assertEquivalent ( [ [ DIFF_DELETE , 'Apple' ] , [ DIFF_INSERT , 'Banana' ] , [ DIFF_EQUAL , 's are a' ] , [ DIFF_INSERT , 'lso' ] , [ DIFF_EQUAL , ' fruit.' ] ] , dmp . diff_main ( 'Apples are a fruit.' , 'Bananas are also fruit.' , false ) ) ;
707
-
708
- assertEquivalent ( [ [ DIFF_DELETE , 'a' ] , [ DIFF_INSERT , '\u0680' ] , [ DIFF_EQUAL , 'x' ] , [ DIFF_DELETE , '\t' ] , [ DIFF_INSERT , '\0' ] ] , dmp . diff_main ( 'ax\t' , '\u0680x\0' , false ) ) ;
709
-
710
- // Overlaps.
711
- assertEquivalent ( [ [ DIFF_DELETE , '1' ] , [ DIFF_EQUAL , 'a' ] , [ DIFF_DELETE , 'y' ] , [ DIFF_EQUAL , 'b' ] , [ DIFF_DELETE , '2' ] , [ DIFF_INSERT , 'xab' ] ] , dmp . diff_main ( '1ayb2' , 'abxab' , false ) ) ;
712
-
713
- assertEquivalent ( [ [ DIFF_INSERT , 'xaxcx' ] , [ DIFF_EQUAL , 'abc' ] , [ DIFF_DELETE , 'y' ] ] , dmp . diff_main ( 'abcy' , 'xaxcxabc' , false ) ) ;
714
-
715
- assertEquivalent ( [ [ DIFF_DELETE , 'ABCD' ] , [ DIFF_EQUAL , 'a' ] , [ DIFF_DELETE , '=' ] , [ DIFF_INSERT , '-' ] , [ DIFF_EQUAL , 'bcd' ] , [ DIFF_DELETE , '=' ] , [ DIFF_INSERT , '-' ] , [ DIFF_EQUAL , 'efghijklmnopqrs' ] , [ DIFF_DELETE , 'EFGHIJKLMNOefg' ] ] , dmp . diff_main ( 'ABCDa=bcd=efghijklmnopqrsEFGHIJKLMNOefg' , 'a-bcd-efghijklmnopqrs' , false ) ) ;
716
-
717
- // Large equality.
718
- assertEquivalent ( [ [ DIFF_INSERT , ' ' ] , [ DIFF_EQUAL , 'a' ] , [ DIFF_INSERT , 'nd' ] , [ DIFF_EQUAL , ' [[Pennsylvania]]' ] , [ DIFF_DELETE , ' and [[New' ] ] , dmp . diff_main ( 'a [[Pennsylvania]] and [[New' , ' and [[Pennsylvania]]' , false ) ) ;
719
-
720
- // Timeout.
721
- dmp . Diff_Timeout = 0.1 ; // 100ms
722
- var a = '`Twas brillig, and the slithy toves\nDid gyre and gimble in the wabe:\nAll mimsy were the borogoves,\nAnd the mome raths outgrabe.\n' ;
723
- var b = 'I am the very model of a modern major general,\nI\'ve information vegetable, animal, and mineral,\nI know the kings of England, and I quote the fights historical,\nFrom Marathon to Waterloo, in order categorical.\n' ;
724
- // Increase the text lengths by 1024 times to ensure a timeout.
725
- for ( var i = 0 ; i < 10 ; i ++ ) {
726
- a += a ;
727
- b += b ;
728
- }
729
- var startTime = ( new Date ( ) ) . getTime ( ) ;
730
- dmp . diff_main ( a , b ) ;
731
- var endTime = ( new Date ( ) ) . getTime ( ) ;
732
- // Test that we took at least the timeout period.
733
- assertTrue ( dmp . Diff_Timeout * 1000 <= endTime - startTime ) ;
734
- // Test that we didn't take forever (be forgiving).
735
- // Theoretically this test could fail very occasionally if the
736
- // OS task swaps or locks up for a second at the wrong moment.
737
- assertTrue ( dmp . Diff_Timeout * 1000 * 2 > endTime - startTime ) ;
738
- dmp . Diff_Timeout = 0 ;
739
-
740
- // Test the linemode speedup.
741
- // Must be long to pass the 100 char cutoff.
742
- // Simple line-mode.
743
- a = '1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n' ;
744
- b = 'abcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\n' ;
745
- assertEquivalent ( dmp . diff_main ( a , b , false ) , dmp . diff_main ( a , b , true ) ) ;
746
-
747
- // Single line-mode.
748
- a = '1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890' ;
749
- b = 'abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij' ;
750
- assertEquivalent ( dmp . diff_main ( a , b , false ) , dmp . diff_main ( a , b , true ) ) ;
751
-
752
- // Overlap line-mode.
753
- a = '1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n' ;
754
- b = 'abcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n' ;
755
- var texts_linemode = diff_rebuildtexts ( dmp . diff_main ( a , b , true ) ) ;
756
- var texts_textmode = diff_rebuildtexts ( dmp . diff_main ( a , b , false ) ) ;
757
- assertEquivalent ( texts_textmode , texts_linemode ) ;
758
-
759
- // Test null inputs.
760
- try {
761
- dmp . diff_main ( null , null ) ;
762
- assertEquals ( Error , null ) ;
763
- } catch ( e ) {
764
- // Exception expected.
765
- }
681
+ // Perform a trivial diff.
682
+ // Null case.
683
+ assertEquivalent ( [ ] , dmp . diff_main ( '' , '' , false ) ) ;
684
+
685
+ // Equality.
686
+ assertEquivalent ( [ [ DIFF_EQUAL , 'abc' ] ] , dmp . diff_main ( 'abc' , 'abc' , false ) ) ;
687
+
688
+ // Simple insertion.
689
+ assertEquivalent ( [ [ DIFF_EQUAL , 'ab' ] , [ DIFF_INSERT , '123' ] , [ DIFF_EQUAL , 'c' ] ] , dmp . diff_main ( 'abc' , 'ab123c' , false ) ) ;
690
+
691
+ // Simple deletion.
692
+ assertEquivalent ( [ [ DIFF_EQUAL , 'a' ] , [ DIFF_DELETE , '123' ] , [ DIFF_EQUAL , 'bc' ] ] , dmp . diff_main ( 'a123bc' , 'abc' , false ) ) ;
693
+
694
+ // Two insertions.
695
+ assertEquivalent ( [ [ DIFF_EQUAL , 'a' ] , [ DIFF_INSERT , '123' ] , [ DIFF_EQUAL , 'b' ] , [ DIFF_INSERT , '456' ] , [ DIFF_EQUAL , 'c' ] ] , dmp . diff_main ( 'abc' , 'a123b456c' , false ) ) ;
696
+
697
+ // Two deletions.
698
+ assertEquivalent ( [ [ DIFF_EQUAL , 'a' ] , [ DIFF_DELETE , '123' ] , [ DIFF_EQUAL , 'b' ] , [ DIFF_DELETE , '456' ] , [ DIFF_EQUAL , 'c' ] ] , dmp . diff_main ( 'a123b456c' , 'abc' , false ) ) ;
699
+
700
+ // Perform a real diff.
701
+ // Switch off the timeout.
702
+ dmp . Diff_Timeout = 0 ;
703
+ // Simple cases.
704
+ assertEquivalent ( [ [ DIFF_DELETE , 'a' ] , [ DIFF_INSERT , 'b' ] ] , dmp . diff_main ( 'a' , 'b' , false ) ) ;
705
+
706
+ assertEquivalent ( [ [ DIFF_DELETE , 'Apple' ] , [ DIFF_INSERT , 'Banana' ] , [ DIFF_EQUAL , 's are a' ] , [ DIFF_INSERT , 'lso' ] , [ DIFF_EQUAL , ' fruit.' ] ] , dmp . diff_main ( 'Apples are a fruit.' , 'Bananas are also fruit.' , false ) ) ;
707
+
708
+ assertEquivalent ( [ [ DIFF_DELETE , 'a' ] , [ DIFF_INSERT , '\u0680' ] , [ DIFF_EQUAL , 'x' ] , [ DIFF_DELETE , '\t' ] , [ DIFF_INSERT , '\0' ] ] , dmp . diff_main ( 'ax\t' , '\u0680x\0' , false ) ) ;
709
+
710
+ // Overlaps.
711
+ assertEquivalent ( [ [ DIFF_DELETE , '1' ] , [ DIFF_EQUAL , 'a' ] , [ DIFF_DELETE , 'y' ] , [ DIFF_EQUAL , 'b' ] , [ DIFF_DELETE , '2' ] , [ DIFF_INSERT , 'xab' ] ] , dmp . diff_main ( '1ayb2' , 'abxab' , false ) ) ;
712
+
713
+ assertEquivalent ( [ [ DIFF_INSERT , 'xaxcx' ] , [ DIFF_EQUAL , 'abc' ] , [ DIFF_DELETE , 'y' ] ] , dmp . diff_main ( 'abcy' , 'xaxcxabc' , false ) ) ;
714
+
715
+ assertEquivalent ( [ [ DIFF_DELETE , 'ABCD' ] , [ DIFF_EQUAL , 'a' ] , [ DIFF_DELETE , '=' ] , [ DIFF_INSERT , '-' ] , [ DIFF_EQUAL , 'bcd' ] , [ DIFF_DELETE , '=' ] , [ DIFF_INSERT , '-' ] , [ DIFF_EQUAL , 'efghijklmnopqrs' ] , [ DIFF_DELETE , 'EFGHIJKLMNOefg' ] ] , dmp . diff_main ( 'ABCDa=bcd=efghijklmnopqrsEFGHIJKLMNOefg' , 'a-bcd-efghijklmnopqrs' , false ) ) ;
716
+
717
+ // Large equality.
718
+ assertEquivalent ( [ [ DIFF_INSERT , ' ' ] , [ DIFF_EQUAL , 'a' ] , [ DIFF_INSERT , 'nd' ] , [ DIFF_EQUAL , ' [[Pennsylvania]]' ] , [ DIFF_DELETE , ' and [[New' ] ] , dmp . diff_main ( 'a [[Pennsylvania]] and [[New' , ' and [[Pennsylvania]]' , false ) ) ;
719
+
720
+ // Timeout.
721
+ dmp . Diff_Timeout = 0.1 ; // 100ms
722
+ var a = '`Twas brillig, and the slithy toves\nDid gyre and gimble in the wabe:\nAll mimsy were the borogoves,\nAnd the mome raths outgrabe.\n' ;
723
+ var b = 'I am the very model of a modern major general,\nI\'ve information vegetable, animal, and mineral,\nI know the kings of England, and I quote the fights historical,\nFrom Marathon to Waterloo, in order categorical.\n' ;
724
+ // Increase the text lengths by 1024 times to ensure a timeout.
725
+ for ( var i = 0 ; i < 10 ; i ++ ) {
726
+ a += a ;
727
+ b += b ;
728
+ }
729
+ var startTime = ( new Date ( ) ) . getTime ( ) ;
730
+ dmp . diff_main ( a , b ) ;
731
+ var endTime = ( new Date ( ) ) . getTime ( ) ;
732
+ // Test that we took at least the timeout period.
733
+ assertTrue ( dmp . Diff_Timeout * 1000 <= endTime - startTime ) ;
734
+ // Test that we didn't take forever (be forgiving).
735
+ // Theoretically this test could fail very occasionally if the
736
+ // OS task swaps or locks up for a second at the wrong moment.
737
+ assertTrue ( dmp . Diff_Timeout * 1000 * 2 > endTime - startTime ) ;
738
+ dmp . Diff_Timeout = 0 ;
739
+
740
+ // Test the linemode speedup.
741
+ // Must be long to pass the 100 char cutoff.
742
+ // Simple line-mode.
743
+ a = '1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n' ;
744
+ b = 'abcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\nabcdefghij\n' ;
745
+ assertEquivalent ( dmp . diff_main ( a , b , false ) , dmp . diff_main ( a , b , true ) ) ;
746
+
747
+ // Single line-mode.
748
+ a = '1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890' ;
749
+ b = 'abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij' ;
750
+ assertEquivalent ( dmp . diff_main ( a , b , false ) , dmp . diff_main ( a , b , true ) ) ;
751
+
752
+ // Overlap line-mode.
753
+ a = '1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n1234567890\n' ;
754
+ b = 'abcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n1234567890\n1234567890\n1234567890\nabcdefghij\n' ;
755
+ var texts_linemode = diff_rebuildtexts ( dmp . diff_main ( a , b , true ) ) ;
756
+ var texts_textmode = diff_rebuildtexts ( dmp . diff_main ( a , b , false ) ) ;
757
+ assertEquivalent ( texts_textmode , texts_linemode ) ;
758
+
759
+ // Test null inputs.
760
+ try {
761
+ dmp . diff_main ( null , null ) ;
762
+ assertEquals ( Error , null ) ;
763
+ } catch ( e ) {
764
+ // Exception expected.
765
+ }
766
766
}
767
767
768
768
769
769
// MATCH TEST FUNCTIONS
770
770
771
771
772
772
function testMatchAlphabet ( ) {
773
- // Initialise the bitmasks for Bitap.
774
- // Unique.
775
- assertEquivalent ( { 'a' :4 , 'b' :2 , 'c' :1 } , dmp . match_alphabet_ ( 'abc' ) ) ;
776
-
777
- // Duplicates.
778
- assertEquivalent ( { 'a' :37 , 'b' :18 , 'c' :8 } , dmp . match_alphabet_ ( 'abcaba' ) ) ;
773
+ // Initialise the bitmasks for Bitap.
774
+ // Unique.
775
+ assertEquivalent ( { 'a' :4 , 'b' :2 , 'c' :1 } , dmp . match_alphabet_ ( 'abc' ) ) ;
776
+
777
+ // Duplicates.
778
+ assertEquivalent ( { 'a' :37 , 'b' :18 , 'c' :8 } , dmp . match_alphabet_ ( 'abcaba' ) ) ;
779
779
}
780
780
781
781
function testMatchBitap ( ) {
782
- // Bitap algorithm.
783
- dmp . Match_Distance = 100 ;
784
- dmp . Match_Threshold = 0.5 ;
785
- // Exact matches.
786
- assertEquals ( 5 , dmp . match_bitap_ ( 'abcdefghijk' , 'fgh' , 5 ) ) ;
787
-
788
- assertEquals ( 5 , dmp . match_bitap_ ( 'abcdefghijk' , 'fgh' , 0 ) ) ;
789
-
790
- // Fuzzy matches.
791
- assertEquals ( 4 , dmp . match_bitap_ ( 'abcdefghijk' , 'efxhi' , 0 ) ) ;
792
-
793
- assertEquals ( 2 , dmp . match_bitap_ ( 'abcdefghijk' , 'cdefxyhijk' , 5 ) ) ;
794
-
795
- assertEquals ( - 1 , dmp . match_bitap_ ( 'abcdefghijk' , 'bxy' , 1 ) ) ;
796
-
797
- // Overflow.
798
- assertEquals ( 2 , dmp . match_bitap_ ( '123456789xx0' , '3456789x0' , 2 ) ) ;
799
-
800
- // Threshold test.
801
- dmp . Match_Threshold = 0.4 ;
802
- assertEquals ( 4 , dmp . match_bitap_ ( 'abcdefghijk' , 'efxyhi' , 1 ) ) ;
803
-
804
- dmp . Match_Threshold = 0.3 ;
805
- assertEquals ( - 1 , dmp . match_bitap_ ( 'abcdefghijk' , 'efxyhi' , 1 ) ) ;
806
-
807
- dmp . Match_Threshold = 0.0 ;
808
- assertEquals ( 1 , dmp . match_bitap_ ( 'abcdefghijk' , 'bcdef' , 1 ) ) ;
809
- dmp . Match_Threshold = 0.5 ;
810
-
811
- // Multiple select.
812
- assertEquals ( 0 , dmp . match_bitap_ ( 'abcdexyzabcde' , 'abccde' , 3 ) ) ;
813
-
814
- assertEquals ( 8 , dmp . match_bitap_ ( 'abcdexyzabcde' , 'abccde' , 5 ) ) ;
815
-
816
- // Distance test.
817
- dmp . Match_Distance = 10 ; // Strict location.
818
- assertEquals ( - 1 , dmp . match_bitap_ ( 'abcdefghijklmnopqrstuvwxyz' , 'abcdefg' , 24 ) ) ;
819
-
820
- assertEquals ( 0 , dmp . match_bitap_ ( 'abcdefghijklmnopqrstuvwxyz' , 'abcdxxefg' , 1 ) ) ;
821
-
822
- dmp . Match_Distance = 1000 ; // Loose location.
823
- assertEquals ( 0 , dmp . match_bitap_ ( 'abcdefghijklmnopqrstuvwxyz' , 'abcdefg' , 24 ) ) ;
782
+ // Bitap algorithm.
783
+ dmp . Match_Distance = 100 ;
784
+ dmp . Match_Threshold = 0.5 ;
785
+ // Exact matches.
786
+ assertEquals ( 5 , dmp . match_bitap_ ( 'abcdefghijk' , 'fgh' , 5 ) ) ;
787
+
788
+ assertEquals ( 5 , dmp . match_bitap_ ( 'abcdefghijk' , 'fgh' , 0 ) ) ;
789
+
790
+ // Fuzzy matches.
791
+ assertEquals ( 4 , dmp . match_bitap_ ( 'abcdefghijk' , 'efxhi' , 0 ) ) ;
792
+
793
+ assertEquals ( 2 , dmp . match_bitap_ ( 'abcdefghijk' , 'cdefxyhijk' , 5 ) ) ;
794
+
795
+ assertEquals ( - 1 , dmp . match_bitap_ ( 'abcdefghijk' , 'bxy' , 1 ) ) ;
796
+
797
+ // Overflow.
798
+ assertEquals ( 2 , dmp . match_bitap_ ( '123456789xx0' , '3456789x0' , 2 ) ) ;
799
+
800
+ // Threshold test.
801
+ dmp . Match_Threshold = 0.4 ;
802
+ assertEquals ( 4 , dmp . match_bitap_ ( 'abcdefghijk' , 'efxyhi' , 1 ) ) ;
803
+
804
+ dmp . Match_Threshold = 0.3 ;
805
+ assertEquals ( - 1 , dmp . match_bitap_ ( 'abcdefghijk' , 'efxyhi' , 1 ) ) ;
806
+
807
+ dmp . Match_Threshold = 0.0 ;
808
+ assertEquals ( 1 , dmp . match_bitap_ ( 'abcdefghijk' , 'bcdef' , 1 ) ) ;
809
+ dmp . Match_Threshold = 0.5 ;
810
+
811
+ // Multiple select.
812
+ assertEquals ( 0 , dmp . match_bitap_ ( 'abcdexyzabcde' , 'abccde' , 3 ) ) ;
813
+
814
+ assertEquals ( 8 , dmp . match_bitap_ ( 'abcdexyzabcde' , 'abccde' , 5 ) ) ;
815
+
816
+ // Distance test.
817
+ dmp . Match_Distance = 10 ; // Strict location.
818
+ assertEquals ( - 1 , dmp . match_bitap_ ( 'abcdefghijklmnopqrstuvwxyz' , 'abcdefg' , 24 ) ) ;
819
+
820
+ assertEquals ( 0 , dmp . match_bitap_ ( 'abcdefghijklmnopqrstuvwxyz' , 'abcdxxefg' , 1 ) ) ;
821
+
822
+ dmp . Match_Distance = 1000 ; // Loose location.
823
+ assertEquals ( 0 , dmp . match_bitap_ ( 'abcdefghijklmnopqrstuvwxyz' , 'abcdefg' , 24 ) ) ;
824
824
}
825
825
826
826
function testMatchMain ( ) {
827
- // Full match.
828
- // Shortcut matches.
829
- assertEquals ( 0 , dmp . match_main ( 'abcdef' , 'abcdef' , 1000 ) ) ;
830
-
831
- assertEquals ( - 1 , dmp . match_main ( '' , 'abcdef' , 1 ) ) ;
832
-
833
- assertEquals ( 3 , dmp . match_main ( 'abcdef' , '' , 3 ) ) ;
834
-
835
- assertEquals ( 3 , dmp . match_main ( 'abcdef' , 'de' , 3 ) ) ;
836
-
837
- // Beyond end match.
838
- assertEquals ( 3 , dmp . match_main ( "abcdef" , "defy" , 4 ) ) ;
839
-
840
- // Oversized pattern.
841
- assertEquals ( 0 , dmp . match_main ( "abcdef" , "abcdefy" , 0 ) ) ;
842
-
843
- // Complex match.
844
- assertEquals ( 4 , dmp . match_main ( 'I am the very model of a modern major general.' , ' that berry ' , 5 ) ) ;
845
-
846
- // Test null inputs.
847
- try {
848
- dmp . match_main ( null , null , 0 ) ;
849
- assertEquals ( Error , null ) ;
850
- } catch ( e ) {
851
- // Exception expected.
852
- }
827
+ // Full match.
828
+ // Shortcut matches.
829
+ assertEquals ( 0 , dmp . match_main ( 'abcdef' , 'abcdef' , 1000 ) ) ;
830
+
831
+ assertEquals ( - 1 , dmp . match_main ( '' , 'abcdef' , 1 ) ) ;
832
+
833
+ assertEquals ( 3 , dmp . match_main ( 'abcdef' , '' , 3 ) ) ;
834
+
835
+ assertEquals ( 3 , dmp . match_main ( 'abcdef' , 'de' , 3 ) ) ;
836
+
837
+ // Beyond end match.
838
+ assertEquals ( 3 , dmp . match_main ( "abcdef" , "defy" , 4 ) ) ;
839
+
840
+ // Oversized pattern.
841
+ assertEquals ( 0 , dmp . match_main ( "abcdef" , "abcdefy" , 0 ) ) ;
842
+
843
+ // Complex match.
844
+ assertEquals ( 4 , dmp . match_main ( 'I am the very model of a modern major general.' , ' that berry ' , 5 ) ) ;
845
+
846
+ // Test null inputs.
847
+ try {
848
+ dmp . match_main ( null , null , 0 ) ;
849
+ assertEquals ( Error , null ) ;
850
+ } catch ( e ) {
851
+ // Exception expected.
852
+ }
853
853
}
854
854
855
855
856
856
// PATCH TEST FUNCTIONS
857
857
858
858
859
859
function testPatchObj ( ) {
860
- // Patch Object.
861
- var p = new diff_match_patch . patch_obj ( ) ;
862
- p . start1 = 20 ;
863
- p . start2 = 21 ;
864
- p . length1 = 18 ;
865
- p . length2 = 17 ;
866
- p . diffs = [ [ DIFF_EQUAL , 'jump' ] , [ DIFF_DELETE , 's' ] , [ DIFF_INSERT , 'ed' ] , [ DIFF_EQUAL , ' over ' ] , [ DIFF_DELETE , 'the' ] , [ DIFF_INSERT , 'a' ] , [ DIFF_EQUAL , '\nlaz' ] ] ;
867
- var strp = p . toString ( ) ;
868
- assertEquals ( '@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n %0Alaz\n' , strp ) ;
860
+ // Patch Object.
861
+ var p = new diff_match_patch . patch_obj ( ) ;
862
+ p . start1 = 20 ;
863
+ p . start2 = 21 ;
864
+ p . length1 = 18 ;
865
+ p . length2 = 17 ;
866
+ p . diffs = [ [ DIFF_EQUAL , 'jump' ] , [ DIFF_DELETE , 's' ] , [ DIFF_INSERT , 'ed' ] , [ DIFF_EQUAL , ' over ' ] , [ DIFF_DELETE , 'the' ] , [ DIFF_INSERT , 'a' ] , [ DIFF_EQUAL , '\nlaz' ] ] ;
867
+ var strp = p . toString ( ) ;
868
+ assertEquals ( '@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n %0Alaz\n' , strp ) ;
869
869
}
870
870
871
871
function testPatchFromText ( ) {
872
- assertEquivalent ( [ ] , dmp . patch_fromText ( strp ) ) ;
873
-
874
- var strp = '@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n %0Alaz\n' ;
875
- assertEquals ( strp , dmp . patch_fromText ( strp ) [ 0 ] . toString ( ) ) ;
876
-
877
- assertEquals ( '@@ -1 +1 @@\n-a\n+b\n' , dmp . patch_fromText ( '@@ -1 +1 @@\n-a\n+b\n' ) [ 0 ] . toString ( ) ) ;
878
-
879
- assertEquals ( '@@ -1,3 +0,0 @@\n-abc\n' , dmp . patch_fromText ( '@@ -1,3 +0,0 @@\n-abc\n' ) [ 0 ] . toString ( ) ) ;
880
-
881
- assertEquals ( '@@ -0,0 +1,3 @@\n+abc\n' , dmp . patch_fromText ( '@@ -0,0 +1,3 @@\n+abc\n' ) [ 0 ] . toString ( ) ) ;
882
-
883
- // Generates error.
884
- try {
885
- dmp . patch_fromText ( 'Bad\nPatch\n' ) ;
886
- assertEquals ( Error , null ) ;
887
- } catch ( e ) {
888
- // Exception expected.
889
- }
872
+ assertEquivalent ( [ ] , dmp . patch_fromText ( strp ) ) ;
873
+
874
+ var strp = '@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n %0Alaz\n' ;
875
+ assertEquals ( strp , dmp . patch_fromText ( strp ) [ 0 ] . toString ( ) ) ;
876
+
877
+ assertEquals ( '@@ -1 +1 @@\n-a\n+b\n' , dmp . patch_fromText ( '@@ -1 +1 @@\n-a\n+b\n' ) [ 0 ] . toString ( ) ) ;
878
+
879
+ assertEquals ( '@@ -1,3 +0,0 @@\n-abc\n' , dmp . patch_fromText ( '@@ -1,3 +0,0 @@\n-abc\n' ) [ 0 ] . toString ( ) ) ;
880
+
881
+ assertEquals ( '@@ -0,0 +1,3 @@\n+abc\n' , dmp . patch_fromText ( '@@ -0,0 +1,3 @@\n+abc\n' ) [ 0 ] . toString ( ) ) ;
882
+
883
+ // Generates error.
884
+ try {
885
+ dmp . patch_fromText ( 'Bad\nPatch\n' ) ;
886
+ assertEquals ( Error , null ) ;
887
+ } catch ( e ) {
888
+ // Exception expected.
889
+ }
890
890
}
891
891
892
892
function testPatchToText ( ) {
893
- var strp = '@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n laz\n' ;
894
- var p = dmp . patch_fromText ( strp ) ;
893
+ var strp = '@@ -21,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n laz\n' ;
894
+ var p = dmp . patch_fromText ( strp ) ;
895
+ assertEquals ( strp , dmp . patch_toText ( p ) ) ;
896
+
897
+ strp = '@@ -1,9 +1,9 @@\n-f\n+F\n oo+fooba\n@@ -7,9 +7,9 @@\n obar\n-,\n+.\n tes\n' ;
898
+ p = dmp . patch_fromText ( strp ) ;
895
899
assertEquals ( strp , dmp . patch_toText ( p ) ) ;
896
-
897
- strp = '@@ -1,9 +1,9 @@\n-f\n+F\n oo+fooba\n@@ -7,9 +7,9 @@\n obar\n-,\n+.\n tes\n' ;
898
- p = dmp . patch_fromText ( strp ) ;
899
- assertEquals ( strp , dmp . patch_toText ( p ) ) ;
900
900
}
901
901
902
902
function testPatchAddContext ( ) {
903
- dmp . Patch_Margin = 4 ;
904
- var p = dmp . patch_fromText ( '@@ -21,4 +21,10 @@\n-jump\n+somersault\n' ) [ 0 ] ;
905
- dmp . patch_addContext_ ( p , 'The quick brown fox jumps over the lazy dog.' ) ;
906
- assertEquals ( '@@ -17,12 +17,18 @@\n fox \n-jump\n+somersault\n s ov\n' , p . toString ( ) ) ;
907
-
908
- // Same, but not enough trailing context.
909
- p = dmp . patch_fromText ( '@@ -21,4 +21,10 @@\n-jump\n+somersault\n' ) [ 0 ] ;
910
- dmp . patch_addContext_ ( p , 'The quick brown fox jumps.' ) ;
911
- assertEquals ( '@@ -17,10 +17,16 @@\n fox \n-jump\n+somersault\n s.\n' , p . toString ( ) ) ;
912
-
913
- // Same, but not enough leading context.
914
- p = dmp . patch_fromText ( '@@ -3 +3,2 @@\n-e\n+at\n' ) [ 0 ] ;
915
- dmp . patch_addContext_ ( p , 'The quick brown fox jumps.' ) ;
916
- assertEquals ( '@@ -1,7 +1,8 @@\n Th\n-e\n+at\n qui\n' , p . toString ( ) ) ;
917
-
918
- // Same, but with ambiguity.
919
- p = dmp . patch_fromText ( '@@ -3 +3,2 @@\n-e\n+at\n' ) [ 0 ] ;
920
- dmp . patch_addContext_ ( p , 'The quick brown fox jumps. The quick brown fox crashes.' ) ;
921
- assertEquals ( '@@ -1,27 +1,28 @@\n Th\n-e\n+at\n quick brown fox jumps. \n' , p . toString ( ) ) ;
903
+ dmp . Patch_Margin = 4 ;
904
+ var p = dmp . patch_fromText ( '@@ -21,4 +21,10 @@\n-jump\n+somersault\n' ) [ 0 ] ;
905
+ dmp . patch_addContext_ ( p , 'The quick brown fox jumps over the lazy dog.' ) ;
906
+ assertEquals ( '@@ -17,12 +17,18 @@\n fox \n-jump\n+somersault\n s ov\n' , p . toString ( ) ) ;
907
+
908
+ // Same, but not enough trailing context.
909
+ p = dmp . patch_fromText ( '@@ -21,4 +21,10 @@\n-jump\n+somersault\n' ) [ 0 ] ;
910
+ dmp . patch_addContext_ ( p , 'The quick brown fox jumps.' ) ;
911
+ assertEquals ( '@@ -17,10 +17,16 @@\n fox \n-jump\n+somersault\n s.\n' , p . toString ( ) ) ;
912
+
913
+ // Same, but not enough leading context.
914
+ p = dmp . patch_fromText ( '@@ -3 +3,2 @@\n-e\n+at\n' ) [ 0 ] ;
915
+ dmp . patch_addContext_ ( p , 'The quick brown fox jumps.' ) ;
916
+ assertEquals ( '@@ -1,7 +1,8 @@\n Th\n-e\n+at\n qui\n' , p . toString ( ) ) ;
917
+
918
+ // Same, but with ambiguity.
919
+ p = dmp . patch_fromText ( '@@ -3 +3,2 @@\n-e\n+at\n' ) [ 0 ] ;
920
+ dmp . patch_addContext_ ( p , 'The quick brown fox jumps. The quick brown fox crashes.' ) ;
921
+ assertEquals ( '@@ -1,27 +1,28 @@\n Th\n-e\n+at\n quick brown fox jumps. \n' , p . toString ( ) ) ;
922
922
}
923
923
924
924
function testPatchMake ( ) {
925
- // Null case.
926
- var patches = dmp . patch_make ( '' , '' ) ;
927
- assertEquals ( '' , dmp . patch_toText ( patches ) ) ;
928
-
929
- var text1 = 'The quick brown fox jumps over the lazy dog.' ;
930
- var text2 = 'That quick brown fox jumped over a lazy dog.' ;
931
- // Text2+Text1 inputs.
932
- var expectedPatch = '@@ -1,8 +1,7 @@\n Th\n-at\n+e\n qui\n@@ -21,17 +21,18 @@\n jump\n-ed\n+s\n over \n-a\n+the\n laz\n' ;
933
- // The second patch must be "-21,17 +21,18", not "-22,17 +21,18" due to rolling context.
934
- patches = dmp . patch_make ( text2 , text1 ) ;
935
- assertEquals ( expectedPatch , dmp . patch_toText ( patches ) ) ;
936
-
937
- // Text1+Text2 inputs.
938
- expectedPatch = '@@ -1,11 +1,12 @@\n Th\n-e\n+at\n quick b\n@@ -22,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n laz\n' ;
939
- patches = dmp . patch_make ( text1 , text2 ) ;
940
- assertEquals ( expectedPatch , dmp . patch_toText ( patches ) ) ;
941
-
942
- // Diff input.
943
- var diffs = dmp . diff_main ( text1 , text2 , false ) ;
944
- patches = dmp . patch_make ( diffs ) ;
945
- assertEquals ( expectedPatch , dmp . patch_toText ( patches ) ) ;
946
-
947
- // Text1+Diff inputs.
948
- patches = dmp . patch_make ( text1 , diffs ) ;
949
- assertEquals ( expectedPatch , dmp . patch_toText ( patches ) ) ;
950
-
951
- // Text1+Text2+Diff inputs (deprecated).
952
- patches = dmp . patch_make ( text1 , text2 , diffs ) ;
953
- assertEquals ( expectedPatch , dmp . patch_toText ( patches ) ) ;
954
-
955
- // Character encoding.
956
- patches = dmp . patch_make ( '`1234567890-=[]\\;\',./' , '~!@#$%^&*()_+{}|:"<>?' ) ;
957
- assertEquals ( '@@ -1,21 +1,21 @@\n-%601234567890-=%5B%5D%5C;\',./\n+~!@#$%25%5E&*()_+%7B%7D%7C:%22%3C%3E?\n' , dmp . patch_toText ( patches ) ) ;
958
-
959
- // Character decoding.
960
- diffs = [ [ DIFF_DELETE , '`1234567890-=[]\\;\',./' ] , [ DIFF_INSERT , '~!@#$%^&*()_+{}|:"<>?' ] ] ;
961
- assertEquivalent ( diffs , dmp . patch_fromText ( '@@ -1,21 +1,21 @@\n-%601234567890-=%5B%5D%5C;\',./\n+~!@#$%25%5E&*()_+%7B%7D%7C:%22%3C%3E?\n' ) [ 0 ] . diffs ) ;
962
-
963
- // Long string with repeats.
964
- text1 = '' ;
965
- for ( var x = 0 ; x < 100 ; x ++ ) {
966
- text1 += 'abcdef' ;
967
- }
968
- text2 = text1 + '123' ;
969
- expectedPatch = '@@ -573,28 +573,31 @@\n cdefabcdefabcdefabcdefabcdef\n+123\n' ;
970
- patches = dmp . patch_make ( text1 , text2 ) ;
971
- assertEquals ( expectedPatch , dmp . patch_toText ( patches ) ) ;
972
-
973
- // Test null inputs.
974
- try {
975
- dmp . patch_make ( null ) ;
976
- assertEquals ( Error , null ) ;
977
- } catch ( e ) {
978
- // Exception expected.
979
- }
925
+ // Null case.
926
+ var patches = dmp . patch_make ( '' , '' ) ;
927
+ assertEquals ( '' , dmp . patch_toText ( patches ) ) ;
928
+
929
+ var text1 = 'The quick brown fox jumps over the lazy dog.' ;
930
+ var text2 = 'That quick brown fox jumped over a lazy dog.' ;
931
+ // Text2+Text1 inputs.
932
+ var expectedPatch = '@@ -1,8 +1,7 @@\n Th\n-at\n+e\n qui\n@@ -21,17 +21,18 @@\n jump\n-ed\n+s\n over \n-a\n+the\n laz\n' ;
933
+ // The second patch must be "-21,17 +21,18", not "-22,17 +21,18" due to rolling context.
934
+ patches = dmp . patch_make ( text2 , text1 ) ;
935
+ assertEquals ( expectedPatch , dmp . patch_toText ( patches ) ) ;
936
+
937
+ // Text1+Text2 inputs.
938
+ expectedPatch = '@@ -1,11 +1,12 @@\n Th\n-e\n+at\n quick b\n@@ -22,18 +22,17 @@\n jump\n-s\n+ed\n over \n-the\n+a\n laz\n' ;
939
+ patches = dmp . patch_make ( text1 , text2 ) ;
940
+ assertEquals ( expectedPatch , dmp . patch_toText ( patches ) ) ;
941
+
942
+ // Diff input.
943
+ var diffs = dmp . diff_main ( text1 , text2 , false ) ;
944
+ patches = dmp . patch_make ( diffs ) ;
945
+ assertEquals ( expectedPatch , dmp . patch_toText ( patches ) ) ;
946
+
947
+ // Text1+Diff inputs.
948
+ patches = dmp . patch_make ( text1 , diffs ) ;
949
+ assertEquals ( expectedPatch , dmp . patch_toText ( patches ) ) ;
950
+
951
+ // Text1+Text2+Diff inputs (deprecated).
952
+ patches = dmp . patch_make ( text1 , text2 , diffs ) ;
953
+ assertEquals ( expectedPatch , dmp . patch_toText ( patches ) ) ;
954
+
955
+ // Character encoding.
956
+ patches = dmp . patch_make ( '`1234567890-=[]\\;\',./' , '~!@#$%^&*()_+{}|:"<>?' ) ;
957
+ assertEquals ( '@@ -1,21 +1,21 @@\n-%601234567890-=%5B%5D%5C;\',./\n+~!@#$%25%5E&*()_+%7B%7D%7C:%22%3C%3E?\n' , dmp . patch_toText ( patches ) ) ;
958
+
959
+ // Character decoding.
960
+ diffs = [ [ DIFF_DELETE , '`1234567890-=[]\\;\',./' ] , [ DIFF_INSERT , '~!@#$%^&*()_+{}|:"<>?' ] ] ;
961
+ assertEquivalent ( diffs , dmp . patch_fromText ( '@@ -1,21 +1,21 @@\n-%601234567890-=%5B%5D%5C;\',./\n+~!@#$%25%5E&*()_+%7B%7D%7C:%22%3C%3E?\n' ) [ 0 ] . diffs ) ;
962
+
963
+ // Long string with repeats.
964
+ text1 = '' ;
965
+ for ( var x = 0 ; x < 100 ; x ++ ) {
966
+ text1 += 'abcdef' ;
967
+ }
968
+ text2 = text1 + '123' ;
969
+ expectedPatch = '@@ -573,28 +573,31 @@\n cdefabcdefabcdefabcdefabcdef\n+123\n' ;
970
+ patches = dmp . patch_make ( text1 , text2 ) ;
971
+ assertEquals ( expectedPatch , dmp . patch_toText ( patches ) ) ;
972
+
973
+ // Test null inputs.
974
+ try {
975
+ dmp . patch_make ( null ) ;
976
+ assertEquals ( Error , null ) ;
977
+ } catch ( e ) {
978
+ // Exception expected.
979
+ }
980
980
}
981
981
982
982
function testPatchSplitMax ( ) {
983
- // Assumes that dmp.Match_MaxBits is 32.
984
- var patches = dmp . patch_make ( 'abcdefghijklmnopqrstuvwxyz01234567890' , 'XabXcdXefXghXijXklXmnXopXqrXstXuvXwxXyzX01X23X45X67X89X0' ) ;
985
- dmp . patch_splitMax ( patches ) ;
986
- assertEquals ( '@@ -1,32 +1,46 @@\n+X\n ab\n+X\n cd\n+X\n ef\n+X\n gh\n+X\n ij\n+X\n kl\n+X\n mn\n+X\n op\n+X\n qr\n+X\n st\n+X\n uv\n+X\n wx\n+X\n yz\n+X\n 012345\n@@ -25,13 +39,18 @@\n zX01\n+X\n 23\n+X\n 45\n+X\n 67\n+X\n 89\n+X\n 0\n' , dmp . patch_toText ( patches ) ) ;
987
-
988
- patches = dmp . patch_make ( 'abcdef1234567890123456789012345678901234567890123456789012345678901234567890uvwxyz' , 'abcdefuvwxyz' ) ;
989
- var oldToText = dmp . patch_toText ( patches ) ;
990
- dmp . patch_splitMax ( patches ) ;
991
- assertEquals ( oldToText , dmp . patch_toText ( patches ) ) ;
992
-
993
- patches = dmp . patch_make ( '1234567890123456789012345678901234567890123456789012345678901234567890' , 'abc' ) ;
994
- dmp . patch_splitMax ( patches ) ;
995
- assertEquals ( '@@ -1,32 +1,4 @@\n-1234567890123456789012345678\n 9012\n@@ -29,32 +1,4 @@\n-9012345678901234567890123456\n 7890\n@@ -57,14 +1,3 @@\n-78901234567890\n+abc\n' , dmp . patch_toText ( patches ) ) ;
996
-
997
- patches = dmp . patch_make ( 'abcdefghij , h : 0 , t : 1 abcdefghij , h : 0 , t : 1 abcdefghij , h : 0 , t : 1' , 'abcdefghij , h : 1 , t : 1 abcdefghij , h : 1 , t : 1 abcdefghij , h : 0 , t : 1' ) ;
998
- dmp . patch_splitMax ( patches ) ;
999
- assertEquals ( '@@ -2,32 +2,32 @@\n bcdefghij , h : \n-0\n+1\n , t : 1 abcdef\n@@ -29,32 +29,32 @@\n bcdefghij , h : \n-0\n+1\n , t : 1 abcdef\n' , dmp . patch_toText ( patches ) ) ;
983
+ // Assumes that dmp.Match_MaxBits is 32.
984
+ var patches = dmp . patch_make ( 'abcdefghijklmnopqrstuvwxyz01234567890' , 'XabXcdXefXghXijXklXmnXopXqrXstXuvXwxXyzX01X23X45X67X89X0' ) ;
985
+ dmp . patch_splitMax ( patches ) ;
986
+ assertEquals ( '@@ -1,32 +1,46 @@\n+X\n ab\n+X\n cd\n+X\n ef\n+X\n gh\n+X\n ij\n+X\n kl\n+X\n mn\n+X\n op\n+X\n qr\n+X\n st\n+X\n uv\n+X\n wx\n+X\n yz\n+X\n 012345\n@@ -25,13 +39,18 @@\n zX01\n+X\n 23\n+X\n 45\n+X\n 67\n+X\n 89\n+X\n 0\n' , dmp . patch_toText ( patches ) ) ;
987
+
988
+ patches = dmp . patch_make ( 'abcdef1234567890123456789012345678901234567890123456789012345678901234567890uvwxyz' , 'abcdefuvwxyz' ) ;
989
+ var oldToText = dmp . patch_toText ( patches ) ;
990
+ dmp . patch_splitMax ( patches ) ;
991
+ assertEquals ( oldToText , dmp . patch_toText ( patches ) ) ;
992
+
993
+ patches = dmp . patch_make ( '1234567890123456789012345678901234567890123456789012345678901234567890' , 'abc' ) ;
994
+ dmp . patch_splitMax ( patches ) ;
995
+ assertEquals ( '@@ -1,32 +1,4 @@\n-1234567890123456789012345678\n 9012\n@@ -29,32 +1,4 @@\n-9012345678901234567890123456\n 7890\n@@ -57,14 +1,3 @@\n-78901234567890\n+abc\n' , dmp . patch_toText ( patches ) ) ;
996
+
997
+ patches = dmp . patch_make ( 'abcdefghij , h : 0 , t : 1 abcdefghij , h : 0 , t : 1 abcdefghij , h : 0 , t : 1' , 'abcdefghij , h : 1 , t : 1 abcdefghij , h : 1 , t : 1 abcdefghij , h : 0 , t : 1' ) ;
998
+ dmp . patch_splitMax ( patches ) ;
999
+ assertEquals ( '@@ -2,32 +2,32 @@\n bcdefghij , h : \n-0\n+1\n , t : 1 abcdef\n@@ -29,32 +29,32 @@\n bcdefghij , h : \n-0\n+1\n , t : 1 abcdef\n' , dmp . patch_toText ( patches ) ) ;
1000
1000
}
1001
1001
1002
1002
function testPatchAddPadding ( ) {
1003
- // Both edges full.
1004
- var patches = dmp . patch_make ( '' , 'test' ) ;
1005
- assertEquals ( '@@ -0,0 +1,4 @@\n+test\n' , dmp . patch_toText ( patches ) ) ;
1006
- dmp . patch_addPadding ( patches ) ;
1007
- assertEquals ( '@@ -1,8 +1,12 @@\n %01%02%03%04\n+test\n %01%02%03%04\n' , dmp . patch_toText ( patches ) ) ;
1008
-
1009
- // Both edges partial.
1010
- patches = dmp . patch_make ( 'XY' , 'XtestY' ) ;
1011
- assertEquals ( '@@ -1,2 +1,6 @@\n X\n+test\n Y\n' , dmp . patch_toText ( patches ) ) ;
1012
- dmp . patch_addPadding ( patches ) ;
1013
- assertEquals ( '@@ -2,8 +2,12 @@\n %02%03%04X\n+test\n Y%01%02%03\n' , dmp . patch_toText ( patches ) ) ;
1014
-
1015
- // Both edges none.
1016
- patches = dmp . patch_make ( 'XXXXYYYY' , 'XXXXtestYYYY' ) ;
1017
- assertEquals ( '@@ -1,8 +1,12 @@\n XXXX\n+test\n YYYY\n' , dmp . patch_toText ( patches ) ) ;
1018
- dmp . patch_addPadding ( patches ) ;
1019
- assertEquals ( '@@ -5,8 +5,12 @@\n XXXX\n+test\n YYYY\n' , dmp . patch_toText ( patches ) ) ;
1003
+ // Both edges full.
1004
+ var patches = dmp . patch_make ( '' , 'test' ) ;
1005
+ assertEquals ( '@@ -0,0 +1,4 @@\n+test\n' , dmp . patch_toText ( patches ) ) ;
1006
+ dmp . patch_addPadding ( patches ) ;
1007
+ assertEquals ( '@@ -1,8 +1,12 @@\n %01%02%03%04\n+test\n %01%02%03%04\n' , dmp . patch_toText ( patches ) ) ;
1008
+
1009
+ // Both edges partial.
1010
+ patches = dmp . patch_make ( 'XY' , 'XtestY' ) ;
1011
+ assertEquals ( '@@ -1,2 +1,6 @@\n X\n+test\n Y\n' , dmp . patch_toText ( patches ) ) ;
1012
+ dmp . patch_addPadding ( patches ) ;
1013
+ assertEquals ( '@@ -2,8 +2,12 @@\n %02%03%04X\n+test\n Y%01%02%03\n' , dmp . patch_toText ( patches ) ) ;
1014
+
1015
+ // Both edges none.
1016
+ patches = dmp . patch_make ( 'XXXXYYYY' , 'XXXXtestYYYY' ) ;
1017
+ assertEquals ( '@@ -1,8 +1,12 @@\n XXXX\n+test\n YYYY\n' , dmp . patch_toText ( patches ) ) ;
1018
+ dmp . patch_addPadding ( patches ) ;
1019
+ assertEquals ( '@@ -5,8 +5,12 @@\n XXXX\n+test\n YYYY\n' , dmp . patch_toText ( patches ) ) ;
1020
1020
}
1021
1021
1022
1022
function testPatchApply ( ) {
1023
- dmp . Match_Distance = 1000 ;
1024
- dmp . Match_Threshold = 0.5 ;
1025
- dmp . Patch_DeleteThreshold = 0.5 ;
1026
- // Null case.
1027
- var patches = dmp . patch_make ( '' , '' ) ;
1028
- var results = dmp . patch_apply ( patches , 'Hello world.' ) ;
1029
- assertEquivalent ( [ 'Hello world.' , [ ] ] , results ) ;
1030
-
1031
- // Exact match.
1032
- patches = dmp . patch_make ( 'The quick brown fox jumps over the lazy dog.' , 'That quick brown fox jumped over a lazy dog.' ) ;
1033
- results = dmp . patch_apply ( patches , 'The quick brown fox jumps over the lazy dog.' ) ;
1034
- assertEquivalent ( [ 'That quick brown fox jumped over a lazy dog.' , [ true , true ] ] , results ) ;
1035
-
1036
- // Partial match.
1037
- results = dmp . patch_apply ( patches , 'The quick red rabbit jumps over the tired tiger.' ) ;
1038
- assertEquivalent ( [ 'That quick red rabbit jumped over a tired tiger.' , [ true , true ] ] , results ) ;
1039
-
1040
- // Failed match.
1041
- results = dmp . patch_apply ( patches , 'I am the very model of a modern major general.' ) ;
1042
- assertEquivalent ( [ 'I am the very model of a modern major general.' , [ false , false ] ] , results ) ;
1043
-
1044
- // Big delete, small change.
1045
- patches = dmp . patch_make ( 'x1234567890123456789012345678901234567890123456789012345678901234567890y' , 'xabcy' ) ;
1046
- results = dmp . patch_apply ( patches , 'x123456789012345678901234567890-----++++++++++-----123456789012345678901234567890y' ) ;
1047
- assertEquivalent ( [ 'xabcy' , [ true , true ] ] , results ) ;
1048
-
1049
- // Big delete, big change 1.
1050
- patches = dmp . patch_make ( 'x1234567890123456789012345678901234567890123456789012345678901234567890y' , 'xabcy' ) ;
1051
- results = dmp . patch_apply ( patches , 'x12345678901234567890---------------++++++++++---------------12345678901234567890y' ) ;
1052
- assertEquivalent ( [ 'xabc12345678901234567890---------------++++++++++---------------12345678901234567890y' , [ false , true ] ] , results ) ;
1053
-
1054
- // Big delete, big change 2.
1055
- dmp . Patch_DeleteThreshold = 0.6 ;
1056
- patches = dmp . patch_make ( 'x1234567890123456789012345678901234567890123456789012345678901234567890y' , 'xabcy' ) ;
1057
- results = dmp . patch_apply ( patches , 'x12345678901234567890---------------++++++++++---------------12345678901234567890y' ) ;
1058
- assertEquivalent ( [ 'xabcy' , [ true , true ] ] , results ) ;
1059
- dmp . Patch_DeleteThreshold = 0.5 ;
1060
-
1061
- // Compensate for failed patch.
1062
- dmp . Match_Threshold = 0.0 ;
1063
- dmp . Match_Distance = 0 ;
1064
- patches = dmp . patch_make ( 'abcdefghijklmnopqrstuvwxyz--------------------1234567890' , 'abcXXXXXXXXXXdefghijklmnopqrstuvwxyz--------------------1234567YYYYYYYYYY890' ) ;
1065
- results = dmp . patch_apply ( patches , 'ABCDEFGHIJKLMNOPQRSTUVWXYZ--------------------1234567890' ) ;
1066
- assertEquivalent ( [ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ--------------------1234567YYYYYYYYYY890' , [ false , true ] ] , results ) ;
1067
- dmp . Match_Threshold = 0.5 ;
1068
- dmp . Match_Distance = 1000 ;
1069
-
1070
- // No side effects.
1071
- patches = dmp . patch_make ( '' , 'test' ) ;
1072
- var patchstr = dmp . patch_toText ( patches ) ;
1073
- dmp . patch_apply ( patches , '' ) ;
1074
- assertEquals ( patchstr , dmp . patch_toText ( patches ) ) ;
1075
-
1076
- // No side effects with major delete.
1077
- patches = dmp . patch_make ( 'The quick brown fox jumps over the lazy dog.' , 'Woof' ) ;
1078
- patchstr = dmp . patch_toText ( patches ) ;
1079
- dmp . patch_apply ( patches , 'The quick brown fox jumps over the lazy dog.' ) ;
1080
- assertEquals ( patchstr , dmp . patch_toText ( patches ) ) ;
1081
-
1082
- // Edge exact match.
1083
- patches = dmp . patch_make ( '' , 'test' ) ;
1084
- results = dmp . patch_apply ( patches , '' ) ;
1085
- assertEquivalent ( [ 'test' , [ true ] ] , results ) ;
1086
-
1087
- // Near edge exact match.
1088
- patches = dmp . patch_make ( 'XY' , 'XtestY' ) ;
1089
- results = dmp . patch_apply ( patches , 'XY' ) ;
1090
- assertEquivalent ( [ 'XtestY' , [ true ] ] , results ) ;
1091
-
1092
- // Edge partial match.
1093
- patches = dmp . patch_make ( 'y' , 'y123' ) ;
1094
- results = dmp . patch_apply ( patches , 'x' ) ;
1095
- assertEquivalent ( [ 'x123' , [ true ] ] , results ) ;
1023
+ dmp . Match_Distance = 1000 ;
1024
+ dmp . Match_Threshold = 0.5 ;
1025
+ dmp . Patch_DeleteThreshold = 0.5 ;
1026
+ // Null case.
1027
+ var patches = dmp . patch_make ( '' , '' ) ;
1028
+ var results = dmp . patch_apply ( patches , 'Hello world.' ) ;
1029
+ assertEquivalent ( [ 'Hello world.' , [ ] ] , results ) ;
1030
+
1031
+ // Exact match.
1032
+ patches = dmp . patch_make ( 'The quick brown fox jumps over the lazy dog.' , 'That quick brown fox jumped over a lazy dog.' ) ;
1033
+ results = dmp . patch_apply ( patches , 'The quick brown fox jumps over the lazy dog.' ) ;
1034
+ assertEquivalent ( [ 'That quick brown fox jumped over a lazy dog.' , [ true , true ] ] , results ) ;
1035
+
1036
+ // Partial match.
1037
+ results = dmp . patch_apply ( patches , 'The quick red rabbit jumps over the tired tiger.' ) ;
1038
+ assertEquivalent ( [ 'That quick red rabbit jumped over a tired tiger.' , [ true , true ] ] , results ) ;
1039
+
1040
+ // Failed match.
1041
+ results = dmp . patch_apply ( patches , 'I am the very model of a modern major general.' ) ;
1042
+ assertEquivalent ( [ 'I am the very model of a modern major general.' , [ false , false ] ] , results ) ;
1043
+
1044
+ // Big delete, small change.
1045
+ patches = dmp . patch_make ( 'x1234567890123456789012345678901234567890123456789012345678901234567890y' , 'xabcy' ) ;
1046
+ results = dmp . patch_apply ( patches , 'x123456789012345678901234567890-----++++++++++-----123456789012345678901234567890y' ) ;
1047
+ assertEquivalent ( [ 'xabcy' , [ true , true ] ] , results ) ;
1048
+
1049
+ // Big delete, big change 1.
1050
+ patches = dmp . patch_make ( 'x1234567890123456789012345678901234567890123456789012345678901234567890y' , 'xabcy' ) ;
1051
+ results = dmp . patch_apply ( patches , 'x12345678901234567890---------------++++++++++---------------12345678901234567890y' ) ;
1052
+ assertEquivalent ( [ 'xabc12345678901234567890---------------++++++++++---------------12345678901234567890y' , [ false , true ] ] , results ) ;
1053
+
1054
+ // Big delete, big change 2.
1055
+ dmp . Patch_DeleteThreshold = 0.6 ;
1056
+ patches = dmp . patch_make ( 'x1234567890123456789012345678901234567890123456789012345678901234567890y' , 'xabcy' ) ;
1057
+ results = dmp . patch_apply ( patches , 'x12345678901234567890---------------++++++++++---------------12345678901234567890y' ) ;
1058
+ assertEquivalent ( [ 'xabcy' , [ true , true ] ] , results ) ;
1059
+ dmp . Patch_DeleteThreshold = 0.5 ;
1060
+
1061
+ // Compensate for failed patch.
1062
+ dmp . Match_Threshold = 0.0 ;
1063
+ dmp . Match_Distance = 0 ;
1064
+ patches = dmp . patch_make ( 'abcdefghijklmnopqrstuvwxyz--------------------1234567890' , 'abcXXXXXXXXXXdefghijklmnopqrstuvwxyz--------------------1234567YYYYYYYYYY890' ) ;
1065
+ results = dmp . patch_apply ( patches , 'ABCDEFGHIJKLMNOPQRSTUVWXYZ--------------------1234567890' ) ;
1066
+ assertEquivalent ( [ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ--------------------1234567YYYYYYYYYY890' , [ false , true ] ] , results ) ;
1067
+ dmp . Match_Threshold = 0.5 ;
1068
+ dmp . Match_Distance = 1000 ;
1069
+
1070
+ // No side effects.
1071
+ patches = dmp . patch_make ( '' , 'test' ) ;
1072
+ var patchstr = dmp . patch_toText ( patches ) ;
1073
+ dmp . patch_apply ( patches , '' ) ;
1074
+ assertEquals ( patchstr , dmp . patch_toText ( patches ) ) ;
1075
+
1076
+ // No side effects with major delete.
1077
+ patches = dmp . patch_make ( 'The quick brown fox jumps over the lazy dog.' , 'Woof' ) ;
1078
+ patchstr = dmp . patch_toText ( patches ) ;
1079
+ dmp . patch_apply ( patches , 'The quick brown fox jumps over the lazy dog.' ) ;
1080
+ assertEquals ( patchstr , dmp . patch_toText ( patches ) ) ;
1081
+
1082
+ // Edge exact match.
1083
+ patches = dmp . patch_make ( '' , 'test' ) ;
1084
+ results = dmp . patch_apply ( patches , '' ) ;
1085
+ assertEquivalent ( [ 'test' , [ true ] ] , results ) ;
1086
+
1087
+ // Near edge exact match.
1088
+ patches = dmp . patch_make ( 'XY' , 'XtestY' ) ;
1089
+ results = dmp . patch_apply ( patches , 'XY' ) ;
1090
+ assertEquivalent ( [ 'XtestY' , [ true ] ] , results ) ;
1091
+
1092
+ // Edge partial match.
1093
+ patches = dmp . patch_make ( 'y' , 'y123' ) ;
1094
+ results = dmp . patch_apply ( patches , 'x' ) ;
1095
+ assertEquivalent ( [ 'x123' , [ true ] ] , results ) ;
1096
1096
}
0 commit comments