/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_diff.py

Raise NoDiff if 'diff' not present.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005, 2006 Canonical Development Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
 
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 
 
17
import os
 
18
from cStringIO import StringIO
 
19
import errno
 
20
from tempfile import TemporaryFile
 
21
 
 
22
from bzrlib.diff import internal_diff, external_diff, show_diff_trees
 
23
from bzrlib.errors import BinaryFile, NoDiff
 
24
import bzrlib.patiencediff
 
25
from bzrlib.tests import (TestCase, TestCaseWithTransport,
 
26
                          TestCaseInTempDir, TestSkipped)
 
27
 
 
28
 
 
29
def udiff_lines(old, new, allow_binary=False):
 
30
    output = StringIO()
 
31
    internal_diff('old', old, 'new', new, output, allow_binary)
 
32
    output.seek(0, 0)
 
33
    return output.readlines()
 
34
 
 
35
 
 
36
def external_udiff_lines(old, new):
 
37
    output = TemporaryFile()
 
38
    try:
 
39
        external_diff('old', old, 'new', new, output, diff_opts=['-u'])
 
40
    except errors.NoDiff:
 
41
        raise TestSkipped('external "diff" not present to test')
 
42
    output.seek(0, 0)
 
43
    lines = output.readlines()
 
44
    output.close()
 
45
    return lines
 
46
 
 
47
 
 
48
class TestDiff(TestCase):
 
49
 
 
50
    def test_add_nl(self):
 
51
        """diff generates a valid diff for patches that add a newline"""
 
52
        lines = udiff_lines(['boo'], ['boo\n'])
 
53
        self.check_patch(lines)
 
54
        self.assertEquals(lines[4], '\\ No newline at end of file\n')
 
55
            ## "expected no-nl, got %r" % lines[4]
 
56
 
 
57
    def test_add_nl_2(self):
 
58
        """diff generates a valid diff for patches that change last line and
 
59
        add a newline.
 
60
        """
 
61
        lines = udiff_lines(['boo'], ['goo\n'])
 
62
        self.check_patch(lines)
 
63
        self.assertEquals(lines[4], '\\ No newline at end of file\n')
 
64
            ## "expected no-nl, got %r" % lines[4]
 
65
 
 
66
    def test_remove_nl(self):
 
67
        """diff generates a valid diff for patches that change last line and
 
68
        add a newline.
 
69
        """
 
70
        lines = udiff_lines(['boo\n'], ['boo'])
 
71
        self.check_patch(lines)
 
72
        self.assertEquals(lines[5], '\\ No newline at end of file\n')
 
73
            ## "expected no-nl, got %r" % lines[5]
 
74
 
 
75
    def check_patch(self, lines):
 
76
        self.assert_(len(lines) > 1)
 
77
            ## "Not enough lines for a file header for patch:\n%s" % "".join(lines)
 
78
        self.assert_(lines[0].startswith ('---'))
 
79
            ## 'No orig line for patch:\n%s' % "".join(lines)
 
80
        self.assert_(lines[1].startswith ('+++'))
 
81
            ## 'No mod line for patch:\n%s' % "".join(lines)
 
82
        self.assert_(len(lines) > 2)
 
83
            ## "No hunks for patch:\n%s" % "".join(lines)
 
84
        self.assert_(lines[2].startswith('@@'))
 
85
            ## "No hunk header for patch:\n%s" % "".join(lines)
 
86
        self.assert_('@@' in lines[2][2:])
 
87
            ## "Unterminated hunk header for patch:\n%s" % "".join(lines)
 
88
 
 
89
    def test_binary_lines(self):
 
90
        self.assertRaises(BinaryFile, udiff_lines, [1023 * 'a' + '\x00'], [])
 
91
        self.assertRaises(BinaryFile, udiff_lines, [], [1023 * 'a' + '\x00'])
 
92
        udiff_lines([1023 * 'a' + '\x00'], [], allow_binary=True)
 
93
        udiff_lines([], [1023 * 'a' + '\x00'], allow_binary=True)
 
94
 
 
95
    def test_external_diff(self):
 
96
        lines = external_udiff_lines(['boo\n'], ['goo\n'])
 
97
        self.check_patch(lines)
 
98
        
 
99
    def test_internal_diff_default(self):
 
100
        # Default internal diff encoding is utf8
 
101
        output = StringIO()
 
