~bzr-pqm/bzr/bzr.dev

2052.3.1 by John Arbash Meinel
Add tests to cleanup the copyright of all source files
1
# Copyright (C) 2005, 2006 Canonical Ltd
1711.2.16 by John Arbash Meinel
test_diff needs a copyright statement
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.
2052.3.1 by John Arbash Meinel
Add tests to cleanup the copyright of all source files
12
#
1711.2.16 by John Arbash Meinel
test_diff needs a copyright statement
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
1920.1.1 by John Arbash Meinel
fix bug #56307, handle binary files even when LANG is not english
20
import subprocess
1920.1.3 by John Arbash Meinel
Remove spurious import
21
from tempfile import TemporaryFile
1558.15.2 by Aaron Bentley
Implemented binary file handling for diff
22
1692.8.5 by James Henstridge
merge from bzr.dev
23
from bzrlib.diff import internal_diff, external_diff, show_diff_trees
1711.2.56 by John Arbash Meinel
Raise NoDiff if 'diff' not present.
24
from bzrlib.errors import BinaryFile, NoDiff
2321.2.5 by Alexander Belchenko
external diff: no need for special code path for win32 (suggested by John Meinel)
25
import bzrlib.osutils as osutils
1711.2.20 by John Arbash Meinel
Late bind to patiencediff objects to make it easier to plug-in
26
import bzrlib.patiencediff
1711.2.54 by John Arbash Meinel
Use mkstemp instead of NamedTemporary file for external diff.
27
from bzrlib.tests import (TestCase, TestCaseWithTransport,
28
                          TestCaseInTempDir, TestSkipped)
1558.15.2 by Aaron Bentley
Implemented binary file handling for diff
29
30
1558.15.11 by Aaron Bentley
Apply merge review suggestions
31
def udiff_lines(old, new, allow_binary=False):
974.1.6 by Aaron Bentley
Added unit tests
32
    output = StringIO()
1558.15.11 by Aaron Bentley
Apply merge review suggestions
33
    internal_diff('old', old, 'new', new, output, allow_binary)
974.1.6 by Aaron Bentley
Added unit tests
34
    output.seek(0, 0)
35
    return output.readlines()
36
1711.2.54 by John Arbash Meinel
Use mkstemp instead of NamedTemporary file for external diff.
37
1711.2.57 by John Arbash Meinel
Allow external diff to write to a file without a fileno.
38
def external_udiff_lines(old, new, use_stringio=False):
39
    if use_stringio:
40
        # StringIO has no fileno, so it tests a different codepath
41
        output = StringIO()
42
    else:
43
        output = TemporaryFile()
1692.8.7 by James Henstridge
changes suggested by John Meinel
44
    try:
45
        external_diff('old', old, 'new', new, output, diff_opts=['-u'])
1711.2.58 by John Arbash Meinel
Use osutils.pumpfile so we don't have to buffer everything in ram
46
    except NoDiff:
1711.2.56 by John Arbash Meinel
Raise NoDiff if 'diff' not present.
47
        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
48
    output.seek(0, 0)
49
    lines = output.readlines()
50
    output.close()
51
    return lines
52
53
1102 by Martin Pool
- merge test refactoring from robertc
54
class TestDiff(TestCase):
1185.81.25 by Aaron Bentley
Clean up test_diff
55
1102 by Martin Pool
- merge test refactoring from robertc
56
    def test_add_nl(self):
57
        """diff generates a valid diff for patches that add a newline"""
974.1.6 by Aaron Bentley
Added unit tests
58
        lines = udiff_lines(['boo'], ['boo\n'])
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
59
        self.check_patch(lines)
60
        self.assertEquals(lines[4], '\\ No newline at end of file\n')
61
            ## "expected no-nl, got %r" % lines[4]
974.1.6 by Aaron Bentley
Added unit tests
62
1102 by Martin Pool
- merge test refactoring from robertc
63
    def test_add_nl_2(self):
64
        """diff generates a valid diff for patches that change last line and
65
        add a newline.
66
        """
974.1.6 by Aaron Bentley
Added unit tests
67
        lines = udiff_lines(['boo'], ['goo\n'])
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
68
        self.check_patch(lines)
69
        self.assertEquals(lines[4], '\\ No newline at end of file\n')
70
            ## "expected no-nl, got %r" % lines[4]
974.1.6 by Aaron Bentley
Added unit tests
71
1102 by Martin Pool
- merge test refactoring from robertc
72
    def test_remove_nl(self):
73
        """diff generates a valid diff for patches that change last line and
74
        add a newline.
75
        """
974.1.6 by Aaron Bentley
Added unit tests
76
        lines = udiff_lines(['boo\n'], ['boo'])
1185.16.145 by Martin Pool
Remove all assert statements from test cases.
77
        self.check_patch(lines)
78
        self.assertEquals(lines[5], '\\ No newline at end of file\n')
79
            ## "expected no-nl, got %r" % lines[5]
80
81
    def check_patch(self, lines):
82
        self.assert_(len(lines) > 1)
83
            ## "Not enough lines for a file header for patch:\n%s" % "".join(lines)
84
        self.assert_(lines[0].startswith ('---'))
85
            ## 'No orig line for patch:\n%s' % "".join(lines)
86
        self.assert_(lines[1].startswith ('+++'))
87
            ## 'No mod line for patch:\n%s' % "".join(lines)
88
        self.assert_(len(lines) > 2)
89
            ## "No hunks for patch:\n%s" % "".join(lines)
90
        self.assert_(lines[2].startswith('@@'))
91
            ## "No hunk header for patch:\n%s" % "".join(lines)
92
        self.assert_('@@' in lines[2][2:])
