/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_diff.py

  • Committer: Robert Collins
  • Date: 2008-02-13 03:30:01 UTC
  • mfrom: (3221 +trunk)
  • mto: This revision was merged to the branch mainline in revision 3224.
  • Revision ID: robertc@robertcollins.net-20080213033001-rw70ul0zb02ph856
Merge to fix conflicts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
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
19
20
import errno
20
21
import subprocess
21
22
from tempfile import TemporaryFile
22
23
 
23
 
from bzrlib.diff import internal_diff, external_diff, show_diff_trees
24
 
from bzrlib.errors import BinaryFile, NoDiff
 
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
    )
 
35
from bzrlib.errors import BinaryFile, NoDiff, ExecutableMissing
25
36
import bzrlib.osutils as osutils
26
37
import bzrlib.patiencediff
27
38
import bzrlib._patiencediff_py
231
242
                          ]
232
243
                          , lines)
233
244
 
 
245
    def test_internal_diff_no_content(self):
 
246
        output = StringIO()
 
247
        internal_diff(u'old', [], u'new', [], output)
 
248
        self.assertEqual('', output.getvalue())
 
249
 
 
250
    def test_internal_diff_no_changes(self):
 
251
        output = StringIO()
 
252
        internal_diff(u'old', ['text\n', 'contents\n'],
 
253
                      u'new', ['text\n', 'contents\n'],
 
254
                      output)
 
255
        self.assertEqual('', output.getvalue())
 
256
 
234
257
    def test_internal_diff_returns_bytes(self):
235
258
        import StringIO
236
259
        output = StringIO.StringIO()
544
567
        self.assertContainsRe(diff, "=== modified file 'mod_%s'"%autf8)
545
568
        self.assertContainsRe(diff, "=== removed file 'del_%s'"%autf8)
546
569
 
 
570
 
 
571
class DiffWasIs(DiffPath):
 
572
 
 
573
    def diff(self, file_id, old_path, new_path, old_kind, new_kind):
 
574
        self.to_file.write('was: ')
 
575
        self.to_file.write(self.old_tree.get_file(file_id).read())
 
576
        self.to_file.write('is: ')
 
577
        self.to_file.write(self.new_tree.get_file(file_id).read())
 
578
        pass
 
579
 
 
580
 
 
581
class TestDiffTree(TestCaseWithTransport):
 
582
 
 
583
    def setUp(self):
 
584
        TestCaseWithTransport.setUp(self)
 
585
        self.old_tree = self.make_branch_and_tree('old-tree')
 
586
        self.old_tree.lock_write()
 
587
        self.addCleanup(self.old_tree.unlock)
 
588
        self.new_tree = self.make_branch_and_tree('new-tree')
 
589
        self.new_tree.lock_write()
 
590
        self.addCleanup(self.new_tree.unlock)
 
591
        self.differ = DiffTree(self.old_tree, self.new_tree, StringIO())
 
592
 
 
593
    def test_diff_text(self):
 
594
        self.build_tree_contents([('old-tree/olddir/',),
 
595
                                  ('old-tree/olddir/oldfile', 'old\n')])
 
596
        self.old_tree.add('olddir')
 
597
        self.old_tree.add('olddir/oldfile', 'file-id')
 
598
        self.build_tree_contents([('new-tree/newdir/',),
 
599
                                  ('new-tree/newdir/newfile', 'new\n')])
 
600
        self.new_tree.add('newdir')
 
601
        self.new_tree.add('newdir/newfile', 'file-id')
 
602
        differ = DiffText(self.old_tree, self.new_tree, StringIO())
 
603
        differ.diff_text('file-id', None, 'old label', 'new label')
 
604
        self.assertEqual(
 
605
            '--- old label\n+++ new label\n@@ -1,1 +0,0 @@\n-old\n\n',
 
606
            differ.to_file.getvalue())
 
607
        differ.to_file.seek(0)
 
608
        differ.diff_text(None, 'file-id', 'old label', 'new label')
 
609
        self.assertEqual(
 
610
            '--- old label\n+++ new label\n@@ -0,0 +1,1 @@\n+new\n\n',
 
611
            differ.to_file.getvalue())
 
612
        differ.to_file.seek(0)
 
613
        differ.diff_text('file-id', 'file-id', 'old label', 'new label')
 
614
        self.assertEqual(
 
615
            '--- old label\n+++ new label\n@@ -1,1 +1,1 @@\n-old\n+new\n\n',
 
616
            differ.to_file.getvalue())
 
