~bzr-pqm/bzr/bzr.dev

2255.7.83 by John Arbash Meinel
Update some obvious copyright headers to include 2007.
1
# Copyright (C) 2006, 2007 Canonical Ltd
1551.9.21 by Aaron Bentley
Fix copyright statements
2
#
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.
7
#
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.
12
#
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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1551.9.21 by Aaron Bentley
Fix copyright statements
16
2255.11.5 by Martin Pool
Tree.id2path should raise NoSuchId, not return None.
17
from bzrlib import (
18
    errors,
3363.13.1 by Aaron Bentley
Implement PreviewTree.extras
19
    conflicts,
3363.15.4 by Aaron Bentley
Implement PreviewTree.get_file_sha1 properly
20
    osutils,
3363.13.1 by Aaron Bentley
Implement PreviewTree.extras
21
    revisiontree,
2255.2.180 by Martin Pool
merge dirstate
22
    tests,
3363.13.1 by Aaron Bentley
Implement PreviewTree.extras
23
    workingtree_4,
2255.11.5 by Martin Pool
Tree.id2path should raise NoSuchId, not return None.
24
    )
2338.4.4 by Marien Zwart
Increase test coverage.
25
from bzrlib.tests import TestSkipped
4523.1.4 by Martin Pool
Rename remaining *_implementations tests
26
from bzrlib.tests.per_tree import TestCaseWithTree
5967.7.1 by Martin Pool
Deprecate __contains__ on Tree and Inventory
27
from bzrlib.symbol_versioning import (
28
    deprecated_in,
29
    )
30
1551.9.16 by Aaron Bentley
Implement Tree.annotate_iter for RevisionTree and WorkingTree
31
32
class TestAnnotate(TestCaseWithTree):
2255.2.69 by John Arbash Meinel
Implement annotate_iter, get_revision_id, and walkdirs so that all tree_implementations now pass
33
1551.9.16 by Aaron Bentley
Implement Tree.annotate_iter for RevisionTree and WorkingTree
34
    def test_annotate(self):
35
        work_tree = self.make_branch_and_tree('wt')
36
        tree = self.get_tree_no_parents_abc_content(work_tree)
37
        tree_revision = getattr(tree, 'get_revision_id', lambda: 'current:')()
2255.2.69 by John Arbash Meinel
Implement annotate_iter, get_revision_id, and walkdirs so that all tree_implementations now pass
38
        tree.lock_read()
1551.15.48 by Aaron Bentley
Add tests for annotate and plan_merge
39
        self.addCleanup(tree.unlock)
40
        for revision, line in tree.annotate_iter('a-id'):
41
            self.assertEqual('contents of a\n', line)
42
            self.assertEqual(tree_revision, revision)
43
        tree_revision = getattr(tree, 'get_revision_id', lambda: 'random:')()
44
        for revision, line in tree.annotate_iter('a-id', 'random:'):
45
            self.assertEqual('contents of a\n', line)
46
            self.assertEqual(tree_revision, revision)
47
48
1551.15.52 by Aaron Bentley
Tweak from review comments
49
class TestPlanFileMerge(TestCaseWithTree):
1551.15.48 by Aaron Bentley
Add tests for annotate and plan_merge
50
1551.15.52 by Aaron Bentley
Tweak from review comments
51
    def test_plan_file_merge(self):
1551.15.48 by Aaron Bentley
Add tests for annotate and plan_merge
52
        work_a = self.make_branch_and_tree('wta')
53
        self.build_tree_contents([('wta/file', 'a\nb\nc\nd\n')])
54
        work_a.add('file', 'file-id')
55
        work_a.commit('base version')
56
        work_b = work_a.bzrdir.sprout('wtb').open_workingtree()
57
        self.build_tree_contents([('wta/file', 'b\nc\nd\ne\n')])
58
        tree_a = self.workingtree_to_test_tree(work_a)