93
            ## "Unterminated hunk header for patch:\n%s" % "".join(lines)
94
1558.15.2 by Aaron Bentley
Implemented binary file handling for diff
95
    def test_binary_lines(self):
96
        self.assertRaises(BinaryFile, udiff_lines, [1023 * 'a' + '\x00'], [])
97
        self.assertRaises(BinaryFile, udiff_lines, [], [1023 * 'a' + '\x00'])
1558.15.11 by Aaron Bentley
Apply merge review suggestions
98
        udiff_lines([1023 * 'a' + '\x00'], [], allow_binary=True)
99
        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
100
101
    def test_external_diff(self):
102
        lines = external_udiff_lines(['boo\n'], ['goo\n'])
103
        self.check_patch(lines)
1899.1.6 by John Arbash Meinel
internal_diff always adds a trailing \n, make sure external_diff does too
104
        self.assertEqual('\n', lines[-1])
1711.2.57 by John Arbash Meinel
Allow external diff to write to a file without a fileno.
105
106
    def test_external_diff_no_fileno(self):
107
        # Make sure that we can handle not having a fileno, even
108
        # if the diff is large
109
        lines = external_udiff_lines(['boo\n']*10000,
110
                                     ['goo\n']*10000,
111
                                     use_stringio=True)
112
        self.check_patch(lines)
1899.1.1 by John Arbash Meinel
Fix the bug in the NoDiff exception class, and add a test
113
1920.1.1 by John Arbash Meinel
fix bug #56307, handle binary files even when LANG is not english
114
    def test_external_diff_binary_lang_c(self):
2321.2.5 by Alexander Belchenko
external diff: no need for special code path for win32 (suggested by John Meinel)
115
        old_env = {}
116
        for lang in ('LANG', 'LC_ALL', 'LANGUAGE'):
117
            old_env[lang] = osutils.set_or_unset_env(lang, 'C')
1920.1.1 by John Arbash Meinel
fix bug #56307, handle binary files even when LANG is not english
118
        try:
119
            lines = external_udiff_lines(['\x00foobar\n'], ['foo\x00bar\n'])
1959.1.1 by Marien Zwart
merge.
120
            # Older versions of diffutils say "Binary files", newer
121
            # versions just say "Files".
122
            self.assertContainsRe(lines[0],
123
                                  '(Binary f|F)iles old and new differ\n')
124
            self.assertEquals(lines[1:], ['\n'])
1920.1.1 by John Arbash Meinel
fix bug #56307, handle binary files even when LANG is not english
125
        finally:
2321.2.5 by Alexander Belchenko
external diff: no need for special code path for win32 (suggested by John Meinel)
126
            for lang, old_val in old_env.iteritems():
127
                osutils.set_or_unset_env(lang, old_val)
1899.1.4 by John Arbash Meinel
Just swallow a return code of 2
128
1899.1.1 by John Arbash Meinel
Fix the bug in the NoDiff exception class, and add a test
129
    def test_no_external_diff(self):
130
        """Check that NoDiff is raised when diff is not available"""
131
        # Use os.environ['PATH'] to make sure no 'diff' command is available
132
        orig_path = os.environ['PATH']
133
        try:
134
            os.environ['PATH'] = ''
135
            self.assertRaises(NoDiff, external_diff,
136
                              'old', ['boo\n'], 'new', ['goo\n'],
137
                              StringIO(), diff_opts=['-u'])
138
        finally:
139
            os.environ['PATH'] = orig_path
1692.8.2 by James Henstridge
add a test for sending external diff output to a file
140
        
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
141
    def test_internal_diff_default(self):
142
        # Default internal diff encoding is utf8
143
        output = StringIO()
144
        internal_diff(u'old_\xb5', ['old_text\n'],
145
                    u'new_\xe5', ['new_text\n'], output)
146
        lines = output.getvalue().splitlines(True)
147
        self.check_patch(lines)
1740.2.5 by Aaron Bentley
Merge from bzr.dev
148
        self.assertEquals(['--- old_\xc2\xb5\n',
149
                           '+++ new_\xc3\xa5\n',
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
150
                           '@@ -1,1 +1,1 @@\n',
151
                           '-old_text\n',
152
                           '+new_text\n',
153
                           '\n',
154
                          ]
155
                          , lines)
156
157
    def test_internal_diff_utf8(self):
158
        output = StringIO()
159
        internal_diff(u'old_\xb5', ['old_text\n'],
160
                    u'new_\xe5', ['new_text\n'], output,
161
                    path_encoding='utf8')
162
        lines = output.getvalue().splitlines(True)
163
        self.check_patch(lines)
1740.2.5 by Aaron Bentley
Merge from bzr.dev
164
        self.assertEquals(['--- old_\xc2\xb5\n',
165
                           '+++ new_\xc3\xa5\n',
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
166
                           '@@ -1,1 +1,1 @@\n',
167
                           '-old_text\n',
168
                           '+new_text\n',
169
                           '\n',
170
                          ]
171
                          , lines)
172
173
    def test_internal_diff_iso_8859_1(self):
174
        output = StringIO()
175
        internal_diff(u'old_\xb5', ['old_text\n'],
176
                    u'new_\xe5', ['new_text\n'], output,
177
                    path_encoding='iso-8859-1')
178
        lines = output.getvalue().splitlines(True)
179
        self.check_patch(lines)
1740.2.5 by Aaron Bentley
Merge from bzr.dev
180
        self.assertEquals(['--- old_\xb5\n',
181
                           '+++ new_\xe5\n',
1711.2.30 by John Arbash Meinel
Fix bug in internal_diff handling of unicode paths
182
                           '@@ -1,1 +1,1 @@\n',
183
                           '-old_text\n',
184
                           '+new_text\n',
185
                           '\n',
186
                          ]
187
                          , lines)
