1
# Copyright (C) 2006 Canonical Ltd
 
 
3
# This program is free software; you can redistribute it and/or modify
 
 
4
# it under the terms of the GNU General Public License as published by
 
 
5
# the Free Software Foundation; either version 2 of the License, or
 
 
6
# (at your option) any later version.
 
 
8
# This program is distributed in the hope that it will be useful,
 
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 
11
# GNU General Public License for more details.
 
 
13
# You should have received a copy of the GNU General Public License
 
 
14
# along with this program; if not, write to the Free Software
 
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 
17
"""Tests for Tree and InterTree."""
 
 
19
from bzrlib import errors
 
 
20
from bzrlib.tests import TestCaseWithTransport
 
 
21
from bzrlib.tree import InterTree
 
 
24
class TestInterTree(TestCaseWithTransport):
 
 
26
    def test_revision_tree_revision_tree(self):
 
 
27
        # we should have an InterTree registered for RevisionTree to
 
 
29
        tree = self.make_branch_and_tree('.')
 
 
30
        rev_id = tree.commit('first post')
 
 
31
        rev_id2 = tree.commit('second post', allow_pointless=True)
 
 
32
        rev_tree = tree.branch.repository.revision_tree(rev_id)
 
 
33
        rev_tree2 = tree.branch.repository.revision_tree(rev_id2)
 
 
34
        optimiser = InterTree.get(rev_tree, rev_tree2)
 
 
35
        self.assertIsInstance(optimiser, InterTree)
 
 
36
        optimiser = InterTree.get(rev_tree2, rev_tree)
 
 
37
        self.assertIsInstance(optimiser, InterTree)
 
 
39
    def test_working_tree_revision_tree(self):
 
 
40
        # we should have an InterTree available for WorkingTree to 
 
 
42
        tree = self.make_branch_and_tree('.')
 
 
43
        rev_id = tree.commit('first post')
 
 
44
        rev_tree = tree.branch.repository.revision_tree(rev_id)
 
 
45
        optimiser = InterTree.get(rev_tree, tree)
 
 
46
        self.assertIsInstance(optimiser, InterTree)
 
 
47
        optimiser = InterTree.get(tree, rev_tree)
 
 
48
        self.assertIsInstance(optimiser, InterTree)
 
 
50
    def test_working_tree_working_tree(self):
 
 
51
        # we should have an InterTree available for WorkingTree to 
 
 
53
        tree = self.make_branch_and_tree('1')
 
 
54
        tree2 = self.make_branch_and_tree('2')
 
 
55
        optimiser = InterTree.get(tree, tree2)
 
 
56
        self.assertIsInstance(optimiser, InterTree)
 
 
57
        optimiser = InterTree.get(tree2, tree)
 
 
58
        self.assertIsInstance(optimiser, InterTree)
 
 
61
class RecordingOptimiser(InterTree):
 
 
65
    def compare(self, want_unchanged=False, specific_files=None,
 
 
66
        extra_trees=None, require_versioned=False, include_root=False,
 
 
67
        want_unversioned=False):
 
 
69
            ('compare', self.source, self.target, want_unchanged,
 
 
70
             specific_files, extra_trees, require_versioned, 
 
 
71
             include_root, want_unversioned)
 
 
75
    def is_compatible(klass, source, target):
 
 
79
class TestTree(TestCaseWithTransport):
 
 
81
    def test_compare_calls_InterTree_compare(self):
 
 
82
        """This test tests the way Tree.compare() uses InterTree."""
 
 
83
        old_optimisers = InterTree._optimisers
 
 
85
            InterTree._optimisers = []
 
 
86
            RecordingOptimiser.calls = []
 
 
87
            InterTree.register_optimiser(RecordingOptimiser)
 
 
88
            tree = self.make_branch_and_tree('1')
 
 
89
            tree2 = self.make_branch_and_tree('2')
 
 
90
            # do a series of calls:
 
 
92
            tree.changes_from(tree2)
 
 
93
            # pass in all optional arguments by position
 
 
94
            tree.changes_from(tree2, 'unchanged', 'specific', 'extra', 
 
 
96
            # pass in all optional arguments by keyword
 
 
97
            tree.changes_from(tree2,
 
 
98
                specific_files='specific',
 
 
99
                want_unchanged='unchanged',
 
 
101
                require_versioned='require',
 
 
103
                want_unversioned=True,
 
 
106
            InterTree._optimisers = old_optimisers
 
 
109
             ('compare', tree2, tree, False, None, None, False, False, False),
 
 
110
             ('compare', tree2, tree, 'unchanged', 'specific', 'extra',
 
 
111
              'require', True, False),
 
 
112
             ('compare', tree2, tree, 'unchanged', 'specific', 'extra',
 
 
113
              'require', True, True),
 
 
114
            ], RecordingOptimiser.calls)
 
 
116
    def test_changes_from_with_root(self):
 
 
117
        """Ensure the include_root option does what's expected."""
 
 
118
        wt = self.make_branch_and_tree('.')
 
 
119
        delta = wt.changes_from(wt.basis_tree())
 
 
120
        self.assertEqual(len(delta.added), 0)
 
 
121
        delta = wt.changes_from(wt.basis_tree(), wt, include_root=True)
 
 
122
        self.assertEqual(len(delta.added), 1)
 
 
123
        self.assertEqual(delta.added[0][0], '')
 
 
125
    def test_changes_from_with_require_versioned(self):
 
 
126
        """Ensure the require_versioned option does what's expected."""
 
 
127
        wt = self.make_branch_and_tree('.')
 
 
128
        self.build_tree(['known_file', 'unknown_file'])
 
 
131
        self.assertRaises(errors.PathsNotVersionedError,
 
 
132
            wt.changes_from, wt.basis_tree(), wt, specific_files=['known_file',
 
 
133
            'unknown_file'], require_versioned=True)
 
 
135
        # we need to pass a known file with an unknown file to get this to
 
 
136
        # fail when expected.
 
 
137
        delta = wt.changes_from(wt.basis_tree(), wt, 
 
 
138
            specific_files=['known_file', 'unknown_file'] ,
 
 
139
            require_versioned=False)
 
 
140
        self.assertEqual(len(delta.added), 1)