617
 
 
618
    def test_diff_deletion(self):
 
619
        self.build_tree_contents([('old-tree/file', 'contents'),
 
620
                                  ('new-tree/file', 'contents')])
 
621
        self.old_tree.add('file', 'file-id')
 
622
        self.new_tree.add('file', 'file-id')
 
623
        os.unlink('new-tree/file')
 
624
        self.differ.show_diff(None)
 
625
        self.assertContainsRe(self.differ.to_file.getvalue(), '-contents')
 
626
 
 
627
    def test_diff_creation(self):
 
628
        self.build_tree_contents([('old-tree/file', 'contents'),
 
629
                                  ('new-tree/file', 'contents')])
 
630
        self.old_tree.add('file', 'file-id')
 
631
        self.new_tree.add('file', 'file-id')
 
632
        os.unlink('old-tree/file')
 
633
        self.differ.show_diff(None)
 
634
        self.assertContainsRe(self.differ.to_file.getvalue(), '\+contents')
 
635
 
 
636
    def test_diff_symlink(self):
 
637
        differ = DiffSymlink(self.old_tree, self.new_tree, StringIO())
 
638
        differ.diff_symlink('old target', None)
 
639
        self.assertEqual("=== target was 'old target'\n",
 
640
                         differ.to_file.getvalue())
 
641
 
 
642
        differ = DiffSymlink(self.old_tree, self.new_tree, StringIO())
 
643
        differ.diff_symlink(None, 'new target')
 
644
        self.assertEqual("=== target is 'new target'\n",
 
645
                         differ.to_file.getvalue())
 
646
 
 
647
        differ = DiffSymlink(self.old_tree, self.new_tree, StringIO())
 
648
        differ.diff_symlink('old target', 'new target')
 
649
        self.assertEqual("=== target changed 'old target' => 'new target'\n",
 
650
                         differ.to_file.getvalue())
 
651
 
 
652
    def test_diff(self):
 
653
        self.build_tree_contents([('old-tree/olddir/',),
 
654
                                  ('old-tree/olddir/oldfile', 'old\n')])
 
655
        self.old_tree.add('olddir')
 
656
        self.old_tree.add('olddir/oldfile', 'file-id')
 
657
        self.build_tree_contents([('new-tree/newdir/',),
 
658
                                  ('new-tree/newdir/newfile', 'new\n')])
 
659
        self.new_tree.add('newdir')
 
660
        self.new_tree.add('newdir/newfile', 'file-id')
 
661
        self.differ.diff('file-id', 'olddir/oldfile', 'newdir/newfile')
 
662
        self.assertContainsRe(
 
663
            self.differ.to_file.getvalue(),
 
664
            r'--- olddir/oldfile.*\n\+\+\+ newdir/newfile.*\n\@\@ -1,1 \+1,1'
 
665
             ' \@\@\n-old\n\+new\n\n')
 
666
 
 
667
    def test_diff_kind_change(self):
 
668
        self.requireFeature(tests.SymlinkFeature)
 
669
        self.build_tree_contents([('old-tree/olddir/',),
 
670
                                  ('old-tree/olddir/oldfile', 'old\n')])
 
671
        self.old_tree.add('olddir')
 
672
        self.old_tree.add('olddir/oldfile', 'file-id')
 
673
        self.build_tree(['new-tree/newdir/'])
 
674
        os.symlink('new', 'new-tree/newdir/newfile')
 
675
        self.new_tree.add('newdir')
 
676
        self.new_tree.add('newdir/newfile', 'file-id')
 
677
        self.differ.diff('file-id', 'olddir/oldfile', 'newdir/newfile')
 
678
        self.assertContainsRe(
 
679
            self.differ.to_file.getvalue(),
 
680
            r'--- olddir/oldfile.*\n\+\+\+ newdir/newfile.*\n\@\@ -1,1 \+0,0'
 
681
             ' \@\@\n-old\n\n')
 
682
        self.assertContainsRe(self.differ.to_file.getvalue(),
 
683
                              "=== target is 'new'\n")
 
684
 
 
685
    def test_diff_directory(self):
 
686
        self.build_tree(['new-tree/new-dir/'])
 
687
        self.new_tree.add('new-dir', 'new-dir-id')
 
688
        self.differ.diff('new-dir-id', None, 'new-dir')
 
689
        self.assertEqual(self.differ.to_file.getvalue(), '')
 
690
 
 
691
    def create_old_new(self):
 