188
189
    def test_internal_diff_returns_bytes(self):
190
        import StringIO
191
        output = StringIO.StringIO()
192
        internal_diff(u'old_\xb5', ['old_text\n'],
193
                    u'new_\xe5', ['new_text\n'], output)
194
        self.failUnless(isinstance(output.getvalue(), str),
195
            'internal_diff should return bytestrings')
196
1185.81.25 by Aaron Bentley
Clean up test_diff
197
1920.1.1 by John Arbash Meinel
fix bug #56307, handle binary files even when LANG is not english
198
class TestDiffFiles(TestCaseInTempDir):
199
200
    def test_external_diff_binary(self):
201
        """The output when using external diff should use diff's i18n error"""
202
        # Make sure external_diff doesn't fail in the current LANG
203
        lines = external_udiff_lines(['\x00foobar\n'], ['foo\x00bar\n'])
204
2240.1.1 by Alexander Belchenko
test_external_diff_binary: run external diff with --binary flag
205
        cmd = ['diff', '-u', '--binary', 'old', 'new']
1920.1.1 by John Arbash Meinel
fix bug #56307, handle binary files even when LANG is not english
206
        open('old', 'wb').write('\x00foobar\n')
207
        open('new', 'wb').write('foo\x00bar\n')
208
        pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE,
209
                                     stdin=subprocess.PIPE)
210
        out, err = pipe.communicate()
211
        # Diff returns '2' on Binary files.
212
        self.assertEqual(2, pipe.returncode)
213
        # We should output whatever diff tells us, plus a trailing newline
214
        self.assertEqual(out.splitlines(True) + ['\n'], lines)
215
216
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
217
class TestShowDiffTreesHelper(TestCaseWithTransport):
218
    """Has a helper for running show_diff_trees"""
219
220
    def get_diff(self, tree1, tree2, specific_files=None, working_tree=None):
221
        output = StringIO()
222
        if working_tree is not None:
223
            extra_trees = (working_tree,)
224
        else:
225
            extra_trees = ()
226
        show_diff_trees(tree1, tree2, output, specific_files=specific_files,
227
                        extra_trees=extra_trees, old_label='old/',
228
                        new_label='new/')
229
        return output.getvalue()
230
231
232
class TestDiffDates(TestShowDiffTreesHelper):
1740.2.5 by Aaron Bentley
Merge from bzr.dev
233
234
    def setUp(self):
235
        super(TestDiffDates, self).setUp()
236
        self.wt = self.make_branch_and_tree('.')
237
        self.b = self.wt.branch
238
        self.build_tree_contents([
239
            ('file1', 'file1 contents at rev 1\n'),
240
            ('file2', 'file2 contents at rev 1\n')
241
            ])
242
        self.wt.add(['file1', 'file2'])
243
        self.wt.commit(
244
            message='Revision 1',
245
            timestamp=1143849600, # 2006-04-01 00:00:00 UTC
246
            timezone=0,
247
            rev_id='rev-1')
248
        self.build_tree_contents([('file1', 'file1 contents at rev 2\n')])
249
        self.wt.commit(
250
            message='Revision 2',
251
            timestamp=1143936000, # 2006-04-02 00:00:00 UTC
252
            timezone=28800,
253
            rev_id='rev-2')
254
        self.build_tree_contents([('file2', 'file2 contents at rev 3\n')])
255
        self.wt.commit(
256
            message='Revision 3',
257
            timestamp=1144022400, # 2006-04-03 00:00:00 UTC
258
            timezone=-3600,
259
            rev_id='rev-3')
260
        self.wt.remove(['file2'])
261
        self.wt.commit(
262
            message='Revision 4',
263
            timestamp=1144108800, # 2006-04-04 00:00:00 UTC
264
            timezone=0,
265
            rev_id='rev-4')
266
        self.build_tree_contents([
267
            ('file1', 'file1 contents in working tree\n')
268
            ])
269
        # set the date stamps for files in the working tree to known values
270
        os.utime('file1', (1144195200, 1144195200)) # 2006-04-05 00:00:00 UTC
271
272
    def test_diff_rev_tree_working_tree(self):
273
        output = self.get_diff(self.wt.basis_tree(), self.wt)
274
        # note that the date for old/file1 is from rev 2 rather than from
275
        # the basis revision (rev 4)
276
        self.assertEqualDiff(output, '''\
277
=== modified file 'file1'
278
--- old/file1\t2006-04-02 00:00:00 +0000
279
+++ new/file1\t2006-04-05 00:00:00 +0000
280
@@ -1,1 +1,1 @@
281
-file1 contents at rev 2
282
+file1 contents in working tree
283
284
''')
285
286
    def test_diff_rev_tree_rev_tree(self):
287
        tree1 = self.b.repository.revision_tree('rev-2')
288
        tree2 = self.b.repository.revision_tree('rev-3')
289
        output = self.get_diff(tree1, tree2)
290
        self.assertEqualDiff(output, '''\
291
=== modified file 'file2'
292
--- old/file2\t2006-04-01 00:00:00 +0000
293
+++ new/file2\t2006-04-03 00:00:00 +0000
294
@@ -1,1 +1,1 @@
295
-file2 contents at rev 1
296
+file2 contents at rev 3
297
298
''')
299
        
300
    def test_diff_add_files(self):
301
        tree1 = self.b.repository.revision_tree(None)
302
        tree2 = self.b.repository.revision_tree('rev-1')
303
        output = self.get_diff(tree1, tree2)
304
        # the files have the epoch time stamp for the tree in which
305
        # they don't exist.
