~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
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
2255.11.5 by Martin Pool
Tree.id2path should raise NoSuchId, not return None.
17
from bzrlib import (
18
    errors,
2255.2.180 by Martin Pool
merge dirstate
19
    tests,
2748.2.2 by Lukáš Lalinsky
Add TestConflicts to tests.tree_implementations.test_tree. Update NEWS.
20
    conflicts,
2255.11.5 by Martin Pool
Tree.id2path should raise NoSuchId, not return None.
21
    )
2338.4.4 by Marien Zwart
Increase test coverage.
22
from bzrlib.tests import TestSkipped
1551.9.16 by Aaron Bentley
Implement Tree.annotate_iter for RevisionTree and WorkingTree
23
from bzrlib.tests.tree_implementations import TestCaseWithTree
24
25
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
26
1551.9.16 by Aaron Bentley
Implement Tree.annotate_iter for RevisionTree and WorkingTree
27
    def test_annotate(self):
28
        work_tree = self.make_branch_and_tree('wt')
29
        tree = self.get_tree_no_parents_abc_content(work_tree)
30
        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
31
        tree.lock_read()
1551.15.48 by Aaron Bentley
Add tests for annotate and plan_merge
32
        self.addCleanup(tree.unlock)
33
        for revision, line in tree.annotate_iter('a-id'):
34
            self.assertEqual('contents of a\n', line)
35
            self.assertEqual(tree_revision, revision)
36
        tree_revision = getattr(tree, 'get_revision_id', lambda: 'random:')()
37
        for revision, line in tree.annotate_iter('a-id', 'random:'):
38
            self.assertEqual('contents of a\n', line)
39
            self.assertEqual(tree_revision, revision)
40
41
1551.15.52 by Aaron Bentley
Tweak from review comments
42
class TestPlanFileMerge(TestCaseWithTree):
1551.15.48 by Aaron Bentley
Add tests for annotate and plan_merge
43
1551.15.52 by Aaron Bentley
Tweak from review comments
44
    def test_plan_file_merge(self):
1551.15.48 by Aaron Bentley
Add tests for annotate and plan_merge
45
        work_a = self.make_branch_and_tree('wta')
46
        self.build_tree_contents([('wta/file', 'a\nb\nc\nd\n')])
47
        work_a.add('file', 'file-id')
48
        work_a.commit('base version')
49
        work_b = work_a.bzrdir.sprout('wtb').open_workingtree()
50
        self.build_tree_contents([('wta/file', 'b\nc\nd\ne\n')])
51
        tree_a = self.workingtree_to_test_tree(work_a)
52
        tree_a.lock_read()
53
        self.addCleanup(tree_a.unlock)
54
        self.build_tree_contents([('wtb/file', 'a\nc\nd\nf\n')])
55
        tree_b = self.workingtree_to_test_tree(work_b)
56
        tree_b.lock_read()
57
        self.addCleanup(tree_b.unlock)
58
        self.assertEqual([
59
            ('killed-b', 'b\n'),
60
            ('killed-a', 'a\n'),
61
            ('unchanged', 'c\n'),
62
            ('unchanged', 'd\n'),
63
            ('new-a', 'e\n'),
64
            ('new-b', 'f\n'),
1551.15.52 by Aaron Bentley
Tweak from review comments
65
        ], list(tree_a.plan_file_merge('file-id', tree_b)))
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
66
67
68
class TestReference(TestCaseWithTree):
69
70
    def skip_if_no_reference(self, tree):
71
        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.
72
            raise tests.TestNotApplicable('Tree references not supported')
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
73
2100.3.27 by Aaron Bentley
Enable nested commits
74
    def create_nested(self):
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
75
        work_tree = self.make_branch_and_tree('wt')
2255.2.158 by Martin Pool
Most of the integration of dirstate and subtree
76
        work_tree.lock_write()
77
        try:
78
            self.skip_if_no_reference(work_tree)
