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