692
        self.build_tree_contents([('old-tree/olddir/',),
 
693
                                  ('old-tree/olddir/oldfile', 'old\n')])
 
694
        self.old_tree.add('olddir')
 
695
        self.old_tree.add('olddir/oldfile', 'file-id')
 
696
        self.build_tree_contents([('new-tree/newdir/',),
 
697
                                  ('new-tree/newdir/newfile', 'new\n')])
 
698
        self.new_tree.add('newdir')
 
699
        self.new_tree.add('newdir/newfile', 'file-id')
 
700
 
 
701
    def test_register_diff(self):
 
702
        self.create_old_new()
 
703
        old_diff_factories = DiffTree.diff_factories
 
704
        DiffTree.diff_factories=old_diff_factories[:]
 
705
        DiffTree.diff_factories.insert(0, DiffWasIs.from_diff_tree)
 
706
        try:
 
707
            differ = DiffTree(self.old_tree, self.new_tree, StringIO())
 
708
        finally:
 
709
            DiffTree.diff_factories = old_diff_factories
 
710
        differ.diff('file-id', 'olddir/oldfile', 'newdir/newfile')
 
711
        self.assertNotContainsRe(
 
712
            differ.to_file.getvalue(),
 
713
            r'--- olddir/oldfile.*\n\+\+\+ newdir/newfile.*\n\@\@ -1,1 \+1,1'
 
714
             ' \@\@\n-old\n\+new\n\n')
 
715
        self.assertContainsRe(differ.to_file.getvalue(),
 
716
                              'was: old\nis: new\n')
 
717
 
 
718
    def test_extra_factories(self):
 
719
        self.create_old_new()
 
720
        differ = DiffTree(self.old_tree, self.new_tree, StringIO(),
 
721
                            extra_factories=[DiffWasIs.from_diff_tree])
 
722
        differ.diff('file-id', 'olddir/oldfile', 'newdir/newfile')
 
723
        self.assertNotContainsRe(
 
724
            differ.to_file.getvalue(),
 
725
            r'--- olddir/oldfile.*\n\+\+\+ newdir/newfile.*\n\@\@ -1,1 \+1,1'
 
726
             ' \@\@\n-old\n\+new\n\n')
 
727
        self.assertContainsRe(differ.to_file.getvalue(),
 
728
                              'was: old\nis: new\n')
 
729
 
 
730
    def test_alphabetical_order(self):
 
731
        self.build_tree(['new-tree/a-file'])
 
732
        self.new_tree.add('a-file')
 
733
        self.build_tree(['old-tree/b-file'])
 
734
        self.old_tree.add('b-file')
 
735
        self.differ.show_diff(None)
 
736
        self.assertContainsRe(self.differ.to_file.getvalue(),
 
737
            '.*a-file(.|\n)*b-file')
 
738
 
 
739
 
547
740
class TestPatienceDiffLib(TestCase):
548
741
 
549
742
    def setUp(self):
594
787
        # This is what it currently gives:
595
788
        test_one('aBccDe', 'abccde', [(0,0), (5,5)])
596
789
 
 
790
    def assertDiffBlocks(self, a, b, expected_blocks):
 
791
        """Check that the sequence matcher returns the correct blocks.
 
792
 
 
793
        :param a: A sequence to match
 
794
        :param b: Another sequence to match
 
795
        :param expected_blocks: The expected output, not including the final
 
796
            matching block (len(a), len(b), 0)
 
797
        """
 
798
        matcher = self._PatienceSequenceMatcher(None, a, b)
 
799
        blocks = matcher.get_matching_blocks()
 
800
        last = blocks.pop()
 
801
        self.assertEqual((len(a), len(b), 0), last)
 
802
        self.assertEqual(expected_blocks, blocks)
 
803
 
597
804
    def test_matching_blocks(self):
598
 
        def chk_blocks(a, b, expected_blocks):
599
 
            # difflib always adds a signature of the total
600
 
            # length, with no matching entries at the end
601
 
            s = self._PatienceSequenceMatcher(None, a, b)
602
 
            blocks = s.get_matching_blocks()
603
 
            self.assertEquals((len(a), len(b), 0), blocks[-1])
604
 
            self.assertEquals(expected_blocks, blocks[:-1])
605
 
 
606
805
        # Some basic matching tests
607
 
        chk_blocks('', '', [])
608
 
        chk_blocks([], [], [])
609
 
        chk_blocks('abc', '', [])
610
 
        chk_blocks('', 'abc', [])
