~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,
24
        )
25
26
from bzrlib.inventory import (
27
        InventoryDirectory,
28
        InventoryEntry,
29
        InventoryFile,
30
        InventoryLink,
31
        ROOT_ID,
32
        TreeReference,
33
        )
34
35
from bzrlib.tests import (
36
        TestCase,
37
        )
38
39
4090.3.1 by Ian Clatworthy
check delta is legal in Inventory.apply_delta()
40
class TestInventory(TestCase):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
41
2729.2.9 by Martin Pool
Move actual tests from inventory_implementations __init__ into basics.py (Aaron)
42
    def make_inventory(self, root_id):
43
        return self.inventory_class(root_id=root_id)
44
4137.3.1 by Ian Clatworthy
Inventory.filter() API with tests
45
    def prepare_inv_with_nested_dirs(self):
46
        inv = self.make_inventory('tree-root')
47
        for args in [('src', 'directory', 'src-id'),
48
                     ('doc', 'directory', 'doc-id'),
49
                     ('src/hello.c', 'file', 'hello-id'),
50
                     ('src/bye.c', 'file', 'bye-id'),
51
                     ('zz', 'file', 'zz-id'),
52
                     ('src/sub/', 'directory', 'sub-id'),
53
                     ('src/zz.c', 'file', 'zzc-id'),
54
                     ('src/sub/a', 'file', 'a-id'),
55
                     ('Makefile', 'file', 'makefile-id')]:
56
            inv.add_path(*args)
57
        return inv
58
4090.3.1 by Ian Clatworthy
check delta is legal in Inventory.apply_delta()
59
60
class TestInventoryUpdates(TestInventory):
61
2729.2.9 by Martin Pool
Move actual tests from inventory_implementations __init__ into basics.py (Aaron)
62
    def test_creation_from_root_id(self):
63
        # iff a root id is passed to the constructor, a root directory is made
64
        inv = self.make_inventory(root_id='tree-root')
65
        self.assertNotEqual(None, inv.root)
66
        self.assertEqual('tree-root', inv.root.file_id)
67
68
    def test_add_path_of_root(self):
69
        # if no root id is given at creation time, there is no root directory
70
        inv = self.make_inventory(root_id=None)
71
        self.assertIs(None, inv.root)
72
        # add a root entry by adding its path
73
        ie = inv.add_path("", "directory", "my-root")
74
        self.assertEqual("my-root", ie.file_id)
75
        self.assertIs(ie, inv.root)
76
77
    def test_add_path(self):
78
        inv = self.make_inventory(root_id='tree_root')
79
        ie = inv.add_path('hello', 'file', 'hello-id')
80
        self.assertEqual('hello-id', ie.file_id)
81
        self.assertEqual('file', ie.kind)
82
2935.2.1 by Jelmer Vernooij
Fix Inventory.copy() and add a test for it.
83
    def test_copy(self):
84
        """Make sure copy() works and creates a deep copy."""
85
        inv = self.make_inventory(root_id='some-tree-root')
86
        ie = inv.add_path('hello', 'file', 'hello-id')
87
        inv2 = inv.copy()
88
        inv.root.file_id = 'some-new-root'
89
        ie.name = 'file2'
90
        self.assertEqual('some-tree-root', inv2.root.file_id)
91
        self.assertEqual('hello', inv2['hello-id'].name)
92
2938.2.1 by Jelmer Vernooij
Handle empty inventories in Inventory.copy().
93
    def test_copy_empty(self):
94
        """Make sure an empty inventory can be copied."""
95
        inv = self.make_inventory(root_id=None)
96
        inv2 = inv.copy()
97
        self.assertIs(None, inv2.root)
98
3616.1.1 by Jelmer Vernooij
Fix copying of root revision in inventory.
99
    def test_copy_copies_root_revision(self):
100
        """Make sure the revision of the root gets copied."""
101
        inv = self.make_inventory(root_id='someroot')
