~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_diff.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2010-04-21 11:48:39 UTC
  • mfrom: (5169.1.1 integration)
  • Revision ID: pqm@pqm.ubuntu.com-20100421114839-4elxlyab2r06ryj3
(vila) Fix bt.test_diff imports

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
import os
18
 
import os.path
19
18
from cStringIO import StringIO
20
19
import subprocess
21
20
import sys
22
 
from tempfile import TemporaryFile
 
21
import tempfile
23
22
 
24
 
from bzrlib import tests
25
 
from bzrlib.diff import (
26
 
    DiffFromTool,
27
 
    DiffPath,
28
 
    DiffSymlink,
29
 
    DiffTree,
30
 
    DiffText,
31
 
    external_diff,
32
 
    internal_diff,
33
 
    show_diff_trees,
34
 
    get_trees_and_branches_to_diff,
35
 
    get_trees_and_branches_to_diff_locked,
 
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,
36
34
    )
37
 
from bzrlib.errors import BinaryFile, NoDiff, ExecutableMissing
38
 
import bzrlib.osutils as osutils
39
 
import bzrlib.revision as _mod_revision
40
 
import bzrlib.transform as transform
41
 
import bzrlib.patiencediff
42
 
import bzrlib._patiencediff_py
43
 
from bzrlib.tests import (Feature, TestCase, TestCaseWithTransport,
44
 
                          TestCaseInTempDir, TestSkipped)
45
 
from bzrlib.revisiontree import RevisionTree
46
 
from bzrlib.revisionspec import RevisionSpec
47
35
from bzrlib.symbol_versioning import deprecated_in
48
 
 
49
 
from bzrlib.tests.test_win32utils import BackslashDirSeparatorFeature
50
 
 
51
 
 
52
 
class _AttribFeature(Feature):
 
36
from bzrlib.tests import test_win32utils
 
37
 
 
38
 
 
39
class _AttribFeature(tests.Feature):
53
40
 
54
41
    def _probe(self):
55
42
        if (sys.platform not in ('cygwin', 'win32')):
72
59
 
73
60
def udiff_lines(old, new, allow_binary=False):
74
61
    output = StringIO()
75
 
    internal_diff('old', old, 'new', new, output, allow_binary)
 
62
    diff.internal_diff('old', old, 'new', new, output, allow_binary)
76
63
    output.seek(0, 0)
77
64
    return output.readlines()
78
65
 
82
69
        # StringIO has no fileno, so it tests a different codepath
83
70
        output = StringIO()
84
71
    else:
85
 
        output = TemporaryFile()
 
72
        output = tempfile.TemporaryFile()
86
73
    try:
87
 
        external_diff('old', old, 'new', new, output, diff_opts=['-u'])
88
 
    except NoDiff:
89
 
        raise TestSkipped('external "diff" not present to test')
 
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')
90
77
    output.seek(0, 0)
91
78
    lines = output.readlines()
92
79
    output.close()
93
80
    return lines
94
81
 
95
82
 
96
 
class TestDiff(TestCase):
 
83
class TestDiff(tests.TestCase):
97
84
 
98
85
    def test_add_nl(self):
99
86
        """diff generates a valid diff for patches that add a newline"""
135
122
            ## "Unterminated hunk header for patch:\n%s" % "".join(lines)
136
123
 
137
124
    def test_binary_lines(self):
138
 
        self.assertRaises(BinaryFile, udiff_lines, [1023 * 'a' + '\x00'], [])
139
 
        self.assertRaises(BinaryFile, udiff_lines, [], [1023 * 'a' + '\x00'])
140
 
        udiff_lines([1023 * 'a' + '\x00'], [], allow_binary=True)
141
 
        udiff_lines([], [1023 * 'a' + '\x00'], allow_binary=True)
 
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
131
 
143
132
    def test_external_diff(self):
144
133
        lines = external_udiff_lines(['boo\n'], ['goo\n'])
174
163
        orig_path = os.environ['PATH']
175
164
        try:
176
165
            os.environ['PATH'] = ''