102
        internal_diff(u'old_\xb5', ['old_text\n'],
 
103
                    u'new_\xe5', ['new_text\n'], output)
 
104
        lines = output.getvalue().splitlines(True)
 
105
        self.check_patch(lines)
 
106
        self.assertEquals(['--- old_\xc2\xb5\n',
 
107
                           '+++ new_\xc3\xa5\n',
 
108
                           '@@ -1,1 +1,1 @@\n',
 
109
                           '-old_text\n',
 
110
                           '+new_text\n',
 
111
                           '\n',
 
112
                          ]
 
113
                          , lines)
 
114
 
 
115
    def test_internal_diff_utf8(self):
 
116
        output = StringIO()
 
117
        internal_diff(u'old_\xb5', ['old_text\n'],
 
118
                    u'new_\xe5', ['new_text\n'], output,
 
119
                    path_encoding='utf8')
 
120
        lines = output.getvalue().splitlines(True)
 
121
        self.check_patch(lines)
 
122
        self.assertEquals(['--- old_\xc2\xb5\n',
 
123
                           '+++ new_\xc3\xa5\n',
 
124
                           '@@ -1,1 +1,1 @@\n',
 
125
                           '-old_text\n',
 
126
                           '+new_text\n',
 
127
                           '\n',
 
128
                          ]
 
129
                          , lines)
 
130
 
 
131
    def test_internal_diff_iso_8859_1(self):
 
132
        output = StringIO()
 
133
        internal_diff(u'old_\xb5', ['old_text\n'],
 
134
                    u'new_\xe5', ['new_text\n'], output,
 
135
                    path_encoding='iso-8859-1')
 
136
        lines = output.getvalue().splitlines(True)
 
137
        self.check_patch(lines)
 
138
        self.assertEquals(['--- old_\xb5\n',
 
139
                           '+++ new_\xe5\n',
 
140
                           '@@ -1,1 +1,1 @@\n',
 
141
                           '-old_text\n',
 
142
                           '+new_text\n',
 
143
                           '\n',
 
144
                          ]
 
145
                          , lines)
 
146
 
 
147
    def test_internal_diff_returns_bytes(self):
 
148
        import StringIO
 
149
        output = StringIO.StringIO()
 
150
        internal_diff(u'old_\xb5', ['old_text\n'],
 
151
                    u'new_\xe5', ['new_text\n'], output)
 
152
        self.failUnless(isinstance(output.getvalue(), str),
 
153
            'internal_diff should return bytestrings')
 
154
 
 
155
 
 
156
class TestDiffDates(TestCaseWithTransport):
 
157
 
 
158
    def setUp(self):
 
159
        super(TestDiffDates, self).setUp()
 
160
        self.wt = self.make_branch_and_tree('.')
 
161
        self.b = self.wt.branch
 
162
        self.build_tree_contents([
 
163
            ('file1', 'file1 contents at rev 1\n'),
 
164
            ('file2', 'file2 contents at rev 1\n')
 
165
            ])
 
166
        self.wt.add(['file1', 'file2'])
 
167
        self.wt.commit(
 
168
            message='Revision 1',
 
169
            timestamp=1143849600, # 2006-04-01 00:00:00 UTC
 
170
            timezone=0,
 
171
            rev_id='rev-1')
 
172
        self.build_tree_contents([('file1', 'file1 contents at rev 2\n')])
 
173
        self.wt.commit(
 
174
            message='Revision 2',
 
175
            timestamp=1143936000, # 2006-04-02 00:00:00 UTC
 
176
            timezone=28800,
 
177
            rev_id='rev-2')
 
178
        self.build_tree_contents([('file2', 'file2 contents at rev 3\n')])
 
179
        self.wt.commit(
 
180
            message='Revision 3',
 
181
            timestamp=1144022400, # 2006-04-03 00:00:00 UTC
 
182
            timezone=-3600,
 
183
            rev_id='rev-3')
 
184
        self.wt.remove(['file2'])
 
185
        self.wt.commit(
 
186
            message='Revision 4',
 
187
            timestamp=1144108800, # 2006-04-04 00:00:00 UTC
 
188
            timezone=0,
 
189
            rev_id='rev-4')
 
190
        self.build_tree_contents([
 
191
            ('file1', 'file1 contents in working tree\n')
 
192
            ])
 
193
        # set the date stamps for files in the working tree to known values
 