79
            subtree = self.make_branch_and_tree('wt/subtree')
80
            subtree.set_root_id('sub-root')
81
            subtree.commit('foo', rev_id='sub-1')
82
            work_tree.add_reference(subtree)
83
        finally:
84
            work_tree.unlock()
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
85
        tree = self._convert_tree(work_tree)
86
        self.skip_if_no_reference(tree)
2100.3.27 by Aaron Bentley
Enable nested commits
87
        return tree
88
89
    def test_get_reference_revision(self):
90
        tree = self.create_nested()
3504.2.1 by John Arbash Meinel
Shortcut iter_references when we know references aren't supported.
91
        tree.lock_read()
92
        self.addCleanup(tree.unlock)
2100.3.20 by Aaron Bentley
Implement tree comparison for tree references
93
        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.
94
        self.assertEqual('sub-1', tree.get_reference_revision('sub-root', path))
2100.3.27 by Aaron Bentley
Enable nested commits
95
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.
96
    def test_iter_references(self):
2100.3.27 by Aaron Bentley
Enable nested commits
97
        tree = self.create_nested()
2255.2.158 by Martin Pool
Most of the integration of dirstate and subtree
98
        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.
99
        self.addCleanup(tree.unlock)
100
        entry = tree.inventory['sub-root']
3504.2.1 by John Arbash Meinel
Shortcut iter_references when we know references aren't supported.
101
        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.
102
            list(tree.iter_references()))
2255.2.166 by Martin Pool
(broken) Add Tree.get_root_id() & test
103
104
    def test_get_root_id(self):
105
        # trees should return some kind of root id; it can be none
106
        tree = self.make_branch_and_tree('tree')
107
        root_id = tree.get_root_id()
108
        if root_id is not None:
109
            self.assertIsInstance(root_id, str)
2255.2.180 by Martin Pool
merge dirstate
110
111
2255.11.5 by Martin Pool
Tree.id2path should raise NoSuchId, not return None.
112
class TestFileIds(TestCaseWithTree):
113
114
    def test_id2path(self):
115
        # translate from file-id back to path
116
        work_tree = self.make_branch_and_tree('wt')
117
        tree = self.get_tree_no_parents_abc_content(work_tree)
118
        tree.lock_read()
119
        try:
120
            self.assertEqual(u'a', tree.id2path('a-id'))
121
            # other ids give an error- don't return None for this case
122
            self.assertRaises(errors.NoSuchId, tree.id2path, 'a')
123
        finally:
124
            tree.unlock()
2708.1.1 by Aaron Bentley
Implement Tree.extract_files
125
3146.8.16 by Aaron Bentley
Updates from review
126
    def test_all_file_ids(self):
3146.8.2 by Aaron Bentley
Introduce iter_all_file_ids, to avoid hitting Inventory for this case
127
        work_tree = self.make_branch_and_tree('wt')
128
        tree = self.get_tree_no_parents_abc_content(work_tree)
129
        tree.lock_read()
130
        self.addCleanup(tree.unlock)
3146.8.16 by Aaron Bentley
Updates from review
131
        self.assertEqual(tree.all_file_ids(),
3146.8.2 by Aaron Bentley
Introduce iter_all_file_ids, to avoid hitting Inventory for this case
132
                         set(['b-id', 'root-id', 'c-id', 'a-id']))
133
2708.1.1 by Aaron Bentley
Implement Tree.extract_files
134
3146.8.4 by Aaron Bentley
Eliminate direct use of inventory from transform application
135
class TestStoredKind(TestCaseWithTree):
136
137
    def test_stored_kind(self):
138
        tree = self.make_branch_and_tree('tree')
139
        work_tree = self.make_branch_and_tree('wt')
140
        tree = self.get_tree_no_parents_abc_content(work_tree)
141
        tree.lock_read()
142
        self.addCleanup(tree.unlock)
143
        self.assertEqual('file', tree.stored_kind('a-id'))