177
 
            self.assertRaises(NoDiff, external_diff,
 
166
            self.assertRaises(errors.NoDiff, diff.external_diff,
178
167
                              'old', ['boo\n'], 'new', ['goo\n'],
179
168
                              StringIO(), diff_opts=['-u'])
180
169
        finally:
183
172
    def test_internal_diff_default(self):
184
173
        # Default internal diff encoding is utf8
185
174
        output = StringIO()
186
 
        internal_diff(u'old_\xb5', ['old_text\n'],
187
 
                    u'new_\xe5', ['new_text\n'], output)
 
175
        diff.internal_diff(u'old_\xb5', ['old_text\n'],
 
176
                           u'new_\xe5', ['new_text\n'], output)
188
177
        lines = output.getvalue().splitlines(True)
189
178
        self.check_patch(lines)
190
179
        self.assertEquals(['--- old_\xc2\xb5\n',
198
187
 
199
188
    def test_internal_diff_utf8(self):
200
189
        output = StringIO()
201
 
        internal_diff(u'old_\xb5', ['old_text\n'],
202
 
                    u'new_\xe5', ['new_text\n'], output,
203
 
                    path_encoding='utf8')
 
190
        diff.internal_diff(u'old_\xb5', ['old_text\n'],
 
191
                           u'new_\xe5', ['new_text\n'], output,
 
192
                           path_encoding='utf8')
204
193
        lines = output.getvalue().splitlines(True)
205
194
        self.check_patch(lines)
206
195
        self.assertEquals(['--- old_\xc2\xb5\n',
214
203
 
215
204
    def test_internal_diff_iso_8859_1(self):
216
205
        output = StringIO()
217
 
        internal_diff(u'old_\xb5', ['old_text\n'],
218
 
                    u'new_\xe5', ['new_text\n'], output,
219
 
                    path_encoding='iso-8859-1')
 
206
        diff.internal_diff(u'old_\xb5', ['old_text\n'],
 
207
                           u'new_\xe5', ['new_text\n'], output,
 
208
                           path_encoding='iso-8859-1')
220
209
        lines = output.getvalue().splitlines(True)
221
210
        self.check_patch(lines)
222
211
        self.assertEquals(['--- old_\xb5\n',
230
219
 
231
220
    def test_internal_diff_no_content(self):
232
221
        output = StringIO()
233
 
        internal_diff(u'old', [], u'new', [], output)
 
222
        diff.internal_diff(u'old', [], u'new', [], output)
234
223
        self.assertEqual('', output.getvalue())
235
224
 
236
225
    def test_internal_diff_no_changes(self):
237
226
        output = StringIO()
238
 
        internal_diff(u'old', ['text\n', 'contents\n'],
239
 
                      u'new', ['text\n', 'contents\n'],
240
 
                      output)
 
227
        diff.internal_diff(u'old', ['text\n', 'contents\n'],
 
228
                           u'new', ['text\n', 'contents\n'],
 
229
                           output)
241
230
        self.assertEqual('', output.getvalue())
242
231
 
243
232
    def test_internal_diff_returns_bytes(self):
244
233
        import StringIO
245
234
        output = StringIO.StringIO()
246
 
        internal_diff(u'old_\xb5', ['old_text\n'],
247
 
                    u'new_\xe5', ['new_text\n'], output)
 
235
        diff.internal_diff(u'old_\xb5', ['old_text\n'],
 
236
                            u'new_\xe5', ['new_text\n'], output)
248
237
        self.failUnless(isinstance(output.getvalue(), str),
249
238
            'internal_diff should return bytestrings')
250
239
 
251
240
 
252
 
class TestDiffFiles(TestCaseInTempDir):
 
241
class TestDiffFiles(tests.TestCaseInTempDir):
253
242
 
254
243
    def test_external_diff_binary(self):
255
244
        """The output when using external diff should use diff's i18n error"""
268
257
        self.assertEqual(out.splitlines(True) + ['\n'], lines)
269
258
 
270
259
 
271
 
class TestShowDiffTreesHelper(TestCaseWithTransport):
 
260
class TestShowDiffTreesHelper(tests.TestCaseWithTransport):
272
261
    """Has a helper for running show_diff_trees"""
273
262
 
274
263
    def get_diff(self, tree1, tree2, specific_files=None, working_tree=None):
277
266
            extra_trees = (working_tree,)
278
267
        else:
279
268
            extra_trees = ()
280
 
        show_diff_trees(tree1, tree2, output, specific_files=specific_files,
281
 
                        extra_trees=extra_trees, old_label='old/',
282
 
                        new_label='new/')
 
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/')
283
273
        return output.getvalue()
284
274
 
285
275
 
424
414
        tree.commit('one', rev_id='rev-1')
425
415
 
426
416
        self.build_tree_contents([('tree/file', 'new contents\n')])
427
 
        diff = self.get_diff(tree.basis_tree(), tree)
428
 
        self.assertContainsRe(diff, "=== modified file 'file'\n")
429
 
        self.assertContainsRe(diff, '--- old/file\t')
430
 
        self.assertContainsRe(diff, '\\+\\+\\+ new/file\t')
431
 
        self.assertContainsRe(diff, '-contents\n'
432
 
                                    '\\+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')
433
423
 
434
424
    def test_modified_file_in_renamed_dir(self):
435
425
        """Test when a file is modified in a renamed directory."""
441
431
 
442
432
        tree.rename_one('dir', 'other')
443
433
        self.build_tree_contents([('tree/other/file', 'new contents\n')])
444
 
        diff = self.get_diff(tree.basis_tree(), tree)
445
 
        self.assertContainsRe(diff, "=== renamed directory 'dir' => 'other'\n")
446
 
        self.assertContainsRe(diff, "=== modified file 'other/file'\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")
447
437
        # XXX: This is technically incorrect, because it used to be at another
448
438
        # location. What to do?
449
 
        self.assertContainsRe(diff, '--- old/dir/file\t')
450
 
        self.assertContainsRe(diff, '\\+\\+\\+ new/other/file\t')
451
 
        self.assertContainsRe(diff, '-contents\n'
452
 
                                    '\\+new contents\n')
 
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
443
 
454
444
    def test_renamed_directory(self):
455
445
        """Test when only a directory is only renamed."""
460
450
        tree.commit('one', rev_id='rev-1')
461
451
 
462
452
        tree.rename_one('dir', 'newdir')
463
 
        diff = self.get_diff(tree.basis_tree(), tree)
 
453
        d = self.get_diff(tree.basis_tree(), tree)
464
454
        # Renaming a directory should be a single "you renamed this dir" even
465
455
        # when there are files inside.
466
 
        self.assertEqual("=== renamed directory 'dir' => 'newdir'\n", diff)
 
456
        self.assertEqual(d, "=== renamed directory 'dir' => 'newdir'\n")
467
457
 
468
458
    def test_renamed_file(self):
469
459
        """Test when a file is only renamed."""
473
463
        tree.commit('one', rev_id='rev-1')
474
464
 
475
465
        tree.rename_one('file', 'newname')
476
 
        diff = self.get_diff(tree.basis_tree(), tree)
477
 
        self.assertContainsRe(diff, "=== renamed file 'file' => 'newname'\n")
 
466
        d = self.get_diff(tree.basis_tree(), tree)
 
467
        self.assertContainsRe(d, "=== renamed file 'file' => 'newname'\n")
478
468
        # We shouldn't have a --- or +++ line, because there is no content
479
469
        # change
480
 
        self.assertNotContainsRe(diff, '---')
 
470
        self.assertNotContainsRe(d, '---')
481
471
 
482
472
    def test_renamed_and_modified_file(self):
483
473
        """Test when a file is only renamed."""
488
478
 
489
479
        tree.rename_one('file', 'newname')
490
480
        self.build_tree_contents([('tree/newname', 'new contents\n')])
491
 
        diff = self.get_diff(tree.basis_tree(), tree)
492
 
        self.assertContainsRe(diff, "=== renamed file 'file' => 'newname'\n")
493
 
        self.assertContainsRe(diff, '--- old/file\t')
494
 
        self.assertContainsRe(diff, '\\+\\+\\+ new/newname\t')
495
 
        self.assertContainsRe(diff, '-contents\n'
496
 
                                    '\\+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')
497
487
 
498
488
 
499
489
    def test_internal_diff_exec_property(self):
518
508
        tree.rename_one('c', 'new-c')
519
509
        tree.rename_one('d', 'new-d')
520
510
 
521
 
        diff = self.get_diff(tree.basis_tree(), tree)
 
511
        d = self.get_diff(tree.basis_tree(), tree)
522
512
 
523
 
        self.assertContainsRe(diff, r"file 'a'.*\(properties changed:.*\+x to -x.*\)")
524
 
        self.assertContainsRe(diff, r"file 'b'.*\(properties changed:.*-x to \+x.*\)")
525
 
        self.assertContainsRe(diff, r"file 'c'.*\(properties changed:.*\+x to -x.*\)")
526
 
        self.assertContainsRe(diff, r"file 'd'.*\(properties changed:.*-x to \+x.*\)")
527
 
        self.assertNotContainsRe(diff, r"file 'e'")
528
 
        self.assertNotContainsRe(diff, r"file 'f'")
 
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'")
529
523
 
530
524
 
531
525
    def test_binary_unicode_filenames(self):
547
541
        tree.add([alpha], ['file-id'])
548
542
        tree.add([omega], ['file-id-2'])
549
543
        diff_content = StringIO()
550
 
        show_diff_trees(tree.basis_tree(), tree, diff_content)
551
 
        diff = diff_content.getvalue()
552
 
        self.assertContainsRe(diff, r"=== added file '%s'" % alpha_utf8)
553
 
        self.assertContainsRe(
554
 
            diff, "Binary files a/%s.*and b/%s.* differ\n" % (alpha_utf8, alpha_utf8))
555
 
        self.assertContainsRe(diff, r"=== added file '%s'" % omega_utf8)
556
 
        self.assertContainsRe(diff, r"--- a/%s" % (omega_utf8,))
557
 
        self.assertContainsRe(diff, r"\+\+\+ b/%s" % (omega_utf8,))
 
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,))
558
552
 
559
553
    def test_unicode_filename(self):
560
554
        """Test when the filename are unicode."""
579
573
        tree.add(['add_'+alpha], ['file-id'])
580
574
        self.build_tree_contents([('tree/mod_'+alpha, 'contents_mod\n')])
581
575
 
582
 
        diff = self.get_diff(tree.basis_tree(), tree)
583
 
        self.assertContainsRe(diff,
 
576
        d = self.get_diff(tree.basis_tree(), tree)
 
577
        self.assertContainsRe(d,
584
578
                "=== renamed file 'ren_%s' => 'ren_%s'\n"%(autf8, outf8))
585
 
        self.assertContainsRe(diff, "=== added file 'add_%s'"%autf8)
586
 
        self.assertContainsRe(diff, "=== modified file 'mod_%s'"%autf8)
587
 
        self.assertContainsRe(diff, "=== removed file 'del_%s'"%autf8)
588
 
 
589
 
 
590
 
class DiffWasIs(DiffPath):
 
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):
591
585
 
592
586
    def diff(self, file_id, old_path, new_path, old_kind, new_kind):
593
587
        self.to_file.write('was: ')
597
591
        pass
598
592
 
599
593
 
600
 
class TestDiffTree(TestCaseWithTransport):
 
594
class TestDiffTree(tests.TestCaseWithTransport):
601
595
 
602
596
    def setUp(self):
603
 
        TestCaseWithTransport.setUp(self)
 
597
        super(TestDiffTree, self).setUp()
604
598
        self.old_tree = self.make_branch_and_tree('old-tree')
605
599
        self.old_tree.lock_write()
606
600
        self.addCleanup(self.old_tree.unlock)
607
601
        self.new_tree = self.make_branch_and_tree('new-tree')
608
602
        self.new_tree.lock_write()
609
603
        self.addCleanup(self.new_tree.unlock)
610
 
        self.differ = DiffTree(self.old_tree, self.new_tree, StringIO())
 
604
        self.differ = diff.DiffTree(self.old_tree, self.new_tree, StringIO())
611
605
 
612
606
    def test_diff_text(self):
613
607
        self.build_tree_contents([('old-tree/olddir/',),
618
612
                                  ('new-tree/newdir/newfile', 'new\n')])
619
613
        self.new_tree.add('newdir')
620
614
        self.new_tree.add('newdir/newfile', 'file-id')
621
 
        differ = DiffText(self.old_tree, self.new_tree, StringIO())
 
615
        differ = diff.DiffText(self.old_tree, self.new_tree, StringIO())
622
616
        differ.diff_text('file-id', None, 'old label', 'new label')
623
617
        self.assertEqual(
624
618
            '--- old label\n+++ new label\n@@ -1,1 +0,0 @@\n-old\n\n',
653
647
        self.assertContainsRe(self.differ.to_file.getvalue(), '\+contents')
654
648
 
655
649
    def test_diff_symlink(self):
656
 
        differ = DiffSymlink(self.old_tree, self.new_tree, StringIO())
 
650
        differ = diff.DiffSymlink(self.old_tree, self.new_tree, StringIO())
657
651
        differ.diff_symlink('old target', None)
658
652
        self.assertEqual("=== target was 'old target'\n",
659
653
                         differ.to_file.getvalue())
660
654
 
661
 
        differ = DiffSymlink(self.old_tree, self.new_tree, StringIO())
 
655
        differ = diff.DiffSymlink(self.old_tree, self.new_tree, StringIO())
662
656
        differ.diff_symlink(None, 'new target')
663
657
        self.assertEqual("=== target is 'new target'\n",
664
658
                         differ.to_file.getvalue())
665
659
 
666
 
        differ = DiffSymlink(self.old_tree, self.new_tree, StringIO())
 
660
        differ = diff.DiffSymlink(self.old_tree, self.new_tree, StringIO())
667
661
        differ.diff_symlink('old target', 'new target')
668
662
        self.assertEqual("=== target changed 'old target' => 'new target'\n",
669
663
                         differ.to_file.getvalue())
719
713
 
720
714
    def test_register_diff(self):
721
715
        self.create_old_new()
722
 
        old_diff_factories = DiffTree.diff_factories
723
 
        DiffTree.diff_factories=old_diff_factories[:]
724
 
        DiffTree.diff_factories.insert(0, DiffWasIs.from_diff_tree)
 
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)
725
719
        try:
726
 
            differ = DiffTree(self.old_tree, self.new_tree, StringIO())
 
720
            differ = diff.DiffTree(self.old_tree, self.new_tree, StringIO())
727
721
        finally:
728
 
            DiffTree.diff_factories = old_diff_factories
 
722
            diff.DiffTree.diff_factories = old_diff_factories
729
723
        differ.diff('file-id', 'olddir/oldfile', 'newdir/newfile')
730
724
        self.assertNotContainsRe(
731
725
            differ.to_file.getvalue(),
736
730
 
737
731
    def test_extra_factories(self):
738
732
        self.create_old_new()
739
 
        differ = DiffTree(self.old_tree, self.new_tree, StringIO(),
740
 
                            extra_factories=[DiffWasIs.from_diff_tree])
 
733
        differ = diff.DiffTree(self.old_tree, self.new_tree, StringIO(),
 
734
                               extra_factories=[DiffWasIs.from_diff_tree])
741
735
        differ.diff('file-id', 'olddir/oldfile', 'newdir/newfile')
742
736
        self.assertNotContainsRe(
743
737
            differ.to_file.getvalue(),
756
750
            '.*a-file(.|\n)*b-file')
757
751
 
758
752
 
759
 
class TestPatienceDiffLib(TestCase):
 
753
class TestPatienceDiffLib(tests.TestCase):
760
754
 
761
755
    def setUp(self):
762
756
        super(TestPatienceDiffLib, self).setUp()
763
 
        self._unique_lcs = bzrlib._patiencediff_py.unique_lcs_py
764
 
        self._recurse_matches = bzrlib._patiencediff_py.recurse_matches_py
 
757
        self._unique_lcs = _patiencediff_py.unique_lcs_py
 
758
        self._recurse_matches = _patiencediff_py.recurse_matches_py
765
759
        self._PatienceSequenceMatcher = \
766
 
            bzrlib._patiencediff_py.PatienceSequenceMatcher_py
 
760
            _patiencediff_py.PatienceSequenceMatcher_py
767
761
 
768
762
    def test_diff_unicode_string(self):
769
763
        a = ''.join([unichr(i) for i in range(4000, 4500, 3)])
1076
1070
                 'how are you today?\n']
1077
1071
        txt_b = ['hello there\n',
1078
1072
                 'how are you today?\n']
1079
 
        unified_diff = bzrlib.patiencediff.unified_diff
 
1073
        unified_diff = patiencediff.unified_diff
1080
1074
        psm = self._PatienceSequenceMatcher
1081
1075
        self.assertEquals(['--- \n',
1082
1076
                           '+++ \n',
1130
1124
                 'how are you today?\n']
1131
1125
        txt_b = ['hello there\n',
1132
1126
                 'how are you today?\n']
1133
 
        unified_diff = bzrlib.patiencediff.unified_diff
 
1127
        unified_diff = patiencediff.unified_diff
1134
1128
        psm = self._PatienceSequenceMatcher
1135
1129
        self.assertEquals(['--- a\t2008-08-08\n',
1136
1130
                           '+++ b\t2008-09-09\n',
1152
1146
 
1153
1147
    def setUp(self):
1154
1148
        super(TestPatienceDiffLib_c, self).setUp()
1155
 
        import bzrlib._patiencediff_c
1156
 
        self._unique_lcs = bzrlib._patiencediff_c.unique_lcs_c
1157
 
        self._recurse_matches = bzrlib._patiencediff_c.recurse_matches_c
 
1149
        from bzrlib import _patiencediff_c
 
1150
        self._unique_lcs = _patiencediff_c.unique_lcs_c
 
1151
        self._recurse_matches = _patiencediff_c.recurse_matches_c
1158
1152
        self._PatienceSequenceMatcher = \
1159
 
            bzrlib._patiencediff_c.PatienceSequenceMatcher_c
 
1153
            _patiencediff_c.PatienceSequenceMatcher_c
1160
1154
 
1161
1155
    def test_unhashable(self):
1162
1156
        """We should get a proper exception here."""
1172
1166
                                         None, ['valid'], ['valid', []])
1173
1167
 
1174
1168
 
1175
 
class TestPatienceDiffLibFiles(TestCaseInTempDir):
 
1169
class TestPatienceDiffLibFiles(tests.TestCaseInTempDir):
1176
1170
 
1177
1171
    def setUp(self):
1178
1172
        super(TestPatienceDiffLibFiles, self).setUp()
1179
1173
        self._PatienceSequenceMatcher = \
1180
 
            bzrlib._patiencediff_py.PatienceSequenceMatcher_py
 
1174
            _patiencediff_py.PatienceSequenceMatcher_py
1181
1175
 
1182
1176
    def test_patience_unified_diff_files(self):
1183
1177
        txt_a = ['hello there\n',
1188
1182
        open('a1', 'wb').writelines(txt_a)
1189
1183
        open('b1', 'wb').writelines(txt_b)
1190
1184
 
1191
 
        unified_diff_files = bzrlib.patiencediff.unified_diff_files
 
1185
        unified_diff_files = patiencediff.unified_diff_files
1192
1186
        psm = self._PatienceSequenceMatcher
1193
1187
        self.assertEquals(['--- a1\n',
1194
1188
                           '+++ b1\n',
1248
1242
 
1249
1243
    def setUp(self):
1250
1244
        super(TestPatienceDiffLibFiles_c, self).setUp()
1251
 
        import bzrlib._patiencediff_c
 
1245
        from bzrlib import _patiencediff_c
1252
1246
        self._PatienceSequenceMatcher = \
1253
 
            bzrlib._patiencediff_c.PatienceSequenceMatcher_c
1254
 
 
1255
 
 
1256
 
class TestUsingCompiledIfAvailable(TestCase):
 
1247
            _patiencediff_c.PatienceSequenceMatcher_c
 
1248
 
 
1249
 
 
1250
class TestUsingCompiledIfAvailable(tests.TestCase):
1257
1251
 
1258
1252
    def test_PatienceSequenceMatcher(self):
1259
1253
        if compiled_patiencediff_feature.available():
1260
1254
            from bzrlib._patiencediff_c import PatienceSequenceMatcher_c
1261
1255
            self.assertIs(PatienceSequenceMatcher_c,
1262
 
                          bzrlib.patiencediff.PatienceSequenceMatcher)
 
1256
                          patiencediff.PatienceSequenceMatcher)
1263
1257
        else:
1264
1258
            from bzrlib._patiencediff_py import PatienceSequenceMatcher_py
1265
1259
            self.assertIs(PatienceSequenceMatcher_py,
1266
 
                          bzrlib.patiencediff.PatienceSequenceMatcher)
 
1260
                          patiencediff.PatienceSequenceMatcher)
1267
1261
 
1268
1262
    def test_unique_lcs(self):
1269
1263
        if compiled_patiencediff_feature.available():
1270
1264
            from bzrlib._patiencediff_c import unique_lcs_c
1271
1265
            self.assertIs(unique_lcs_c,
1272
 
                          bzrlib.patiencediff.unique_lcs)
 
1266
                          patiencediff.unique_lcs)
1273
1267
        else:
1274
1268
            from bzrlib._patiencediff_py import unique_lcs_py
1275
1269
            self.assertIs(unique_lcs_py,
1276
 
                          bzrlib.patiencediff.unique_lcs)
 
1270
                          patiencediff.unique_lcs)
1277
1271
 
1278
1272
    def test_recurse_matches(self):
1279
1273
        if compiled_patiencediff_feature.available():
1280
1274
            from bzrlib._patiencediff_c import recurse_matches_c
1281
1275
            self.assertIs(recurse_matches_c,
1282
 
                          bzrlib.patiencediff.recurse_matches)
 
1276
                          patiencediff.recurse_matches)
1283
1277
        else:
1284
1278
            from bzrlib._patiencediff_py import recurse_matches_py
1285
1279
            self.assertIs(recurse_matches_py,
1286
 
                          bzrlib.patiencediff.recurse_matches)
1287
 
 
1288
 
 
1289
 
class TestDiffFromTool(TestCaseWithTransport):
 
1280
                          patiencediff.recurse_matches)
 
1281
 
 
1282
 
 
1283
class TestDiffFromTool(tests.TestCaseWithTransport):
1290
1284
 
1291
1285
    def test_from_string(self):
1292
 
        diff_obj = DiffFromTool.from_string('diff', None, None, None)
 
1286
        diff_obj = diff.DiffFromTool.from_string('diff', None, None, None)
1293
1287
        self.addCleanup(diff_obj.finish)
1294
1288
        self.assertEqual(['diff', '@old_path', '@new_path'],
1295
1289
            diff_obj.command_template)
1296
1290
 
1297
1291
    def test_from_string_u5(self):
1298
 
        diff_obj = DiffFromTool.from_string('diff "-u 5"', None, None, None)
 
1292
        diff_obj = diff.DiffFromTool.from_string('diff "-u 5"',
 
1293
                                                 None, None, None)
1299
1294
        self.addCleanup(diff_obj.finish)
1300
1295
        self.assertEqual(['diff', '-u 5', '@old_path', '@new_path'],
1301
1296
                         diff_obj.command_template)
1302
1297
        self.assertEqual(['diff', '-u 5', 'old-path', 'new-path'],
1303
1298
                         diff_obj._get_command('old-path', 'new-path'))
1304
 
        
 
1299
 
1305
1300
    def test_from_string_path_with_backslashes(self):
1306
 
        self.requireFeature(BackslashDirSeparatorFeature)
 
1301
        self.requireFeature(test_win32utils.BackslashDirSeparatorFeature)
1307
1302
        tool = 'C:\\Tools\\Diff.exe'
1308
 
        diff_obj = DiffFromTool.from_string(tool, None, None, None)
 
1303
        diff_obj = diff.DiffFromTool.from_string(tool, None, None, None)
1309
1304
        self.addCleanup(diff_obj.finish)
1310
1305
        self.assertEqual(['C:\\Tools\\Diff.exe', '@old_path', '@new_path'],
1311
1306
                         diff_obj.command_template)
1314
1309
 
1315
1310
    def test_execute(self):
1316
1311
        output = StringIO()
1317
 
        diff_obj = DiffFromTool(['python', '-c',
1318
 
                                 'print "@old_path @new_path"'],
1319
 
                                None, None, output)
 
1312
        diff_obj = diff.DiffFromTool(['python', '-c',
 
1313
                                      'print "@old_path @new_path"'],
 
1314
                                     None, None, output)
1320
1315
        self.addCleanup(diff_obj.finish)
1321
1316
        diff_obj._execute('old', 'new')
1322
1317
        self.assertEqual(output.getvalue().rstrip(), 'old new')
1323
1318
 
1324
1319
    def test_excute_missing(self):
1325
 
        diff_obj = DiffFromTool(['a-tool-which-is-unlikely-to-exist'],
1326
 
                                None, None, None)
 
1320
        diff_obj = diff.DiffFromTool(['a-tool-which-is-unlikely-to-exist'],
 
1321
                                     None, None, None)
1327
1322
        self.addCleanup(diff_obj.finish)
1328
 
        e = self.assertRaises(ExecutableMissing, diff_obj._execute, 'old',
1329
 
                              'new')
 
1323
        e = self.assertRaises(errors.ExecutableMissing, diff_obj._execute,
 
1324
                              'old', 'new')
1330
1325
        self.assertEqual('a-tool-which-is-unlikely-to-exist could not be found'
1331
1326
                         ' on this machine', str(e))
1332
1327
 
1342
1337
        basis_tree = tree.basis_tree()
1343
1338
        basis_tree.lock_read()
1344
1339
        self.addCleanup(basis_tree.unlock)
1345
 
        diff_obj = DiffFromTool(['python', '-c',
1346
 
                                 'print "@old_path @new_path"'],
1347
 
                                basis_tree, tree, output)
 
1340
        diff_obj = diff.DiffFromTool(['python', '-c',
 
1341
                                      'print "@old_path @new_path"'],
 
1342
                                     basis_tree, tree, output)
1348
1343
        diff_obj._prepare_files('file-id', 'file', 'file')
1349
1344
        # The old content should be readonly
1350
1345
        self.assertReadableByAttrib(diff_obj._root, 'old\\file',
1378
1373
        self.addCleanup(old_tree.unlock)
1379
1374
        tree.lock_read()
1380
1375
        self.addCleanup(tree.unlock)
1381
 
        diff_obj = DiffFromTool(['python', '-c',
1382
 
                                 'print "@old_path @new_path"'],
1383
 
                                old_tree, tree, output)
 
1376
        diff_obj = diff.DiffFromTool(['python', '-c',
 
1377
                                      'print "@old_path @new_path"'],
 
1378
                                     old_tree, tree, output)
1384
1379
        self.addCleanup(diff_obj.finish)
1385
1380
        self.assertContainsRe(diff_obj._root, 'bzr-diff-[^/]*')
1386
1381
        old_path, new_path = diff_obj._prepare_files('file-id', 'oldname',
1396
1391
        diff_obj._prepare_files('file2-id', 'oldname2', 'newname2')
1397
1392
 
1398
1393
 
1399
 
class TestGetTreesAndBranchesToDiffLocked(TestCaseWithTransport):
 
1394
class TestGetTreesAndBranchesToDiffLocked(tests.TestCaseWithTransport):
1400
1395
 
1401
1396
    def call_gtabtd(self, path_list, revision_specs, old_url, new_url):
1402
1397
        """Call get_trees_and_branches_to_diff_locked.  Overridden by
1403
1398
        TestGetTreesAndBranchesToDiff.
1404
1399
        """
1405
 
        return get_trees_and_branches_to_diff_locked(
 
1400
        return diff.get_trees_and_branches_to_diff_locked(
1406
1401
            path_list, revision_specs, old_url, new_url, self.addCleanup)
1407
1402
 
1408
1403
    def test_basic(self):
1412
1407
         specific_files, extra_trees) = self.call_gtabtd(
1413
1408
             ['tree'], None, None, None)
1414
1409
 
1415
 
        self.assertIsInstance(old_tree, RevisionTree)
1416
 
        self.assertEqual(_mod_revision.NULL_REVISION, old_tree.get_revision_id())
 
1410
        self.assertIsInstance(old_tree, revisiontree.RevisionTree)
 
1411
        self.assertEqual(_mod_revision.NULL_REVISION,
 
1412
                         old_tree.get_revision_id())
1417
1413
        self.assertEqual(tree.basedir, new_tree.basedir)
1418
1414
        self.assertEqual(tree.branch.base, old_branch.base)
1419
1415
        self.assertEqual(tree.branch.base, new_branch.base)
1428
1424
        self.build_tree_contents([('tree/file', 'newcontent')])
1429
1425
        tree.commit('new tree', timestamp=0, rev_id="new-id")
1430
1426
 
1431
 
        revisions = [RevisionSpec.from_string('1'),
1432
 
                     RevisionSpec.from_string('2')]
 
1427
        revisions = [revisionspec.RevisionSpec.from_string('1'),
 
1428
                     revisionspec.RevisionSpec.from_string('2')]
1433
1429
        (old_tree, new_tree,
1434
1430
         old_branch, new_branch,
1435
1431
         specific_files, extra_trees) = self.call_gtabtd(
1436
1432
            ['tree'], revisions, None, None)
1437
1433
 
1438
 
        self.assertIsInstance(old_tree, RevisionTree)
 
1434
        self.assertIsInstance(old_tree, revisiontree.RevisionTree)
1439
1435
        self.assertEqual("old-id", old_tree.get_revision_id())
1440
 
        self.assertIsInstance(new_tree, RevisionTree)
 
1436
        self.assertIsInstance(new_tree, revisiontree.RevisionTree)
1441
1437
        self.assertEqual("new-id", new_tree.get_revision_id())
1442
1438
        self.assertEqual(tree.branch.base, old_branch.base)
1443
1439
        self.assertEqual(tree.branch.base, new_branch.base)
1452
1448
 
1453
1449
    def call_gtabtd(self, path_list, revision_specs, old_url, new_url):
1454
1450
        return self.applyDeprecated(
1455
 
            deprecated_in((2, 2, 0)), get_trees_and_branches_to_diff,
 
1451
            deprecated_in((2, 2, 0)), diff.get_trees_and_branches_to_diff,
1456
1452
            path_list, revision_specs, old_url, new_url)
1457
1453