194
        os.utime('file1', (1144195200, 1144195200)) # 2006-04-05 00:00:00 UTC
 
195
 
 
196
    def get_diff(self, tree1, tree2):
 
197
        output = StringIO()
 
198
        show_diff_trees(tree1, tree2, output,
 
199
                        old_label='old/', new_label='new/')
 
200
        return output.getvalue()
 
201
 
 
202
    def test_diff_rev_tree_working_tree(self):
 
203
        output = self.get_diff(self.wt.basis_tree(), self.wt)
 
204
        # note that the date for old/file1 is from rev 2 rather than from
 
205
        # the basis revision (rev 4)
 
206
        self.assertEqualDiff(output, '''\
 
207
=== modified file 'file1'
 
208
--- old/file1\t2006-04-02 00:00:00 +0000
 
209
+++ new/file1\t2006-04-05 00:00:00 +0000
 
210
@@ -1,1 +1,1 @@
 
211
-file1 contents at rev 2
 
212
+file1 contents in working tree
 
213
 
 
214
''')
 
215
 
 
216
    def test_diff_rev_tree_rev_tree(self):
 
217
        tree1 = self.b.repository.revision_tree('rev-2')
 
218
        tree2 = self.b.repository.revision_tree('rev-3')
 
219
        output = self.get_diff(tree1, tree2)
 
220
        self.assertEqualDiff(output, '''\
 
221
=== modified file 'file2'
 
222
--- old/file2\t2006-04-01 00:00:00 +0000
 
223
+++ new/file2\t2006-04-03 00:00:00 +0000
 
224
@@ -1,1 +1,1 @@
 
225
-file2 contents at rev 1
 
226
+file2 contents at rev 3
 
227
 
 
228
''')
 
229
        
 
230
    def test_diff_add_files(self):
 
231
        tree1 = self.b.repository.revision_tree(None)
 
232
        tree2 = self.b.repository.revision_tree('rev-1')
 
233
        output = self.get_diff(tree1, tree2)
 
234
        # the files have the epoch time stamp for the tree in which
 
235
        # they don't exist.
 
236
        self.assertEqualDiff(output, '''\
 
237
=== added file 'file1'
 
238
--- old/file1\t1970-01-01 00:00:00 +0000
 
239
+++ new/file1\t2006-04-01 00:00:00 +0000
 
240
@@ -0,0 +1,1 @@
 
241
+file1 contents at rev 1
 
242
 
 
243
=== added file 'file2'
 
244
--- old/file2\t1970-01-01 00:00:00 +0000
 
245
+++ new/file2\t2006-04-01 00:00:00 +0000
 
246
@@ -0,0 +1,1 @@
 
247
+file2 contents at rev 1
 
248
 
 
249
''')
 
250
 
 
251
    def test_diff_remove_files(self):
 
252
        tree1 = self.b.repository.revision_tree('rev-3')
 
253
        tree2 = self.b.repository.revision_tree('rev-4')
 
254
        output = self.get_diff(tree1, tree2)
 
255
        # the file has the epoch time stamp for the tree in which
 
256
        # it doesn't exist.
 
257
        self.assertEqualDiff(output, '''\
 
258
=== removed file 'file2'
 
259
--- old/file2\t2006-04-03 00:00:00 +0000
 
260
+++ new/file2\t1970-01-01 00:00:00 +0000
 
261
@@ -1,1 +0,0 @@
 
262
-file2 contents at rev 3
 
263
 
 
264
''')
 
265
 
 
266
 
 
267
class TestPatienceDiffLib(TestCase):
 
268
 
 
269
    def test_unique_lcs(self):
 
270
        unique_lcs = bzrlib.patiencediff.unique_lcs
 
271
        self.assertEquals(unique_lcs('', ''), [])
 
272
        self.assertEquals(unique_lcs('a', 'a'), [(0,0)])
 
273
        self.assertEquals(unique_lcs('a', 'b'), [])
 
274
        self.assertEquals(unique_lcs('ab', 'ab'), [(0,0), (1,1)])
 
275
        self.assertEquals(unique_lcs('abcde', 'cdeab'), [(2,0), (3,1), (4,2)])
 
276
        self.assertEquals(unique_lcs('cdeab', 'abcde'), [(0,2), (1,3), (2,4)])
 
277
        self.assertEquals(unique_lcs('abXde', 'abYde'), [(0,0), (1,1), 
 
278
                                                         (3,3), (4,4)])
 