59
        tree_a.lock_read()
60
        self.addCleanup(tree_a.unlock)
61
        self.build_tree_contents([('wtb/file', 'a\nc\nd\nf\n')])
62
        tree_b = self.workingtree_to_test_tree(work_b)
63
        tree_b.lock_read()
64
        self.addCleanup(tree_b.unlock)
65
        self.assertEqual([
3514.2.3 by John Arbash Meinel
Fix a failing test in tree_implementations
66
            ('killed-a', 'a\n'),
1551.15.48 by Aaron Bentley
Add tests for annotate and plan_merge
67
            ('killed-b', 'b\n'),
68
            ('unchanged', 'c\n'),
69
            ('unchanged', 'd\n'),
70
            ('new-a', 'e\n'),
71
            ('new-b', 'f\n'),
1551.15.52 by Aaron Bentley
Tweak from review comments
72
        ], list(tree_a.plan_file_merge('file-id', tree_b)))
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
73
74
75
class TestReference(TestCaseWithTree):
76
77
    def skip_if_no_reference(self, tree):
78
        if not getattr(tree, 'supports_tree_reference', lambda: False)():
3504.2.1 by John Arbash Meinel
Shortcut iter_references when we know references aren't supported.
79
            raise tests.TestNotApplicable('Tree references not supported')
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
80
2100.3.27 by Aaron Bentley
Enable nested commits
81
    def create_nested(self):
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
82
        work_tree = self.make_branch_and_tree('wt')
2255.2.158 by Martin Pool
Most of the integration of dirstate and subtree
83
        work_tree.lock_write()
84
        try:
85
            self.skip_if_no_reference(work_tree)
86
            subtree = self.make_branch_and_tree('wt/subtree')
87
            subtree.set_root_id('sub-root')
88
            subtree.commit('foo', rev_id='sub-1')
89
            work_tree.add_reference(subtree)
90
        finally:
91
            work_tree.unlock()
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
92
        tree = self._convert_tree(work_tree)
93
        self.skip_if_no_reference(tree)
2100.3.27 by Aaron Bentley
Enable nested commits
94
        return tree
95
96
    def test_get_reference_revision(self):
97
        tree = self.create_nested()
3504.2.1 by John Arbash Meinel
Shortcut iter_references when we know references aren't supported.
98
        tree.lock_read()
99
        self.addCleanup(tree.unlock)
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
100
        path = tree.id2path('sub-root')
5967.7.1 by Martin Pool
Deprecate __contains__ on Tree and Inventory
101
        self.assertEqual('sub-1',
102
            tree.get_reference_revision('sub-root', path))
2100.3.27 by Aaron Bentley
Enable nested commits
103
2255.2.226 by Robert Collins
Get merge_nested finally working: change nested tree iterators to take file_ids, and ensure the right branch is connected to in the merge logic. May not be suitable for shared repositories yet.
104
    def test_iter_references(self):
2100.3.27 by Aaron Bentley
Enable nested commits
105
        tree = self.create_nested()
2255.2.158 by Martin Pool
Most of the integration of dirstate and subtree
106
        tree.lock_read()
2255.2.226 by Robert Collins
Get merge_nested finally working: change nested tree iterators to take file_ids, and ensure the right branch is connected to in the merge logic. May not be suitable for shared repositories yet.
107
        self.addCleanup(tree.unlock)
108
        entry = tree.inventory['sub-root']
3504.2.1 by John Arbash Meinel
Shortcut iter_references when we know references aren't supported.
109
        self.assertEqual([(u'subtree', 'sub-root')],
2255.2.226 by Robert Collins
Get merge_nested finally working: change nested tree iterators to take file_ids, and ensure the right branch is connected to in the merge logic. May not be suitable for shared repositories yet.
110
            list(tree.iter_references()))
2255.2.166 by Martin Pool
(broken) Add Tree.get_root_id() & test
111
112
    def test_get_root_id(self):
