/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
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
1692.8.7 by James Henstridge
changes suggested by John Meinel
19
import errno
1692.8.5 by James Henstridge
merge from bzr.dev
20
from tempfile import TemporaryFile
1558.15.2 by Aaron Bentley
Implemented binary file handling for diff
21
1692.8.5 by James Henstridge
merge from bzr.dev
22
from bzrlib.diff import internal_diff, external_diff, show_diff_trees
1711.2.56 by John Arbash Meinel
Raise NoDiff if 'diff' not present.
23
from bzrlib.errors import BinaryFile, NoDiff
1711.2.20 by John Arbash Meinel
Late bind to patiencediff objects to make it easier to plug-in
24
import bzrlib.patiencediff
1711.2.54 by John Arbash Meinel
Use mkstemp instead of NamedTemporary file for external diff.
25
from bzrlib.tests import (TestCase, TestCaseWithTransport,
26
                          TestCaseInTempDir, TestSkipped)
1558.15.2 by Aaron Bentley
Implemented binary file handling for diff
27
28
1558.15.11 by Aaron Bentley
Apply merge review suggestions
29
def udiff_lines(old, new, allow_binary=False):
974.1.6 by Aaron Bentley
Added unit tests
30
    output = StringIO()
1558.15.11 by Aaron Bentley
Apply merge review suggestions
31
    internal_diff('old', old, 'new', new, output, allow_binary)
974.1.6 by Aaron Bentley
Added unit tests
32
    output.seek(0, 0)
33
    return output.readlines()
34
1711.2.54 by John Arbash Meinel
Use mkstemp instead of NamedTemporary file for external diff.
35
1692.8.2 by James Henstridge
add a test for sending external diff output to a file
36
def external_udiff_lines(old, new):
37
    output = TemporaryFile()
1692.8.7 by James Henstridge
changes suggested by John Meinel
38
    try:
39
        external_diff('old', old, 'new', new, output, diff_opts=['-u'])
1711.2.56 by John Arbash Meinel
Raise NoDiff if 'diff' not present.
40
    except errors.NoDiff:
41
        raise TestSkipped('external "diff" not present to test')
1692.8.2 by James Henstridge
add a test for sending external diff output to a file
42
    output.seek(0, 0)
43
    lines = output.readlines()
44
    output.close()
45
    return lines
46
47
1102 by Martin Pool
- merge test refactoring from robertc
48
class TestDiff(TestCase):
1185.81.25 by Aaron Bentley
Clean up test_diff
49
1102 by Martin Pool
- merge test refactoring from robertc
50
    def test_add_nl(self):
51
        """diff generates a valid diff for patches that add a newline"""
974.1.6 by Aaron Bentley
Added unit tests
52
        lines = udiff_lines(['boo'], ['boo\n'])
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
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]
974.1.6 by Aaron Bentley
Added unit tests
56
1102 by Martin Pool
- merge test refactoring from robertc
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
        """
974.1.6 by Aaron Bentley
Added unit tests
61
        lines = udiff_lines(['boo'], ['goo\n'])
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
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]
974.1.6 by Aaron Bentley
Added unit tests
65
1102 by Martin Pool
- merge test refactoring from robertc
66
    def test_remove_nl(self):
67
        """diff generates a valid diff for patches that change last line and
68
        add a newline.