611
 
        chk_blocks('abcd', 'abcd', [(0, 0, 4)])
612
 
        chk_blocks('abcd', 'abce', [(0, 0, 3)])
613
 
        chk_blocks('eabc', 'abce', [(1, 0, 3)])
614
 
        chk_blocks('eabce', 'abce', [(1, 0, 4)])
615
 
        chk_blocks('abcde', 'abXde', [(0, 0, 2), (3, 3, 2)])
616
 
        chk_blocks('abcde', 'abXYZde', [(0, 0, 2), (3, 5, 2)])
617
 
        chk_blocks('abde', 'abXYZde', [(0, 0, 2), (2, 5, 2)])
618
 
        # This may check too much, but it checks to see that 
 
806
        self.assertDiffBlocks('', '', [])
 
807
        self.assertDiffBlocks([], [], [])
 
808
        self.assertDiffBlocks('abc', '', [])
 
809
        self.assertDiffBlocks('', 'abc', [])
 
810
        self.assertDiffBlocks('abcd', 'abcd', [(0, 0, 4)])
 
811
        self.assertDiffBlocks('abcd', 'abce', [(0, 0, 3)])
 
812
        self.assertDiffBlocks('eabc', 'abce', [(1, 0, 3)])
 
813
        self.assertDiffBlocks('eabce', 'abce', [(1, 0, 4)])
 
814
        self.assertDiffBlocks('abcde', 'abXde', [(0, 0, 2), (3, 3, 2)])
 
815
        self.assertDiffBlocks('abcde', 'abXYZde', [(0, 0, 2), (3, 5, 2)])
 
816
        self.assertDiffBlocks('abde', 'abXYZde', [(0, 0, 2), (2, 5, 2)])
 
817
        # This may check too much, but it checks to see that
619
818
        # a copied block stays attached to the previous section,
620
819
        # not the later one.
621
820
        # difflib would tend to grab the trailing longest match
622
821
        # which would make the diff not look right
623
 
        chk_blocks('abcdefghijklmnop', 'abcdefxydefghijklmnop',
624
 
                   [(0, 0, 6), (6, 11, 10)])
 
822
        self.assertDiffBlocks('abcdefghijklmnop', 'abcdefxydefghijklmnop',
 
823
                              [(0, 0, 6), (6, 11, 10)])
625
824
 
626
825
        # make sure it supports passing in lists