102
        inv.root.revision = 'therev'
103
        inv2 = inv.copy()
104
        self.assertEquals('someroot', inv2.root.file_id)
105
        self.assertEquals('therev', inv2.root.revision)
106
2729.2.9 by Martin Pool
Move actual tests from inventory_implementations __init__ into basics.py (Aaron)
107
    def test_create_tree_reference(self):
108
        inv = self.make_inventory('tree-root-123')
109
        inv.add(TreeReference('nested-id', 'nested', parent_id='tree-root-123',
110
                              revision='rev', reference_revision='rev2'))
111
112
    def test_error_encoding(self):
113
        inv = self.make_inventory('tree-root')
114
        inv.add(InventoryFile('a-id', u'\u1234', 'tree-root'))
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.
115
        e = self.assertRaises(errors.InconsistentDelta, inv.add,
116
            InventoryFile('b-id', u'\u1234', 'tree-root'))
117
        self.assertContainsRe(str(e), r'\\u1234')
2729.2.9 by Martin Pool
Move actual tests from inventory_implementations __init__ into basics.py (Aaron)
118
4090.3.1 by Ian Clatworthy
check delta is legal in Inventory.apply_delta()
119
    def test_add_recursive(self):
120
        parent = InventoryDirectory('src-id', 'src', 'tree-root')
121
        child = InventoryFile('hello-id', 'hello.c', 'src-id')
122
        parent.children[child.file_id] = child
123
        inv = self.make_inventory('tree-root')
124
        inv.add(parent)
125
        self.assertEqual('src/hello.c', inv.id2path('hello-id'))