279
        self.assertEquals(unique_lcs('acbac', 'abc'), [(2,1)])
 
280
 
 
281
    def test_recurse_matches(self):
 
282
        def test_one(a, b, matches):
 
283
            test_matches = []
 
284
            bzrlib.patiencediff.recurse_matches(a, b, 0, 0, len(a), len(b),
 
285
                test_matches, 10)
 
286
            self.assertEquals(test_matches, matches)
 
287
 
 
288
        test_one(['a', '', 'b', '', 'c'], ['a', 'a', 'b', 'c', 'c'],
 
289
                 [(0, 0), (2, 2), (4, 4)])
 
290
        test_one(['a', 'c', 'b', 'a', 'c'], ['a', 'b', 'c'],
 
291
                 [(0, 0), (2, 1), (4, 2)])
 
292
 
 
293
        # recurse_matches doesn't match non-unique 
 
294
        # lines surrounded by bogus text.
 
295
        # The update has been done in patiencediff.SequenceMatcher instead
 
296
 
 
297
        # This is what it could be
 
298
        #test_one('aBccDe', 'abccde', [(0,0), (2,2), (3,3), (5,5)])
 
299
 
 
300
        # This is what it currently gives:
 
301
        test_one('aBccDe', 'abccde', [(0,0), (5,5)])
 
302
 
 
303
    def test_matching_blocks(self):
 
304
        def chk_blocks(a, b, expected_blocks):
 
305
            # difflib always adds a signature of the total
 
306
            # length, with no matching entries at the end
 
307
            s = bzrlib.patiencediff.PatienceSequenceMatcher(None, a, b)
 
308
            blocks = s.get_matching_blocks()
 
309
            self.assertEquals((len(a), len(b), 0), blocks[-1])
 
310
            self.assertEquals(expected_blocks, blocks[:-1])
 
311
 
 
312
        # Some basic matching tests
 
313
        chk_blocks('', '', [])
 
314
        chk_blocks([], [], [])
 
315
        chk_blocks('abcd', 'abcd', [(0, 0, 4)])
 
316
        chk_blocks('abcd', 'abce', [(0, 0, 3)])
 
317
        chk_blocks('eabc', 'abce', [(1, 0, 3)])
 
318
        chk_blocks('eabce', 'abce', [(1, 0, 4)])
 
319
        chk_blocks('abcde', 'abXde', [(0, 0, 2), (3, 3, 2)])
 
320
        chk_blocks('abcde', 'abXYZde', [(0, 0, 2), (3, 5, 2)])
 
321
        chk_blocks('abde', 'abXYZde', [(0, 0, 2), (2, 5, 2)])
 
322
        # This may check too much, but it checks to see that 
 
323
        # a copied block stays attached to the previous section,
 
324
        # not the later one.
 
325
        # difflib would tend to grab the trailing longest match
 
326
        # which would make the diff not look right
 
327
        chk_blocks('abcdefghijklmnop', 'abcdefxydefghijklmnop',
 
328
                   [(0, 0, 6), (6, 11, 10)])
 
329
 
 
330
        # make sure it supports passing in lists
 
331
        chk_blocks(
 
332
                   ['hello there\n',
 
333
                    'world\n',
 
334
                    'how are you today?\n'],
 
335
                   ['hello there\n',
 
336
                    'how are you today?\n'],
 
337
                [(0, 0, 1), (2, 1, 1)])
 
338
 
 
339
        # non unique lines surrounded by non-matching lines
 
340
        # won't be found
 
341
        chk_blocks('aBccDe', 'abccde', [(0,0,1), (5,5,1)])
 
342
 
 
343
        # But they only need to be locally unique
 
344
        chk_blocks('aBcDec', 'abcdec', [(0,0,1), (2,2,1), (4,4,2)])
 
345
 
 
346
        # non unique blocks won't be matched
 
347
        chk_blocks('aBcdEcdFg', 'abcdecdfg', [(0,0,1), (8,8,1)])
 
348
 
 
349
        # but locally unique ones will
 
350
        chk_blocks('aBcdEeXcdFg', 'abcdecdfg', [(0,0,1), (2,2,2),
 
351
                                              (5,4,1), (7,5,2), (10,8,1)])
 
352
 
 
353
        chk_blocks('abbabbXd', 'cabbabxd', [(7,7,1)])
 