627
 
        chk_blocks(
 
826
        self.assertDiffBlocks(
628
827
                   ['hello there\n',
629
828
                    'world\n',
630
829
                    'how are you today?\n'],
634
833
 
635
834
        # non unique lines surrounded by non-matching lines
636
835
        # won't be found
637
 
        chk_blocks('aBccDe', 'abccde', [(0,0,1), (5,5,1)])
 
836
        self.assertDiffBlocks('aBccDe', 'abccde', [(0,0,1), (5,5,1)])
638
837
 
639
838
        # But they only need to be locally unique
640
 
        chk_blocks('aBcDec', 'abcdec', [(0,0,1), (2,2,1), (4,4,2)])
 
839
        self.assertDiffBlocks('aBcDec', 'abcdec', [(0,0,1), (2,2,1), (4,4,2)])
641
840
 
642
841
        # non unique blocks won't be matched
643
 
        chk_blocks('aBcdEcdFg', 'abcdecdfg', [(0,0,1), (8,8,1)])
 
842
        self.assertDiffBlocks('aBcdEcdFg', 'abcdecdfg', [(0,0,1), (8,8,1)])
644
843
 
645
844
        # but locally unique ones will
646
 
        chk_blocks('aBcdEeXcdFg', 'abcdecdfg', [(0,0,1), (2,2,2),
 
845
        self.assertDiffBlocks('aBcdEeXcdFg', 'abcdecdfg', [(0,0,1), (2,2,2),
647
846
                                              (5,4,1), (7,5,2), (10,8,1)])
648
847
 
649
 
        chk_blocks('abbabbXd', 'cabbabxd', [(7,7,1)])
650
 
        chk_blocks('abbabbbb', 'cabbabbc', [])
651
 
        chk_blocks('bbbbbbbb', 'cbbbbbbc', [])
 
848
        self.assertDiffBlocks('abbabbXd', 'cabbabxd', [(7,7,1)])
 
849
        self.assertDiffBlocks('abbabbbb', 'cabbabbc', [])
 
850
        self.assertDiffBlocks('bbbbbbbb', 'cbbbbbbc', [])
 
851
 
 
852
    def test_matching_blocks_tuples(self):
 
853
        # Some basic matching tests
 
854
        self.assertDiffBlocks([], [], [])
 
855
        self.assertDiffBlocks([('a',), ('b',), ('c,')], [], [])
 
856
        self.assertDiffBlocks([], [('a',), ('b',), ('c,')], [])
 
857
        self.assertDiffBlocks([('a',), ('b',), ('c,')],
 
858
                              [('a',), ('b',), ('c,')],
 
859
                              [(0, 0, 3)])
 
860
        self.assertDiffBlocks([('a',), ('b',), ('c,')],
 
861
                              [('a',), ('b',), ('d,')],
 
862
                              [(0, 0, 2)])
 
863
        self.assertDiffBlocks([('d',), ('b',), ('c,')],
 
864
                              [('a',), ('b',), ('c,')],
 
865
                              [(1, 1, 2)])
 
866
        self.assertDiffBlocks([('d',), ('a',), ('b',), ('c,')],
 
867
                              [('a',), ('b',), ('c,')],
 
868
                              [(1, 0, 3)])
 
869
        self.assertDiffBlocks([('a', 'b'), ('c', 'd'), ('e', 'f')],
 
870
                              [('a', 'b'), ('c', 'X'), ('e', 'f')],
 
871
                              [(0, 0, 1), (2, 2, 1)])
 
872
        self.assertDiffBlocks([('a', 'b'), ('c', 'd'), ('e', 'f')],
 
873
                              [('a', 'b'), ('c', 'dX'), ('e', 'f')],
 
874
                              [(0, 0, 1), (2, 2, 1)])
652
875
 
653
876
    def test_opcodes(self):
654
877
        def chk_ops(a, b, expected_codes):
766
989
    def test_multiple_ranges(self):
767
990
        # There was an earlier bug where we used a bad set of ranges,
768
991
        # this triggers that specific bug, to make sure it doesn't regress
769
 
        def chk_blocks(a, b, expected_blocks):
770
 
            # difflib always adds a signature of the total
771
 
            # length, with no matching entries at the end
772
 
            s = self._PatienceSequenceMatcher(None, a, b)
773
 
            blocks = s.get_matching_blocks()
774
 
            x = blocks.pop()
775
 
            self.assertEquals(x, (len(a), len(b), 0))
776
 
            self.assertEquals(expected_blocks, blocks)
777
 
 
778
 
        chk_blocks('abcdefghijklmnop'
779
 
                 , 'abcXghiYZQRSTUVWXYZijklmnop'
780
 
                 , [(0, 0, 3), (6, 4, 3), (9, 20, 7)])
781
 
 
782
 
        chk_blocks('ABCd efghIjk  L'
783
 
                 , 'AxyzBCn mo pqrstuvwI1 2  L'
784
 
                 , [(0,0,1), (1, 4, 2), (9, 19, 1), (12, 23, 3)])
 
992
        self.assertDiffBlocks('abcdefghijklmnop',
 
993
                              'abcXghiYZQRSTUVWXYZijklmnop',
 
994
                              [(0, 0, 3), (6, 4, 3), (9, 20, 7)])
 
995
 
 
996
        self.assertDiffBlocks('ABCd efghIjk  L',
 
997
                              'AxyzBCn mo pqrstuvwI1 2  L',
 
998
                              [(0,0,1), (1, 4, 2), (9, 19, 1), (12, 23, 3)])
785
999
 
786
1000
        # These are rot13 code snippets.
787
 
        chk_blocks('''\
 
1001
        self.assertDiffBlocks('''\
788
1002
    trg nqqrq jura lbh nqq n svyr va gur qverpgbel.
789
1003
    """
790
1004
    gnxrf_netf = ['svyr*']
897
1111
        self._PatienceSequenceMatcher = \
898
1112
            bzrlib._patiencediff_c.PatienceSequenceMatcher_c
899
1113
 
 
1114
    def test_unhashable(self):
 
1115
        """We should get a proper exception here."""
 
1116
        # We need to be able to hash items in the sequence, lists are
 
1117
        # unhashable, and thus cannot be diffed
 
1118
        e = self.assertRaises(TypeError, self._PatienceSequenceMatcher,
 
1119
                                         None, [[]], [])
 
1120
        e = self.assertRaises(TypeError, self._PatienceSequenceMatcher,
 
1121
                                         None, ['valid', []], [])
 
1122
        e = self.assertRaises(TypeError, self._PatienceSequenceMatcher,
 
1123
                                         None, ['valid'], [[]])
 
1124
        e = self.assertRaises(TypeError, self._PatienceSequenceMatcher,
 
1125
                                         None, ['valid'], ['valid', []])
 
1126
 
900
1127
 
901
1128
class TestPatienceDiffLibFiles(TestCaseInTempDir):
902
1129
 
1010
1237
            from bzrlib._patiencediff_py import recurse_matches_py
1011
1238
            self.assertIs(recurse_matches_py,
1012
1239
                          bzrlib.patiencediff.recurse_matches)
 
1240
 
 
1241
 
 
1242
class TestDiffFromTool(TestCaseWithTransport):
 
1243
 
 
1244
    def test_from_string(self):
 
1245
        diff_obj = DiffFromTool.from_string('diff', None, None, None)
 
1246
        self.addCleanup(diff_obj.finish)
 
1247
        self.assertEqual(['diff', '%(old_path)s', '%(new_path)s'],
 
1248
            diff_obj.command_template)
 
1249
 
 
1250
    def test_from_string_u5(self):
 
1251
        diff_obj = DiffFromTool.from_string('diff -u\\ 5', None, None, None)
 
1252
        self.addCleanup(diff_obj.finish)
 
1253
        self.assertEqual(['diff', '-u 5', '%(old_path)s', '%(new_path)s'],
 
1254
                         diff_obj.command_template)
 
1255
        self.assertEqual(['diff', '-u 5', 'old-path', 'new-path'],
 
1256
                         diff_obj._get_command('old-path', 'new-path'))
 
1257
 
 
1258
    def test_execute(self):
 
1259
        output = StringIO()
 
1260
        diff_obj = DiffFromTool(['python', '-c',
 
1261
                                 'print "%(old_path)s %(new_path)s"'],
 
1262
                                None, None, output)
 
1263
        self.addCleanup(diff_obj.finish)
 
1264
        diff_obj._execute('old', 'new')
 
1265
        self.assertEqual(output.getvalue().rstrip(), 'old new')
 
1266
 
 
1267
    def test_excute_missing(self):
 
1268
        diff_obj = DiffFromTool(['a-tool-which-is-unlikely-to-exist'],
 
1269
                                None, None, None)
 
1270
        self.addCleanup(diff_obj.finish)
 
1271
        e = self.assertRaises(ExecutableMissing, diff_obj._execute, 'old',
 
1272
                              'new')
 
1273
        self.assertEqual('a-tool-which-is-unlikely-to-exist could not be found'
 
1274
                         ' on this machine', str(e))
 
1275
 
 
1276
    def test_prepare_files(self):
 
1277
        output = StringIO()
 
1278
        tree = self.make_branch_and_tree('tree')
 
1279
        self.build_tree_contents([('tree/oldname', 'oldcontent')])
 
1280
        tree.add('oldname', 'file-id')
 
1281
        tree.commit('old tree', timestamp=0)
 
1282
        tree.rename_one('oldname', 'newname')
 
1283
        self.build_tree_contents([('tree/newname', 'newcontent')])
 
1284
        old_tree = tree.basis_tree()
 
1285
        old_tree.lock_read()
 
1286
        self.addCleanup(old_tree.unlock)
 
1287
        tree.lock_read()
 
1288
        self.addCleanup(tree.unlock)
 
1289
        diff_obj = DiffFromTool(['python', '-c',
 
1290
                                 'print "%(old_path)s %(new_path)s"'],
 
1291
                                old_tree, tree, output)
 
1292
        self.addCleanup(diff_obj.finish)
 
1293
        self.assertContainsRe(diff_obj._root, 'bzr-diff-[^/]*')
 
1294
        old_path, new_path = diff_obj._prepare_files('file-id', 'oldname',
 
1295
                                                     'newname')
 
1296
        self.assertContainsRe(old_path, 'old/oldname$')
 
1297
        self.assertEqual(0, os.stat(old_path).st_mtime)
 
1298
        self.assertContainsRe(new_path, 'new/newname$')
 
1299
        self.assertFileEqual('oldcontent', old_path)
 
1300
        self.assertFileEqual('newcontent', new_path)
 
1301
        if osutils.has_symlinks():
 
1302
            self.assertTrue(os.path.samefile('tree/newname', new_path))
 
1303
        # make sure we can create files with the same parent directories
 
1304
        diff_obj._prepare_files('file-id', 'oldname2', 'newname2')