1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
"""Tests for different inventory implementations"""
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
28
from bzrlib.inventory import (
36
from bzrlib.tests.per_inventory import TestCaseWithInventory
40
class TestInventory(TestCaseWithInventory):
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)
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
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
61
def prepare_inv_with_nested_dirs(self):
62
inv = inventory.Inventory('tree-root')
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')]:
72
ie = inv.add_path(*args)
74
ie.text_sha1 = osutils.sha_string('content\n')
75
ie.text_size = len('content\n')
76
return self.inv_to_test_inv(inv)
79
class TestInventoryCreateByApplyDelta(TestInventory):
80
"""A subset of the inventory delta application tests.
82
See test_inv which has comprehensive delta application tests for
83
inventories, dirstate, and repository based inventories.
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')),
90
self.assertEqual('a', inv.id2path('a-id'))
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')),
97
self.assertEqual('a', inv.id2path('a-id'))
98
inv = inv.create_by_apply_delta([
99
("a", None, "a-id", None),
101
self.assertRaises(errors.NoSuchId, inv.id2path, 'a-id')
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')),
108
self.assertEqual('a', inv.id2path('a-id'))
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')
112
self.assertEqual("b", inv.id2path('a-id'))
114
def test_illegal(self):
115
# A file-id cannot appear in a delta more than once
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')),
123
class TestInventoryReads(TestInventory):
125
def test_is_root(self):
126
"""Ensure our root-checking code is accurate."""
127
inv = self.make_init_inventory()
128
self.assertTrue(inv.is_root('tree-root'))
129
self.assertFalse(inv.is_root('booga'))
130
ie = inv['tree-root'].copy()
132
inv = inv.create_by_apply_delta([("", None, "tree-root", None),
133
(None, "", "booga", ie)], 'new-rev-2')
134
self.assertFalse(inv.is_root('TREE_ROOT'))
135
self.assertTrue(inv.is_root('booga'))
138
"""Test detection of files within selected directories."""
139
inv = inventory.Inventory('TREE_ROOT')
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')]:
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)
150
self.assertEqual(inv.path2id('src'), 'src-id')
151
self.assertEqual(inv.path2id('src/bye.c'), 'bye-id')
152
self.assertTrue('src-id' in inv)
154
def test_non_directory_children(self):
155
"""Test path2id when a parent directory has no children"""
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'))
159
self.assertIs(None, inv.path2id('file/subfile'))
160
self.assertIs(None, inv.path2id('link/subfile'))
162
def test_iter_entries(self):
163
inv = self.prepare_inv_with_nested_dirs()
168
('Makefile', 'makefile-id'),
171
('src/bye.c', 'bye-id'),
172
('src/hello.c', 'hello-id'),
173
('src/sub', 'sub-id'),
174
('src/sub/a', 'a-id'),
175
('src/zz.c', 'zzc-id'),
177
], [(path, ie.file_id) for path, ie in inv.iter_entries()])
179
# Test a subdirectory
182
('hello.c', 'hello-id'),
186
], [(path, ie.file_id) for path, ie in inv.iter_entries(
189
# Test not recursing at the root level
192
('Makefile', 'makefile-id'),
196
], [(path, ie.file_id) for path, ie in inv.iter_entries(
199
# Test not recursing at a subdirectory level
202
('hello.c', 'hello-id'),
205
], [(path, ie.file_id) for path, ie in inv.iter_entries(
206
from_dir='src-id', recursive=False)])
208
def test_iter_just_entries(self):
209
inv = self.prepare_inv_with_nested_dirs()
221
], sorted([ie.file_id for ie in inv.iter_just_entries()]))
223
def test_iter_entries_by_dir(self):
224
inv = self. prepare_inv_with_nested_dirs()
227
('Makefile', 'makefile-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()])
239
('Makefile', 'makefile-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',
254
('Makefile', 'makefile-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'))])
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'))])
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'))])
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',))])
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)])
290
class TestInventoryFiltering(TestInventory):
292
def test_inv_filter_empty(self):
293
inv = self.prepare_inv_with_nested_dirs()
294
new_inv = inv.filter([])
297
], [(path, ie.file_id) for path, ie in new_inv.iter_entries()])
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'])
305
('src/hello.c', 'hello-id'),
306
('src/sub', 'sub-id'),
307
('src/sub/a', 'a-id'),
309
], [(path, ie.file_id) for path, ie in new_inv.iter_entries()])
311
def test_inv_filter_dirs(self):
312
inv = self.prepare_inv_with_nested_dirs()
313
new_inv = inv.filter(['doc-id', 'sub-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()])
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'])
327
('Makefile', 'makefile-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()])
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'])
341
], [(path, ie.file_id) for path, ie in new_inv.iter_entries()])