354
        chk_blocks('abbabbbb', 'cabbabbc', [])
 
355
        chk_blocks('bbbbbbbb', 'cbbbbbbc', [])
 
356
 
 
357
    def test_opcodes(self):
 
358
        def chk_ops(a, b, expected_codes):
 
359
            s = bzrlib.patiencediff.PatienceSequenceMatcher(None, a, b)
 
360
            self.assertEquals(expected_codes, s.get_opcodes())
 
361
 
 
362
        chk_ops('', '', [])
 
363
        chk_ops([], [], [])
 
364
        chk_ops('abcd', 'abcd', [('equal',    0,4, 0,4)])
 
365
        chk_ops('abcd', 'abce', [('equal',   0,3, 0,3),
 
366
                                 ('replace', 3,4, 3,4)
 
367
                                ])
 
368
        chk_ops('eabc', 'abce', [('delete', 0,1, 0,0),
 
369
                                 ('equal',  1,4, 0,3),
 
370
                                 ('insert', 4,4, 3,4)
 
371
                                ])
 
372
        chk_ops('eabce', 'abce', [('delete', 0,1, 0,0),
 
373
                                  ('equal',  1,5, 0,4)
 
374
                                 ])
 
375
        chk_ops('abcde', 'abXde', [('equal',   0,2, 0,2),
 
376
                                   ('replace', 2,3, 2,3),
 
377
                                   ('equal',   3,5, 3,5)
 
378
                                  ])
 
379
        chk_ops('abcde', 'abXYZde', [('equal',   0,2, 0,2),
 
380
                                     ('replace', 2,3, 2,5),
 
381
                                     ('equal',   3,5, 5,7)
 
382
                                    ])
 
383
        chk_ops('abde', 'abXYZde', [('equal',  0,2, 0,2),
 
384
                                    ('insert', 2,2, 2,5),
 
385
                                    ('equal',  2,4, 5,7)
 
386
                                   ])
 
387
        chk_ops('abcdefghijklmnop', 'abcdefxydefghijklmnop',
 
388
                [('equal',  0,6,  0,6),
 
389
                 ('insert', 6,6,  6,11),
 
390
                 ('equal',  6,16, 11,21)
 
391
                ])
 
392
        chk_ops(
 
393
                [ 'hello there\n'
 
394
                , 'world\n'
 
395
                , 'how are you today?\n'],
 
396
                [ 'hello there\n'
 
397
                , 'how are you today?\n'],
 
398
                [('equal',  0,1, 0,1),
 
399
                 ('delete', 1,2, 1,1),
 
400
                 ('equal',  2,3, 1,2),
 
401
                ])
 
402
        chk_ops('aBccDe', 'abccde', 
 
403
                [('equal',   0,1, 0,1),
 
404
                 ('replace', 1,5, 1,5),
 
405
                 ('equal',   5,6, 5,6),
 
406
                ])
 
407
        chk_ops('aBcDec', 'abcdec', 
 
408
                [('equal',   0,1, 0,1),
 
409
                 ('replace', 1,2, 1,2),
 
410
                 ('equal',   2,3, 2,3),
 
411
                 ('replace', 3,4, 3,4),
 
412
                 ('equal',   4,6, 4,6),
 
413
                ])
 
414
        chk_ops('aBcdEcdFg', 'abcdecdfg', 
 
415
                [('equal',   0,1, 0,1),
 
416
                 ('replace', 1,8, 1,8),
 
417
                 ('equal',   8,9, 8,9)
 
418
                ])
 
419
        chk_ops('aBcdEeXcdFg', 'abcdecdfg', 
 
420
                [('equal',   0,1, 0,1),
 
421
                 ('replace', 1,2, 1,2),
 
422
                 ('equal',   2,4, 2,4),
 
423
                 ('delete', 4,5, 4,4),
 
424
                 ('equal',   5,6, 4,5),
 
425
                 ('delete', 6,7, 5,5),
 
426
                 ('equal',   7,9, 5,7),
 
427
                 ('replace', 9,10, 7,8),
 
428
                 ('equal',   10,11, 8,9)
 
429
                ])
 
430
 
 
431
    def test_multiple_ranges(self):
 
432
        # There was an earlier bug where we used a bad set of ranges,
 
433
        # this triggers that specific bug, to make sure it doesn't regress
 
434
        def chk_blocks(a, b, expected_blocks):
 
435
            # difflib always adds a signature of the total
 
