~bzr-pqm/bzr/bzr.dev

2729.2.9 by Martin Pool
Move actual tests from inventory_implementations __init__ into basics.py (Aaron)
1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
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
2729.2.9 by Martin Pool
Move actual tests from inventory_implementations __init__ into basics.py (Aaron)
16
17
"""Tests for different inventory implementations"""
18
19
# NOTE: Don't import Inventory here, to make sure that we don't accidentally
20
# hardcode that when we should be using self.make_inventory
21
22
from bzrlib import (
23
        errors,
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
24
        inventory,
25
        osutils,
2729.2.9 by Martin Pool
Move actual tests from inventory_implementations __init__ into basics.py (Aaron)
26
        )
27
28
from bzrlib.inventory import (
29
        InventoryDirectory,
30
        InventoryEntry,
31
        InventoryFile,
32
        InventoryLink,
33
        TreeReference,
34
        )
35
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
36
from bzrlib.tests.per_inventory import TestCaseWithInventory
37
38
39
40
class TestInventory(TestCaseWithInventory):
41
42
    def make_init_inventory(self):
43
        inv = inventory.Inventory('tree-root')
44
        inv.revision = 'initial-rev'
45
        inv.root.revision = 'initial-rev'
46
        return self.inv_to_test_inv(inv)
47
48
    def make_file(self, file_id, name, parent_id, content='content\n',
49
                  revision='new-test-rev'):
50
        ie = InventoryFile(file_id, name, parent_id)
51
        ie.text_sha1 = osutils.sha_string(content)
52
        ie.text_size = len(content)
53
        ie.revision = revision
54
        return ie
55
56
    def make_link(self, file_id, name, parent_id, target='link-target\n'):
57
        ie = InventoryLink(file_id, name, parent_id)
58
        ie.symlink_target = target
59
        return ie
2729.2.9 by Martin Pool
Move actual tests from inventory_implementations __init__ into basics.py (Aaron)
60
4137.3.1 by Ian Clatworthy
Inventory.filter() API with tests
61
    def prepare_inv_with_nested_dirs(self):
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
62
        inv = inventory.Inventory('tree-root')
4137.3.1 by Ian Clatworthy
Inventory.filter() API with tests
63
        for args in [('src', 'directory', 'src-id'),
64
                     ('doc', 'directory', 'doc-id'),
65
                     ('src/hello.c', 'file', 'hello-id'),
66
                     ('src/bye.c', 'file', 'bye-id'),
67
                     ('zz', 'file', 'zz-id'),
68
                     ('src/sub/', 'directory', 'sub-id'),
69
                     ('src/zz.c', 'file', 'zzc-id'),
70
                     ('src/sub/a', 'file', 'a-id'),
71
                     ('Makefile', 'file', 'makefile-id')]:
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
72
            ie = inv.add_path(*args)
73
            if args[1] == 'file':
74
                ie.text_sha1 = osutils.sha_string('content\n')
75
                ie.text_size = len('content\n')
76
        return self.inv_to_test_inv(inv)
77
78
79
class TestInventoryCreateByApplyDelta(TestInventory):
4505.5.8 by Robert Collins
Fix fallout from the delta checking work, don't error on deltas containing the root inventory item in CHK delta application, and clean up Inventory docs.
80
    """A subset of the inventory delta application tests.
81
82
    See test_inv which has comprehensive delta application tests for
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
83
    inventories, dirstate, and repository based inventories.
4505.5.8 by Robert Collins
Fix fallout from the delta checking work, don't error on deltas containing the root inventory item in CHK delta application, and clean up Inventory docs.
84
    """
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
85
    def test_add(self):
86
        inv = self.make_init_inventory()
87
        inv = inv.create_by_apply_delta([
88
            (None, "a", "a-id", self.make_file('a-id', 'a', 'tree-root')),
89
            ], 'new-test-rev')
90
        self.assertEqual('a', inv.id2path('a-id'))
91
92
    def test_delete(self):
93
        inv = self.make_init_inventory()
94
        inv = inv.create_by_apply_delta([
95
            (None, "a", "a-id", self.make_file('a-id', 'a', 'tree-root')),
96
            ], 'new-rev-1')
97
        self.assertEqual('a', inv.id2path('a-id'))
98
        inv = inv.create_by_apply_delta([
99
            ("a", None, "a-id", None),
100
            ], 'new-rev-2')
4090.3.1 by Ian Clatworthy
check delta is legal in Inventory.apply_delta()
101
        self.assertRaises(errors.NoSuchId, inv.id2path, 'a-id')
102
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
103
    def test_rename(self):
104
        inv = self.make_init_inventory()
105
        inv = inv.create_by_apply_delta([
106
            (None, "a", "a-id", self.make_file('a-id', 'a', 'tree-root')),
107
            ], 'new-rev-1')