69
        """
974.1.6 by Aaron Bentley
Added unit tests
70
        lines = udiff_lines(['boo\n'], ['boo'])
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
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
1558.15.2 by Aaron Bentley
Implemented binary file handling for diff
89
    def test_binary_lines(self):
90
        self.assertRaises(BinaryFile, udiff_lines, [1023 * 'a' + '\x00'], [])
91
        self.assertRaises(BinaryFile, udiff_lines, [], [1023 * 'a' + '\x00'])
1558.15.11 by Aaron Bentley
Apply merge review suggestions
92
        udiff_lines([1023 * 'a' + '\x00'], [], allow_binary=True)
93
        udiff_lines([], [1023 * 'a' + '\x00'], allow_binary=True)
1692.8.2 by James Henstridge
add a test for sending external diff output to a file
94
95
    def test_external_diff(self):
96
        lines = external_udiff_lines(['boo\n'], ['goo\n'])
97
        self.check_patch(lines)
98
        
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
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)
1740.2.5 by Aaron Bentley
Merge from bzr.dev
106
        self.assertEquals(['--- old_\xc2\xb5\n',
107
                           '+++ new_\xc3\xa5\n',
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
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)
1740.2.5 by Aaron Bentley
Merge from bzr.dev
122
        self.assertEquals(['--- old_\xc2\xb5\n',
123
                           '+++ new_\xc3\xa5\n',
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
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)
1740.2.5 by Aaron Bentley
Merge from bzr.dev
138
        self.assertEquals(['--- old_\xb5\n',
139
                           '+++ new_\xe5\n',
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
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
1185.81.25 by Aaron Bentley
Clean up test_diff
155
1740.2.5 by Aaron Bentley
Merge from bzr.dev
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
1711.2.15 by John Arbash Meinel
Found a couple CDV left
267
class TestPatienceDiffLib(TestCase):
1185.81.1 by John Arbash Meinel
Adding nofrillsprecisemerge's diff algorithm, wrapped in difflib.
268
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
269
    def test_unique_lcs(self):
1711.2.20 by John Arbash Meinel
Late bind to patiencediff objects to make it easier to plug-in
270
        unique_lcs = bzrlib.patiencediff.unique_lcs
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
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 = []
1711.2.22 by John Arbash Meinel
Passing the alo parameter to recurse_matches shaves of 5% of the diff time.
284
            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
285
                test_matches, 10)
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
286
            self.assertEquals(test_matches, matches)
287
1711.2.17 by John Arbash Meinel
Small cleanups to patience_diff code.
288
        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,
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
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
293
        # recurse_matches doesn't match non-unique 
294
        # lines surrounded by bogus text.
1185.81.24 by Aaron Bentley
Reoganize patience-related code
295
        # 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
296
297
        # This is what it could be
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
298
        #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
299
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
300
        # This is what it currently gives:
301
        test_one('aBccDe', 'abccde', [(0,0), (5,5)])
302
1185.81.1 by John Arbash Meinel
Adding nofrillsprecisemerge's diff algorithm, wrapped in difflib.
303
    def test_matching_blocks(self):
1711.2.10 by John Arbash Meinel
Clarify the patience tests a little bit.
304
        def chk_blocks(a, b, expected_blocks):
1185.81.1 by John Arbash Meinel
Adding nofrillsprecisemerge's diff algorithm, wrapped in difflib.
305
            # difflib always adds a signature of the total
306
            # 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
307
            s = bzrlib.patiencediff.PatienceSequenceMatcher(None, a, b)
1185.81.11 by John Arbash Meinel
Found some edge cases that weren't being matched.
308
            blocks = s.get_matching_blocks()
1711.2.10 by John Arbash Meinel
Clarify the patience tests a little bit.
309
            self.assertEquals((len(a), len(b), 0), blocks[-1])
310
            self.assertEquals(expected_blocks, blocks[:-1])
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
        # Some basic matching tests
1185.81.1 by John Arbash Meinel
Adding nofrillsprecisemerge's diff algorithm, wrapped in difflib.
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)])
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
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
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
327
        chk_blocks('abcdefghijklmnop', 'abcdefxydefghijklmnop',
328
                   [(0, 0, 6), (6, 11, 10)])
1185.81.1 by John Arbash Meinel
Adding nofrillsprecisemerge's diff algorithm, wrapped in difflib.
329
1185.81.2 by John Arbash Meinel
A couple small tests.
330
        # make sure it supports passing in lists
331
        chk_blocks(
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
332
                   ['hello there\n',
333
                    'world\n',
334
                    'how are you today?\n'],
335
                   ['hello there\n',
336
                    'how are you today?\n'],
1185.81.2 by John Arbash Meinel
A couple small tests.
337
                [(0, 0, 1), (2, 1, 1)])
1185.81.1 by John Arbash Meinel
Adding nofrillsprecisemerge's diff algorithm, wrapped in difflib.
338
1711.2.21 by John Arbash Meinel
Cleanup patiencediff, remove the use of difflib.SequenceMatcher.
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', [])
1185.81.11 by John Arbash Meinel
Found some edge cases that weren't being matched.
356
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
357
    def test_opcodes(self):
1711.2.10 by John Arbash Meinel
Clarify the patience tests a little bit.
358
        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
359
            s = bzrlib.patiencediff.PatienceSequenceMatcher(None, a, b)
1711.2.10 by John Arbash Meinel
Clarify the patience tests a little bit.
360
            self.assertEquals(expected_codes, s.get_opcodes())
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
361
362
        chk_ops('', '', [])
363
        chk_ops([], [], [])
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
364
        chk_ops('abcd', 'abcd', [('equal',    0,4, 0,4)])
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
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)
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
374
                                 ])
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
375
        chk_ops('abcde', 'abXde', [('equal',   0,2, 0,2),
376
                                   ('replace', 2,3, 2,3),
377
                                   ('equal',   3,5, 3,5)
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
378
                                  ])
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
379
        chk_ops('abcde', 'abXYZde', [('equal',   0,2, 0,2),
380
                                     ('replace', 2,3, 2,5),
381
                                     ('equal',   3,5, 5,7)
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
382
                                    ])
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
383
        chk_ops('abde', 'abXYZde', [('equal',  0,2, 0,2),
384
                                    ('insert', 2,2, 2,5),
385
                                    ('equal',  2,4, 5,7)
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
386
                                   ])
387
        chk_ops('abcdefghijklmnop', 'abcdefxydefghijklmnop',
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
388
                [('equal',  0,6,  0,6),
389
                 ('insert', 6,6,  6,11),
390
                 ('equal',  6,16, 11,21)
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
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'],
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
398
                [('equal',  0,1, 0,1),
399
                 ('delete', 1,2, 1,1),
1711.2.21 by John Arbash Meinel
Cleanup patiencediff, remove the use of difflib.SequenceMatcher.
400
                 ('equal',  2,3, 1,2),
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
401
                ])
402
        chk_ops('aBccDe', 'abccde', 
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
403
                [('equal',   0,1, 0,1),
1711.2.21 by John Arbash Meinel
Cleanup patiencediff, remove the use of difflib.SequenceMatcher.
404
                 ('replace', 1,5, 1,5),
405
                 ('equal',   5,6, 5,6),
406
                ])
407
        chk_ops('aBcDec', 'abcdec', 
408
                [('equal',   0,1, 0,1),
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
409
                 ('replace', 1,2, 1,2),
1711.2.21 by John Arbash Meinel
Cleanup patiencediff, remove the use of difflib.SequenceMatcher.
410
                 ('equal',   2,3, 2,3),
411
                 ('replace', 3,4, 3,4),
412
                 ('equal',   4,6, 4,6),
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
413
                ])
1185.81.10 by John Arbash Meinel
Added some more test cases.
414
        chk_ops('aBcdEcdFg', 'abcdecdfg', 
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
415
                [('equal',   0,1, 0,1),
1711.2.21 by John Arbash Meinel
Cleanup patiencediff, remove the use of difflib.SequenceMatcher.
416
                 ('replace', 1,8, 1,8),
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
417
                 ('equal',   8,9, 8,9)
1185.81.10 by John Arbash Meinel
Added some more test cases.
418
                ])
1711.2.21 by John Arbash Meinel
Cleanup patiencediff, remove the use of difflib.SequenceMatcher.
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
                ])
1185.81.10 by John Arbash Meinel
Added some more test cases.
430
1185.81.16 by John Arbash Meinel
Added tests, and an assert check to make sure ranges are always increasing.
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
1711.2.10 by John Arbash Meinel
Clarify the patience tests a little bit.
434
        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.
435
            # difflib always adds a signature of the total
436
            # 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
437
            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.
438
            blocks = s.get_matching_blocks()
439
            x = blocks.pop()
440
            self.assertEquals(x, (len(a), len(b), 0))
1711.2.10 by John Arbash Meinel
Clarify the patience tests a little bit.
441
            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.
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'
1711.2.21 by John Arbash Meinel
Cleanup patiencediff, remove the use of difflib.SequenceMatcher.
449
                 , [(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.
450
1711.2.8 by John Arbash Meinel
rot13 the code snippet to help with clarity.
451
        # 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.
452
        chk_blocks('''\
1711.2.8 by John Arbash Meinel
rot13 the code snippet to help with clarity.
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):
1185.81.16 by John Arbash Meinel
Added tests, and an assert check to make sure ranges are always increasing.
495
'''.splitlines(True)
496
, [(0,0,1), (1, 4, 2), (9, 19, 1), (12, 23, 3)])
497
1711.2.9 by John Arbash Meinel
Rename cdv => patience
498
    def test_patience_unified_diff(self):
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
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']
1711.2.20 by John Arbash Meinel
Late bind to patiencediff objects to make it easier to plug-in
504
        unified_diff = bzrlib.patiencediff.unified_diff
505
        psm = bzrlib.patiencediff.PatienceSequenceMatcher
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
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'
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
512
                          ]
1711.2.20 by John Arbash Meinel
Late bind to patiencediff objects to make it easier to plug-in
513
                          , list(unified_diff(txt_a, txt_b,
514
                                 sequencematcher=psm)))
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
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
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
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']
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
532
                          , list(unified_diff(txt_a, txt_b)))
1711.2.9 by John Arbash Meinel
Rename cdv => patience
533
        # And the patience diff
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
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',
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
548
                          ]
1185.81.25 by Aaron Bentley
Clean up test_diff
549
                          , 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
550
                                 sequencematcher=psm)))
1185.81.25 by Aaron Bentley
Clean up test_diff
551
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
552
1711.2.15 by John Arbash Meinel
Found a couple CDV left
553
class TestPatienceDiffLibFiles(TestCaseInTempDir):
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
554
1711.2.9 by John Arbash Meinel
Rename cdv => patience
555
    def test_patience_unified_diff_files(self):
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
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']
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
561
        open('a1', 'wb').writelines(txt_a)
562
        open('b1', 'wb').writelines(txt_b)
563
1711.2.20 by John Arbash Meinel
Late bind to patiencediff objects to make it easier to plug-in
564
        unified_diff_files = bzrlib.patiencediff.unified_diff_files
565
        psm = bzrlib.patiencediff.PatienceSequenceMatcher
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
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',
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
572
                          ]
1185.81.25 by Aaron Bentley
Clean up test_diff
573
                          , 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
574
                                 sequencematcher=psm)))
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
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
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
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']
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
596
                          , list(unified_diff_files('a2', 'b2')))
597
1711.2.9 by John Arbash Meinel
Rename cdv => patience
598
        # And the patience diff
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
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',
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
613
                          ]
1185.81.25 by Aaron Bentley
Clean up test_diff
614
                          , 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
615
                                 sequencematcher=psm)))