436
            # length, with no matching entries at the end
 
437
            s = bzrlib.patiencediff.PatienceSequenceMatcher(None, a, b)
 
438
            blocks = s.get_matching_blocks()
 
439
            x = blocks.pop()
 
440
            self.assertEquals(x, (len(a), len(b), 0))
 
441
            self.assertEquals(expected_blocks, blocks)
 
442
 
 
443
        chk_blocks('abcdefghijklmnop'
 
444
                 , 'abcXghiYZQRSTUVWXYZijklmnop'
 
445
                 , [(0, 0, 3), (6, 4, 3), (9, 20, 7)])
 
446
 
 
447
        chk_blocks('ABCd efghIjk  L'
 
448
                 , 'AxyzBCn mo pqrstuvwI1 2  L'
 
449
                 , [(0,0,1), (1, 4, 2), (9, 19, 1), (12, 23, 3)])
 
450
 
 
451
        # These are rot13 code snippets.
 
452
        chk_blocks('''\
 
453
    trg nqqrq jura lbh nqq n svyr va gur qverpgbel.
 
454
    """
 
455
    gnxrf_netf = ['svyr*']
 
456
    gnxrf_bcgvbaf = ['ab-erphefr']
 
457
  
 
458
    qrs eha(frys, svyr_yvfg, ab_erphefr=Snyfr):
 
459
        sebz omeyvo.nqq vzcbeg fzneg_nqq, nqq_ercbegre_cevag, nqq_ercbegre_ahyy
 
460
        vs vf_dhvrg():
 
461
            ercbegre = nqq_ercbegre_ahyy
 
462
        ryfr:
 
463
            ercbegre = nqq_ercbegre_cevag
 
464
        fzneg_nqq(svyr_yvfg, abg ab_erphefr, ercbegre)
 
465
 
 
466
 
 
467
pynff pzq_zxqve(Pbzznaq):
 
468
'''.splitlines(True), '''\
 
469
    trg nqqrq jura lbh nqq n svyr va gur qverpgbel.
 
470
 
 
471
    --qel-eha jvyy fubj juvpu svyrf jbhyq or nqqrq, ohg abg npghnyyl 
 
472
    nqq gurz.
 
473
    """
 
474
    gnxrf_netf = ['svyr*']
 
475
    gnxrf_bcgvbaf = ['ab-erphefr', 'qel-eha']
 
476
 
 
477
    qrs eha(frys, svyr_yvfg, ab_erphefr=Snyfr, qel_eha=Snyfr):
 
478
        vzcbeg omeyvo.nqq
 
479
 
 
480
        vs qel_eha:
 
481
            vs vf_dhvrg():
 
482
                # Guvf vf cbvagyrff, ohg V'q engure abg envfr na reebe
 
483
                npgvba = omeyvo.nqq.nqq_npgvba_ahyy
 
484
            ryfr:
 
485
  npgvba = omeyvo.nqq.nqq_npgvba_cevag
 
486
        ryvs vf_dhvrg():
 
487
            npgvba = omeyvo.nqq.nqq_npgvba_nqq
 
488
        ryfr:
 
489
       npgvba = omeyvo.nqq.nqq_npgvba_nqq_naq_cevag
 
490
 
 
491
        omeyvo.nqq.fzneg_nqq(svyr_yvfg, abg ab_erphefr, npgvba)
 
492
 
 
493
 
 
494
pynff pzq_zxqve(Pbzznaq):
 
495
'''.splitlines(True)
 
496
, [(0,0,1), (1, 4, 2), (9, 19, 1), (12, 23, 3)])
 
497
 
 
498
    def test_patience_unified_diff(self):
 
499
        txt_a = ['hello there\n',
 
500
                 'world\n',
 
501
                 'how are you today?\n']
 
502
        txt_b = ['hello there\n',
 
503
                 'how are you today?\n']
 
504
        unified_diff = bzrlib.patiencediff.unified_diff
 
505
        psm = bzrlib.patiencediff.PatienceSequenceMatcher
 
506
        self.assertEquals([ '---  \n',
 
507
                           '+++  \n',
 
508
                           '@@ -1,3 +1,2 @@\n',
 
509
                           ' hello there\n',
 
510
                           '-world\n',
 
511
                           ' how are you today?\n'
 
512
                          ]
 
513
                          , list(unified_diff(txt_a, txt_b,
 
514
                                 sequencematcher=psm)))
 