306
        self.assertEqualDiff(output, '''\
307
=== added file 'file1'
308
--- old/file1\t1970-01-01 00:00:00 +0000
309
+++ new/file1\t2006-04-01 00:00:00 +0000
310
@@ -0,0 +1,1 @@
311
+file1 contents at rev 1
312
313
=== added file 'file2'
314
--- old/file2\t1970-01-01 00:00:00 +0000
315
+++ new/file2\t2006-04-01 00:00:00 +0000
316
@@ -0,0 +1,1 @@
317
+file2 contents at rev 1
318
319
''')
320
321
    def test_diff_remove_files(self):
322
        tree1 = self.b.repository.revision_tree('rev-3')
323
        tree2 = self.b.repository.revision_tree('rev-4')
324
        output = self.get_diff(tree1, tree2)
325
        # the file has the epoch time stamp for the tree in which
326
        # it doesn't exist.
327
        self.assertEqualDiff(output, '''\
328
=== removed file 'file2'
329
--- old/file2\t2006-04-03 00:00:00 +0000
330
+++ new/file2\t1970-01-01 00:00:00 +0000
331
@@ -1,1 +0,0 @@
332
-file2 contents at rev 3
333
334
''')
335
1551.7.17 by Aaron Bentley
Switch to PathsNotVersioned, accept extra_trees
336
    def test_show_diff_specified(self):
1551.7.22 by Aaron Bentley
Changes from review
337
        """A working tree filename can be used to identify a file"""
1551.7.17 by Aaron Bentley
Switch to PathsNotVersioned, accept extra_trees
338
        self.wt.rename_one('file1', 'file1b')
339
        old_tree = self.b.repository.revision_tree('rev-1')
340
        new_tree = self.b.repository.revision_tree('rev-4')
1551.7.22 by Aaron Bentley
Changes from review
341
        out = self.get_diff(old_tree, new_tree, specific_files=['file1b'], 
342
                            working_tree=self.wt)
343
        self.assertContainsRe(out, 'file1\t')
1551.7.17 by Aaron Bentley
Switch to PathsNotVersioned, accept extra_trees
344
1551.7.22 by Aaron Bentley
Changes from review
345
    def test_recursive_diff(self):
346
        """Children of directories are matched"""
347
        os.mkdir('dir1')
348
        os.mkdir('dir2')
349
        self.wt.add(['dir1', 'dir2'])
350
        self.wt.rename_one('file1', 'dir1/file1')
351
        old_tree = self.b.repository.revision_tree('rev-1')
352
        new_tree = self.b.repository.revision_tree('rev-4')
353
        out = self.get_diff(old_tree, new_tree, specific_files=['dir1'], 
354
                            working_tree=self.wt)
355
        self.assertContainsRe(out, 'file1\t')
356
        out = self.get_diff(old_tree, new_tree, specific_files=['dir2'], 
357
                            working_tree=self.wt)
358
        self.assertNotContainsRe(out, 'file1\t')
1740.2.5 by Aaron Bentley
Merge from bzr.dev
359
1899.1.1 by John Arbash Meinel
Fix the bug in the NoDiff exception class, and add a test
360
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
361
362
class TestShowDiffTrees(TestShowDiffTreesHelper):
363
    """Direct tests for show_diff_trees"""
364
365
    def test_modified_file(self):
366
        """Test when a file is modified."""
367
        tree = self.make_branch_and_tree('tree')
368
        self.build_tree_contents([('tree/file', 'contents\n')])
369
        tree.add(['file'], ['file-id'])
370
        tree.commit('one', rev_id='rev-1')
371
372
        self.build_tree_contents([('tree/file', 'new contents\n')])
373
        diff = self.get_diff(tree.basis_tree(), tree)
374
        self.assertContainsRe(diff, "=== modified file 'file'\n")
375
        self.assertContainsRe(diff, '--- old/file\t')
376
        self.assertContainsRe(diff, '\\+\\+\\+ new/file\t')
377
        self.assertContainsRe(diff, '-contents\n'
378
                                    '\\+new contents\n')
379
2405.1.2 by John Arbash Meinel
Fix bug #103870 by passing None instead of a (sometimes wrong) path
380
    def test_modified_file_in_renamed_dir(self):
381
        """Test when a file is modified in a renamed directory."""
382
        tree = self.make_branch_and_tree('tree')
383
        self.build_tree(['tree/dir/'])
384
        self.build_tree_contents([('tree/dir/file', 'contents\n')])
385
        tree.add(['dir', 'dir/file'], ['dir-id', 'file-id'])
386
        tree.commit('one', rev_id='rev-1')
387
388
        tree.rename_one('dir', 'other')
389
        self.build_tree_contents([('tree/other/file', 'new contents\n')])
390
        diff = self.get_diff(tree.basis_tree(), tree)
391
        self.assertContainsRe(diff, "=== renamed directory 'dir' => 'other'\n")
392
        self.assertContainsRe(diff, "=== modified file 'other/file'\n")
393
        # XXX: This is technically incorrect, because it used to be at another
394
        # location. What to do?
2405.1.3 by John Arbash Meinel
Do a better fix, which recognizes that we should pass the correct old path.
395
        self.assertContainsRe(diff, '--- old/dir/file\t')
2405.1.2 by John Arbash Meinel
Fix bug #103870 by passing None instead of a (sometimes wrong) path
396
        self.assertContainsRe(diff, '\\+\\+\\+ new/other/file\t')
397
        self.assertContainsRe(diff, '-contents\n'
398
                                    '\\+new contents\n')
399
2405.1.1 by John Arbash Meinel
Add a bunch of direct tests for 'show_diff_trees'
400
    def test_renamed_directory(self):
401
        """Test when only a directory is only renamed."""