113
        # trees should return some kind of root id; it can be none
114
        tree = self.make_branch_and_tree('tree')
115
        root_id = tree.get_root_id()
116
        if root_id is not None:
117
            self.assertIsInstance(root_id, str)
2255.2.180 by Martin Pool
merge dirstate
118
119
2255.11.5 by Martin Pool
Tree.id2path should raise NoSuchId, not return None.
120
class TestFileIds(TestCaseWithTree):
121
122
    def test_id2path(self):
123
        # translate from file-id back to path
124
        work_tree = self.make_branch_and_tree('wt')
125
        tree = self.get_tree_no_parents_abc_content(work_tree)
126
        tree.lock_read()
127
        try:
128
            self.assertEqual(u'a', tree.id2path('a-id'))
129
            # other ids give an error- don't return None for this case
130
            self.assertRaises(errors.NoSuchId, tree.id2path, 'a')
131
        finally:
132
            tree.unlock()
2708.1.1 by Aaron Bentley
Implement Tree.extract_files
133
3146.8.16 by Aaron Bentley
Updates from review
134
    def test_all_file_ids(self):
3146.8.2 by Aaron Bentley
Introduce iter_all_file_ids, to avoid hitting Inventory for this case
135
        work_tree = self.make_branch_and_tree('wt')
136
        tree = self.get_tree_no_parents_abc_content(work_tree)
137
        tree.lock_read()
138
        self.addCleanup(tree.unlock)
3146.8.16 by Aaron Bentley
Updates from review
139
        self.assertEqual(tree.all_file_ids(),
3146.8.2 by Aaron Bentley
Introduce iter_all_file_ids, to avoid hitting Inventory for this case
140
                         set(['b-id', 'root-id', 'c-id', 'a-id']))
141
2708.1.1 by Aaron Bentley
Implement Tree.extract_files
142
3146.8.4 by Aaron Bentley
Eliminate direct use of inventory from transform application
143
class TestStoredKind(TestCaseWithTree):
144
145
    def test_stored_kind(self):
146
        tree = self.make_branch_and_tree('tree')
147
        work_tree = self.make_branch_and_tree('wt')
148
        tree = self.get_tree_no_parents_abc_content(work_tree)
149
        tree.lock_read()
150
        self.addCleanup(tree.unlock)
151
        self.assertEqual('file', tree.stored_kind('a-id'))
152
        self.assertEqual('directory', tree.stored_kind('b-id'))
153
154
2743.3.5 by Ian Clatworthy
Incorporate feedback from abentley
155
class TestFileContent(TestCaseWithTree):
156
157
    def test_get_file(self):
158
        work_tree = self.make_branch_and_tree('wt')
159
        tree = self.get_tree_no_parents_abc_content_2(work_tree)
160
        tree.lock_read()
161
        try:
162
            # Test lookup without path works
163
            lines = tree.get_file('a-id').readlines()
164
            self.assertEqual(['foobar\n'], lines)
165
            # Test lookup with path works
166
            lines = tree.get_file('a-id', path='a').readlines()
167
            self.assertEqual(['foobar\n'], lines)
168
        finally:
169
            tree.unlock()
170
3774.1.1 by Aaron Bentley
Test Tree.get_file_text() and supply default implementation.
171
    def test_get_file_text(self):
172
        work_tree = self.make_branch_and_tree('wt')
173
        tree = self.get_tree_no_parents_abc_content_2(work_tree)
174
        tree.lock_read()
175
        self.addCleanup(tree.unlock)
176
        # test read by file-id
177
        self.assertEqual('foobar\n', tree.get_file_text('a-id'))
178
        # test read by path
179
        self.assertEqual('foobar\n', tree.get_file_text('a-id', path='a'))
180
3774.1.2 by Aaron Bentley
Test Tree.get_file_lines, provide a default implementation
181
    def test_get_file_lines(self):