144
        self.assertEqual('directory', tree.stored_kind('b-id'))
145
146
2743.3.5 by Ian Clatworthy
Incorporate feedback from abentley
147
class TestFileContent(TestCaseWithTree):
148
149
    def test_get_file(self):
150
        work_tree = self.make_branch_and_tree('wt')
151
        tree = self.get_tree_no_parents_abc_content_2(work_tree)
152
        tree.lock_read()
153
        try:
154
            # Test lookup without path works
155
            lines = tree.get_file('a-id').readlines()
156
            self.assertEqual(['foobar\n'], lines)
157
            # Test lookup with path works
158
            lines = tree.get_file('a-id', path='a').readlines()
159
            self.assertEqual(['foobar\n'], lines)
160
        finally:
161
            tree.unlock()
162
163
2708.1.1 by Aaron Bentley
Implement Tree.extract_files
164
class TestExtractFilesBytes(TestCaseWithTree):
165
2708.1.7 by Aaron Bentley
Rename extract_files_bytes to iter_files_bytes
166
    def test_iter_files_bytes(self):
2708.1.1 by Aaron Bentley
Implement Tree.extract_files
167
        work_tree = self.make_branch_and_tree('wt')
168
        self.build_tree_contents([('wt/foo', 'foo'),
169
                                  ('wt/bar', 'bar'),
170
                                  ('wt/baz', 'baz')])
171
        work_tree.add(['foo', 'bar', 'baz'], ['foo-id', 'bar-id', 'baz-id'])
172
        tree = self._convert_tree(work_tree)
173
        tree.lock_read()
174
        self.addCleanup(tree.unlock)
2708.1.6 by Aaron Bentley
Turn extract_files_bytes into an iterator
175
        extracted = dict((i, ''.join(b)) for i, b in
2708.1.7 by Aaron Bentley
Rename extract_files_bytes to iter_files_bytes
176
                         tree.iter_files_bytes([('foo-id', 'id1'),
177
                                                ('bar-id', 'id2'),
178
                                                ('baz-id', 'id3')]))
2708.1.6 by Aaron Bentley
Turn extract_files_bytes into an iterator
179
        self.assertEqual('foo', extracted['id1'])
180
        self.assertEqual('bar', extracted['id2'])
181
        self.assertEqual('baz', extracted['id3'])
2708.1.11 by Aaron Bentley
Test and tweak error handling
182
        self.assertRaises(errors.NoSuchId, lambda: list(
183
                          tree.iter_files_bytes(
184
                          [('qux-id', 'file1-notpresent')])))
2748.2.2 by Lukáš Lalinsky
Add TestConflicts to tests.tree_implementations.test_tree. Update NEWS.
185
186
187
class TestConflicts(TestCaseWithTree):
188
189
    def test_conflicts(self):
190
        """Tree.conflicts() should return a ConflictList instance."""
191
        work_tree = self.make_branch_and_tree('wt')
192
        tree = self._convert_tree(work_tree)
2761.1.3 by Aaron Bentley
Update test to use assertIsInstance
193
        self.assertIsInstance(tree.conflicts(), conflicts.ConflictList)
3363.5.4 by Aaron Bentley
Fix iteration order of iter_entries_by_dir
194
195
196
class TestIterEntriesByDir(TestCaseWithTree):
197
198
    def test_iteration_order(self):
199
        work_tree = self.make_branch_and_tree('.')
200
        self.build_tree(['a/', 'a/b/', 'a/b/c', 'a/d/', 'a/d/e', 'f/', 'f/g'])
201
        work_tree.add(['a', 'a/b', 'a/b/c', 'a/d', 'a/d/e', 'f', 'f/g'])
202
        tree = self._convert_tree(work_tree)
203
        output_order = [p for p, e in tree.iter_entries_by_dir()]
204
        self.assertEqual(['', 'a', 'f', 'a/b', 'a/d', 'a/b/c', 'a/d/e', 'f/g'],
205
                         output_order)