/brz/remove-bazaar

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