1
# Copyright (C) 2006-2009, 2011 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
"""Tests for Tree and InterTree."""
24
from breezy.tests import (
26
TestCaseWithTransport,
28
from breezy.tree import (
29
FileTimestampUnavailable,
36
class TestErrors(TestCase):
38
def test_file_timestamp_unavailable(self):
39
e = FileTimestampUnavailable("/path/foo")
40
self.assertEqual("The filestamp for /path/foo is not available.",
44
class TestInterTree(TestCaseWithTransport):
46
def test_revision_tree_revision_tree(self):
47
# we should have an InterTree registered for RevisionTree to
49
tree = self.make_branch_and_tree('.')
50
rev_id = tree.commit('first post')
51
rev_id2 = tree.commit('second post', allow_pointless=True)
52
rev_tree = tree.branch.repository.revision_tree(rev_id)
53
rev_tree2 = tree.branch.repository.revision_tree(rev_id2)
54
optimiser = InterTree.get(rev_tree, rev_tree2)
55
self.assertIsInstance(optimiser, InterTree)
56
optimiser = InterTree.get(rev_tree2, rev_tree)
57
self.assertIsInstance(optimiser, InterTree)
59
def test_working_tree_revision_tree(self):
60
# we should have an InterTree available for WorkingTree to
62
tree = self.make_branch_and_tree('.')
63
rev_id = tree.commit('first post')
64
rev_tree = tree.branch.repository.revision_tree(rev_id)
65
optimiser = InterTree.get(rev_tree, tree)
66
self.assertIsInstance(optimiser, InterTree)
67
optimiser = InterTree.get(tree, rev_tree)
68
self.assertIsInstance(optimiser, InterTree)
70
def test_working_tree_working_tree(self):
71
# we should have an InterTree available for WorkingTree to
73
tree = self.make_branch_and_tree('1')
74
tree2 = self.make_branch_and_tree('2')
75
optimiser = InterTree.get(tree, tree2)
76
self.assertIsInstance(optimiser, InterTree)
77
optimiser = InterTree.get(tree2, tree)
78
self.assertIsInstance(optimiser, InterTree)
81
class RecordingOptimiser(InterTree):
85
def compare(self, want_unchanged=False, specific_files=None,
86
extra_trees=None, require_versioned=False, include_root=False,
87
want_unversioned=False):
89
('compare', self.source, self.target, want_unchanged,
90
specific_files, extra_trees, require_versioned,
91
include_root, want_unversioned)
95
def is_compatible(klass, source, target):
99
class TestTree(TestCaseWithTransport):
101
def test_compare_calls_InterTree_compare(self):
102
"""This test tests the way Tree.compare() uses InterTree."""
103
old_optimisers = InterTree._optimisers
105
InterTree._optimisers = []
106
RecordingOptimiser.calls = []
107
InterTree.register_optimiser(RecordingOptimiser)
108
tree = self.make_branch_and_tree('1')
109
tree2 = self.make_branch_and_tree('2')
110
# do a series of calls:
112
tree.changes_from(tree2)
113
# pass in all optional arguments by position
114
tree.changes_from(tree2, 'unchanged', 'specific', 'extra',
116
# pass in all optional arguments by keyword
117
tree.changes_from(tree2,
118
specific_files='specific',
119
want_unchanged='unchanged',
121
require_versioned='require',
123
want_unversioned=True,
126
InterTree._optimisers = old_optimisers
129
('compare', tree2, tree, False, None, None, False, False,
131
('compare', tree2, tree, 'unchanged', 'specific', 'extra',
132
'require', True, False),
133
('compare', tree2, tree, 'unchanged', 'specific', 'extra',
134
'require', True, True),
135
], RecordingOptimiser.calls)
137
def test_changes_from_with_root(self):
138
"""Ensure the include_root option does what's expected."""
139
wt = self.make_branch_and_tree('.')
140
delta = wt.changes_from(wt.basis_tree())
141
self.assertEqual(len(delta.added), 0)
142
delta = wt.changes_from(wt.basis_tree(), include_root=True)
143
self.assertEqual(len(delta.added), 1)
144
self.assertEqual(delta.added[0].path[1], '')
146
def test_changes_from_with_require_versioned(self):
147
"""Ensure the require_versioned option does what's expected."""
148
wt = self.make_branch_and_tree('.')
149
self.build_tree(['known_file', 'unknown_file'])
153
errors.PathsNotVersionedError,
154
wt.changes_from, wt.basis_tree(), wt,
155
specific_files=['known_file', 'unknown_file'],
156
require_versioned=True)
158
# we need to pass a known file with an unknown file to get this to
159
# fail when expected.
160
delta = wt.changes_from(wt.basis_tree(),
161
specific_files=['known_file', 'unknown_file'],
162
require_versioned=False)
163
self.assertEqual(len(delta.added), 1)
166
class FindPreviousPathsTests(TestCaseWithTransport):
169
tree = self.make_branch_and_tree('tree')
170
self.build_tree(['tree/b'])
172
revid1 = tree.commit('first')
173
tree1 = tree.branch.repository.revision_tree(revid1)
175
tree0 = tree.branch.repository.revision_tree(revision.NULL_REVISION)
177
self.assertEqual({'b': None}, find_previous_paths(tree1, tree0, ['b']))
179
def test_find_previous_paths(self):
180
tree = self.make_branch_and_tree('tree')
181
self.build_tree(['tree/b'])
183
revid1 = tree.commit('first')
184
tree1 = tree.branch.repository.revision_tree(revid1)
186
tree.rename_one('b', 'c')
187
self.build_tree(['tree/b'])
189
revid2 = tree.commit('second')
190
tree2 = tree.branch.repository.revision_tree(revid2)
192
self.assertEqual({'c': 'b', 'b': None},
193
find_previous_paths(tree2, tree1, ['b', 'c']))
196
class GetCanonicalPath(TestCaseWithTransport):
198
def test_existing_case(self):
199
# Test that we can find a file from a path with different case
200
tree = self.make_branch_and_tree('tree')
201
self.build_tree(['tree/b'])
205
get_canonical_path(tree, 'b', lambda x: x.lower()))
208
get_canonical_path(tree, 'B', lambda x: x.lower()))
210
def test_nonexistant_preserves_case(self):
211
tree = self.make_branch_and_tree('tree')
214
get_canonical_path(tree, 'b', lambda x: x.lower()))
217
get_canonical_path(tree, 'B', lambda x: x.lower()))
219
def test_in_directory_with_case(self):
220
tree = self.make_branch_and_tree('tree')
221
self.build_tree(['tree/a/', 'tree/a/b'])
222
tree.add(['a', 'a/b'])
225
get_canonical_path(tree, 'a/b', lambda x: x.lower()))
228
get_canonical_path(tree, 'A/B', lambda x: x.lower()))
231
get_canonical_path(tree, 'A/b', lambda x: x.lower()))
234
get_canonical_path(tree, 'A/C', lambda x: x.lower()))