182
        work_tree = self.make_branch_and_tree('wt')
183
        tree = self.get_tree_no_parents_abc_content_2(work_tree)
184
        tree.lock_read()
185
        self.addCleanup(tree.unlock)
186
        # test read by file-id
187
        self.assertEqual(['foobar\n'], tree.get_file_lines('a-id'))
188
        # test read by path
189
        self.assertEqual(['foobar\n'], tree.get_file_lines('a-id', path='a'))
2743.3.5 by Ian Clatworthy
Incorporate feedback from abentley
190
3774.1.4 by Aaron Bentley
Use file.readlines on working trees.
191
    def test_get_file_lines_multi_line_breaks(self):
192
        work_tree = self.make_branch_and_tree('wt')
193
        self.build_tree_contents([('wt/foobar', 'a\rb\nc\r\nd')])
194
        work_tree.add('foobar', 'foobar-id')
195
        tree = self._convert_tree(work_tree)
196
        tree.lock_read()
197
        self.addCleanup(tree.unlock)
198
        self.assertEqual(['a\rb\n', 'c\r\n', 'd'],
199
                         tree.get_file_lines('foobar-id'))
200
201
2708.1.1 by Aaron Bentley
Implement Tree.extract_files
202
class TestExtractFilesBytes(TestCaseWithTree):
203
2708.1.7 by Aaron Bentley
Rename extract_files_bytes to iter_files_bytes
204
    def test_iter_files_bytes(self):
2708.1.1 by Aaron Bentley
Implement Tree.extract_files
205
        work_tree = self.make_branch_and_tree('wt')
206
        self.build_tree_contents([('wt/foo', 'foo'),
207
                                  ('wt/bar', 'bar'),
208
                                  ('wt/baz', 'baz')])
209
        work_tree.add(['foo', 'bar', 'baz'], ['foo-id', 'bar-id', 'baz-id'])
210
        tree = self._convert_tree(work_tree)
211
        tree.lock_read()
212
        self.addCleanup(tree.unlock)
2708.1.6 by Aaron Bentley
Turn extract_files_bytes into an iterator
213
        extracted = dict((i, ''.join(b)) for i, b in
2708.1.7 by Aaron Bentley
Rename extract_files_bytes to iter_files_bytes
214
                         tree.iter_files_bytes([('foo-id', 'id1'),
215
                                                ('bar-id', 'id2'),
216
                                                ('baz-id', 'id3')]))
2708.1.6 by Aaron Bentley
Turn extract_files_bytes into an iterator
217
        self.assertEqual('foo', extracted['id1'])
218
        self.assertEqual('bar', extracted['id2'])
219
        self.assertEqual('baz', extracted['id3'])
2708.1.11 by Aaron Bentley
Test and tweak error handling
220
        self.assertRaises(errors.NoSuchId, lambda: list(
221
                          tree.iter_files_bytes(
222
                          [('qux-id', 'file1-notpresent')])))
2748.2.2 by Lukáš Lalinsky
Add TestConflicts to tests.tree_implementations.test_tree. Update NEWS.
223
224
225
class TestConflicts(TestCaseWithTree):
226
227
    def test_conflicts(self):
228
        """Tree.conflicts() should return a ConflictList instance."""
229
        work_tree = self.make_branch_and_tree('wt')
230
        tree = self._convert_tree(work_tree)
2761.1.3 by Aaron Bentley
Update test to use assertIsInstance
231
        self.assertIsInstance(tree.conflicts(), conflicts.ConflictList)
3363.5.4 by Aaron Bentley
Fix iteration order of iter_entries_by_dir
232
233
234
class TestIterEntriesByDir(TestCaseWithTree):
235
236
    def test_iteration_order(self):
237
        work_tree = self.make_branch_and_tree('.')
238
        self.build_tree(['a/', 'a/b/', 'a/b/c', 'a/d/', 'a/d/e', 'f/', 'f/g'])
