~bzr-pqm/bzr/bzr.dev

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