515
        txt_a = map(lambda x: x+'\n', 'abcdefghijklmnop')
 
516
        txt_b = map(lambda x: x+'\n', 'abcdefxydefghijklmnop')
 
517
        # This is the result with LongestCommonSubstring matching
 
518
        self.assertEquals(['---  \n',
 
519
                           '+++  \n',
 
520
                           '@@ -1,6 +1,11 @@\n',
 
521
                           ' a\n',
 
522
                           ' b\n',
 
523
                           ' c\n',
 
524
                           '+d\n',
 
525
                           '+e\n',
 
526
                           '+f\n',
 
527
                           '+x\n',
 
528
                           '+y\n',
 
529
                           ' d\n',
 
530
                           ' e\n',
 
531
                           ' f\n']
 
532
                          , list(unified_diff(txt_a, txt_b)))
 
533
        # And the patience diff
 
534
        self.assertEquals(['---  \n',
 
535
                           '+++  \n',
 
536
                           '@@ -4,6 +4,11 @@\n',
 
537
                           ' d\n',
 
538
                           ' e\n',
 
539
                           ' f\n',
 
540
                           '+x\n',
 
541
                           '+y\n',
 
542
                           '+d\n',
 
543
                           '+e\n',
 
544
                           '+f\n',
 
545
                           ' g\n',
 
546
                           ' h\n',
 
547
                           ' i\n',
 
548
                          ]
 
549
                          , list(unified_diff(txt_a, txt_b,
 
550
                                 sequencematcher=psm)))
 
551
 
 
552
 
 
553
class TestPatienceDiffLibFiles(TestCaseInTempDir):
 
554
 
 
555
    def test_patience_unified_diff_files(self):
 
556
        txt_a = ['hello there\n',
 
557
                 'world\n',
 
558
                 'how are you today?\n']
 
559
        txt_b = ['hello there\n',
 
560
                 'how are you today?\n']
 
561
        open('a1', 'wb').writelines(txt_a)
 
562
        open('b1', 'wb').writelines(txt_b)
 
563
 
 
564
        unified_diff_files = bzrlib.patiencediff.unified_diff_files
 
565
        psm = bzrlib.patiencediff.PatienceSequenceMatcher
 
566
        self.assertEquals(['--- a1 \n',
 
567
                           '+++ b1 \n',
 
568
                           '@@ -1,3 +1,2 @@\n',
 
569
                           ' hello there\n',
 
570
                           '-world\n',
 
571
                           ' how are you today?\n',
 
572
                          ]
 
573
                          , list(unified_diff_files('a1', 'b1',
 
574
                                 sequencematcher=psm)))
 
575
 
 
576
        txt_a = map(lambda x: x+'\n', 'abcdefghijklmnop')
 
577
        txt_b = map(lambda x: x+'\n', 'abcdefxydefghijklmnop')
 
578
        open('a2', 'wb').writelines(txt_a)
 
579
        open('b2', 'wb').writelines(txt_b)
 
580
 
 
581
        # This is the result with LongestCommonSubstring matching
 
582
        self.assertEquals(['--- a2 \n',
 
583
                           '+++ b2 \n',
 
584
                           '@@ -1,6 +1,11 @@\n',
 
585
                           ' a\n',
 
586
                           ' b\n',
 
587
                           ' c\n',
 
588
                           '+d\n',
 
589
                           '+e\n',
 
590
                           '+f\n',
 
591
                           '+x\n',
 
592
                           '+y\n',
 
593
                           ' d\n',
 
594
                           ' e\n',
 
595
                           ' f\n']
 
596
                          , list(unified_diff_files('a2', 'b2')))
 
597
 
 
598
        # And the patience diff
 
599
        self.assertEquals(['--- a2 \n',
 
600
                           '+++ b2 \n',
 
601
                           '@@ -4,6 +4,11 @@\n',
 
602
                           ' d\n',
 
603
                           ' e\n',
 
604
                           ' f\n',
 
605
                           '+x\n',
 
606
                           '+y\n',
 
607
                           '+d\n',
 
608
                           '+e\n',
 
609
                           '+f\n',
 
610
                           ' g\n',
 
611
                           ' h\n',
 
612
                           ' i\n',
 
613
                          ]
 
614
                          , list(unified_diff_files('a2', 'b2',
 
615
                                 sequencematcher=psm)))