402
        tree = self.make_branch_and_tree('tree')
403
        self.build_tree(['tree/dir/'])
404
        self.build_tree_contents([('tree/dir/file', 'contents\n')])
405
        tree.add(['dir', 'dir/file'], ['dir-id', 'file-id'])
406
        tree.commit('one', rev_id='rev-1')
407
408
        tree.rename_one('dir', 'newdir')
409
        diff = self.get_diff(tree.basis_tree(), tree)
410
        # Renaming a directory should be a single "you renamed this dir" even
411
        # when there are files inside.
412
        self.assertEqual("=== renamed directory 'dir' => 'newdir'\n", diff)
413
414
    def test_renamed_file(self):
415
        """Test when a file is only renamed."""
416
        tree = self.make_branch_and_tree('tree')
417
        self.build_tree_contents([('tree/file', 'contents\n')])
418
        tree.add(['file'], ['file-id'])
419
        tree.commit('one', rev_id='rev-1')
420
421
        tree.rename_one('file', 'newname')
422
        diff = self.get_diff(tree.basis_tree(), tree)
423
        self.assertContainsRe(diff, "=== renamed file 'file' => 'newname'\n")
424
        # We shouldn't have a --- or +++ line, because there is no content
425
        # change
426
        self.assertNotContainsRe(diff, '---')
427
428
    def test_renamed_and_modified_file(self):
429
        """Test when a file is only renamed."""
430
        tree = self.make_branch_and_tree('tree')
431
        self.build_tree_contents([('tree/file', 'contents\n')])
432
        tree.add(['file'], ['file-id'])
433
        tree.commit('one', rev_id='rev-1')
434
435
        tree.rename_one('file', 'newname')
436
        self.build_tree_contents([('tree/newname', 'new contents\n')])
437
        diff = self.get_diff(tree.basis_tree(), tree)
438
        self.assertContainsRe(diff, "=== renamed file 'file' => 'newname'\n")
439
        self.assertContainsRe(diff, '--- old/file\t')
440
        self.assertContainsRe(diff, '\\+\\+\\+ new/newname\t')
441
        self.assertContainsRe(diff, '-contents\n'
442
                                    '\\+new contents\n')
443
444
1711.2.15 by John Arbash Meinel
Found a couple CDV left
445
class TestPatienceDiffLib(TestCase):
1185.81.1 by John Arbash Meinel
Adding nofrillsprecisemerge's diff algorithm, wrapped in difflib.
446
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
447
    def test_unique_lcs(self):
1711.2.20 by John Arbash Meinel
Late bind to patiencediff objects to make it easier to plug-in
448
        unique_lcs = bzrlib.patiencediff.unique_lcs
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
449
        self.assertEquals(unique_lcs('', ''), [])
450
        self.assertEquals(unique_lcs('a', 'a'), [(0,0)])
451
        self.assertEquals(unique_lcs('a', 'b'), [])
452
        self.assertEquals(unique_lcs('ab', 'ab'), [(0,0), (1,1)])
453
        self.assertEquals(unique_lcs('abcde', 'cdeab'), [(2,0), (3,1), (4,2)])
454
        self.assertEquals(unique_lcs('cdeab', 'abcde'), [(0,2), (1,3), (2,4)])
455
        self.assertEquals(unique_lcs('abXde', 'abYde'), [(0,0), (1,1), 
456
                                                         (3,3), (4,4)])
457
        self.assertEquals(unique_lcs('acbac', 'abc'), [(2,1)])
458
459
    def test_recurse_matches(self):
460
        def test_one(a, b, matches):
461
            test_matches = []
1711.2.22 by John Arbash Meinel
Passing the alo parameter to recurse_matches shaves of 5% of the diff time.
462
            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
463
                test_matches, 10)
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
464
            self.assertEquals(test_matches, matches)
465
1711.2.17 by John Arbash Meinel
Small cleanups to patience_diff code.
466
        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,
467
                 [(0, 0), (2, 2), (4, 4)])
468
        test_one(['a', 'c', 'b', 'a', 'c'], ['a', 'b', 'c'],
469
                 [(0, 0), (2, 1), (4, 2)])
470
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
471
        # recurse_matches doesn't match non-unique 
472
        # lines surrounded by bogus text.
1185.81.24 by Aaron Bentley
Reoganize patience-related code
473
        # 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
474
475
        # This is what it could be
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
476
        #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
477
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
478
        # This is what it currently gives:
479
        test_one('aBccDe', 'abccde', [(0,0), (5,5)])
480
1185.81.1 by John Arbash Meinel
Adding nofrillsprecisemerge's diff algorithm, wrapped in difflib.
481
    def test_matching_blocks(self):
1711.2.10 by John Arbash Meinel
Clarify the patience tests a little bit.
482
        def chk_blocks(a, b, expected_blocks):
1185.81.1 by John Arbash Meinel
Adding nofrillsprecisemerge's diff algorithm, wrapped in difflib.
483
            # difflib always adds a signature of the total
484
            # 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
485
            s = bzrlib.patiencediff.PatienceSequenceMatcher(None, a, b)
1185.81.11 by John Arbash Meinel
Found some edge cases that weren't being matched.
486
            blocks = s.get_matching_blocks()
1711.2.10 by John Arbash Meinel
Clarify the patience tests a little bit.
487
            self.assertEquals((len(a), len(b), 0), blocks[-1])
488
            self.assertEquals(expected_blocks, blocks[:-1])
1185.81.1 by John Arbash Meinel
Adding nofrillsprecisemerge's diff algorithm, wrapped in difflib.
489
1185.81.2 by John Arbash Meinel
A couple small tests.
490
        # Some basic matching tests