4090.3.1 by Ian Clatworthy
check delta is legal in Inventory.apply_delta()
108
        self.assertEqual('a', inv.id2path('a-id'))
109
        a_ie = inv['a-id']
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
110
        b_ie = self.make_file(a_ie.file_id, "b", a_ie.parent_id)
111
        inv = inv.create_by_apply_delta([("a", "b", "a-id", b_ie)], 'new-rev-2')
4090.3.1 by Ian Clatworthy
check delta is legal in Inventory.apply_delta()
112
        self.assertEqual("b", inv.id2path('a-id'))
113
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
114
    def test_illegal(self):
4090.3.1 by Ian Clatworthy
check delta is legal in Inventory.apply_delta()
115
        # A file-id cannot appear in a delta more than once
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
116
        inv = self.make_init_inventory()
117
        self.assertRaises(errors.InconsistentDelta, inv.create_by_apply_delta, [
118
            (None, "a", "id-1", self.make_file('id-1', 'a', 'tree-root')),
119
            (None, "b", "id-1", self.make_file('id-1', 'b', 'tree-root')),
120
            ], 'new-rev-1')
4090.3.1 by Ian Clatworthy
check delta is legal in Inventory.apply_delta()
121
122
123
class TestInventoryReads(TestInventory):
124
125
    def test_is_root(self):
126
        """Ensure our root-checking code is accurate."""
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
127
        inv = self.make_init_inventory()
128
        self.assertTrue(inv.is_root('tree-root'))
4090.3.1 by Ian Clatworthy
check delta is legal in Inventory.apply_delta()
129
        self.assertFalse(inv.is_root('booga'))
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
130
        ie = inv['tree-root'].copy()
131
        ie.file_id = 'booga'
132
        inv = inv.create_by_apply_delta([("", None, "tree-root", None),
133
                                         (None, "", "booga", ie)], 'new-rev-2')
4090.3.1 by Ian Clatworthy
check delta is legal in Inventory.apply_delta()
134
        self.assertFalse(inv.is_root('TREE_ROOT'))
135
        self.assertTrue(inv.is_root('booga'))
136
2729.2.9 by Martin Pool
Move actual tests from inventory_implementations __init__ into basics.py (Aaron)
137
    def test_ids(self):
138
        """Test detection of files within selected directories."""
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
139
        inv = inventory.Inventory('TREE_ROOT')
2729.2.9 by Martin Pool
Move actual tests from inventory_implementations __init__ into basics.py (Aaron)
140
        for args in [('src', 'directory', 'src-id'),
141
                     ('doc', 'directory', 'doc-id'),
142
                     ('src/hello.c', 'file'),
143
                     ('src/bye.c', 'file', 'bye-id'),
144
                     ('Makefile', 'file')]:
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
145
            ie = inv.add_path(*args)
146
            if args[1] == 'file':
147
                ie.text_sha1 = osutils.sha_string('content\n')
148
                ie.text_size = len('content\n')
149
        inv = self.inv_to_test_inv(inv)
2729.2.9 by Martin Pool
Move actual tests from inventory_implementations __init__ into basics.py (Aaron)
150
        self.assertEqual(inv.path2id('src'), 'src-id')
151
        self.assertEqual(inv.path2id('src/bye.c'), 'bye-id')
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
152
        self.assertTrue('src-id' in inv)
2729.2.9 by Martin Pool
Move actual tests from inventory_implementations __init__ into basics.py (Aaron)
153
154
    def test_non_directory_children(self):
155
        """Test path2id when a parent directory has no children"""
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
156
        inv = inventory.Inventory('tree-root')
157
        inv.add(self.make_file('file-id','file', 'tree-root'))
158
        inv.add(self.make_link('link-id','link', 'tree-root'))
2729.2.9 by Martin Pool
Move actual tests from inventory_implementations __init__ into basics.py (Aaron)
159
        self.assertIs(None, inv.path2id('file/subfile'))
160
        self.assertIs(None, inv.path2id('link/subfile'))
161
162
    def test_iter_entries(self):
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
163
        inv = self.prepare_inv_with_nested_dirs()
4370.5.1 by Ian Clatworthy
add recursive parameter to iter_entries()
164
165
        # Test all entries
2729.2.9 by Martin Pool
Move actual tests from inventory_implementations __init__ into basics.py (Aaron)
166
        self.assertEqual([
167
            ('', 'tree-root'),
168
            ('Makefile', 'makefile-id'),
169
            ('doc', 'doc-id'),
170
            ('src', 'src-id'),
171
            ('src/bye.c', 'bye-id'),
172
            ('src/hello.c', 'hello-id'),
4370.5.1 by Ian Clatworthy
add recursive parameter to iter_entries()
173
            ('src/sub', 'sub-id'),
174
            ('src/sub/a', 'a-id'),
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
175
            ('src/zz.c', 'zzc-id'),
176
            ('zz', 'zz-id'),
2729.2.9 by Martin Pool
Move actual tests from inventory_implementations __init__ into basics.py (Aaron)
177
            ], [(path, ie.file_id) for path, ie in inv.iter_entries()])
