diff-lcs 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,19 @@
1
+ #! /usr/env/bin ruby
2
+ #--
3
+ # Copyright 2004 Austin Ziegler <diff-lcs@halostatue.ca>
4
+ # adapted from:
5
+ # Algorithm::Diff (Perl) by Ned Konz <perl@bike-nomad.com>
6
+ # Smalltalk by Mario I. Wolczko <mario@wolczko.com>
7
+ # implements McIlroy-Hunt diff algorithm
8
+ #
9
+ # This program is free software. It may be redistributed and/or modified under
10
+ # the terms of the GPL version 2 (or later), the Perl Artistic licence, or the
11
+ # Ruby licence.
12
+ #
13
+ # $Id: string.rb,v 1.3 2004/08/08 20:33:09 austin Exp $
14
+ #++
15
+ # Includes Diff::LCS into String.
16
+
17
+ class String
18
+ include Diff::LCS
19
+ end
@@ -0,0 +1,626 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../lib") if __FILE__ == $0
4
+
5
+ require 'diff/lcs'
6
+ require 'test/unit'
7
+ require 'pp'
8
+ require 'diff/lcs/array'
9
+
10
+ module Diff::LCS::Tests
11
+ def __format_diffs(diffs)
12
+ diffs.map do |e|
13
+ if e.kind_of?(Array)
14
+ e.map { |f| f.to_a.join }.join(", ")
15
+ else
16
+ e.to_a.join
17
+ end
18
+ end.join("; ")
19
+ end
20
+
21
+ def __map_diffs(diffs, klass = Diff::LCS::ContextChange)
22
+ diffs.map do |chunks|
23
+ if klass == Diff::LCS::ContextChange
24
+ klass.from_a(chunks)
25
+ else
26
+ chunks.map { |changes| klass.from_a(changes) }
27
+ end
28
+ end
29
+ end
30
+
31
+ def __simple_callbacks
32
+ callbacks = Object.new
33
+ class << callbacks
34
+ attr_reader :matched_a
35
+ attr_reader :matched_b
36
+ attr_reader :discards_a
37
+ attr_reader :discards_b
38
+ attr_reader :done_a
39
+ attr_reader :done_b
40
+
41
+ def reset
42
+ @matched_a = []
43
+ @matched_b = []
44
+ @discards_a = []
45
+ @discards_b = []
46
+ @done_a = []
47
+ @done_b = []
48
+ end
49
+
50
+ def match(event)
51
+ @matched_a << event.old_element
52
+ @matched_b << event.new_element
53
+ end
54
+
55
+ def discard_b(event)
56
+ @discards_b << event.new_element
57
+ end
58
+
59
+ def discard_a(event)
60
+ @discards_a << event.old_element
61
+ end
62
+
63
+ def finished_a(event)
64
+ @done_a << [event.old_element, event.old_position]
65
+ end
66
+
67
+ def finished_b(event)
68
+ @done_b << [event.new_element, event.new_position]
69
+ end
70
+ end
71
+ callbacks.reset
72
+ callbacks
73
+ end
74
+
75
+ def __balanced_callback
76
+ cb = Object.new
77
+ class << cb
78
+ attr_reader :result
79
+
80
+ def reset
81
+ @result = ""
82
+ end
83
+
84
+ def match(event)
85
+ @result << "M#{event.old_position}#{event.new_position} "
86
+ end
87
+
88
+ def discard_a(event)
89
+ @result << "DA#{event.old_position}#{event.new_position} "
90
+ end
91
+
92
+ def discard_b(event)
93
+ @result << "DB#{event.old_position}#{event.new_position} "
94
+ end
95
+
96
+ def change(event)
97
+ @result << "C#{event.old_position}#{event.new_position} "
98
+ end
99
+ end
100
+ cb.reset
101
+ cb
102
+ end
103
+
104
+ def setup
105
+ @seq1 = %w(a b c e h j l m n p)
106
+ @seq2 = %w(b c d e f j k l m r s t)
107
+
108
+ @correct_lcs = %w(b c e j l m)
109
+
110
+ @skipped_seq1 = 'a h n p'
111
+ @skipped_seq2 = 'd f k r s t'
112
+
113
+ correct_diff = [
114
+ [ [ '-', 0, 'a' ] ],
115
+ [ [ '+', 2, 'd' ] ],
116
+ [ [ '-', 4, 'h' ],
117
+ [ '+', 4, 'f' ] ],
118
+ [ [ '+', 6, 'k' ] ],
119
+ [ [ '-', 8, 'n' ],
120
+ [ '-', 9, 'p' ],
121
+ [ '+', 9, 'r' ],
122
+ [ '+', 10, 's' ],
123
+ [ '+', 11, 't' ] ] ]
124
+ @correct_diff = __map_diffs(correct_diff, Diff::LCS::Change)
125
+ end
126
+ end
127
+
128
+ class TestLCS < Test::Unit::TestCase
129
+ include Diff::LCS::Tests
130
+
131
+ def test_lcs
132
+ res = ares = bres = nil
133
+ assert_nothing_raised { res = Diff::LCS.__lcs(@seq1, @seq2) }
134
+ # The result of the LCS (less the +nil+ values) must be as long as the
135
+ # correct result.
136
+ assert_equal(res.compact.size, @correct_lcs.size)
137
+ res.each_with_index { |ee, ii| assert(ee.nil? || (@seq1[ii] == @seq2[ee])) }
138
+ assert_nothing_raised { ares = (0...res.size).map { |ii| res[ii] ? @seq1[ii] : nil } }
139
+ assert_nothing_raised { bres = (0...res.size).map { |ii| res[ii] ? @seq2[res[ii]] : nil } }
140
+ assert_equal(@correct_lcs, ares.compact)
141
+ assert_equal(@correct_lcs, bres.compact)
142
+ assert_nothing_raised { res = Diff::LCS.LCS(@seq1, @seq2) }
143
+ assert_equal(res.compact, @correct_lcs)
144
+ end
145
+ end
146
+
147
+ class TestSequences < Test::Unit::TestCase
148
+ include Diff::LCS::Tests
149
+
150
+ def test_sequences
151
+ callbacks = nil
152
+ assert_nothing_raised do
153
+ callbacks = __simple_callbacks
154
+ class << callbacks
155
+ undef :finished_a
156
+ undef :finished_b
157
+ end
158
+ Diff::LCS.traverse_sequences(@seq1, @seq2, callbacks)
159
+ end
160
+ assert_equal(@correct_lcs.size, callbacks.matched_a.size)
161
+ assert_equal(@correct_lcs.size, callbacks.matched_b.size)
162
+ assert_equal(@skipped_seq1, callbacks.discards_a.join(" "))
163
+ assert_equal(@skipped_seq2, callbacks.discards_b.join(" "))
164
+ assert_nothing_raised do
165
+ callbacks = __simple_callbacks
166
+ Diff::LCS.traverse_sequences(@seq1, @seq2, callbacks)
167
+ end
168
+ assert_equal(@correct_lcs.size, callbacks.matched_a.size)
169
+ assert_equal(@correct_lcs.size, callbacks.matched_b.size)
170
+ assert_equal(@skipped_seq1, callbacks.discards_a.join(" "))
171
+ assert_equal(@skipped_seq2, callbacks.discards_b.join(" "))
172
+ assert_equal(9, callbacks.done_a[0][1])
173
+ assert_nil(callbacks.done_b[0])
174
+
175
+ # seqw = %w(abcd efgh ijkl mnopqrstuvwxyz)
176
+ # assert_nothing_raised do
177
+ # callbacks = __simple_callbacks
178
+ # class << callbacks
179
+ # undef :finished_a
180
+ # undef :finished_b
181
+ # end
182
+ # Diff::LCS.traverse_sequences(seqw, [], callbacks)
183
+ # end
184
+ end
185
+
186
+ def test_diff
187
+ diff = nil
188
+ assert_nothing_raised { diff = Diff::LCS.diff(@seq1, @seq2) }
189
+ assert_equal(__format_diffs(@correct_diff), __format_diffs(diff))
190
+ assert_equal(@correct_diff, diff)
191
+ end
192
+
193
+ def test_diff_empty
194
+ seqw = %w(abcd efgh ijkl mnopqrstuvwxyz)
195
+ correct_diff = [
196
+ [ [ '-', 0, 'abcd' ],
197
+ [ '-', 1, 'efgh' ],
198
+ [ '-', 2, 'ijkl' ],
199
+ [ '-', 3, 'mnopqrstuvwxyz' ] ] ]
200
+ diff = nil
201
+
202
+ assert_nothing_raised { diff = Diff::LCS.diff(seqw, []) }
203
+ assert_equal(__format_diffs(correct_diff), __format_diffs(diff))
204
+
205
+ correct_diff = [
206
+ [ [ '+', 0, 'abcd' ],
207
+ [ '+', 1, 'efgh' ],
208
+ [ '+', 2, 'ijkl' ],
209
+ [ '+', 3, 'mnopqrstuvwxyz' ] ] ]
210
+ assert_nothing_raised { diff = Diff::LCS.diff([], seqw) }
211
+ assert_equal(__format_diffs(correct_diff), __format_diffs(diff))
212
+ end
213
+ end
214
+
215
+ class TestBalanced < Test::Unit::TestCase
216
+ include Diff::LCS::Tests
217
+
218
+ def test_sdiff_a
219
+ sdiff = nil
220
+ seq1 = %w(abc def yyy xxx ghi jkl)
221
+ seq2 = %w(abc dxf xxx ghi jkl)
222
+ correct_sdiff = [
223
+ [ '=', [ 0, 'abc' ], [ 0, 'abc' ] ],
224
+ [ '!', [ 1, 'def' ], [ 1, 'dxf' ] ],
225
+ [ '-', [ 2, 'yyy' ], [ 2, nil ] ],
226
+ [ '=', [ 3, 'xxx' ], [ 2, 'xxx' ] ],
227
+ [ '=', [ 4, 'ghi' ], [ 3, 'ghi' ] ],
228
+ [ '=', [ 5, 'jkl' ], [ 4, 'jkl' ] ] ]
229
+ correct_sdiff = __map_diffs(correct_sdiff)
230
+ assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
231
+ assert_equal(correct_sdiff, sdiff)
232
+ end
233
+
234
+ def test_sdiff_b
235
+ sdiff = nil
236
+ correct_sdiff = [
237
+ [ '-', [ 0, 'a' ], [ 0, nil ] ],
238
+ [ '=', [ 1, 'b' ], [ 0, 'b' ] ],
239
+ [ '=', [ 2, 'c' ], [ 1, 'c' ] ],
240
+ [ '+', [ 3, nil ], [ 2, 'd' ] ],
241
+ [ '=', [ 3, 'e' ], [ 3, 'e' ] ],
242
+ [ '!', [ 4, 'h' ], [ 4, 'f' ] ],
243
+ [ '=', [ 5, 'j' ], [ 5, 'j' ] ],
244
+ [ '+', [ 6, nil ], [ 6, 'k' ] ],
245
+ [ '=', [ 6, 'l' ], [ 7, 'l' ] ],
246
+ [ '=', [ 7, 'm' ], [ 8, 'm' ] ],
247
+ [ '!', [ 8, 'n' ], [ 9, 'r' ] ],
248
+ [ '!', [ 9, 'p' ], [ 10, 's' ] ],
249
+ [ '+', [ 10, nil ], [ 11, 't' ] ] ]
250
+ correct_sdiff = __map_diffs(correct_sdiff)
251
+ assert_nothing_raised { sdiff = Diff::LCS.sdiff(@seq1, @seq2) }
252
+ assert_equal(correct_sdiff, sdiff)
253
+ end
254
+
255
+ def test_sdiff_c
256
+ sdiff = nil
257
+ seq1 = %w(a b c d e)
258
+ seq2 = %w(a e)
259
+ correct_sdiff = [
260
+ [ '=', [ 0, 'a' ], [ 0, 'a' ] ],
261
+ [ '-', [ 1, 'b' ], [ 1, nil ] ],
262
+ [ '-', [ 2, 'c' ], [ 1, nil ] ],
263
+ [ '-', [ 3, 'd' ], [ 1, nil ] ],
264
+ [ '=', [ 4, 'e' ], [ 1, 'e' ] ] ]
265
+ correct_sdiff = __map_diffs(correct_sdiff)
266
+ assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
267
+ assert_equal(correct_sdiff, sdiff)
268
+ end
269
+
270
+ def test_sdiff_d
271
+ sdiff = nil
272
+ seq1 = %w(a e)
273
+ seq2 = %w(a b c d e)
274
+ correct_sdiff = [
275
+ [ '=', [ 0, 'a' ], [ 0, 'a' ] ],
276
+ [ '+', [ 1, nil ], [ 1, 'b' ] ],
277
+ [ '+', [ 1, nil ], [ 2, 'c' ] ],
278
+ [ '+', [ 1, nil ], [ 3, 'd' ] ],
279
+ [ '=', [ 1, 'e' ], [ 4, 'e' ] ] ]
280
+ correct_sdiff = __map_diffs(correct_sdiff)
281
+ assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
282
+ assert_equal(correct_sdiff, sdiff)
283
+ end
284
+
285
+ def test_sdiff_e
286
+ sdiff = nil
287
+ seq1 = %w(v x a e)
288
+ seq2 = %w(w y a b c d e)
289
+ correct_sdiff = [
290
+ [ '!', [ 0, 'v' ], [ 0, 'w' ] ],
291
+ [ '!', [ 1, 'x' ], [ 1, 'y' ] ],
292
+ [ '=', [ 2, 'a' ], [ 2, 'a' ] ],
293
+ [ '+', [ 3, nil ], [ 3, 'b' ] ],
294
+ [ '+', [ 3, nil ], [ 4, 'c' ] ],
295
+ [ '+', [ 3, nil ], [ 5, 'd' ] ],
296
+ [ '=', [ 3, 'e' ], [ 6, 'e' ] ] ]
297
+ correct_sdiff = __map_diffs(correct_sdiff)
298
+ assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
299
+ assert_equal(correct_sdiff, sdiff)
300
+ end
301
+
302
+ def test_sdiff_f
303
+ sdiff = nil
304
+ seq1 = %w(x a e)
305
+ seq2 = %w(a b c d e)
306
+ correct_sdiff = [
307
+ [ '-', [ 0, 'x' ], [ 0, nil ] ],
308
+ [ '=', [ 1, 'a' ], [ 0, 'a' ] ],
309
+ [ '+', [ 2, nil ], [ 1, 'b' ] ],
310
+ [ '+', [ 2, nil ], [ 2, 'c' ] ],
311
+ [ '+', [ 2, nil ], [ 3, 'd' ] ],
312
+ [ '=', [ 2, 'e' ], [ 4, 'e' ] ] ]
313
+ correct_sdiff = __map_diffs(correct_sdiff)
314
+ assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
315
+ assert_equal(correct_sdiff, sdiff)
316
+ end
317
+
318
+ def test_sdiff_g
319
+ sdiff = nil
320
+ seq1 = %w(a e)
321
+ seq2 = %w(x a b c d e)
322
+ correct_sdiff = [
323
+ [ '+', [ 0, nil ], [ 0, 'x' ] ],
324
+ [ '=', [ 0, 'a' ], [ 1, 'a' ] ],
325
+ [ '+', [ 1, nil ], [ 2, 'b' ] ],
326
+ [ '+', [ 1, nil ], [ 3, 'c' ] ],
327
+ [ '+', [ 1, nil ], [ 4, 'd' ] ],
328
+ [ '=', [ 1, 'e' ], [ 5, 'e' ] ] ]
329
+ correct_sdiff = __map_diffs(correct_sdiff)
330
+ assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
331
+ assert_equal(correct_sdiff, sdiff)
332
+ end
333
+
334
+ def test_sdiff_h
335
+ sdiff = nil
336
+ seq1 = %w(a e v)
337
+ seq2 = %w(x a b c d e w x)
338
+ correct_sdiff = [
339
+ [ '+', [ 0, nil ], [ 0, 'x' ] ],
340
+ [ '=', [ 0, 'a' ], [ 1, 'a' ] ],
341
+ [ '+', [ 1, nil ], [ 2, 'b' ] ],
342
+ [ '+', [ 1, nil ], [ 3, 'c' ] ],
343
+ [ '+', [ 1, nil ], [ 4, 'd' ] ],
344
+ [ '=', [ 1, 'e' ], [ 5, 'e' ] ],
345
+ [ '!', [ 2, 'v' ], [ 6, 'w' ] ],
346
+ [ '+', [ 3, nil ], [ 7, 'x' ] ] ]
347
+ correct_sdiff = __map_diffs(correct_sdiff)
348
+ assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
349
+ assert_equal(correct_sdiff, sdiff)
350
+ end
351
+
352
+ def test_sdiff_i
353
+ sdiff = nil
354
+ seq1 = %w()
355
+ seq2 = %w(a b c)
356
+ correct_sdiff = [
357
+ [ '+', [ 0, nil ], [ 0, 'a' ] ],
358
+ [ '+', [ 0, nil ], [ 1, 'b' ] ],
359
+ [ '+', [ 0, nil ], [ 2, 'c' ] ] ]
360
+ correct_sdiff = __map_diffs(correct_sdiff)
361
+ assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
362
+ assert_equal(correct_sdiff, sdiff)
363
+ end
364
+
365
+ def test_sdiff_j
366
+ sdiff = nil
367
+ seq1 = %w(a b c)
368
+ seq2 = %w()
369
+ correct_sdiff = [
370
+ [ '-', [ 0, 'a' ], [ 0, nil ] ],
371
+ [ '-', [ 1, 'b' ], [ 0, nil ] ],
372
+ [ '-', [ 2, 'c' ], [ 0, nil ] ] ]
373
+ correct_sdiff = __map_diffs(correct_sdiff)
374
+ assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
375
+ assert_equal(correct_sdiff, sdiff)
376
+ end
377
+
378
+ def test_sdiff_k
379
+ sdiff = nil
380
+ seq1 = %w(a b c)
381
+ seq2 = %w(1)
382
+ correct_sdiff = [
383
+ [ '!', [ 0, 'a' ], [ 0, '1' ] ],
384
+ [ '-', [ 1, 'b' ], [ 1, nil ] ],
385
+ [ '-', [ 2, 'c' ], [ 1, nil ] ] ]
386
+ correct_sdiff = __map_diffs(correct_sdiff)
387
+ assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
388
+ assert_equal(correct_sdiff, sdiff)
389
+ end
390
+
391
+ def test_sdiff_l
392
+ sdiff = nil
393
+ seq1 = %w(a b c)
394
+ seq2 = %w(c)
395
+ correct_sdiff = [
396
+ [ '-', [ 0, 'a' ], [ 0, nil ] ],
397
+ [ '-', [ 1, 'b' ], [ 0, nil ] ],
398
+ [ '=', [ 2, 'c' ], [ 0, 'c' ] ]
399
+ ]
400
+ correct_sdiff = __map_diffs(correct_sdiff)
401
+ assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
402
+ assert_equal(correct_sdiff, sdiff)
403
+ end
404
+
405
+ def test_sdiff_m
406
+ sdiff = nil
407
+ seq1 = %w(abcd efgh ijkl mnop)
408
+ seq2 = []
409
+ correct_sdiff = [
410
+ [ '-', [ 0, 'abcd' ], [ 0, nil ] ],
411
+ [ '-', [ 1, 'efgh' ], [ 0, nil ] ],
412
+ [ '-', [ 2, 'ijkl' ], [ 0, nil ] ],
413
+ [ '-', [ 3, 'mnop' ], [ 0, nil ] ]
414
+ ]
415
+ correct_sdiff = __map_diffs(correct_sdiff)
416
+ assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
417
+ assert_equal(correct_sdiff, sdiff)
418
+ end
419
+
420
+ def test_sdiff_n
421
+ sdiff = nil
422
+ seq1 = []
423
+ seq2 = %w(abcd efgh ijkl mnop)
424
+ correct_sdiff = [
425
+ [ '+', [ 0, nil ], [ 0, 'abcd' ] ],
426
+ [ '+', [ 0, nil ], [ 1, 'efgh' ] ],
427
+ [ '+', [ 0, nil ], [ 2, 'ijkl' ] ],
428
+ [ '+', [ 0, nil ], [ 3, 'mnop' ] ]
429
+ ]
430
+ correct_sdiff = __map_diffs(correct_sdiff)
431
+ assert_nothing_raised { sdiff = Diff::LCS.sdiff(seq1, seq2) }
432
+ assert_equal(correct_sdiff, sdiff)
433
+ end
434
+
435
+ def test_balanced_a
436
+ seq1 = %w(a b c)
437
+ seq2 = %w(a x c)
438
+ callback = nil
439
+ assert_nothing_raised { callback = __balanced_callback }
440
+ assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
441
+ assert_equal("M00 C11 M22 ", callback.result)
442
+ end
443
+
444
+ def test_balanced_b
445
+ seq1 = %w(a b c)
446
+ seq2 = %w(a x c)
447
+ callback = nil
448
+ assert_nothing_raised do
449
+ callback = __balanced_callback
450
+ class << callback
451
+ undef change
452
+ end
453
+ end
454
+ assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
455
+ assert_equal("M00 DA11 DB21 M22 ", callback.result)
456
+ end
457
+
458
+ def test_balanced_c
459
+ seq1 = %w(a x y c)
460
+ seq2 = %w(a v w c)
461
+ callback = nil
462
+ assert_nothing_raised { callback = __balanced_callback }
463
+ assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
464
+ assert_equal("M00 C11 C22 M33 ", callback.result)
465
+ end
466
+
467
+ def test_balanced_d
468
+ seq1 = %w(x y c)
469
+ seq2 = %w(v w c)
470
+ callback = nil
471
+ assert_nothing_raised { callback = __balanced_callback }
472
+ assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
473
+ assert_equal("C00 C11 M22 ", callback.result)
474
+ end
475
+
476
+ def test_balanced_e
477
+ seq1 = %w(a x y z)
478
+ seq2 = %w(b v w)
479
+ callback = nil
480
+ assert_nothing_raised { callback = __balanced_callback }
481
+ assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
482
+ assert_equal("C00 C11 C22 DA33 ", callback.result)
483
+ end
484
+
485
+ def test_balanced_f
486
+ seq1 = %w(a z)
487
+ seq2 = %w(a)
488
+ callback = nil
489
+ assert_nothing_raised { callback = __balanced_callback }
490
+ assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
491
+ assert_equal("M00 DA11 ", callback.result)
492
+ end
493
+
494
+ def test_balanced_g
495
+ seq1 = %w(z a)
496
+ seq2 = %w(a)
497
+ callback = nil
498
+ assert_nothing_raised { callback = __balanced_callback }
499
+ assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
500
+ assert_equal("DA00 M10 ", callback.result)
501
+ end
502
+
503
+ def test_balanced_h
504
+ seq1 = %w(a b c)
505
+ seq2 = %w(x y z)
506
+ callback = nil
507
+ assert_nothing_raised { callback = __balanced_callback }
508
+ assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
509
+ assert_equal("C00 C11 C22 ", callback.result)
510
+ end
511
+
512
+ def test_balanced_i
513
+ seq1 = %w(abcd efgh ijkl mnopqrstuvwxyz)
514
+ seq2 = []
515
+ callback = nil
516
+ assert_nothing_raised { callback = __balanced_callback }
517
+ assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
518
+ assert_equal("DA00 DA10 DA20 DA30 ", callback.result)
519
+ end
520
+
521
+ def test_balanced_j
522
+ seq1 = []
523
+ seq2 = %w(abcd efgh ijkl mnopqrstuvwxyz)
524
+ callback = nil
525
+ assert_nothing_raised { callback = __balanced_callback }
526
+ assert_nothing_raised { Diff::LCS.traverse_balanced(seq1, seq2, callback) }
527
+ assert_equal("DB00 DB01 DB02 DB03 ", callback.result)
528
+ end
529
+ end
530
+
531
+ class TestPatching < Test::Unit::TestCase
532
+ include Diff::LCS::Tests
533
+
534
+ def test_patch_diff
535
+ ps = ms1 = ms2 = ms3 = nil
536
+ assert_nothing_raised do
537
+ ps = Diff::LCS.diff(@seq1, @seq2)
538
+ ms1 = Diff::LCS.patch(@seq1, ps)
539
+ ms2 = Diff::LCS.patch(@seq2, ps, :unpatch)
540
+ ms3 = Diff::LCS.patch(@seq2, ps)
541
+ end
542
+ assert_equal(@seq2, ms1)
543
+ assert_equal(@seq1, ms2)
544
+ assert_equal(@seq1, ms3)
545
+ assert_nothing_raised do
546
+ ps = Diff::LCS.diff(@seq1, @seq2, Diff::LCS::ContextDiffCallbacks)
547
+ ms1 = Diff::LCS.patch(@seq1, ps)
548
+ ms2 = Diff::LCS.patch(@seq2, ps, :unpatch)
549
+ ms2 = Diff::LCS.patch(@seq2, ps)
550
+ end
551
+ assert_equal(@seq2, ms1)
552
+ assert_equal(@seq1, ms2)
553
+ assert_equal(@seq1, ms3)
554
+ assert_nothing_raised do
555
+ ps = Diff::LCS.diff(@seq1, @seq2, Diff::LCS::SDiffCallbacks)
556
+ ms1 = Diff::LCS.patch(@seq1, ps)
557
+ ms2 = Diff::LCS.patch(@seq2, ps, :unpatch)
558
+ ms3 = Diff::LCS.patch(@seq2, ps)
559
+ end
560
+ assert_equal(@seq2, ms1)
561
+ assert_equal(@seq1, ms2)
562
+ assert_equal(@seq1, ms3)
563
+ end
564
+
565
+ # Tests patch bug #891:
566
+ # http://rubyforge.org/tracker/?func=detail&atid=407&aid=891&group_id=84
567
+ def test_patch_bug891
568
+ s1 = s2 = s3 = s4 = s5 = ps = nil
569
+ assert_nothing_raised do
570
+ s1 = %w{a b c d e f g h i j k }
571
+ s2 = %w{a b c d D e f g h i j k }
572
+ ps = Diff::LCS::diff(s1, s2)
573
+ s3 = Diff::LCS.patch(s1, ps, :patch)
574
+ ps = Diff::LCS::diff(s1, s2, Diff::LCS::ContextDiffCallbacks)
575
+ s4 = Diff::LCS.patch(s1, ps, :patch)
576
+ ps = Diff::LCS::diff(s1, s2, Diff::LCS::SDiffCallbacks)
577
+ s5 = Diff::LCS.patch(s1, ps, :patch)
578
+ end
579
+ assert_equal(s2, s3)
580
+ assert_equal(s2, s4)
581
+ assert_equal(s2, s5)
582
+
583
+ assert_nothing_raised do
584
+ ps = Diff::LCS::sdiff(s1, s2)
585
+ s3 = Diff::LCS.patch(s1, ps, :patch)
586
+ ps = Diff::LCS::diff(s1, s2, Diff::LCS::ContextDiffCallbacks)
587
+ s4 = Diff::LCS.patch(s1, ps, :patch)
588
+ ps = Diff::LCS::diff(s1, s2, Diff::LCS::DiffCallbacks)
589
+ s5 = Diff::LCS.patch(s1, ps, :patch)
590
+ end
591
+ assert_equal(s2, s3)
592
+ assert_equal(s2, s4)
593
+ assert_equal(s2, s5)
594
+ end
595
+
596
+ def test_patch_sdiff
597
+ ps = ms1 = ms2 = ms3 = nil
598
+ assert_nothing_raised do
599
+ ps = Diff::LCS.sdiff(@seq1, @seq2)
600
+ ms1 = Diff::LCS.patch(@seq1, ps)
601
+ ms2 = Diff::LCS.patch(@seq2, ps, :unpatch)
602
+ ms3 = Diff::LCS.patch(@seq2, ps)
603
+ end
604
+ assert_equal(@seq2, ms1)
605
+ assert_equal(@seq1, ms2)
606
+ assert_equal(@seq1, ms3)
607
+ assert_nothing_raised do
608
+ ps = Diff::LCS.sdiff(@seq1, @seq2, Diff::LCS::ContextDiffCallbacks)
609
+ ms1 = Diff::LCS.patch(@seq1, ps)
610
+ ms2 = Diff::LCS.patch(@seq2, ps, :unpatch)
611
+ ms3 = Diff::LCS.patch(@seq2, ps)
612
+ end
613
+ assert_equal(@seq2, ms1)
614
+ assert_equal(@seq1, ms2)
615
+ assert_equal(@seq1, ms3)
616
+ assert_nothing_raised do
617
+ ps = Diff::LCS.sdiff(@seq1, @seq2, Diff::LCS::DiffCallbacks)
618
+ ms1 = Diff::LCS.patch(@seq1, ps)
619
+ ms2 = Diff::LCS.patch(@seq2, ps, :unpatch)
620
+ ms3 = Diff::LCS.patch(@seq2, ps)
621
+ end
622
+ assert_equal(@seq2, ms1)
623
+ assert_equal(@seq1, ms2)
624
+ assert_equal(@seq1, ms3)
625
+ end
626
+ end