1185.81.1 by John Arbash Meinel
Adding nofrillsprecisemerge's diff algorithm, wrapped in difflib.
491
        chk_blocks('', '', [])
492
        chk_blocks([], [], [])
493
        chk_blocks('abcd', 'abcd', [(0, 0, 4)])
494
        chk_blocks('abcd', 'abce', [(0, 0, 3)])
495
        chk_blocks('eabc', 'abce', [(1, 0, 3)])
496
        chk_blocks('eabce', 'abce', [(1, 0, 4)])
497
        chk_blocks('abcde', 'abXde', [(0, 0, 2), (3, 3, 2)])
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
498
        chk_blocks('abcde', 'abXYZde', [(0, 0, 2), (3, 5, 2)])
499
        chk_blocks('abde', 'abXYZde', [(0, 0, 2), (2, 5, 2)])
500
        # This may check too much, but it checks to see that 
501
        # a copied block stays attached to the previous section,
502
        # not the later one.
503
        # difflib would tend to grab the trailing longest match
504
        # 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,
505
        chk_blocks('abcdefghijklmnop', 'abcdefxydefghijklmnop',
506
                   [(0, 0, 6), (6, 11, 10)])
1185.81.1 by John Arbash Meinel
Adding nofrillsprecisemerge's diff algorithm, wrapped in difflib.
507
1185.81.2 by John Arbash Meinel
A couple small tests.
508
        # make sure it supports passing in lists
509
        chk_blocks(
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
510
                   ['hello there\n',
511
                    'world\n',
512
                    'how are you today?\n'],
513
                   ['hello there\n',
514
                    'how are you today?\n'],
1185.81.2 by John Arbash Meinel
A couple small tests.
515
                [(0, 0, 1), (2, 1, 1)])
1185.81.1 by John Arbash Meinel
Adding nofrillsprecisemerge's diff algorithm, wrapped in difflib.
516
1711.2.21 by John Arbash Meinel
Cleanup patiencediff, remove the use of difflib.SequenceMatcher.
517
        # non unique lines surrounded by non-matching lines
518
        # won't be found
519
        chk_blocks('aBccDe', 'abccde', [(0,0,1), (5,5,1)])
520
521
        # But they only need to be locally unique
522
        chk_blocks('aBcDec', 'abcdec', [(0,0,1), (2,2,1), (4,4,2)])
523
524
        # non unique blocks won't be matched
525
        chk_blocks('aBcdEcdFg', 'abcdecdfg', [(0,0,1), (8,8,1)])
526
527
        # but locally unique ones will
528
        chk_blocks('aBcdEeXcdFg', 'abcdecdfg', [(0,0,1), (2,2,2),
529
                                              (5,4,1), (7,5,2), (10,8,1)])
530
531
        chk_blocks('abbabbXd', 'cabbabxd', [(7,7,1)])
532
        chk_blocks('abbabbbb', 'cabbabbc', [])
533
        chk_blocks('bbbbbbbb', 'cbbbbbbc', [])
1185.81.11 by John Arbash Meinel
Found some edge cases that weren't being matched.
534
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
535
    def test_opcodes(self):
1711.2.10 by John Arbash Meinel
Clarify the patience tests a little bit.
536
        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
537
            s = bzrlib.patiencediff.PatienceSequenceMatcher(None, a, b)
1711.2.10 by John Arbash Meinel
Clarify the patience tests a little bit.
538
            self.assertEquals(expected_codes, s.get_opcodes())
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
539
540
        chk_ops('', '', [])
541
        chk_ops([], [], [])
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
542
        chk_ops('abcd', 'abcd', [('equal',    0,4, 0,4)])
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
543
        chk_ops('abcd', 'abce', [('equal',   0,3, 0,3),
544
                                 ('replace', 3,4, 3,4)
545
                                ])
546
        chk_ops('eabc', 'abce', [('delete', 0,1, 0,0),
547
                                 ('equal',  1,4, 0,3),
548
                                 ('insert', 4,4, 3,4)
549
                                ])
550
        chk_ops('eabce', 'abce', [('delete', 0,1, 0,0),
551
                                  ('equal',  1,5, 0,4)
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
552
                                 ])
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
553
        chk_ops('abcde', 'abXde', [('equal',   0,2, 0,2),
554
                                   ('replace', 2,3, 2,3),
555
                                   ('equal',   3,5, 3,5)
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
556
                                  ])
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
557
        chk_ops('abcde', 'abXYZde', [('equal',   0,2, 0,2),
558
                                     ('replace', 2,3, 2,5),
559
                                     ('equal',   3,5, 5,7)
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
560
                                    ])
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
561
        chk_ops('abde', 'abXYZde', [('equal',  0,2, 0,2),
562
                                    ('insert', 2,2, 2,5),
563
                                    ('equal',  2,4, 5,7)
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
564
                                   ])
565
        chk_ops('abcdefghijklmnop', 'abcdefxydefghijklmnop',
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
566
                [('equal',  0,6,  0,6),
567
                 ('insert', 6,6,  6,11),
568
                 ('equal',  6,16, 11,21)
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
569
                ])
570
        chk_ops(
571
                [ 'hello there\n'
572
                , 'world\n'
573
                , 'how are you today?\n'],
574
                [ 'hello there\n'
575
                , 'how are you today?\n'],
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
576
                [('equal',  0,1, 0,1),
577
                 ('delete', 1,2, 1,1),
1711.2.21 by John Arbash Meinel
Cleanup patiencediff, remove the use of difflib.SequenceMatcher.
578
                 ('equal',  2,3, 1,2),
1185.81.9 by John Arbash Meinel
Added (failing) tests for cdv.recurse_matches with common sections,
579
                ])
