28
from bzrlib.inventory import (CHKInventory, Inventory, ROOT_ID, InventoryFile,
29
InventoryDirectory, InventoryEntry, TreeReference)
29
from bzrlib.inventory import (
37
mutable_inventory_from_tree,
30
39
from bzrlib.tests import (
32
41
TestCaseWithTransport,
35
split_suite_by_condition,
37
from bzrlib.tests.per_workingtree import workingtree_formats
40
def load_tests(standard_tests, module, loader):
41
"""Parameterise some inventory tests."""
42
to_adapt, result = split_suite_by_condition(standard_tests,
43
condition_isinstance(TestDeltaApplication))
43
from bzrlib.tests.scenarios import load_tests_apply_scenarios
46
load_tests = load_tests_apply_scenarios
49
def delta_application_scenarios():
45
51
('Inventory', {'apply_delta':apply_inventory_Inventory}),
51
57
# just creating trees.
53
59
for _, format in repository.format_registry.iteritems():
54
scenarios.append((str(format.__name__), {
55
'apply_delta':apply_inventory_Repository_add_inventory_by_delta,
57
for format in workingtree_formats():
60
if format.supports_full_versioned_files:
61
scenarios.append((str(format.__name__), {
62
'apply_delta':apply_inventory_Repository_add_inventory_by_delta,
64
for format in workingtree.format_registry._get_all():
65
repo_fmt = format._matchingbzrdir.repository_format
66
if not repo_fmt.supports_full_versioned_files:
59
69
(str(format.__class__.__name__) + ".update_basis_by_delta", {
60
70
'apply_delta':apply_inventory_WT_basis,
165
176
# This reads basis from the repo and puts it into the tree's local
166
177
# cache, if it has one.
167
178
tree.set_parent_ids(['basis'])
170
for old, new, id, entry in delta:
171
if None in (new, entry):
173
paths[new] = (entry.file_id, entry.kind)
174
parents.add(osutils.dirname(new))
175
parents = osutils.minimum_path_selection(parents)
177
# Put place holders in the tree to permit adding the other entries.
178
for pos, parent in enumerate(parents):
179
if not tree.path2id(parent):
180
# add a synthetic directory in the tree so we can can put the
181
# tree0 entries in place for dirstate.
182
tree.add([parent], ["id%d" % pos], ["directory"])
184
# Many deltas may cause this mini-apply to fail, but we want to see what
185
# the delta application code says, not the prep that we do to deal with
186
# limitations of dirstate's update_basis code.
187
for path, (file_id, kind) in sorted(paths.items()):
189
tree.add([path], [file_id], [kind])
190
except (KeyboardInterrupt, SystemExit):
196
181
# Fresh lock, reads disk again.
573
560
self.assertRaises(errors.InconsistentDelta, self.apply_delta, self,
577
class TestInventory(TestCase):
563
def test_add_file(self):
564
inv = self.get_empty_inventory()
565
file1 = inventory.InventoryFile('file-id', 'path', inv.root.file_id)
566
file1.revision = 'result'
569
delta = [(None, u'path', 'file-id', file1)]
570
res_inv = self.apply_delta(self, inv, delta)
571
self.assertEqual('file-id', res_inv['file-id'].file_id)
573
def test_remove_file(self):
574
inv = self.get_empty_inventory()
575
file1 = inventory.InventoryFile('file-id', 'path', inv.root.file_id)
576
file1.revision = 'result'
580
delta = [(u'path', None, 'file-id', None)]
581
res_inv = self.apply_delta(self, inv, delta)
582
self.assertEqual(None, res_inv.path2id('path'))
583
self.assertRaises(errors.NoSuchId, res_inv.id2path, 'file-id')
585
def test_rename_file(self):
586
inv = self.get_empty_inventory()
587
file1 = inventory.InventoryFile('file-id', 'path', inv.root.file_id)
588
file1.revision = 'result'
594
delta = [(u'path', 'path2', 'file-id', file2)]
595
res_inv = self.apply_delta(self, inv, delta)
596
self.assertEqual(None, res_inv.path2id('path'))
597
self.assertEqual('file-id', res_inv.path2id('path2'))
579
599
def test_is_root(self):
580
600
"""Ensure our root-checking code is accurate."""
643
663
def test_file_has_text(self):
644
664
file = inventory.InventoryFile('123', 'hello.c', ROOT_ID)
645
self.failUnless(file.has_text())
665
self.assertTrue(file.has_text())
647
667
def test_directory_has_text(self):
648
668
dir = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
649
self.failIf(dir.has_text())
669
self.assertFalse(dir.has_text())
651
671
def test_link_has_text(self):
652
672
link = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
653
self.failIf(link.has_text())
673
self.assertFalse(link.has_text())
655
675
def test_make_entry(self):
656
676
self.assertIsInstance(inventory.make_entry("file", "name", ROOT_ID),
1211
1231
self.assertEqual(('tree\xce\xa9name', 'tree-root-id', 'tree-rev-id'),
1212
1232
inv._bytes_to_utf8name_key(bytes))
1234
def make_basic_utf8_inventory(self):
1236
inv.revision_id = "revid"
1237
inv.root.revision = "rootrev"
1238
root_id = inv.root.file_id
1239
inv.add(InventoryFile("fileid", u'f\xefle', root_id))
1240
inv["fileid"].revision = "filerev"
1241
inv["fileid"].text_sha1 = "ffff"
1242
inv["fileid"].text_size = 0
1243
inv.add(InventoryDirectory("dirid", u'dir-\N{EURO SIGN}', root_id))
1244
inv.add(InventoryFile("childid", u'ch\xefld', "dirid"))
1245
inv["childid"].revision = "filerev"
1246
inv["childid"].text_sha1 = "ffff"
1247
inv["childid"].text_size = 0
1248
chk_bytes = self.get_chk_bytes()
1249
chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
1250
bytes = ''.join(chk_inv.to_lines())
1251
return CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
1253
def test__preload_handles_utf8(self):
1254
new_inv = self.make_basic_utf8_inventory()
1255
self.assertEqual({}, new_inv._fileid_to_entry_cache)
1256
self.assertFalse(new_inv._fully_cached)
1257
new_inv._preload_cache()
1259
sorted([new_inv.root_id, "fileid", "dirid", "childid"]),
1260
sorted(new_inv._fileid_to_entry_cache.keys()))
1261
ie_root = new_inv._fileid_to_entry_cache[new_inv.root_id]
1262
self.assertEqual([u'dir-\N{EURO SIGN}', u'f\xefle'],
1263
sorted(ie_root._children.keys()))
1264
ie_dir = new_inv._fileid_to_entry_cache['dirid']
1265
self.assertEqual([u'ch\xefld'], sorted(ie_dir._children.keys()))
1267
def test__preload_populates_cache(self):
1269
inv.revision_id = "revid"
1270
inv.root.revision = "rootrev"
1271
root_id = inv.root.file_id
1272
inv.add(InventoryFile("fileid", "file", root_id))
1273
inv["fileid"].revision = "filerev"
1274
inv["fileid"].executable = True
1275
inv["fileid"].text_sha1 = "ffff"
1276
inv["fileid"].text_size = 1
1277
inv.add(InventoryDirectory("dirid", "dir", root_id))
1278
inv.add(InventoryFile("childid", "child", "dirid"))
1279
inv["childid"].revision = "filerev"
1280
inv["childid"].executable = False
1281
inv["childid"].text_sha1 = "dddd"
1282
inv["childid"].text_size = 1
1283
chk_bytes = self.get_chk_bytes()
1284
chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
1285
bytes = ''.join(chk_inv.to_lines())
1286
new_inv = CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
1287
self.assertEqual({}, new_inv._fileid_to_entry_cache)
1288
self.assertFalse(new_inv._fully_cached)
1289
new_inv._preload_cache()
1291
sorted([root_id, "fileid", "dirid", "childid"]),
1292
sorted(new_inv._fileid_to_entry_cache.keys()))
1293
self.assertTrue(new_inv._fully_cached)
1294
ie_root = new_inv._fileid_to_entry_cache[root_id]
1295
self.assertEqual(['dir', 'file'], sorted(ie_root._children.keys()))
1296
ie_dir = new_inv._fileid_to_entry_cache['dirid']
1297
self.assertEqual(['child'], sorted(ie_dir._children.keys()))
1299
def test__preload_handles_partially_evaluated_inventory(self):
1300
new_inv = self.make_basic_utf8_inventory()
1301
ie = new_inv[new_inv.root_id]
1302
self.assertIs(None, ie._children)
1303
self.assertEqual([u'dir-\N{EURO SIGN}', u'f\xefle'],
1304
sorted(ie.children.keys()))
1305
# Accessing .children loads _children
1306
self.assertEqual([u'dir-\N{EURO SIGN}', u'f\xefle'],
1307
sorted(ie._children.keys()))
1308
new_inv._preload_cache()
1310
self.assertEqual([u'dir-\N{EURO SIGN}', u'f\xefle'],
1311
sorted(ie._children.keys()))
1312
ie_dir = new_inv["dirid"]
1313
self.assertEqual([u'ch\xefld'],
1314
sorted(ie_dir._children.keys()))
1215
1317
class TestCHKInventoryExpand(tests.TestCaseWithMemoryTransport):
1342
1444
inv = self.make_simple_inventory()
1343
1445
self.assertExpand(['TREE_ROOT', 'dir1-id', 'sub-dir1-id', 'top-id',
1344
1446
'subsub-file1-id'], inv, ['top-id', 'subsub-file1-id'])
1449
class TestMutableInventoryFromTree(TestCaseWithTransport):
1451
def test_empty(self):
1452
repository = self.make_repository('.')
1453
tree = repository.revision_tree(revision.NULL_REVISION)
1454
inv = mutable_inventory_from_tree(tree)
1455
self.assertEquals(revision.NULL_REVISION, inv.revision_id)
1456
self.assertEquals(0, len(inv))
1458
def test_some_files(self):
1459
wt = self.make_branch_and_tree('.')
1460
self.build_tree(['a'])
1461
wt.add(['a'], ['thefileid'])
1462
revid = wt.commit("commit")
1463
tree = wt.branch.repository.revision_tree(revid)
1464
inv = mutable_inventory_from_tree(tree)
1465
self.assertEquals(revid, inv.revision_id)
1466
self.assertEquals(2, len(inv))
1467
self.assertEquals("a", inv['thefileid'].name)
1468
# The inventory should be mutable and independent of
1470
self.assertFalse(tree.inventory['thefileid'].executable)
1471
inv['thefileid'].executable = True
1472
self.assertFalse(tree.inventory['thefileid'].executable)