178
4370.5.1 by Ian Clatworthy
add recursive parameter to iter_entries()
179
        # Test a subdirectory
180
        self.assertEqual([
181
            ('bye.c', 'bye-id'),
182
            ('hello.c', 'hello-id'),
183
            ('sub', 'sub-id'),
184
            ('sub/a', 'a-id'),
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
185
            ('zz.c', 'zzc-id'),
4370.5.1 by Ian Clatworthy
add recursive parameter to iter_entries()
186
            ], [(path, ie.file_id) for path, ie in inv.iter_entries(
187
            from_dir='src-id')])
188
189
        # Test not recursing at the root level
190
        self.assertEqual([
191
            ('', 'tree-root'),
192
            ('Makefile', 'makefile-id'),
193
            ('doc', 'doc-id'),
194
            ('src', 'src-id'),
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
195
            ('zz', 'zz-id'),
4370.5.1 by Ian Clatworthy
add recursive parameter to iter_entries()
196
            ], [(path, ie.file_id) for path, ie in inv.iter_entries(
197
            recursive=False)])
198
199
        # Test not recursing at a subdirectory level
200
        self.assertEqual([
201
            ('bye.c', 'bye-id'),
202
            ('hello.c', 'hello-id'),
203
            ('sub', 'sub-id'),
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
204
            ('zz.c', 'zzc-id'),
4370.5.1 by Ian Clatworthy
add recursive parameter to iter_entries()
205
            ], [(path, ie.file_id) for path, ie in inv.iter_entries(
206
            from_dir='src-id', recursive=False)])
207
3735.2.155 by Ian Clatworthy
Inventory.iter_just_entries() API & test
208
    def test_iter_just_entries(self):
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
209
        inv = self.prepare_inv_with_nested_dirs()
3735.2.155 by Ian Clatworthy
Inventory.iter_just_entries() API & test
210
        self.assertEqual([
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
211
            'a-id',
3735.2.155 by Ian Clatworthy
Inventory.iter_just_entries() API & test
212
            'bye-id',
213
            'doc-id',
214
            'hello-id',
215
            'makefile-id',
216
            'src-id',
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
217
            'sub-id',
3735.2.155 by Ian Clatworthy
Inventory.iter_just_entries() API & test
218
            'tree-root',
4634.51.7 by John Arbash Meinel
Finish adding CHKInventory as a permutation in per_inventory.
219
            'zz-id',
220
            'zzc-id',
3735.2.155 by Ian Clatworthy
Inventory.iter_just_entries() API & test
221
            ], sorted([ie.file_id for ie in inv.iter_just_entries()]))
222
2729.2.9 by Martin Pool
Move actual tests from inventory_implementations __init__ into basics.py (Aaron)
223
    def test_iter_entries_by_dir(self):
4137.3.1 by Ian Clatworthy
Inventory.filter() API with tests
224
        inv = self. prepare_inv_with_nested_dirs()
2729.2.9 by Martin Pool
Move actual tests from inventory_implementations __init__ into basics.py (Aaron)
225
        self.assertEqual([
226
            ('', 'tree-root'),
227
            ('Makefile', 'makefile-id'),
228
            ('doc', 'doc-id'),
229
            ('src', 'src-id'),
230
            ('zz', 'zz-id'),
231
            ('src/bye.c', 'bye-id'),
232
            ('src/hello.c', 'hello-id'),
233
            ('src/sub', 'sub-id'),
234
            ('src/zz.c', 'zzc-id'),
235
            ('src/sub/a', 'a-id'),
236
            ], [(path, ie.file_id) for path, ie in inv.iter_entries_by_dir()])
237
        self.assertEqual([
238
            ('', 'tree-root'),
239
            ('Makefile', 'makefile-id'),
240
            ('doc', 'doc-id'),
241
            ('src', 'src-id'),
242
            ('zz', 'zz-id'),
243
            ('src/bye.c', 'bye-id'),
244
            ('src/hello.c', 'hello-id'),
245
            ('src/sub', 'sub-id'),
246
            ('src/zz.c', 'zzc-id'),
247
            ('src/sub/a', 'a-id'),
248
            ], [(path, ie.file_id) for path, ie in inv.iter_entries_by_dir(
249
                specific_file_ids=('a-id', 'zzc-id', 'doc-id', 'tree-root',
250
                'hello-id', 'bye-id', 'zz-id', 'src-id', 'makefile-id',
251
                'sub-id'))])