580
        chk_ops('aBccDe', 'abccde', 
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
581
                [('equal',   0,1, 0,1),
1711.2.21 by John Arbash Meinel
Cleanup patiencediff, remove the use of difflib.SequenceMatcher.
582
                 ('replace', 1,5, 1,5),
583
                 ('equal',   5,6, 5,6),
584
                ])
585
        chk_ops('aBcDec', 'abcdec', 
586
                [('equal',   0,1, 0,1),
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
587
                 ('replace', 1,2, 1,2),
1711.2.21 by John Arbash Meinel
Cleanup patiencediff, remove the use of difflib.SequenceMatcher.
588
                 ('equal',   2,3, 2,3),
589
                 ('replace', 3,4, 3,4),
590
                 ('equal',   4,6, 4,6),
1185.81.3 by John Arbash Meinel
Adding tests for checking opcodes.
591
                ])
1185.81.10 by John Arbash Meinel
Added some more test cases.
592
        chk_ops('aBcdEcdFg', 'abcdecdfg', 
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
593
                [('equal',   0,1, 0,1),
1711.2.21 by John Arbash Meinel
Cleanup patiencediff, remove the use of difflib.SequenceMatcher.
594
                 ('replace', 1,8, 1,8),
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
595
                 ('equal',   8,9, 8,9)
1185.81.10 by John Arbash Meinel
Added some more test cases.
596
                ])
1711.2.21 by John Arbash Meinel
Cleanup patiencediff, remove the use of difflib.SequenceMatcher.
597
        chk_ops('aBcdEeXcdFg', 'abcdecdfg', 
598
                [('equal',   0,1, 0,1),
599
                 ('replace', 1,2, 1,2),
600
                 ('equal',   2,4, 2,4),
601
                 ('delete', 4,5, 4,4),
602
                 ('equal',   5,6, 4,5),
603
                 ('delete', 6,7, 5,5),
604
                 ('equal',   7,9, 5,7),
605
                 ('replace', 9,10, 7,8),
606
                 ('equal',   10,11, 8,9)
607
                ])
1185.81.10 by John Arbash Meinel
Added some more test cases.
608
1185.81.16 by John Arbash Meinel
Added tests, and an assert check to make sure ranges are always increasing.
609
    def test_multiple_ranges(self):
610
        # There was an earlier bug where we used a bad set of ranges,
611
        # 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.
612
        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.
613
            # difflib always adds a signature of the total
614
            # 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
615
            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.
616
            blocks = s.get_matching_blocks()
617
            x = blocks.pop()
618
            self.assertEquals(x, (len(a), len(b), 0))
1711.2.10 by John Arbash Meinel
Clarify the patience tests a little bit.
619
            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.
620
621
        chk_blocks('abcdefghijklmnop'
622
                 , 'abcXghiYZQRSTUVWXYZijklmnop'
623
                 , [(0, 0, 3), (6, 4, 3), (9, 20, 7)])