239
        work_tree.add(['a', 'a/b', 'a/b/c', 'a/d', 'a/d/e', 'f', 'f/g'])
240
        tree = self._convert_tree(work_tree)
241
        output_order = [p for p, e in tree.iter_entries_by_dir()]
242
        self.assertEqual(['', 'a', 'f', 'a/b', 'a/d', 'a/b/c', 'a/d/e', 'f/g'],
243
                         output_order)
3363.13.1 by Aaron Bentley
Implement PreviewTree.extras
244
245
3363.12.7 by Aaron Bentley
Add HasId test
246
class TestHasId(TestCaseWithTree):
247
248
    def test_has_id(self):
249
        work_tree = self.make_branch_and_tree('tree')
250
        self.build_tree(['tree/file'])
251
        work_tree.add('file', 'file-id')
252
        tree = self._convert_tree(work_tree)
253
        tree.lock_read()
254
        self.addCleanup(tree.unlock)
255
        self.assertTrue(tree.has_id('file-id'))
256
        self.assertFalse(tree.has_id('dir-id'))
3363.13.5 by Aaron Bentley
Merge with paths2ids
257
3363.16.6 by Aaron Bentley
Fix redundant test classes
258
    def test___contains__(self):
259
        work_tree = self.make_branch_and_tree('tree')
260
        self.build_tree(['tree/file'])
261
        work_tree.add('file', 'file-id')
262
        tree = self._convert_tree(work_tree)
263
        tree.lock_read()
264
        self.addCleanup(tree.unlock)
5967.7.1 by Martin Pool
Deprecate __contains__ on Tree and Inventory
265
        self.assertTrue(
266
            self.applyDeprecated(
267
                deprecated_in((2, 4, 0)),
268
                tree.__contains__, 'file-id'))
269
        self.assertFalse(
270
            self.applyDeprecated(
271
                deprecated_in((2, 4, 0)),
272
                tree.__contains__, 'dir-id'))
3363.16.6 by Aaron Bentley
Fix redundant test classes
273
3363.13.5 by Aaron Bentley
Merge with paths2ids
274
3363.13.1 by Aaron Bentley
Implement PreviewTree.extras
275
class TestExtras(TestCaseWithTree):
276
277
    def test_extras(self):
278
        work_tree = self.make_branch_and_tree('tree')
3363.13.4 by Aaron Bentley
Ensure versioned files are not listed by extras
279
        self.build_tree(['tree/file', 'tree/versioned-file'])
280
        work_tree.add(['file', 'versioned-file'])
281
        work_tree.commit('add files')
3363.13.1 by Aaron Bentley
Implement PreviewTree.extras
282
        work_tree.remove('file')
283
        tree = self._convert_tree(work_tree)
284
        if isinstance(tree,
285
                      (revisiontree.RevisionTree,
286
                       workingtree_4.DirStateRevisionTree)):
287
            expected = []
288
        else:
289
            expected = ['file']
290
        tree.lock_read()
291
        self.addCleanup(tree.unlock)
292
        self.assertEqual(expected, list(tree.extras()))
3363.15.1 by Aaron Bentley
Add test for has_id
293
3363.17.3 by Aaron Bentley
Merge with has_id
294
3363.15.4 by Aaron Bentley
Implement PreviewTree.get_file_sha1 properly
295
class TestGetFileSha1(TestCaseWithTree):
296
297
    def test_get_file_sha1(self):
298
        work_tree = self.make_branch_and_tree('tree')
299
        self.build_tree_contents([('tree/file', 'file content')])
300
        work_tree.add('file', 'file-id')
301
        tree = self._convert_tree(work_tree)
302
        tree.lock_read()
303
        self.addCleanup(tree.unlock)
304
        expected = osutils.sha_strings('file content')
305
        self.assertEqual(expected, tree.get_file_sha1('file-id'))