~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_diff.py

  • Committer: Robert Collins
  • Date: 2008-08-12 07:19:29 UTC
  • mto: This revision was merged to the branch mainline in revision 3621.
  • Revision ID: robertc@robertcollins.net-20080812071929-jf7qv5f2v7any84b
Tighten up the handling of carried-over inventory entries.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2005, 2006 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
import os
 
18
import os.path
18
19
from cStringIO import StringIO
 
20
import errno
19
21
import subprocess
20
22
import sys
21
 
import tempfile
 
23
from tempfile import TemporaryFile
22
24
 
23
 
from bzrlib import (
24
 
    diff,
25
 
    errors,
26
 
    osutils,
27
 
    patiencediff,
28
 
    _patiencediff_py,
29
 
    revision as _mod_revision,
30
 
    revisionspec,
31
 
    revisiontree,
32
 
    tests,
33
 
    transform,
 
25
from bzrlib import tests
 
26
from bzrlib.diff import (
 
27
    DiffFromTool,
 
28
    DiffPath,
 
29
    DiffSymlink,
 
30
    DiffTree,
 
31
    DiffText,
 
32
    external_diff,
 
33
    internal_diff,
 
34
    show_diff_trees,
34
35
    )
35
 
from bzrlib.symbol_versioning import deprecated_in
36
 
from bzrlib.tests import test_win32utils
37
 
 
38
 
 
39
 
class _AttribFeature(tests.Feature):
 
36
from bzrlib.errors import BinaryFile, NoDiff, ExecutableMissing
 
37
import bzrlib.osutils as osutils
 
38
import bzrlib.transform as transform
 
39
import bzrlib.patiencediff
 
40
import bzrlib._patiencediff_py
 
41
from bzrlib.tests import (Feature, TestCase, TestCaseWithTransport,
 
42
                          TestCaseInTempDir, TestSkipped)
 
43
 
 
44
 
 
45
class _AttribFeature(Feature):
40
46
 
41
47
    def _probe(self):
42
48
        if (sys.platform not in ('cygwin', 'win32')):
53
59
AttribFeature = _AttribFeature()
54
60
 
55
61
 
56
 
compiled_patiencediff_feature = tests.ModuleAvailableFeature(
57
 
                                    'bzrlib._patiencediff_c')
 
62
class _CompiledPatienceDiffFeature(Feature):
 
63
 
 
64
    def _probe(self):
 
65
        try:
 
66
            import bzrlib._patiencediff_c
 
67
        except ImportError:
 
68
            return False
 
69
        return True
 
70
 
 
71
    def feature_name(self):
 
72
        return 'bzrlib._patiencediff_c'
 
73
 
 
74
CompiledPatienceDiffFeature = _CompiledPatienceDiffFeature()
58
75
 
59
76
 
60
77
def udiff_lines(old, new, allow_binary=False):
61
78
    output = StringIO()
62
 
    diff.internal_diff('old', old, 'new', new, output, allow_binary)
 
79
    internal_diff('old', old, 'new', new, output, allow_binary)
63
80
    output.seek(0, 0)
64
81
    return output.readlines()
65
82
 
69
86
        # StringIO has no fileno, so it tests a different codepath
70
87
        output = StringIO()
71
88
    else:
72
 
        output = tempfile.TemporaryFile()
 
89
        output = TemporaryFile()
73
90
    try:
74
 
        diff.external_diff('old', old, 'new', new, output, diff_opts=['-u'])
75
 
    except errors.NoDiff:
76
 
        raise tests.TestSkipped('external "diff" not present to test')
 
91
        external_diff('old', old, 'new', new, output, diff_opts=['-u'])
 
92
    except NoDiff:
 
93
        raise TestSkipped('external "diff" not present to test')
77
94
    output.seek(0, 0)
78
95
    lines = output.readlines()
79
96
    output.close()
80
97
    return lines
81
98
 
82
99
 
83
 
class TestDiff(tests.TestCase):
 
100
class TestDiff(TestCase):
84
101
 
85
102
    def test_add_nl(self):
86
103
        """diff generates a valid diff for patches that add a newline"""
122
139
            ## "Unterminated hunk header for patch:\n%s" % "".join(lines)
123
140
 
124
141
    def test_binary_lines(self):
125
 
        empty = []
126
 
        uni_lines = [1023 * 'a' + '\x00']
127
 
        self.assertRaises(errors.BinaryFile, udiff_lines, uni_lines , empty)
128
 
        self.assertRaises(errors.BinaryFile, udiff_lines, empty, uni_lines)
129
 
        udiff_lines(uni_lines , empty, allow_binary=True)
130
 
        udiff_lines(empty, uni_lines, allow_binary=True)
 
142
        self.assertRaises(BinaryFile, udiff_lines, [1023 * 'a' + '\x00'], [])
 
143
        self.assertRaises(BinaryFile, udiff_lines, [], [1023 * 'a' + '\x00'])
 
144
        udiff_lines([1023 * 'a' + '\x00'], [], allow_binary=True)
 
145
        udiff_lines([], [1023 * 'a' + '\x00'], allow_binary=True)
131
146
 
132
147
    def test_external_diff(self):
133
148
        lines = external_udiff_lines(['boo\n'], ['goo\n'])
163
178
        orig_path = os.environ['PATH']
164
179
        try:
165
180
            os.environ['PATH'] = ''
166
 
            self.assertRaises(errors.NoDiff, diff.external_diff,
 
181
            self.assertRaises(NoDiff, external_diff,
167
182
                              'old', ['boo\n'], 'new', ['goo\n'],
168
183
                              StringIO(), diff_opts=['-u'])
169
184
        finally:
170
185
            os.environ['PATH'] = orig_path
171
 
 
 
186
        
172
187
    def test_internal_diff_default(self):
173
188
        # Default internal diff encoding is utf8
174
189
        output = StringIO()
175
 
        diff.internal_diff(u'old_\xb5', ['old_text\n'],
176
 
                           u'new_\xe5', ['new_text\n'], output)
 
190
        internal_diff(u'old_\xb5', ['old_text\n'],
 
191
                    u'new_\xe5', ['new_text\n'], output)
177
192
        lines = output.getvalue().splitlines(True)
178
193
        self.check_patch(lines)
179
194
        self.assertEquals(['--- old_\xc2\xb5\n',
187
202
 
188
203
    def test_internal_diff_utf8(self):
189
204
        output = StringIO()
190
 
        diff.internal_diff(u'old_\xb5', ['old_text\n'],
191
 
                           u'new_\xe5', ['new_text\n'], output,
192
 
                           path_encoding='utf8')
 
205
        internal_diff(u'old_\xb5', ['old_text\n'],
 
206
                    u'new_\xe5', ['new_text\n'], output,
 
207
                    path_encoding='utf8')
193
208
        lines = output.getvalue().splitlines(True)
194
209
        self.check_patch(lines)
195
210
        self.assertEquals(['--- old_\xc2\xb5\n',
203
218
 
204
219
    def test_internal_diff_iso_8859_1(self):
205
220
        output = StringIO()
206
 
        diff.internal_diff(u'old_\xb5', ['old_text\n'],
207
 
                           u'new_\xe5', ['new_text\n'], output,
208
 
                           path_encoding='iso-8859-1')
 
221
        internal_diff(u'old_\xb5', ['old_text\n'],
 
222
                    u'new_\xe5', ['new_text\n'], output,
 
223
                    path_encoding='iso-8859-1')
209
224
        lines = output.getvalue().splitlines(True)
210
225
        self.check_patch(lines)
211
226
        self.assertEquals(['--- old_\xb5\n',
219
234
 
220
235
    def test_internal_diff_no_content(self):
221
236
        output = StringIO()
222
 
        diff.internal_diff(u'old', [], u'new', [], output)
 
237
        internal_diff(u'old', [], u'new', [], output)
223
238
        self.assertEqual('', output.getvalue())
224
239
 
225
240
    def test_internal_diff_no_changes(self):
226
241
        output = StringIO()
227
 
        diff.internal_diff(u'old', ['text\n', 'contents\n'],
228
 
                           u'new', ['text\n', 'contents\n'],
229
 
                           output)
 
242
        internal_diff(u'old', ['text\n', 'contents\n'],
 
243
                      u'new', ['text\n', 'contents\n'],
 
244
                      output)
230
245
        self.assertEqual('', output.getvalue())
231
246
 
232
247
    def test_internal_diff_returns_bytes(self):
233
248
        import StringIO
234
249
        output = StringIO.StringIO()
235
 
        diff.internal_diff(u'old_\xb5', ['old_text\n'],
236
 
                            u'new_\xe5', ['new_text\n'], output)
 
250
        internal_diff(u'old_\xb5', ['old_text\n'],
 
251
                    u'new_\xe5', ['new_text\n'], output)
237
252
        self.failUnless(isinstance(output.getvalue(), str),
238
253
            'internal_diff should return bytestrings')
239
254
 
240
255
 
241
 
class TestDiffFiles(tests.TestCaseInTempDir):
 
256
class TestDiffFiles(TestCaseInTempDir):
242
257
 
243
258
    def test_external_diff_binary(self):
244
259
        """The output when using external diff should use diff's i18n error"""
257
272
        self.assertEqual(out.splitlines(True) + ['\n'], lines)
258
273
 
259
274
 
260
 
class TestShowDiffTreesHelper(tests.TestCaseWithTransport):
 
275
class TestShowDiffTreesHelper(TestCaseWithTransport):
261
276
    """Has a helper for running show_diff_trees"""
262
277
 
263
278
    def get_diff(self, tree1, tree2, specific_files=None, working_tree=None):
266
281
            extra_trees = (working_tree,)
267
282
        else:
268
283
            extra_trees = ()
269
 
        diff.show_diff_trees(tree1, tree2, output,
270
 
                             specific_files=specific_files,
271
 
                             extra_trees=extra_trees, old_label='old/',
272
 
                             new_label='new/')
 
284
        show_diff_trees(tree1, tree2, output, specific_files=specific_files,
 
285
                        extra_trees=extra_trees, old_label='old/',
 
286
                        new_label='new/')
273
287
        return output.getvalue()
274
288
 
275
289
 
340
354
+file2 contents at rev 3
341
355
 
342
356
''')
343
 
 
 
357
        
344
358
    def test_diff_add_files(self):
345
 
        tree1 = self.b.repository.revision_tree(_mod_revision.NULL_REVISION)
 
359
        tree1 = self.b.repository.revision_tree(None)
346
360
        tree2 = self.b.repository.revision_tree('rev-1')
347
361
        output = self.get_diff(tree1, tree2)
348
362
        # the files have the epoch time stamp for the tree in which
382
396
        self.wt.rename_one('file1', 'file1b')
383
397
        old_tree = self.b.repository.revision_tree('rev-1')
384
398
        new_tree = self.b.repository.revision_tree('rev-4')
385
 
        out = self.get_diff(old_tree, new_tree, specific_files=['file1b'],
 
399
        out = self.get_diff(old_tree, new_tree, specific_files=['file1b'], 
386
400
                            working_tree=self.wt)
387
401
        self.assertContainsRe(out, 'file1\t')
388
402
 
394
408
        self.wt.rename_one('file1', 'dir1/file1')
395
409
        old_tree = self.b.repository.revision_tree('rev-1')
396
410
        new_tree = self.b.repository.revision_tree('rev-4')
397
 
        out = self.get_diff(old_tree, new_tree, specific_files=['dir1'],
 
411
        out = self.get_diff(old_tree, new_tree, specific_files=['dir1'], 
398
412
                            working_tree=self.wt)
399
413
        self.assertContainsRe(out, 'file1\t')
400
 
        out = self.get_diff(old_tree, new_tree, specific_files=['dir2'],
 
414
        out = self.get_diff(old_tree, new_tree, specific_files=['dir2'], 
401
415
                            working_tree=self.wt)
402
416
        self.assertNotContainsRe(out, 'file1\t')
403
417
 
414
428
        tree.commit('one', rev_id='rev-1')
415
429
 
416
430
        self.build_tree_contents([('tree/file', 'new contents\n')])
417
 
        d = self.get_diff(tree.basis_tree(), tree)
418
 
        self.assertContainsRe(d, "=== modified file 'file'\n")
419
 
        self.assertContainsRe(d, '--- old/file\t')
420
 
        self.assertContainsRe(d, '\\+\\+\\+ new/file\t')
421
 
        self.assertContainsRe(d, '-contents\n'
422
 
                                 '\\+new contents\n')
 
431
        diff = self.get_diff(tree.basis_tree(), tree)
 
432
        self.assertContainsRe(diff, "=== modified file 'file'\n")
 
433
        self.assertContainsRe(diff, '--- old/file\t')
 
434
        self.assertContainsRe(diff, '\\+\\+\\+ new/file\t')
 
435
        self.assertContainsRe(diff, '-contents\n'
 
436
                                    '\\+new contents\n')
423
437
 
424
438
    def test_modified_file_in_renamed_dir(self):
425
439
        """Test when a file is modified in a renamed directory."""
431
445
 
432
446
        tree.rename_one('dir', 'other')
433
447
        self.build_tree_contents([('tree/other/file', 'new contents\n')])
434
 
        d = self.get_diff(tree.basis_tree(), tree)
435
 
        self.assertContainsRe(d, "=== renamed directory 'dir' => 'other'\n")
436
 
        self.assertContainsRe(d, "=== modified file 'other/file'\n")
 
448
        diff = self.get_diff(tree.basis_tree(), tree)
 
449
        self.assertContainsRe(diff, "=== renamed directory 'dir' => 'other'\n")
 
450
        self.assertContainsRe(diff, "=== modified file 'other/file'\n")
437
451
        # XXX: This is technically incorrect, because it used to be at another
438
452
        # location. What to do?
439
 
        self.assertContainsRe(d, '--- old/dir/file\t')
440
 
        self.assertContainsRe(d, '\\+\\+\\+ new/other/file\t')
441
 
        self.assertContainsRe(d, '-contents\n'
442
 
                                 '\\+new contents\n')
 
453
        self.assertContainsRe(diff, '--- old/dir/file\t')
 
454
        self.assertContainsRe(diff, '\\+\\+\\+ new/other/file\t')
 
455
        self.assertContainsRe(diff, '-contents\n'
 
456
                                    '\\+new contents\n')
443
457
 
444
458
    def test_renamed_directory(self):
445
459
        """Test when only a directory is only renamed."""
450
464
        tree.commit('one', rev_id='rev-1')
451
465
 
452
466
        tree.rename_one('dir', 'newdir')
453
 
        d = self.get_diff(tree.basis_tree(), tree)
 
467
        diff = self.get_diff(tree.basis_tree(), tree)
454
468
        # Renaming a directory should be a single "you renamed this dir" even
455
469
        # when there are files inside.
456
 
        self.assertEqual(d, "=== renamed directory 'dir' => 'newdir'\n")
 
470
        self.assertEqual("=== renamed directory 'dir' => 'newdir'\n", diff)
457
471
 
458
472
    def test_renamed_file(self):
459
473
        """Test when a file is only renamed."""
463
477
        tree.commit('one', rev_id='rev-1')
464
478
 
465
479
        tree.rename_one('file', 'newname')
466
 
        d = self.get_diff(tree.basis_tree(), tree)
467
 
        self.assertContainsRe(d, "=== renamed file 'file' => 'newname'\n")
 
480
        diff = self.get_diff(tree.basis_tree(), tree)
 
481
        self.assertContainsRe(diff, "=== renamed file 'file' => 'newname'\n")
468
482
        # We shouldn't have a --- or +++ line, because there is no content
469
483
        # change
470
 
        self.assertNotContainsRe(d, '---')
 
484
        self.assertNotContainsRe(diff, '---')
471
485
 
472
486
    def test_renamed_and_modified_file(self):
473
487
        """Test when a file is only renamed."""
478
492
 
479
493
        tree.rename_one('file', 'newname')
480
494
        self.build_tree_contents([('tree/newname', 'new contents\n')])
481
 
        d = self.get_diff(tree.basis_tree(), tree)
482
 
        self.assertContainsRe(d, "=== renamed file 'file' => 'newname'\n")
483
 
        self.assertContainsRe(d, '--- old/file\t')
484
 
        self.assertContainsRe(d, '\\+\\+\\+ new/newname\t')
485
 
        self.assertContainsRe(d, '-contents\n'
486
 
                                 '\\+new contents\n')
 
495
        diff = self.get_diff(tree.basis_tree(), tree)
 
496
        self.assertContainsRe(diff, "=== renamed file 'file' => 'newname'\n")
 
497
        self.assertContainsRe(diff, '--- old/file\t')
 
498
        self.assertContainsRe(diff, '\\+\\+\\+ new/newname\t')
 
499
        self.assertContainsRe(diff, '-contents\n'
 
500
                                    '\\+new contents\n')
487
501
 
488
502
 
489
503
    def test_internal_diff_exec_property(self):
508
522
        tree.rename_one('c', 'new-c')
509
523
        tree.rename_one('d', 'new-d')
510
524
 
511
 
        d = self.get_diff(tree.basis_tree(), tree)
 
525
        diff = self.get_diff(tree.basis_tree(), tree)
512
526
 
513
 
        self.assertContainsRe(d, r"file 'a'.*\(properties changed:"
514
 
                                  ".*\+x to -x.*\)")
515
 
        self.assertContainsRe(d, r"file 'b'.*\(properties changed:"
516
 
                                  ".*-x to \+x.*\)")
517
 
        self.assertContainsRe(d, r"file 'c'.*\(properties changed:"
518
 
                                  ".*\+x to -x.*\)")
519
 
        self.assertContainsRe(d, r"file 'd'.*\(properties changed:"
520
 
                                  ".*-x to \+x.*\)")
521
 
        self.assertNotContainsRe(d, r"file 'e'")
522
 
        self.assertNotContainsRe(d, r"file 'f'")
 
527
        self.assertContainsRe(diff, r"file 'a'.*\(properties changed:.*\+x to -x.*\)")
 
528
        self.assertContainsRe(diff, r"file 'b'.*\(properties changed:.*-x to \+x.*\)")
 
529
        self.assertContainsRe(diff, r"file 'c'.*\(properties changed:.*\+x to -x.*\)")
 
530
        self.assertContainsRe(diff, r"file 'd'.*\(properties changed:.*-x to \+x.*\)")
 
531
        self.assertNotContainsRe(diff, r"file 'e'")
 
532
        self.assertNotContainsRe(diff, r"file 'f'")
523
533
 
524
534
 
525
535
    def test_binary_unicode_filenames(self):
541
551
        tree.add([alpha], ['file-id'])
542
552
        tree.add([omega], ['file-id-2'])
543
553
        diff_content = StringIO()
544
 
        diff.show_diff_trees(tree.basis_tree(), tree, diff_content)
545
 
        d = diff_content.getvalue()
546
 
        self.assertContainsRe(d, r"=== added file '%s'" % alpha_utf8)
547
 
        self.assertContainsRe(d, "Binary files a/%s.*and b/%s.* differ\n"
548
 
                              % (alpha_utf8, alpha_utf8))
549
 
        self.assertContainsRe(d, r"=== added file '%s'" % omega_utf8)
550
 
        self.assertContainsRe(d, r"--- a/%s" % (omega_utf8,))
551
 
        self.assertContainsRe(d, r"\+\+\+ b/%s" % (omega_utf8,))
 
554
        show_diff_trees(tree.basis_tree(), tree, diff_content)
 
555
        diff = diff_content.getvalue()
 
556
        self.assertContainsRe(diff, r"=== added file '%s'" % alpha_utf8)
 
557
        self.assertContainsRe(
 
558
            diff, "Binary files a/%s.*and b/%s.* differ\n" % (alpha_utf8, alpha_utf8))
 
559
        self.assertContainsRe(diff, r"=== added file '%s'" % omega_utf8)
 
560
        self.assertContainsRe(diff, r"--- a/%s" % (omega_utf8,))
 
561
        self.assertContainsRe(diff, r"\+\+\+ b/%s" % (omega_utf8,))
552
562
 
553
563
    def test_unicode_filename(self):
554
564
        """Test when the filename are unicode."""
573
583
        tree.add(['add_'+alpha], ['file-id'])
574
584
        self.build_tree_contents([('tree/mod_'+alpha, 'contents_mod\n')])
575
585
 
576
 
        d = self.get_diff(tree.basis_tree(), tree)
577
 
        self.assertContainsRe(d,
 
586
        diff = self.get_diff(tree.basis_tree(), tree)
 
587
        self.assertContainsRe(diff,
578
588
                "=== renamed file 'ren_%s' => 'ren_%s'\n"%(autf8, outf8))
579
 
        self.assertContainsRe(d, "=== added file 'add_%s'"%autf8)
580
 
        self.assertContainsRe(d, "=== modified file 'mod_%s'"%autf8)
581
 
        self.assertContainsRe(d, "=== removed file 'del_%s'"%autf8)
582
 
 
583
 
 
584
 
class DiffWasIs(diff.DiffPath):
 
589
        self.assertContainsRe(diff, "=== added file 'add_%s'"%autf8)
 
590
        self.assertContainsRe(diff, "=== modified file 'mod_%s'"%autf8)
 
591
        self.assertContainsRe(diff, "=== removed file 'del_%s'"%autf8)
 
592
 
 
593
 
 
594
class DiffWasIs(DiffPath):
585
595
 
586
596
    def diff(self, file_id, old_path, new_path, old_kind, new_kind):
587
597
        self.to_file.write('was: ')
591
601
        pass
592
602
 
593
603
 
594
 
class TestDiffTree(tests.TestCaseWithTransport):
 
604
class TestDiffTree(TestCaseWithTransport):
595
605
 
596
606
    def setUp(self):
597
 
        super(TestDiffTree, self).setUp()
 
607
        TestCaseWithTransport.setUp(self)
598
608
        self.old_tree = self.make_branch_and_tree('old-tree')
599
609
        self.old_tree.lock_write()
600
610
        self.addCleanup(self.old_tree.unlock)
601
611
        self.new_tree = self.make_branch_and_tree('new-tree')
602
612
        self.new_tree.lock_write()
603
613
        self.addCleanup(self.new_tree.unlock)
604
 
        self.differ = diff.DiffTree(self.old_tree, self.new_tree, StringIO())
 
614
        self.differ = DiffTree(self.old_tree, self.new_tree, StringIO())
605
615
 
606
616
    def test_diff_text(self):
607
617
        self.build_tree_contents([('old-tree/olddir/',),
612
622
                                  ('new-tree/newdir/newfile', 'new\n')])
613
623
        self.new_tree.add('newdir')
614
624
        self.new_tree.add('newdir/newfile', 'file-id')
615
 
        differ = diff.DiffText(self.old_tree, self.new_tree, StringIO())
 
625
        differ = DiffText(self.old_tree, self.new_tree, StringIO())
616
626
        differ.diff_text('file-id', None, 'old label', 'new label')
617
627
        self.assertEqual(
618
628
            '--- old label\n+++ new label\n@@ -1,1 +0,0 @@\n-old\n\n',
647
657
        self.assertContainsRe(self.differ.to_file.getvalue(), '\+contents')
648
658
 
649
659
    def test_diff_symlink(self):
650
 
        differ = diff.DiffSymlink(self.old_tree, self.new_tree, StringIO())
 
660
        differ = DiffSymlink(self.old_tree, self.new_tree, StringIO())
651
661
        differ.diff_symlink('old target', None)
652
662
        self.assertEqual("=== target was 'old target'\n",
653
663
                         differ.to_file.getvalue())
654
664
 
655
 
        differ = diff.DiffSymlink(self.old_tree, self.new_tree, StringIO())
 
665
        differ = DiffSymlink(self.old_tree, self.new_tree, StringIO())
656
666
        differ.diff_symlink(None, 'new target')
657
667
        self.assertEqual("=== target is 'new target'\n",
658
668
                         differ.to_file.getvalue())
659
669
 
660
 
        differ = diff.DiffSymlink(self.old_tree, self.new_tree, StringIO())
 
670
        differ = DiffSymlink(self.old_tree, self.new_tree, StringIO())
661
671
        differ.diff_symlink('old target', 'new target')
662
672
        self.assertEqual("=== target changed 'old target' => 'new target'\n",
663
673
                         differ.to_file.getvalue())
693
703
            r'--- olddir/oldfile.*\n\+\+\+ newdir/newfile.*\n\@\@ -1,1 \+0,0'
694
704
             ' \@\@\n-old\n\n')
695
705
        self.assertContainsRe(self.differ.to_file.getvalue(),
696
 
                              "=== target is u'new'\n")
 
706
                              "=== target is 'new'\n")
697
707
 
698
708
    def test_diff_directory(self):
699
709
        self.build_tree(['new-tree/new-dir/'])
713
723
 
714
724
    def test_register_diff(self):
715
725
        self.create_old_new()
716
 
        old_diff_factories = diff.DiffTree.diff_factories
717
 
        diff.DiffTree.diff_factories=old_diff_factories[:]
718
 
        diff.DiffTree.diff_factories.insert(0, DiffWasIs.from_diff_tree)
 
726
        old_diff_factories = DiffTree.diff_factories
 
727
        DiffTree.diff_factories=old_diff_factories[:]
 
728
        DiffTree.diff_factories.insert(0, DiffWasIs.from_diff_tree)
719
729
        try:
720
 
            differ = diff.DiffTree(self.old_tree, self.new_tree, StringIO())
 
730
            differ = DiffTree(self.old_tree, self.new_tree, StringIO())
721
731
        finally:
722
 
            diff.DiffTree.diff_factories = old_diff_factories
 
732
            DiffTree.diff_factories = old_diff_factories
723
733
        differ.diff('file-id', 'olddir/oldfile', 'newdir/newfile')
724
734
        self.assertNotContainsRe(
725
735
            differ.to_file.getvalue(),
730
740
 
731
741
    def test_extra_factories(self):
732
742
        self.create_old_new()
733
 
        differ = diff.DiffTree(self.old_tree, self.new_tree, StringIO(),
734
 
                               extra_factories=[DiffWasIs.from_diff_tree])
 
743
        differ = DiffTree(self.old_tree, self.new_tree, StringIO(),
 
744
                            extra_factories=[DiffWasIs.from_diff_tree])
735
745
        differ.diff('file-id', 'olddir/oldfile', 'newdir/newfile')
736
746
        self.assertNotContainsRe(
737
747
            differ.to_file.getvalue(),
750
760
            '.*a-file(.|\n)*b-file')
751
761
 
752
762
 
753
 
class TestPatienceDiffLib(tests.TestCase):
 
763
class TestPatienceDiffLib(TestCase):
754
764
 
755
765
    def setUp(self):
756
766
        super(TestPatienceDiffLib, self).setUp()
757
 
        self._unique_lcs = _patiencediff_py.unique_lcs_py
758
 
        self._recurse_matches = _patiencediff_py.recurse_matches_py
 
767
        self._unique_lcs = bzrlib._patiencediff_py.unique_lcs_py
 
768
        self._recurse_matches = bzrlib._patiencediff_py.recurse_matches_py
759
769
        self._PatienceSequenceMatcher = \
760
 
            _patiencediff_py.PatienceSequenceMatcher_py
761
 
 
762
 
    def test_diff_unicode_string(self):
763
 
        a = ''.join([unichr(i) for i in range(4000, 4500, 3)])
764
 
        b = ''.join([unichr(i) for i in range(4300, 4800, 2)])
765
 
        sm = self._PatienceSequenceMatcher(None, a, b)
766
 
        mb = sm.get_matching_blocks()
767
 
        self.assertEquals(35, len(mb))
 
770
            bzrlib._patiencediff_py.PatienceSequenceMatcher_py
768
771
 
769
772
    def test_unique_lcs(self):
770
773
        unique_lcs = self._unique_lcs
776
779
        self.assertEquals(unique_lcs('ab', 'ab'), [(0,0), (1,1)])
777
780
        self.assertEquals(unique_lcs('abcde', 'cdeab'), [(2,0), (3,1), (4,2)])
778
781
        self.assertEquals(unique_lcs('cdeab', 'abcde'), [(0,2), (1,3), (2,4)])
779
 
        self.assertEquals(unique_lcs('abXde', 'abYde'), [(0,0), (1,1),
 
782
        self.assertEquals(unique_lcs('abXde', 'abYde'), [(0,0), (1,1), 
780
783
                                                         (3,3), (4,4)])
781
784
        self.assertEquals(unique_lcs('acbac', 'abc'), [(2,1)])
782
785
 
797
800
        test_one('abcdbce', 'afbcgdbce', [(0,0), (1, 2), (2, 3), (3, 5),
798
801
                                          (4, 6), (5, 7), (6, 8)])
799
802
 
800
 
        # recurse_matches doesn't match non-unique
 
803
        # recurse_matches doesn't match non-unique 
801
804
        # lines surrounded by bogus text.
802
805
        # The update has been done in patiencediff.SequenceMatcher instead
803
806
 
940
943
                 ('delete', 1,2, 1,1),
941
944
                 ('equal',  2,3, 1,2),
942
945
                ])
943
 
        chk_ops('aBccDe', 'abccde',
 
946
        chk_ops('aBccDe', 'abccde', 
944
947
                [('equal',   0,1, 0,1),
945
948
                 ('replace', 1,5, 1,5),
946
949
                 ('equal',   5,6, 5,6),
947
950
                ])
948
 
        chk_ops('aBcDec', 'abcdec',
 
951
        chk_ops('aBcDec', 'abcdec', 
949
952
                [('equal',   0,1, 0,1),
950
953
                 ('replace', 1,2, 1,2),
951
954
                 ('equal',   2,3, 2,3),
952
955
                 ('replace', 3,4, 3,4),
953
956
                 ('equal',   4,6, 4,6),
954
957
                ])
955
 
        chk_ops('aBcdEcdFg', 'abcdecdfg',
 
958
        chk_ops('aBcdEcdFg', 'abcdecdfg', 
956
959
                [('equal',   0,1, 0,1),
957
960
                 ('replace', 1,8, 1,8),
958
961
                 ('equal',   8,9, 8,9)
959
962
                ])
960
 
        chk_ops('aBcdEeXcdFg', 'abcdecdfg',
 
963
        chk_ops('aBcdEeXcdFg', 'abcdecdfg', 
961
964
                [('equal',   0,1, 0,1),
962
965
                 ('replace', 1,2, 1,2),
963
966
                 ('equal',   2,4, 2,4),
1023
1026
    """
1024
1027
    gnxrf_netf = ['svyr*']
1025
1028
    gnxrf_bcgvbaf = ['ab-erphefr']
1026
 
 
 
1029
  
1027
1030
    qrs eha(frys, svyr_yvfg, ab_erphefr=Snyfr):
1028
1031
        sebz omeyvo.nqq vzcbeg fzneg_nqq, nqq_ercbegre_cevag, nqq_ercbegre_ahyy
1029
1032
        vs vf_dhvrg():
1037
1040
'''.splitlines(True), '''\
1038
1041
    trg nqqrq jura lbh nqq n svyr va gur qverpgbel.
1039
1042
 
1040
 
    --qel-eha jvyy fubj juvpu svyrf jbhyq or nqqrq, ohg abg npghnyyl
 
1043
    --qel-eha jvyy fubj juvpu svyrf jbhyq or nqqrq, ohg abg npghnyyl 
1041
1044
    nqq gurz.
1042
1045
    """
1043
1046
    gnxrf_netf = ['svyr*']
1070
1073
                 'how are you today?\n']
1071
1074
        txt_b = ['hello there\n',
1072
1075
                 'how are you today?\n']
1073
 
        unified_diff = patiencediff.unified_diff
 
1076
        unified_diff = bzrlib.patiencediff.unified_diff
1074
1077
        psm = self._PatienceSequenceMatcher
1075
 
        self.assertEquals(['--- \n',
1076
 
                           '+++ \n',
 
1078
        self.assertEquals([ '---  \n',
 
1079
                           '+++  \n',
1077
1080
                           '@@ -1,3 +1,2 @@\n',
1078
1081
                           ' hello there\n',
1079
1082
                           '-world\n',
1084
1087
        txt_a = map(lambda x: x+'\n', 'abcdefghijklmnop')
1085
1088
        txt_b = map(lambda x: x+'\n', 'abcdefxydefghijklmnop')
1086
1089
        # This is the result with LongestCommonSubstring matching
1087
 
        self.assertEquals(['--- \n',
1088
 
                           '+++ \n',
 
1090
        self.assertEquals(['---  \n',
 
1091
                           '+++  \n',
1089
1092
                           '@@ -1,6 +1,11 @@\n',
1090
1093
                           ' a\n',
1091
1094
                           ' b\n',
1100
1103
                           ' f\n']
1101
1104
                          , list(unified_diff(txt_a, txt_b)))
1102
1105
        # And the patience diff
1103
 
        self.assertEquals(['--- \n',
1104
 
                           '+++ \n',
 
1106
        self.assertEquals(['---  \n',
 
1107
                           '+++  \n',
1105
1108
                           '@@ -4,6 +4,11 @@\n',
1106
1109
                           ' d\n',
1107
1110
                           ' e\n',
1118
1121
                          , list(unified_diff(txt_a, txt_b,
1119
1122
                                 sequencematcher=psm)))
1120
1123
 
1121
 
    def test_patience_unified_diff_with_dates(self):
1122
 
        txt_a = ['hello there\n',
1123
 
                 'world\n',
1124
 
                 'how are you today?\n']
1125
 
        txt_b = ['hello there\n',
1126
 
                 'how are you today?\n']
1127
 
        unified_diff = patiencediff.unified_diff
1128
 
        psm = self._PatienceSequenceMatcher
1129
 
        self.assertEquals(['--- a\t2008-08-08\n',
1130
 
                           '+++ b\t2008-09-09\n',
1131
 
                           '@@ -1,3 +1,2 @@\n',
1132
 
                           ' hello there\n',
1133
 
                           '-world\n',
1134
 
                           ' how are you today?\n'
1135
 
                          ]
1136
 
                          , list(unified_diff(txt_a, txt_b,
1137
 
                                 fromfile='a', tofile='b',
1138
 
                                 fromfiledate='2008-08-08',
1139
 
                                 tofiledate='2008-09-09',
1140
 
                                 sequencematcher=psm)))
1141
 
 
1142
1124
 
1143
1125
class TestPatienceDiffLib_c(TestPatienceDiffLib):
1144
1126
 
1145
 
    _test_needs_features = [compiled_patiencediff_feature]
 
1127
    _test_needs_features = [CompiledPatienceDiffFeature]
1146
1128
 
1147
1129
    def setUp(self):
1148
1130
        super(TestPatienceDiffLib_c, self).setUp()
1149
 
        from bzrlib import _patiencediff_c
1150
 
        self._unique_lcs = _patiencediff_c.unique_lcs_c
1151
 
        self._recurse_matches = _patiencediff_c.recurse_matches_c
 
1131
        import bzrlib._patiencediff_c
 
1132
        self._unique_lcs = bzrlib._patiencediff_c.unique_lcs_c
 
1133
        self._recurse_matches = bzrlib._patiencediff_c.recurse_matches_c
1152
1134
        self._PatienceSequenceMatcher = \
1153
 
            _patiencediff_c.PatienceSequenceMatcher_c
 
1135
            bzrlib._patiencediff_c.PatienceSequenceMatcher_c
1154
1136
 
1155
1137
    def test_unhashable(self):
1156
1138
        """We should get a proper exception here."""
1166
1148
                                         None, ['valid'], ['valid', []])
1167
1149
 
1168
1150
 
1169
 
class TestPatienceDiffLibFiles(tests.TestCaseInTempDir):
 
1151
class TestPatienceDiffLibFiles(TestCaseInTempDir):
1170
1152
 
1171
1153
    def setUp(self):
1172
1154
        super(TestPatienceDiffLibFiles, self).setUp()
1173
1155
        self._PatienceSequenceMatcher = \
1174
 
            _patiencediff_py.PatienceSequenceMatcher_py
 
1156
            bzrlib._patiencediff_py.PatienceSequenceMatcher_py
1175
1157
 
1176
1158
    def test_patience_unified_diff_files(self):
1177
1159
        txt_a = ['hello there\n',
1182
1164
        open('a1', 'wb').writelines(txt_a)
1183
1165
        open('b1', 'wb').writelines(txt_b)
1184
1166
 
1185
 
        unified_diff_files = patiencediff.unified_diff_files
 
1167
        unified_diff_files = bzrlib.patiencediff.unified_diff_files
1186
1168
        psm = self._PatienceSequenceMatcher
1187
 
        self.assertEquals(['--- a1\n',
1188
 
                           '+++ b1\n',
 
1169
        self.assertEquals(['--- a1 \n',
 
1170
                           '+++ b1 \n',
1189
1171
                           '@@ -1,3 +1,2 @@\n',
1190
1172
                           ' hello there\n',
1191
1173
                           '-world\n',
1200
1182
        open('b2', 'wb').writelines(txt_b)
1201
1183
 
1202
1184
        # This is the result with LongestCommonSubstring matching
1203
 
        self.assertEquals(['--- a2\n',
1204
 
                           '+++ b2\n',
 
1185
        self.assertEquals(['--- a2 \n',
 
1186
                           '+++ b2 \n',
1205
1187
                           '@@ -1,6 +1,11 @@\n',
1206
1188
                           ' a\n',
1207
1189
                           ' b\n',
1217
1199
                          , list(unified_diff_files('a2', 'b2')))
1218
1200
 
1219
1201
        # And the patience diff
1220
 
        self.assertEquals(['--- a2\n',
1221
 
                           '+++ b2\n',
 
1202
        self.assertEquals(['--- a2 \n',
 
1203
                           '+++ b2 \n',
1222
1204
                           '@@ -4,6 +4,11 @@\n',
1223
1205
                           ' d\n',
1224
1206
                           ' e\n',
1238
1220
 
1239
1221
class TestPatienceDiffLibFiles_c(TestPatienceDiffLibFiles):
1240
1222
 
1241
 
    _test_needs_features = [compiled_patiencediff_feature]
 
1223
    _test_needs_features = [CompiledPatienceDiffFeature]
1242
1224
 
1243
1225
    def setUp(self):
1244
1226
        super(TestPatienceDiffLibFiles_c, self).setUp()
1245
 
        from bzrlib import _patiencediff_c
 
1227
        import bzrlib._patiencediff_c
1246
1228
        self._PatienceSequenceMatcher = \
1247
 
            _patiencediff_c.PatienceSequenceMatcher_c
1248
 
 
1249
 
 
1250
 
class TestUsingCompiledIfAvailable(tests.TestCase):
 
1229
            bzrlib._patiencediff_c.PatienceSequenceMatcher_c
 
1230
 
 
1231
 
 
1232
class TestUsingCompiledIfAvailable(TestCase):
1251
1233
 
1252
1234
    def test_PatienceSequenceMatcher(self):
1253
 
        if compiled_patiencediff_feature.available():
 
1235
        if CompiledPatienceDiffFeature.available():
1254
1236
            from bzrlib._patiencediff_c import PatienceSequenceMatcher_c
1255
1237
            self.assertIs(PatienceSequenceMatcher_c,
1256
 
                          patiencediff.PatienceSequenceMatcher)
 
1238
                          bzrlib.patiencediff.PatienceSequenceMatcher)
1257
1239
        else:
1258
1240
            from bzrlib._patiencediff_py import PatienceSequenceMatcher_py
1259
1241
            self.assertIs(PatienceSequenceMatcher_py,
1260
 
                          patiencediff.PatienceSequenceMatcher)
 
1242
                          bzrlib.patiencediff.PatienceSequenceMatcher)
1261
1243
 
1262
1244
    def test_unique_lcs(self):
1263
 
        if compiled_patiencediff_feature.available():
 
1245
        if CompiledPatienceDiffFeature.available():
1264
1246
            from bzrlib._patiencediff_c import unique_lcs_c
1265
1247
            self.assertIs(unique_lcs_c,
1266
 
                          patiencediff.unique_lcs)
 
1248
                          bzrlib.patiencediff.unique_lcs)
1267
1249
        else:
1268
1250
            from bzrlib._patiencediff_py import unique_lcs_py
1269
1251
            self.assertIs(unique_lcs_py,
1270
 
                          patiencediff.unique_lcs)
 
1252
                          bzrlib.patiencediff.unique_lcs)
1271
1253
 
1272
1254
    def test_recurse_matches(self):
1273
 
        if compiled_patiencediff_feature.available():
 
1255
        if CompiledPatienceDiffFeature.available():
1274
1256
            from bzrlib._patiencediff_c import recurse_matches_c
1275
1257
            self.assertIs(recurse_matches_c,
1276
 
                          patiencediff.recurse_matches)
 
1258
                          bzrlib.patiencediff.recurse_matches)
1277
1259
        else:
1278
1260
            from bzrlib._patiencediff_py import recurse_matches_py
1279
1261
            self.assertIs(recurse_matches_py,
1280
 
                          patiencediff.recurse_matches)
1281
 
 
1282
 
 
1283
 
class TestDiffFromTool(tests.TestCaseWithTransport):
 
1262
                          bzrlib.patiencediff.recurse_matches)
 
1263
 
 
1264
 
 
1265
class TestDiffFromTool(TestCaseWithTransport):
1284
1266
 
1285
1267
    def test_from_string(self):
1286
 
        diff_obj = diff.DiffFromTool.from_string('diff', None, None, None)
 
1268
        diff_obj = DiffFromTool.from_string('diff', None, None, None)
1287
1269
        self.addCleanup(diff_obj.finish)
1288
 
        self.assertEqual(['diff', '@old_path', '@new_path'],
 
1270
        self.assertEqual(['diff', '%(old_path)s', '%(new_path)s'],
1289
1271
            diff_obj.command_template)
1290
1272
 
1291
1273
    def test_from_string_u5(self):
1292
 
        diff_obj = diff.DiffFromTool.from_string('diff "-u 5"',
1293
 
                                                 None, None, None)
 
1274
        diff_obj = DiffFromTool.from_string('diff -u\\ 5', None, None, None)
1294
1275
        self.addCleanup(diff_obj.finish)
1295
 
        self.assertEqual(['diff', '-u 5', '@old_path', '@new_path'],
 
1276
        self.assertEqual(['diff', '-u 5', '%(old_path)s', '%(new_path)s'],
1296
1277
                         diff_obj.command_template)
1297
1278
        self.assertEqual(['diff', '-u 5', 'old-path', 'new-path'],
1298
1279
                         diff_obj._get_command('old-path', 'new-path'))
1299
1280
 
1300
 
    def test_from_string_path_with_backslashes(self):
1301
 
        self.requireFeature(test_win32utils.BackslashDirSeparatorFeature)
1302
 
        tool = 'C:\\Tools\\Diff.exe'
1303
 
        diff_obj = diff.DiffFromTool.from_string(tool, None, None, None)
1304
 
        self.addCleanup(diff_obj.finish)
1305
 
        self.assertEqual(['C:\\Tools\\Diff.exe', '@old_path', '@new_path'],
1306
 
                         diff_obj.command_template)
1307
 
        self.assertEqual(['C:\\Tools\\Diff.exe', 'old-path', 'new-path'],
1308
 
                         diff_obj._get_command('old-path', 'new-path'))
1309
 
 
1310
1281
    def test_execute(self):
1311
1282
        output = StringIO()
1312
 
        diff_obj = diff.DiffFromTool(['python', '-c',
1313
 
                                      'print "@old_path @new_path"'],
1314
 
                                     None, None, output)
 
1283
        diff_obj = DiffFromTool(['python', '-c',
 
1284
                                 'print "%(old_path)s %(new_path)s"'],
 
1285
                                None, None, output)
1315
1286
        self.addCleanup(diff_obj.finish)
1316
1287
        diff_obj._execute('old', 'new')
1317
1288
        self.assertEqual(output.getvalue().rstrip(), 'old new')
1318
1289
 
1319
1290
    def test_excute_missing(self):
1320
 
        diff_obj = diff.DiffFromTool(['a-tool-which-is-unlikely-to-exist'],
1321
 
                                     None, None, None)
 
1291
        diff_obj = DiffFromTool(['a-tool-which-is-unlikely-to-exist'],
 
1292
                                None, None, None)
1322
1293
        self.addCleanup(diff_obj.finish)
1323
 
        e = self.assertRaises(errors.ExecutableMissing, diff_obj._execute,
1324
 
                              'old', 'new')
 
1294
        e = self.assertRaises(ExecutableMissing, diff_obj._execute, 'old',
 
1295
                              'new')
1325
1296
        self.assertEqual('a-tool-which-is-unlikely-to-exist could not be found'
1326
1297
                         ' on this machine', str(e))
1327
1298
 
1334
1305
        tree.commit('old tree')
1335
1306
        tree.lock_read()
1336
1307
        self.addCleanup(tree.unlock)
1337
 
        basis_tree = tree.basis_tree()
1338
 
        basis_tree.lock_read()
1339
 
        self.addCleanup(basis_tree.unlock)
1340
 
        diff_obj = diff.DiffFromTool(['python', '-c',
1341
 
                                      'print "@old_path @new_path"'],
1342
 
                                     basis_tree, tree, output)
 
1308
        diff_obj = DiffFromTool(['python', '-c',
 
1309
                                 'print "%(old_path)s %(new_path)s"'],
 
1310
                                tree, tree, output)
1343
1311
        diff_obj._prepare_files('file-id', 'file', 'file')
1344
 
        # The old content should be readonly
1345
 
        self.assertReadableByAttrib(diff_obj._root, 'old\\file',
1346
 
                                    r'R.*old\\file$')
1347
 
        # The new content should use the tree object, not a 'new' file anymore
1348
 
        self.assertEndsWith(tree.basedir, 'work/tree')
1349
 
        self.assertReadableByAttrib(tree.basedir, 'file', r'work\\tree\\file$')
 
1312
        self.assertReadableByAttrib(diff_obj._root, 'old\\file', r'old\\file')
 
1313
        self.assertReadableByAttrib(diff_obj._root, 'new\\file', r'new\\file')
1350
1314
 
1351
1315
    def assertReadableByAttrib(self, cwd, relpath, regex):
1352
1316
        proc = subprocess.Popen(['attrib', relpath],
1353
1317
                                stdout=subprocess.PIPE,
1354
1318
                                cwd=cwd)
1355
 
        (result, err) = proc.communicate()
1356
 
        self.assertContainsRe(result.replace('\r\n', '\n'), regex)
 
1319
        proc.wait()
 
1320
        result = proc.stdout.read()
 
1321
        self.assertContainsRe(result, regex)
1357
1322
 
1358
1323
    def test_prepare_files(self):
1359
1324
        output = StringIO()
1362
1327
        self.build_tree_contents([('tree/oldname2', 'oldcontent2')])
1363
1328
        tree.add('oldname', 'file-id')
1364
1329
        tree.add('oldname2', 'file2-id')
1365
 
        # Earliest allowable date on FAT32 filesystems is 1980-01-01
1366
 
        tree.commit('old tree', timestamp=315532800)
 
1330
        tree.commit('old tree', timestamp=0)
1367
1331
        tree.rename_one('oldname', 'newname')
1368
1332
        tree.rename_one('oldname2', 'newname2')
1369
1333
        self.build_tree_contents([('tree/newname', 'newcontent')])
1373
1337
        self.addCleanup(old_tree.unlock)
1374
1338
        tree.lock_read()
1375
1339
        self.addCleanup(tree.unlock)
1376
 
        diff_obj = diff.DiffFromTool(['python', '-c',
1377
 
                                      'print "@old_path @new_path"'],
1378
 
                                     old_tree, tree, output)
 
1340
        diff_obj = DiffFromTool(['python', '-c',
 
1341
                                 'print "%(old_path)s %(new_path)s"'],
 
1342
                                old_tree, tree, output)
1379
1343
        self.addCleanup(diff_obj.finish)
1380
1344
        self.assertContainsRe(diff_obj._root, 'bzr-diff-[^/]*')
1381
1345
        old_path, new_path = diff_obj._prepare_files('file-id', 'oldname',
1382
1346
                                                     'newname')
1383
1347
        self.assertContainsRe(old_path, 'old/oldname$')
1384
 
        self.assertEqual(315532800, os.stat(old_path).st_mtime)
1385
 
        self.assertContainsRe(new_path, 'tree/newname$')
 
1348
        self.assertEqual(0, os.stat(old_path).st_mtime)
 
1349
        self.assertContainsRe(new_path, 'new/newname$')
1386
1350
        self.assertFileEqual('oldcontent', old_path)
1387
1351
        self.assertFileEqual('newcontent', new_path)
1388
1352
        if osutils.host_os_dereferences_symlinks():
1389
1353
            self.assertTrue(os.path.samefile('tree/newname', new_path))
1390
1354
        # make sure we can create files with the same parent directories
1391
1355
        diff_obj._prepare_files('file2-id', 'oldname2', 'newname2')
1392
 
 
1393
 
 
1394
 
class TestGetTreesAndBranchesToDiffLocked(tests.TestCaseWithTransport):
1395
 
 
1396
 
    def call_gtabtd(self, path_list, revision_specs, old_url, new_url):
1397
 
        """Call get_trees_and_branches_to_diff_locked.  Overridden by
1398
 
        TestGetTreesAndBranchesToDiff.
1399
 
        """
1400
 
        return diff.get_trees_and_branches_to_diff_locked(
1401
 
            path_list, revision_specs, old_url, new_url, self.addCleanup)
1402
 
 
1403
 
    def test_basic(self):
1404
 
        tree = self.make_branch_and_tree('tree')
1405
 
        (old_tree, new_tree,
1406
 
         old_branch, new_branch,
1407
 
         specific_files, extra_trees) = self.call_gtabtd(
1408
 
             ['tree'], None, None, None)
1409
 
 
1410
 
        self.assertIsInstance(old_tree, revisiontree.RevisionTree)
1411
 
        self.assertEqual(_mod_revision.NULL_REVISION,
1412
 
                         old_tree.get_revision_id())
1413
 
        self.assertEqual(tree.basedir, new_tree.basedir)
1414
 
        self.assertEqual(tree.branch.base, old_branch.base)
1415
 
        self.assertEqual(tree.branch.base, new_branch.base)
1416
 
        self.assertIs(None, specific_files)
1417
 
        self.assertIs(None, extra_trees)
1418
 
 
1419
 
    def test_with_rev_specs(self):
1420
 
        tree = self.make_branch_and_tree('tree')
1421
 
        self.build_tree_contents([('tree/file', 'oldcontent')])
1422
 
        tree.add('file', 'file-id')
1423
 
        tree.commit('old tree', timestamp=0, rev_id="old-id")
1424
 
        self.build_tree_contents([('tree/file', 'newcontent')])
1425
 
        tree.commit('new tree', timestamp=0, rev_id="new-id")
1426
 
 
1427
 
        revisions = [revisionspec.RevisionSpec.from_string('1'),
1428
 
                     revisionspec.RevisionSpec.from_string('2')]
1429
 
        (old_tree, new_tree,
1430
 
         old_branch, new_branch,
1431
 
         specific_files, extra_trees) = self.call_gtabtd(
1432
 
            ['tree'], revisions, None, None)
1433
 
 
1434
 
        self.assertIsInstance(old_tree, revisiontree.RevisionTree)
1435
 
        self.assertEqual("old-id", old_tree.get_revision_id())
1436
 
        self.assertIsInstance(new_tree, revisiontree.RevisionTree)
1437
 
        self.assertEqual("new-id", new_tree.get_revision_id())
1438
 
        self.assertEqual(tree.branch.base, old_branch.base)
1439
 
        self.assertEqual(tree.branch.base, new_branch.base)
1440
 
        self.assertIs(None, specific_files)
1441
 
        self.assertEqual(tree.basedir, extra_trees[0].basedir)
1442
 
 
1443
 
 
1444
 
class TestGetTreesAndBranchesToDiff(TestGetTreesAndBranchesToDiffLocked):
1445
 
    """Apply the tests for get_trees_and_branches_to_diff_locked to the
1446
 
    deprecated get_trees_and_branches_to_diff function.
1447
 
    """
1448
 
 
1449
 
    def call_gtabtd(self, path_list, revision_specs, old_url, new_url):
1450
 
        return self.applyDeprecated(
1451
 
            deprecated_in((2, 2, 0)), diff.get_trees_and_branches_to_diff,
1452
 
            path_list, revision_specs, old_url, new_url)
1453