252
253
        self.assertEqual([
254
            ('Makefile', 'makefile-id'),
255
            ('doc', 'doc-id'),
256
            ('zz', 'zz-id'),
257
            ('src/bye.c', 'bye-id'),
258
            ('src/hello.c', 'hello-id'),
259
            ('src/zz.c', 'zzc-id'),
260
            ('src/sub/a', 'a-id'),
261
            ], [(path, ie.file_id) for path, ie in inv.iter_entries_by_dir(
262
                specific_file_ids=('a-id', 'zzc-id', 'doc-id',
263
                'hello-id', 'bye-id', 'zz-id', 'makefile-id'))])
264
265
        self.assertEqual([
266
            ('Makefile', 'makefile-id'),
267
            ('src/bye.c', 'bye-id'),
268
            ], [(path, ie.file_id) for path, ie in inv.iter_entries_by_dir(
269
                specific_file_ids=('bye-id', 'makefile-id'))])
270
271
        self.assertEqual([
272
            ('Makefile', 'makefile-id'),
273
            ('src/bye.c', 'bye-id'),
274
            ], [(path, ie.file_id) for path, ie in inv.iter_entries_by_dir(
275
                specific_file_ids=('bye-id', 'makefile-id'))])
276
277
        self.assertEqual([
278
            ('src/bye.c', 'bye-id'),
279
            ], [(path, ie.file_id) for path, ie in inv.iter_entries_by_dir(
280
                specific_file_ids=('bye-id',))])
281
2825.7.1 by Robert Collins
* Partial commits are now approximately 40% faster by walking over the
282
        self.assertEqual([
283
            ('', 'tree-root'),
284
            ('src', 'src-id'),
285
            ('src/bye.c', 'bye-id'),
286
            ], [(path, ie.file_id) for path, ie in inv.iter_entries_by_dir(
287
                specific_file_ids=('bye-id',), yield_parents=True)])
4137.3.1 by Ian Clatworthy
Inventory.filter() API with tests
288
 
289
290
class TestInventoryFiltering(TestInventory):
291
292
    def test_inv_filter_empty(self):
293
        inv = self.prepare_inv_with_nested_dirs()
294
        new_inv = inv.filter([])
295
        self.assertEqual([
296
            ('', 'tree-root'),
297
            ], [(path, ie.file_id) for path, ie in new_inv.iter_entries()])
298
    
299
    def test_inv_filter_files(self):
300
        inv = self.prepare_inv_with_nested_dirs()
301
        new_inv = inv.filter(['zz-id', 'hello-id', 'a-id'])
302
        self.assertEqual([
303
            ('', 'tree-root'),
304
            ('src', 'src-id'),
305
            ('src/hello.c', 'hello-id'),
306
            ('src/sub', 'sub-id'),
307
            ('src/sub/a', 'a-id'),
308
            ('zz', 'zz-id'),
309
            ], [(path, ie.file_id) for path, ie in new_inv.iter_entries()])
310
    
311
    def test_inv_filter_dirs(self):
312
        inv = self.prepare_inv_with_nested_dirs()
313
        new_inv = inv.filter(['doc-id', 'sub-id'])
314
        self.assertEqual([
315
            ('', 'tree-root'),
316
            ('doc', 'doc-id'),
317
            ('src', 'src-id'),
318
            ('src/sub', 'sub-id'),
319
            ('src/sub/a', 'a-id'),
320
            ], [(path, ie.file_id) for path, ie in new_inv.iter_entries()])
321
322
    def test_inv_filter_files_and_dirs(self):
323
        inv = self.prepare_inv_with_nested_dirs()
324
        new_inv = inv.filter(['makefile-id', 'src-id'])
325
        self.assertEqual([
326
            ('', 'tree-root'),
327
            ('Makefile', 'makefile-id'),
328
            ('src', 'src-id'),
329
            ('src/bye.c', 'bye-id'),
330
            ('src/hello.c', 'hello-id'),
331
            ('src/sub', 'sub-id'),
332
            ('src/sub/a', 'a-id'),
333
            ('src/zz.c', 'zzc-id'),
334
            ], [(path, ie.file_id) for path, ie in new_inv.iter_entries()])
4634.51.11 by John Arbash Meinel
Handle the case when the specific_fileids don't exist in this revision.
335
336
    def test_inv_filter_entry_not_present(self):
337
        inv = self.prepare_inv_with_nested_dirs()
338
        new_inv = inv.filter(['not-present-id'])
339
        self.assertEqual([
340
            ('', 'tree-root'),
341
            ], [(path, ie.file_id) for path, ie in new_inv.iter_entries()])