126
127
128
class TestInventoryApplyDelta(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.
129
    """A subset of the inventory delta application tests.
130
131
    See test_inv which has comprehensive delta application tests for
132
    inventories, dirstate, and repository based inventories, unlike the tests
133
    here which only test in-memory implementations that can support a plain
134
    'apply_delta'.
135
    """
4090.3.1 by Ian Clatworthy
check delta is legal in Inventory.apply_delta()
136
137
    def test_apply_delta_add(self):
138
        inv = self.make_inventory('tree-root')
139
        inv.apply_delta([
140
            (None, "a", "a-id", InventoryFile('a-id', 'a', 'tree-root')),
141
            ])
142
        self.assertEqual('a', inv.id2path('a-id'))
143
144
    def test_apply_delta_delete(self):
145
        inv = self.make_inventory('tree-root')
146
        inv.apply_delta([
147
            (None, "a", "a-id", InventoryFile('a-id', 'a', 'tree-root')),
148
            ])
149
        self.assertEqual('a', inv.id2path('a-id'))
150
        a_ie = inv['a-id']
4526.9.13 by Robert Collins
Fixup broken test case to use a valid inventory delta
151
        inv.apply_delta([("a", None, "a-id", None)])
4090.3.1 by Ian Clatworthy
check delta is legal in Inventory.apply_delta()
152
        self.assertRaises(errors.NoSuchId, inv.id2path, 'a-id')
153
154
    def test_apply_delta_rename(self):
155
        inv = self.make_inventory('tree-root')
156
        inv.apply_delta([
157
            (None, "a", "a-id", InventoryFile('a-id', 'a', 'tree-root')),
158
            ])
159
        self.assertEqual('a', inv.id2path('a-id'))
160
        a_ie = inv['a-id']
161
        b_ie = InventoryFile(a_ie.file_id, "b", a_ie.parent_id)
162
        inv.apply_delta([("a", "b", "a-id", b_ie)])
163
        self.assertEqual("b", inv.id2path('a-id'))
164
165
    def test_apply_delta_illegal(self):
166
        # A file-id cannot appear in a delta more than once
167
        inv = self.make_inventory('tree-root')
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.
168
        self.assertRaises(errors.InconsistentDelta, inv.apply_delta, [
4090.3.1 by Ian Clatworthy
check delta is legal in Inventory.apply_delta()
169
            ("a", "a", "id-1", InventoryFile('id-1', 'a', 'tree-root')),
170
            ("a", "b", "id-1", InventoryFile('id-1', 'b', 'tree-root')),
171
            ])
172
173
174
class TestInventoryReads(TestInventory):
175
176
    def test_is_root(self):
177
        """Ensure our root-checking code is accurate."""
178
        inv = self.make_inventory('TREE_ROOT')
179
        self.assertTrue(inv.is_root('TREE_ROOT'))
180
        self.assertFalse(inv.is_root('booga'))
181
        inv.root.file_id = 'booga'
182
        self.assertFalse(inv.is_root('TREE_ROOT'))
183
        self.assertTrue(inv.is_root('booga'))
184
        # works properly even if no root is set
185
        inv.root = None
186
        self.assertFalse(inv.is_root('TREE_ROOT'))
187
        self.assertFalse(inv.is_root('booga'))
188
2729.2.9 by Martin Pool
Move actual tests from inventory_implementations __init__ into basics.py (Aaron)
189
    def test_ids(self):
190
        """Test detection of files within selected directories."""
191
        inv = self.make_inventory(ROOT_ID)
192
        for args in [('src', 'directory', 'src-id'),
193
                     ('doc', 'directory', 'doc-id'),
194
                     ('src/hello.c', 'file'),
195
                     ('src/bye.c', 'file', 'bye-id'),
196
                     ('Makefile', 'file')]:
197
            inv.add_path(*args)
198
        self.assertEqual(inv.path2id('src'), 'src-id')
199
        self.assertEqual(inv.path2id('src/bye.c'), 'bye-id')
200
        self.assert_('src-id' in inv)
201
202
    def test_non_directory_children(self):
203
        """Test path2id when a parent directory has no children"""
204
        inv = self.make_inventory('tree_root')
205
        inv.add(InventoryFile('file-id','file',
206
                                        parent_id='tree_root'))
207
        inv.add(InventoryLink('link-id','link',
208
                                        parent_id='tree_root'))
209
        self.assertIs(None, inv.path2id('file/subfile'))
210
        self.assertIs(None, inv.path2id('link/subfile'))
211
212
    def test_iter_entries(self):
213
        inv = self.make_inventory('tree-root')
214
        for args in [('src', 'directory', 'src-id'),
215
                     ('doc', 'directory', 'doc-id'),
216
                     ('src/hello.c', 'file', 'hello-id'),
217
                     ('src/bye.c', 'file', 'bye-id'),
4370.5.1 by Ian Clatworthy
add recursive parameter to iter_entries()
218
                     ('src/sub', 'directory', 'sub-id'),
219
                     ('src/sub/a', 'file', 'a-id'),
2729.2.9 by Martin Pool
Move actual tests from inventory_implementations __init__ into basics.py (Aaron)
220
                     ('Makefile', 'file', 'makefile-id')]:
221
            inv.add_path(*args)
4370.5.1 by Ian Clatworthy
add recursive parameter to iter_entries()
222
223
        # Test all entries
2729.2.9 by Martin Pool
Move actual tests from inventory_implementations __init__ into basics.py (Aaron)
224
        self.assertEqual([
225
            ('', 'tree-root'),
226
            ('Makefile', 'makefile-id'),
227
            ('doc', 'doc-id'),
228
            ('src', 'src-id'),
229
            ('src/bye.c', 'bye-id'),
230
            ('src/hello.c', 'hello-id'),
4370.5.1 by Ian Clatworthy
add recursive parameter to iter_entries()
231
            ('src/sub', 'sub-id'),
232
            ('src/sub/a', 'a-id'),
2729.2.9 by Martin Pool
Move actual tests from inventory_implementations __init__ into basics.py (Aaron)
233
            ], [(path, ie.file_id) for path, ie in inv.iter_entries()])
234
4370.5.1 by Ian Clatworthy
add recursive parameter to iter_entries()
235
        # Test a subdirectory
236
        self.assertEqual([
237
            ('bye.c', 'bye-id'),
238
            ('hello.c', 'hello-id'),
239
            ('sub', 'sub-id'),
240
            ('sub/a', 'a-id'),
241
            ], [(path, ie.file_id) for path, ie in inv.iter_entries(
242
            from_dir='src-id')])
243
244
        # Test not recursing at the root level
245
        self.assertEqual([
246
            ('', 'tree-root'),
247
            ('Makefile', 'makefile-id'),
248
            ('doc', 'doc-id'),
249
            ('src', 'src-id'),
250
            ], [(path, ie.file_id) for path, ie in inv.iter_entries(
251
            recursive=False)])
252
253
        # Test not recursing at a subdirectory level
254
        self.assertEqual([
255
            ('bye.c', 'bye-id'),
256
            ('hello.c', 'hello-id'),
257
            ('sub', 'sub-id'),
258
            ], [(path, ie.file_id) for path, ie in inv.iter_entries(
259
            from_dir='src-id', recursive=False)])
260
3735.2.155 by Ian Clatworthy
Inventory.iter_just_entries() API & test
261
    def test_iter_just_entries(self):
262
        inv = self.make_inventory('tree-root')
263
        for args in [('src', 'directory', 'src-id'),
264
                     ('doc', 'directory', 'doc-id'),
265
                     ('src/hello.c', 'file', 'hello-id'),
266
                     ('src/bye.c', 'file', 'bye-id'),
267
                     ('Makefile', 'file', 'makefile-id')]:
268
            inv.add_path(*args)
269
        self.assertEqual([
270
            'bye-id',
271
            'doc-id',
272
            'hello-id',
273
            'makefile-id',
274
            'src-id',
275
            'tree-root',
276
            ], sorted([ie.file_id for ie in inv.iter_just_entries()]))
277
2729.2.9 by Martin Pool
Move actual tests from inventory_implementations __init__ into basics.py (Aaron)
278
    def test_iter_entries_by_dir(self):
4137.3.1 by Ian Clatworthy
Inventory.filter() API with tests
279
        inv = self. prepare_inv_with_nested_dirs()
2729.2.9 by Martin Pool
Move actual tests from inventory_implementations __init__ into basics.py (Aaron)
280
        self.assertEqual([
281
            ('', 'tree-root'),
282
            ('Makefile', 'makefile-id'),
283
            ('doc', 'doc-id'),
284
            ('src', 'src-id'),
285
            ('zz', 'zz-id'),
286
            ('src/bye.c', 'bye-id'),
287
            ('src/hello.c', 'hello-id'),
288
            ('src/sub', 'sub-id'),
289
            ('src/zz.c', 'zzc-id'),
290
            ('src/sub/a', 'a-id'),
291
            ], [(path, ie.file_id) for path, ie in inv.iter_entries_by_dir()])
292
        self.assertEqual([
293
            ('', 'tree-root'),
294
            ('Makefile', 'makefile-id'),
295
            ('doc', 'doc-id'),
296
            ('src', 'src-id'),
297
            ('zz', 'zz-id'),
298
            ('src/bye.c', 'bye-id'),
299
            ('src/hello.c', 'hello-id'),
300
            ('src/sub', 'sub-id'),
301
            ('src/zz.c', 'zzc-id'),
302
            ('src/sub/a', 'a-id'),
303
            ], [(path, ie.file_id) for path, ie in inv.iter_entries_by_dir(
304
                specific_file_ids=('a-id', 'zzc-id', 'doc-id', 'tree-root',
305
                'hello-id', 'bye-id', 'zz-id', 'src-id', 'makefile-id',
306
                'sub-id'))])
307
308
        self.assertEqual([
309
            ('Makefile', 'makefile-id'),
310
            ('doc', 'doc-id'),
311
            ('zz', 'zz-id'),
312
            ('src/bye.c', 'bye-id'),
313
            ('src/hello.c', 'hello-id'),
314
            ('src/zz.c', 'zzc-id'),
315
            ('src/sub/a', 'a-id'),
316
            ], [(path, ie.file_id) for path, ie in inv.iter_entries_by_dir(
317
                specific_file_ids=('a-id', 'zzc-id', 'doc-id',
318
                'hello-id', 'bye-id', 'zz-id', 'makefile-id'))])
319
320
        self.assertEqual([
321
            ('Makefile', 'makefile-id'),
322
            ('src/bye.c', 'bye-id'),
323
            ], [(path, ie.file_id) for path, ie in inv.iter_entries_by_dir(
324
                specific_file_ids=('bye-id', 'makefile-id'))])
325
326
        self.assertEqual([
327
            ('Makefile', 'makefile-id'),
328
            ('src/bye.c', 'bye-id'),
329
            ], [(path, ie.file_id) for path, ie in inv.iter_entries_by_dir(
330
                specific_file_ids=('bye-id', 'makefile-id'))])
331
332
        self.assertEqual([
333
            ('src/bye.c', 'bye-id'),
334
            ], [(path, ie.file_id) for path, ie in inv.iter_entries_by_dir(
335
                specific_file_ids=('bye-id',))])
336
2825.7.1 by Robert Collins
* Partial commits are now approximately 40% faster by walking over the
337
        self.assertEqual([
338
            ('', 'tree-root'),
339
            ('src', 'src-id'),
340
            ('src/bye.c', 'bye-id'),
341
            ], [(path, ie.file_id) for path, ie in inv.iter_entries_by_dir(
342
                specific_file_ids=('bye-id',), yield_parents=True)])
4137.3.1 by Ian Clatworthy
Inventory.filter() API with tests
343
 
344
345
class TestInventoryFiltering(TestInventory):
346
347
    def test_inv_filter_empty(self):
348
        inv = self.prepare_inv_with_nested_dirs()
349
        new_inv = inv.filter([])
350
        self.assertEqual([
351
            ('', 'tree-root'),
352
            ], [(path, ie.file_id) for path, ie in new_inv.iter_entries()])
353
    
354
    def test_inv_filter_files(self):
355
        inv = self.prepare_inv_with_nested_dirs()
356
        new_inv = inv.filter(['zz-id', 'hello-id', 'a-id'])
357
        self.assertEqual([
358
            ('', 'tree-root'),
359
            ('src', 'src-id'),
360
            ('src/hello.c', 'hello-id'),
361
            ('src/sub', 'sub-id'),
362
            ('src/sub/a', 'a-id'),
363
            ('zz', 'zz-id'),
364
            ], [(path, ie.file_id) for path, ie in new_inv.iter_entries()])
365
    
366
    def test_inv_filter_dirs(self):
367
        inv = self.prepare_inv_with_nested_dirs()
368
        new_inv = inv.filter(['doc-id', 'sub-id'])
369
        self.assertEqual([
370
            ('', 'tree-root'),
371
            ('doc', 'doc-id'),
372
            ('src', 'src-id'),
373
            ('src/sub', 'sub-id'),
374
            ('src/sub/a', 'a-id'),
375
            ], [(path, ie.file_id) for path, ie in new_inv.iter_entries()])
376
377
    def test_inv_filter_files_and_dirs(self):
378
        inv = self.prepare_inv_with_nested_dirs()
379
        new_inv = inv.filter(['makefile-id', 'src-id'])
380
        self.assertEqual([
381
            ('', 'tree-root'),
382
            ('Makefile', 'makefile-id'),
383
            ('src', 'src-id'),
384
            ('src/bye.c', 'bye-id'),
385
            ('src/hello.c', 'hello-id'),
386
            ('src/sub', 'sub-id'),
387
            ('src/sub/a', 'a-id'),
388
            ('src/zz.c', 'zzc-id'),
389
            ], [(path, ie.file_id) for path, ie in new_inv.iter_entries()])