624
625
        chk_blocks('ABCd efghIjk  L'
626
                 , 'AxyzBCn mo pqrstuvwI1 2  L'
1711.2.21 by John Arbash Meinel
Cleanup patiencediff, remove the use of difflib.SequenceMatcher.
627
                 , [(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.
628
1711.2.8 by John Arbash Meinel
rot13 the code snippet to help with clarity.
629
        # 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.
630
        chk_blocks('''\
1711.2.8 by John Arbash Meinel
rot13 the code snippet to help with clarity.
631
    trg nqqrq jura lbh nqq n svyr va gur qverpgbel.
632
    """
633
    gnxrf_netf = ['svyr*']
634
    gnxrf_bcgvbaf = ['ab-erphefr']
635
  
636
    qrs eha(frys, svyr_yvfg, ab_erphefr=Snyfr):
637
        sebz omeyvo.nqq vzcbeg fzneg_nqq, nqq_ercbegre_cevag, nqq_ercbegre_ahyy
638
        vs vf_dhvrg():
639
            ercbegre = nqq_ercbegre_ahyy
640
        ryfr:
641
            ercbegre = nqq_ercbegre_cevag
642
        fzneg_nqq(svyr_yvfg, abg ab_erphefr, ercbegre)
643
644
645
pynff pzq_zxqve(Pbzznaq):
646
'''.splitlines(True), '''\
647
    trg nqqrq jura lbh nqq n svyr va gur qverpgbel.
648
649
    --qel-eha jvyy fubj juvpu svyrf jbhyq or nqqrq, ohg abg npghnyyl 
650
    nqq gurz.
651
    """
652
    gnxrf_netf = ['svyr*']
653
    gnxrf_bcgvbaf = ['ab-erphefr', 'qel-eha']
654
655
    qrs eha(frys, svyr_yvfg, ab_erphefr=Snyfr, qel_eha=Snyfr):
656
        vzcbeg omeyvo.nqq
657
658
        vs qel_eha:
659
            vs vf_dhvrg():
660
                # Guvf vf cbvagyrff, ohg V'q engure abg envfr na reebe
661
                npgvba = omeyvo.nqq.nqq_npgvba_ahyy
662
            ryfr:
663
  npgvba = omeyvo.nqq.nqq_npgvba_cevag
664
        ryvs vf_dhvrg():
665
            npgvba = omeyvo.nqq.nqq_npgvba_nqq
666
        ryfr:
667
       npgvba = omeyvo.nqq.nqq_npgvba_nqq_naq_cevag
668
669
        omeyvo.nqq.fzneg_nqq(svyr_yvfg, abg ab_erphefr, npgvba)
670
671
672
pynff pzq_zxqve(Pbzznaq):
1185.81.16 by John Arbash Meinel
Added tests, and an assert check to make sure ranges are always increasing.
673
'''.splitlines(True)
674
, [(0,0,1), (1, 4, 2), (9, 19, 1), (12, 23, 3)])
675
1711.2.9 by John Arbash Meinel
Rename cdv => patience
676
    def test_patience_unified_diff(self):
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
677
        txt_a = ['hello there\n',
678
                 'world\n',
679
                 'how are you today?\n']
680
        txt_b = ['hello there\n',
681
                 'how are you today?\n']
1711.2.20 by John Arbash Meinel
Late bind to patiencediff objects to make it easier to plug-in
682
        unified_diff = bzrlib.patiencediff.unified_diff
683
        psm = bzrlib.patiencediff.PatienceSequenceMatcher
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
684
        self.assertEquals([ '---  \n',
685
                           '+++  \n',
686
                           '@@ -1,3 +1,2 @@\n',
687
                           ' hello there\n',
688
                           '-world\n',
689
                           ' 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
690
                          ]
1711.2.20 by John Arbash Meinel
Late bind to patiencediff objects to make it easier to plug-in
691
                          , list(unified_diff(txt_a, txt_b,
692
                                 sequencematcher=psm)))
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
693
        txt_a = map(lambda x: x+'\n', 'abcdefghijklmnop')
694
        txt_b = map(lambda x: x+'\n', 'abcdefxydefghijklmnop')
695
        # This is the result with LongestCommonSubstring matching
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
696
        self.assertEquals(['---  \n',
697
                           '+++  \n',
698
                           '@@ -1,6 +1,11 @@\n',
699
                           ' a\n',
700
                           ' b\n',
701
                           ' c\n',
702
                           '+d\n',
703
                           '+e\n',
704
                           '+f\n',
705
                           '+x\n',
706
                           '+y\n',
707
                           ' d\n',
708
                           ' e\n',
709
                           ' f\n']
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
710
                          , list(unified_diff(txt_a, txt_b)))
1711.2.9 by John Arbash Meinel
Rename cdv => patience
711
        # And the patience diff
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
712
        self.assertEquals(['---  \n',
713
                           '+++  \n',
714
                           '@@ -4,6 +4,11 @@\n',
715
                           ' d\n',
716
                           ' e\n',
717
                           ' f\n',
718
                           '+x\n',
719
                           '+y\n',
720
                           '+d\n',
721
                           '+e\n',
722
                           '+f\n',
723
                           ' g\n',
724
                           ' h\n',
725
                           ' i\n',
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
726
                          ]
1185.81.25 by Aaron Bentley
Clean up test_diff
727
                          , 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
728
                                 sequencematcher=psm)))
1185.81.25 by Aaron Bentley
Clean up test_diff
729
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
730
1711.2.15 by John Arbash Meinel
Found a couple CDV left
731
class TestPatienceDiffLibFiles(TestCaseInTempDir):
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
732
1711.2.9 by John Arbash Meinel
Rename cdv => patience
733
    def test_patience_unified_diff_files(self):
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
734
        txt_a = ['hello there\n',
735
                 'world\n',
736
                 'how are you today?\n']
737
        txt_b = ['hello there\n',
738
                 '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
739
        open('a1', 'wb').writelines(txt_a)
740
        open('b1', 'wb').writelines(txt_b)
741
1711.2.20 by John Arbash Meinel
Late bind to patiencediff objects to make it easier to plug-in
742
        unified_diff_files = bzrlib.patiencediff.unified_diff_files
743
        psm = bzrlib.patiencediff.PatienceSequenceMatcher
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
744
        self.assertEquals(['--- a1 \n',
745
                           '+++ b1 \n',
746
                           '@@ -1,3 +1,2 @@\n',
747
                           ' hello there\n',
748
                           '-world\n',
749
                           ' 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
750
                          ]
1185.81.25 by Aaron Bentley
Clean up test_diff
751
                          , 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
752
                                 sequencematcher=psm)))
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
753
754
        txt_a = map(lambda x: x+'\n', 'abcdefghijklmnop')
755
        txt_b = map(lambda x: x+'\n', 'abcdefxydefghijklmnop')
756
        open('a2', 'wb').writelines(txt_a)
757
        open('b2', 'wb').writelines(txt_b)
758
759
        # This is the result with LongestCommonSubstring matching
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
760
        self.assertEquals(['--- a2 \n',
761
                           '+++ b2 \n',
762
                           '@@ -1,6 +1,11 @@\n',
763
                           ' a\n',
764
                           ' b\n',
765
                           ' c\n',
766
                           '+d\n',
767
                           '+e\n',
768
                           '+f\n',
769
                           '+x\n',
770
                           '+y\n',
771
                           ' d\n',
772
                           ' e\n',
773
                           ' f\n']
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
774
                          , list(unified_diff_files('a2', 'b2')))
775
1711.2.9 by John Arbash Meinel
Rename cdv => patience
776
        # And the patience diff
1185.81.29 by Aaron Bentley
Fix style issues and duplicated tests
777
        self.assertEquals(['--- a2 \n',
778
                           '+++ b2 \n',
779
                           '@@ -4,6 +4,11 @@\n',
780
                           ' d\n',
781
                           ' e\n',
782
                           ' f\n',
783
                           '+x\n',
784
                           '+y\n',
785
                           '+d\n',
786
                           '+e\n',
787
                           '+f\n',
788
                           ' g\n',
789
                           ' h\n',
790
                           ' i\n',
1185.81.14 by John Arbash Meinel
Added a main function for running cdvdifflib manually, included tests for unified_diff interfaces
791
                          ]
1185.81.25 by Aaron Bentley
Clean up test_diff
792
                          , 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
793
                                 sequencematcher=psm)))