/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_inv.py

  • Committer: John Arbash Meinel
  • Date: 2009-06-18 18:18:36 UTC
  • mto: This revision was merged to the branch mainline in revision 4461.
  • Revision ID: john@arbash-meinel.com-20090618181836-biodfkat9a8eyzjz
The new add_inventory_by_delta is returning a CHKInventory when mapping from NULL
Which is completely valid, but 'broke' one of the tests.
So to fix it, changed the test to use CHKInventories on both sides, and add an __eq__
member. The nice thing is that CHKInventory.__eq__ is fairly cheap, since it only
has to check the root keys.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
16
 
 
17
 
 
18
from bzrlib import errors, chk_map, inventory, osutils
 
19
from bzrlib.inventory import (CHKInventory, Inventory, ROOT_ID, InventoryFile,
 
20
    InventoryDirectory, InventoryEntry, TreeReference)
 
21
from bzrlib.tests import TestCase, TestCaseWithTransport
 
22
 
 
23
 
 
24
class TestInventoryEntry(TestCase):
 
25
 
 
26
    def test_file_kind_character(self):
 
27
        file = inventory.InventoryFile('123', 'hello.c', ROOT_ID)
 
28
        self.assertEqual(file.kind_character(), '')
 
29
 
 
30
    def test_dir_kind_character(self):
 
31
        dir = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
 
32
        self.assertEqual(dir.kind_character(), '/')
 
33
 
 
34
    def test_link_kind_character(self):
 
35
        dir = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
 
36
        self.assertEqual(dir.kind_character(), '')
 
37
 
 
38
    def test_dir_detect_changes(self):
 
39
        left = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
 
40
        left.text_sha1 = 123
 
41
        left.executable = True
 
42
        left.symlink_target='foo'
 
43
        right = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
 
44
        right.text_sha1 = 321
 
45
        right.symlink_target='bar'
 
46
        self.assertEqual((False, False), left.detect_changes(right))
 
47
        self.assertEqual((False, False), right.detect_changes(left))
 
48
 
 
49
    def test_file_detect_changes(self):
 
50
        left = inventory.InventoryFile('123', 'hello.c', ROOT_ID)
 
51
        left.text_sha1 = 123
 
52
        right = inventory.InventoryFile('123', 'hello.c', ROOT_ID)
 
53
        right.text_sha1 = 123
 
54
        self.assertEqual((False, False), left.detect_changes(right))
 
55
        self.assertEqual((False, False), right.detect_changes(left))
 
56
        left.executable = True
 
57
        self.assertEqual((False, True), left.detect_changes(right))
 
58
        self.assertEqual((False, True), right.detect_changes(left))
 
59
        right.text_sha1 = 321
 
60
        self.assertEqual((True, True), left.detect_changes(right))
 
61
        self.assertEqual((True, True), right.detect_changes(left))
 
62
 
 
63
    def test_symlink_detect_changes(self):
 
64
        left = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
 
65
        left.text_sha1 = 123
 
66
        left.executable = True
 
67
        left.symlink_target='foo'
 
68
        right = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
 
69
        right.text_sha1 = 321
 
70
        right.symlink_target='foo'
 
71
        self.assertEqual((False, False), left.detect_changes(right))
 
72
        self.assertEqual((False, False), right.detect_changes(left))
 
73
        left.symlink_target = 'different'
 
74
        self.assertEqual((True, False), left.detect_changes(right))
 
75
        self.assertEqual((True, False), right.detect_changes(left))
 
76
 
 
77
    def test_file_has_text(self):
 
78
        file = inventory.InventoryFile('123', 'hello.c', ROOT_ID)
 
79
        self.failUnless(file.has_text())
 
80
 
 
81
    def test_directory_has_text(self):
 
82
        dir = inventory.InventoryDirectory('123', 'hello.c', ROOT_ID)
 
83
        self.failIf(dir.has_text())
 
84
 
 
85
    def test_link_has_text(self):
 
86
        link = inventory.InventoryLink('123', 'hello.c', ROOT_ID)
 
87
        self.failIf(link.has_text())
 
88
 
 
89
    def test_make_entry(self):
 
90
        self.assertIsInstance(inventory.make_entry("file", "name", ROOT_ID),
 
91
            inventory.InventoryFile)
 
92
        self.assertIsInstance(inventory.make_entry("symlink", "name", ROOT_ID),
 
93
            inventory.InventoryLink)
 
94
        self.assertIsInstance(inventory.make_entry("directory", "name", ROOT_ID),
 
95
            inventory.InventoryDirectory)
 
96
 
 
97
    def test_make_entry_non_normalized(self):
 
98
        orig_normalized_filename = osutils.normalized_filename
 
99
 
 
100
        try:
 
101
            osutils.normalized_filename = osutils._accessible_normalized_filename
 
102
            entry = inventory.make_entry("file", u'a\u030a', ROOT_ID)
 
103
            self.assertEqual(u'\xe5', entry.name)
 
104
            self.assertIsInstance(entry, inventory.InventoryFile)
 
105
 
 
106
            osutils.normalized_filename = osutils._inaccessible_normalized_filename
 
107
            self.assertRaises(errors.InvalidNormalization,
 
108
                    inventory.make_entry, 'file', u'a\u030a', ROOT_ID)
 
109
        finally:
 
110
            osutils.normalized_filename = orig_normalized_filename
 
111
 
 
112
 
 
113
class TestDescribeChanges(TestCase):
 
114
 
 
115
    def test_describe_change(self):
 
116
        # we need to test the following change combinations:
 
117
        # rename
 
118
        # reparent
 
119
        # modify
 
120
        # gone
 
121
        # added
 
122
        # renamed/reparented and modified
 
123
        # change kind (perhaps can't be done yet?)
 
124
        # also, merged in combination with all of these?
 
125
        old_a = InventoryFile('a-id', 'a_file', ROOT_ID)
 
126
        old_a.text_sha1 = '123132'
 
127
        old_a.text_size = 0
 
128
        new_a = InventoryFile('a-id', 'a_file', ROOT_ID)
 
129
        new_a.text_sha1 = '123132'
 
130
        new_a.text_size = 0
 
131
 
 
132
        self.assertChangeDescription('unchanged', old_a, new_a)
 
133
 
 
134
        new_a.text_size = 10
 
135
        new_a.text_sha1 = 'abcabc'
 
136
        self.assertChangeDescription('modified', old_a, new_a)
 
137
 
 
138
        self.assertChangeDescription('added', None, new_a)
 
139
        self.assertChangeDescription('removed', old_a, None)
 
140
        # perhaps a bit questionable but seems like the most reasonable thing...
 
141
        self.assertChangeDescription('unchanged', None, None)
 
142
 
 
143
        # in this case it's both renamed and modified; show a rename and
 
144
        # modification:
 
145
        new_a.name = 'newfilename'
 
146
        self.assertChangeDescription('modified and renamed', old_a, new_a)
 
147
 
 
148
        # reparenting is 'renaming'
 
149
        new_a.name = old_a.name
 
150
        new_a.parent_id = 'somedir-id'
 
151
        self.assertChangeDescription('modified and renamed', old_a, new_a)
 
152
 
 
153
        # reset the content values so its not modified
 
154
        new_a.text_size = old_a.text_size
 
155
        new_a.text_sha1 = old_a.text_sha1
 
156
        new_a.name = old_a.name
 
157
 
 
158
        new_a.name = 'newfilename'
 
159
        self.assertChangeDescription('renamed', old_a, new_a)
 
160
 
 
161
        # reparenting is 'renaming'
 
162
        new_a.name = old_a.name
 
163
        new_a.parent_id = 'somedir-id'
 
164
        self.assertChangeDescription('renamed', old_a, new_a)
 
165
 
 
166
    def assertChangeDescription(self, expected_change, old_ie, new_ie):
 
167
        change = InventoryEntry.describe_change(old_ie, new_ie)
 
168
        self.assertEqual(expected_change, change)
 
169
 
 
170
 
 
171
class TestCHKInventory(TestCaseWithTransport):
 
172
 
 
173
    def get_chk_bytes(self):
 
174
        # The easiest way to get a CHK store is a development6 repository and
 
175
        # then work with the chk_bytes attribute directly.
 
176
        repo = self.make_repository(".", format="development6-rich-root")
 
177
        repo.lock_write()
 
178
        self.addCleanup(repo.unlock)
 
179
        repo.start_write_group()
 
180
        self.addCleanup(repo.abort_write_group)
 
181
        return repo.chk_bytes
 
182
 
 
183
    def read_bytes(self, chk_bytes, key):
 
184
        stream = chk_bytes.get_record_stream([key], 'unordered', True)
 
185
        return stream.next().get_bytes_as("fulltext")
 
186
 
 
187
    def test_deserialise_gives_CHKInventory(self):
 
188
        inv = Inventory()
 
189
        inv.revision_id = "revid"
 
190
        inv.root.revision = "rootrev"
 
191
        chk_bytes = self.get_chk_bytes()
 
192
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
 
193
        bytes = ''.join(chk_inv.to_lines())
 
194
        new_inv = CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
 
195
        self.assertEqual("revid", new_inv.revision_id)
 
196
        self.assertEqual("directory", new_inv.root.kind)
 
197
        self.assertEqual(inv.root.file_id, new_inv.root.file_id)
 
198
        self.assertEqual(inv.root.parent_id, new_inv.root.parent_id)
 
199
        self.assertEqual(inv.root.name, new_inv.root.name)
 
200
        self.assertEqual("rootrev", new_inv.root.revision)
 
201
        self.assertEqual('plain', new_inv._search_key_name)
 
202
 
 
203
    def test_deserialise_wrong_revid(self):
 
204
        inv = Inventory()
 
205
        inv.revision_id = "revid"
 
206
        inv.root.revision = "rootrev"
 
207
        chk_bytes = self.get_chk_bytes()
 
208
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
 
209
        bytes = ''.join(chk_inv.to_lines())
 
210
        self.assertRaises(ValueError, CHKInventory.deserialise, chk_bytes,
 
211
            bytes, ("revid2",))
 
212
 
 
213
    def test_captures_rev_root_byid(self):
 
214
        inv = Inventory()
 
215
        inv.revision_id = "foo"
 
216
        inv.root.revision = "bar"
 
217
        chk_bytes = self.get_chk_bytes()
 
218
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
 
219
        lines = chk_inv.to_lines()
 
220
        self.assertEqual([
 
221
            'chkinventory:\n',
 
222
            'revision_id: foo\n',
 
223
            'root_id: TREE_ROOT\n',
 
224
            'parent_id_basename_to_file_id: sha1:eb23f0ad4b07f48e88c76d4c94292be57fb2785f\n',
 
225
            'id_to_entry: sha1:debfe920f1f10e7929260f0534ac9a24d7aabbb4\n',
 
226
            ], lines)
 
227
        chk_inv = CHKInventory.deserialise(chk_bytes, ''.join(lines), ('foo',))
 
228
        self.assertEqual('plain', chk_inv._search_key_name)
 
229
 
 
230
    def test_captures_parent_id_basename_index(self):
 
231
        inv = Inventory()
 
232
        inv.revision_id = "foo"
 
233
        inv.root.revision = "bar"
 
234
        chk_bytes = self.get_chk_bytes()
 
235
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
 
236
        lines = chk_inv.to_lines()
 
237
        self.assertEqual([
 
238
            'chkinventory:\n',
 
239
            'revision_id: foo\n',
 
240
            'root_id: TREE_ROOT\n',
 
241
            'parent_id_basename_to_file_id: sha1:eb23f0ad4b07f48e88c76d4c94292be57fb2785f\n',
 
242
            'id_to_entry: sha1:debfe920f1f10e7929260f0534ac9a24d7aabbb4\n',
 
243
            ], lines)
 
244
        chk_inv = CHKInventory.deserialise(chk_bytes, ''.join(lines), ('foo',))
 
245
        self.assertEqual('plain', chk_inv._search_key_name)
 
246
 
 
247
    def test_captures_search_key_name(self):
 
248
        inv = Inventory()
 
249
        inv.revision_id = "foo"
 
250
        inv.root.revision = "bar"
 
251
        chk_bytes = self.get_chk_bytes()
 
252
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv,
 
253
                                              search_key_name='hash-16-way')
 
254
        lines = chk_inv.to_lines()
 
255
        self.assertEqual([
 
256
            'chkinventory:\n',
 
257
            'search_key_name: hash-16-way\n',
 
258
            'root_id: TREE_ROOT\n',
 
259
            'parent_id_basename_to_file_id: sha1:eb23f0ad4b07f48e88c76d4c94292be57fb2785f\n',
 
260
            'revision_id: foo\n',
 
261
            'id_to_entry: sha1:debfe920f1f10e7929260f0534ac9a24d7aabbb4\n',
 
262
            ], lines)
 
263
        chk_inv = CHKInventory.deserialise(chk_bytes, ''.join(lines), ('foo',))
 
264
        self.assertEqual('hash-16-way', chk_inv._search_key_name)
 
265
 
 
266
    def test_directory_children_on_demand(self):
 
267
        inv = Inventory()
 
268
        inv.revision_id = "revid"
 
269
        inv.root.revision = "rootrev"
 
270
        inv.add(InventoryFile("fileid", "file", inv.root.file_id))
 
271
        inv["fileid"].revision = "filerev"
 
272
        inv["fileid"].executable = True
 
273
        inv["fileid"].text_sha1 = "ffff"
 
274
        inv["fileid"].text_size = 1
 
275
        chk_bytes = self.get_chk_bytes()
 
276
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
 
277
        bytes = ''.join(chk_inv.to_lines())
 
278
        new_inv = CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
 
279
        root_entry = new_inv[inv.root.file_id]
 
280
        self.assertEqual(None, root_entry._children)
 
281
        self.assertEqual(['file'], root_entry.children.keys())
 
282
        file_direct = new_inv["fileid"]
 
283
        file_found = root_entry.children['file']
 
284
        self.assertEqual(file_direct.kind, file_found.kind)
 
285
        self.assertEqual(file_direct.file_id, file_found.file_id)
 
286
        self.assertEqual(file_direct.parent_id, file_found.parent_id)
 
287
        self.assertEqual(file_direct.name, file_found.name)
 
288
        self.assertEqual(file_direct.revision, file_found.revision)
 
289
        self.assertEqual(file_direct.text_sha1, file_found.text_sha1)
 
290
        self.assertEqual(file_direct.text_size, file_found.text_size)
 
291
        self.assertEqual(file_direct.executable, file_found.executable)
 
292
 
 
293
    def test_from_inventory_maximum_size(self):
 
294
        # from_inventory supports the maximum_size parameter.
 
295
        inv = Inventory()
 
296
        inv.revision_id = "revid"
 
297
        inv.root.revision = "rootrev"
 
298
        chk_bytes = self.get_chk_bytes()
 
299
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv, 120)
 
300
        chk_inv.id_to_entry._ensure_root()
 
301
        self.assertEqual(120, chk_inv.id_to_entry._root_node.maximum_size)
 
302
        self.assertEqual(1, chk_inv.id_to_entry._root_node._key_width)
 
303
        p_id_basename = chk_inv.parent_id_basename_to_file_id
 
304
        p_id_basename._ensure_root()
 
305
        self.assertEqual(120, p_id_basename._root_node.maximum_size)
 
306
        self.assertEqual(2, p_id_basename._root_node._key_width)
 
307
 
 
308
    def test___iter__(self):
 
309
        inv = Inventory()
 
310
        inv.revision_id = "revid"
 
311
        inv.root.revision = "rootrev"
 
312
        inv.add(InventoryFile("fileid", "file", inv.root.file_id))
 
313
        inv["fileid"].revision = "filerev"
 
314
        inv["fileid"].executable = True
 
315
        inv["fileid"].text_sha1 = "ffff"
 
316
        inv["fileid"].text_size = 1
 
317
        chk_bytes = self.get_chk_bytes()
 
318
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
 
319
        bytes = ''.join(chk_inv.to_lines())
 
320
        new_inv = CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
 
321
        fileids = list(new_inv.__iter__())
 
322
        fileids.sort()
 
323
        self.assertEqual([inv.root.file_id, "fileid"], fileids)
 
324
 
 
325
    def test__len__(self):
 
326
        inv = Inventory()
 
327
        inv.revision_id = "revid"
 
328
        inv.root.revision = "rootrev"
 
329
        inv.add(InventoryFile("fileid", "file", inv.root.file_id))
 
330
        inv["fileid"].revision = "filerev"
 
331
        inv["fileid"].executable = True
 
332
        inv["fileid"].text_sha1 = "ffff"
 
333
        inv["fileid"].text_size = 1
 
334
        chk_bytes = self.get_chk_bytes()
 
335
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
 
336
        self.assertEqual(2, len(chk_inv))
 
337
 
 
338
    def test___getitem__(self):
 
339
        inv = Inventory()
 
340
        inv.revision_id = "revid"
 
341
        inv.root.revision = "rootrev"
 
342
        inv.add(InventoryFile("fileid", "file", inv.root.file_id))
 
343
        inv["fileid"].revision = "filerev"
 
344
        inv["fileid"].executable = True
 
345
        inv["fileid"].text_sha1 = "ffff"
 
346
        inv["fileid"].text_size = 1
 
347
        chk_bytes = self.get_chk_bytes()
 
348
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
 
349
        bytes = ''.join(chk_inv.to_lines())
 
350
        new_inv = CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
 
351
        root_entry = new_inv[inv.root.file_id]
 
352
        file_entry = new_inv["fileid"]
 
353
        self.assertEqual("directory", root_entry.kind)
 
354
        self.assertEqual(inv.root.file_id, root_entry.file_id)
 
355
        self.assertEqual(inv.root.parent_id, root_entry.parent_id)
 
356
        self.assertEqual(inv.root.name, root_entry.name)
 
357
        self.assertEqual("rootrev", root_entry.revision)
 
358
        self.assertEqual("file", file_entry.kind)
 
359
        self.assertEqual("fileid", file_entry.file_id)
 
360
        self.assertEqual(inv.root.file_id, file_entry.parent_id)
 
361
        self.assertEqual("file", file_entry.name)
 
362
        self.assertEqual("filerev", file_entry.revision)
 
363
        self.assertEqual("ffff", file_entry.text_sha1)
 
364
        self.assertEqual(1, file_entry.text_size)
 
365
        self.assertEqual(True, file_entry.executable)
 
366
        self.assertRaises(errors.NoSuchId, new_inv.__getitem__, 'missing')
 
367
 
 
368
    def test_has_id_true(self):
 
369
        inv = Inventory()
 
370
        inv.revision_id = "revid"
 
371
        inv.root.revision = "rootrev"
 
372
        inv.add(InventoryFile("fileid", "file", inv.root.file_id))
 
373
        inv["fileid"].revision = "filerev"
 
374
        inv["fileid"].executable = True
 
375
        inv["fileid"].text_sha1 = "ffff"
 
376
        inv["fileid"].text_size = 1
 
377
        chk_bytes = self.get_chk_bytes()
 
378
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
 
379
        self.assertTrue(chk_inv.has_id('fileid'))
 
380
        self.assertTrue(chk_inv.has_id(inv.root.file_id))
 
381
 
 
382
    def test_has_id_not(self):
 
383
        inv = Inventory()
 
384
        inv.revision_id = "revid"
 
385
        inv.root.revision = "rootrev"
 
386
        chk_bytes = self.get_chk_bytes()
 
387
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
 
388
        self.assertFalse(chk_inv.has_id('fileid'))
 
389
 
 
390
    def test_id2path(self):
 
391
        inv = Inventory()
 
392
        inv.revision_id = "revid"
 
393
        inv.root.revision = "rootrev"
 
394
        direntry = InventoryDirectory("dirid", "dir", inv.root.file_id)
 
395
        fileentry = InventoryFile("fileid", "file", "dirid")
 
396
        inv.add(direntry)
 
397
        inv.add(fileentry)
 
398
        inv["fileid"].revision = "filerev"
 
399
        inv["fileid"].executable = True
 
400
        inv["fileid"].text_sha1 = "ffff"
 
401
        inv["fileid"].text_size = 1
 
402
        inv["dirid"].revision = "filerev"
 
403
        chk_bytes = self.get_chk_bytes()
 
404
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
 
405
        bytes = ''.join(chk_inv.to_lines())
 
406
        new_inv = CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
 
407
        self.assertEqual('', new_inv.id2path(inv.root.file_id))
 
408
        self.assertEqual('dir', new_inv.id2path('dirid'))
 
409
        self.assertEqual('dir/file', new_inv.id2path('fileid'))
 
410
 
 
411
    def test_path2id(self):
 
412
        inv = Inventory()
 
413
        inv.revision_id = "revid"
 
414
        inv.root.revision = "rootrev"
 
415
        direntry = InventoryDirectory("dirid", "dir", inv.root.file_id)
 
416
        fileentry = InventoryFile("fileid", "file", "dirid")
 
417
        inv.add(direntry)
 
418
        inv.add(fileentry)
 
419
        inv["fileid"].revision = "filerev"
 
420
        inv["fileid"].executable = True
 
421
        inv["fileid"].text_sha1 = "ffff"
 
422
        inv["fileid"].text_size = 1
 
423
        inv["dirid"].revision = "filerev"
 
424
        chk_bytes = self.get_chk_bytes()
 
425
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
 
426
        bytes = ''.join(chk_inv.to_lines())
 
427
        new_inv = CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
 
428
        self.assertEqual(inv.root.file_id, new_inv.path2id(''))
 
429
        self.assertEqual('dirid', new_inv.path2id('dir'))
 
430
        self.assertEqual('fileid', new_inv.path2id('dir/file'))
 
431
 
 
432
    def test_create_by_apply_delta_sets_root(self):
 
433
        inv = Inventory()
 
434
        inv.revision_id = "revid"
 
435
        chk_bytes = self.get_chk_bytes()
 
436
        base_inv = CHKInventory.from_inventory(chk_bytes, inv)
 
437
        inv.add_path("", "directory", "myrootid", None)
 
438
        inv.revision_id = "expectedid"
 
439
        reference_inv = CHKInventory.from_inventory(chk_bytes, inv)
 
440
        delta = [(None, "",  "myrootid", inv.root)]
 
441
        new_inv = base_inv.create_by_apply_delta(delta, "expectedid")
 
442
        self.assertEquals(reference_inv.root, new_inv.root)
 
443
 
 
444
    def test_create_by_apply_delta_empty_add_child(self):
 
445
        inv = Inventory()
 
446
        inv.revision_id = "revid"
 
447
        inv.root.revision = "rootrev"
 
448
        chk_bytes = self.get_chk_bytes()
 
449
        base_inv = CHKInventory.from_inventory(chk_bytes, inv)
 
450
        a_entry = InventoryFile("A-id", "A", inv.root.file_id)
 
451
        a_entry.revision = "filerev"
 
452
        a_entry.executable = True
 
453
        a_entry.text_sha1 = "ffff"
 
454
        a_entry.text_size = 1
 
455
        inv.add(a_entry)
 
456
        inv.revision_id = "expectedid"
 
457
        reference_inv = CHKInventory.from_inventory(chk_bytes, inv)
 
458
        delta = [(None, "A",  "A-id", a_entry)]
 
459
        new_inv = base_inv.create_by_apply_delta(delta, "expectedid")
 
460
        # new_inv should be the same as reference_inv.
 
461
        self.assertEqual(reference_inv.revision_id, new_inv.revision_id)
 
462
        self.assertEqual(reference_inv.root_id, new_inv.root_id)
 
463
        reference_inv.id_to_entry._ensure_root()
 
464
        new_inv.id_to_entry._ensure_root()
 
465
        self.assertEqual(reference_inv.id_to_entry._root_node._key,
 
466
            new_inv.id_to_entry._root_node._key)
 
467
 
 
468
    def test_create_by_apply_delta_empty_add_child_updates_parent_id(self):
 
469
        inv = Inventory()
 
470
        inv.revision_id = "revid"
 
471
        inv.root.revision = "rootrev"
 
472
        chk_bytes = self.get_chk_bytes()
 
473
        base_inv = CHKInventory.from_inventory(chk_bytes, inv)
 
474
        a_entry = InventoryFile("A-id", "A", inv.root.file_id)
 
475
        a_entry.revision = "filerev"
 
476
        a_entry.executable = True
 
477
        a_entry.text_sha1 = "ffff"
 
478
        a_entry.text_size = 1
 
479
        inv.add(a_entry)
 
480
        inv.revision_id = "expectedid"
 
481
        reference_inv = CHKInventory.from_inventory(chk_bytes, inv)
 
482
        delta = [(None, "A",  "A-id", a_entry)]
 
483
        new_inv = base_inv.create_by_apply_delta(delta, "expectedid")
 
484
        reference_inv.id_to_entry._ensure_root()
 
485
        reference_inv.parent_id_basename_to_file_id._ensure_root()
 
486
        new_inv.id_to_entry._ensure_root()
 
487
        new_inv.parent_id_basename_to_file_id._ensure_root()
 
488
        # new_inv should be the same as reference_inv.
 
489
        self.assertEqual(reference_inv.revision_id, new_inv.revision_id)
 
490
        self.assertEqual(reference_inv.root_id, new_inv.root_id)
 
491
        self.assertEqual(reference_inv.id_to_entry._root_node._key,
 
492
            new_inv.id_to_entry._root_node._key)
 
493
        self.assertEqual(reference_inv.parent_id_basename_to_file_id._root_node._key,
 
494
            new_inv.parent_id_basename_to_file_id._root_node._key)
 
495
 
 
496
    def test_iter_changes(self):
 
497
        # Low level bootstrapping smoke test; comprehensive generic tests via
 
498
        # InterTree are coming.
 
499
        inv = Inventory()
 
500
        inv.revision_id = "revid"
 
501
        inv.root.revision = "rootrev"
 
502
        inv.add(InventoryFile("fileid", "file", inv.root.file_id))
 
503
        inv["fileid"].revision = "filerev"
 
504
        inv["fileid"].executable = True
 
505
        inv["fileid"].text_sha1 = "ffff"
 
506
        inv["fileid"].text_size = 1
 
507
        inv2 = Inventory()
 
508
        inv2.revision_id = "revid2"
 
509
        inv2.root.revision = "rootrev"
 
510
        inv2.add(InventoryFile("fileid", "file", inv.root.file_id))
 
511
        inv2["fileid"].revision = "filerev2"
 
512
        inv2["fileid"].executable = False
 
513
        inv2["fileid"].text_sha1 = "bbbb"
 
514
        inv2["fileid"].text_size = 2
 
515
        # get fresh objects.
 
516
        chk_bytes = self.get_chk_bytes()
 
517
        chk_inv = CHKInventory.from_inventory(chk_bytes, inv)
 
518
        bytes = ''.join(chk_inv.to_lines())
 
519
        inv_1 = CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
 
520
        chk_inv2 = CHKInventory.from_inventory(chk_bytes, inv2)
 
521
        bytes = ''.join(chk_inv2.to_lines())
 
522
        inv_2 = CHKInventory.deserialise(chk_bytes, bytes, ("revid2",))
 
523
        self.assertEqual([('fileid', (u'file', u'file'), True, (True, True),
 
524
            ('TREE_ROOT', 'TREE_ROOT'), (u'file', u'file'), ('file', 'file'),
 
525
            (False, True))],
 
526
            list(inv_1.iter_changes(inv_2)))
 
527
 
 
528
    def test_parent_id_basename_to_file_id_index_enabled(self):
 
529
        inv = Inventory()
 
530
        inv.revision_id = "revid"
 
531
        inv.root.revision = "rootrev"
 
532
        inv.add(InventoryFile("fileid", "file", inv.root.file_id))
 
533
        inv["fileid"].revision = "filerev"
 
534
        inv["fileid"].executable = True
 
535
        inv["fileid"].text_sha1 = "ffff"
 
536
        inv["fileid"].text_size = 1
 
537
        # get fresh objects.
 
538
        chk_bytes = self.get_chk_bytes()
 
539
        tmp_inv = CHKInventory.from_inventory(chk_bytes, inv)
 
540
        bytes = ''.join(tmp_inv.to_lines())
 
541
        chk_inv = CHKInventory.deserialise(chk_bytes, bytes, ("revid",))
 
542
        self.assertIsInstance(chk_inv.parent_id_basename_to_file_id, chk_map.CHKMap)
 
543
        self.assertEqual(
 
544
            {('', ''): 'TREE_ROOT', ('TREE_ROOT', 'file'): 'fileid'},
 
545
            dict(chk_inv.parent_id_basename_to_file_id.iteritems()))
 
546
 
 
547
    def test_file_entry_to_bytes(self):
 
548
        inv = CHKInventory(None)
 
549
        ie = inventory.InventoryFile('file-id', 'filename', 'parent-id')
 
550
        ie.executable = True
 
551
        ie.revision = 'file-rev-id'
 
552
        ie.text_sha1 = 'abcdefgh'
 
553
        ie.text_size = 100
 
554
        bytes = inv._entry_to_bytes(ie)
 
555
        self.assertEqual('file: file-id\nparent-id\nfilename\n'
 
556
                         'file-rev-id\nabcdefgh\n100\nY', bytes)
 
557
        ie2 = inv._bytes_to_entry(bytes)
 
558
        self.assertEqual(ie, ie2)
 
559
        self.assertIsInstance(ie2.name, unicode)
 
560
        self.assertEqual(('filename', 'file-id', 'file-rev-id'),
 
561
                         inv._bytes_to_utf8name_key(bytes))
 
562
 
 
563
    def test_file2_entry_to_bytes(self):
 
564
        inv = CHKInventory(None)
 
565
        # \u30a9 == 'omega'
 
566
        ie = inventory.InventoryFile('file-id', u'\u03a9name', 'parent-id')
 
567
        ie.executable = False
 
568
        ie.revision = 'file-rev-id'
 
569
        ie.text_sha1 = '123456'
 
570
        ie.text_size = 25
 
571
        bytes = inv._entry_to_bytes(ie)
 
572
        self.assertEqual('file: file-id\nparent-id\n\xce\xa9name\n'
 
573
                         'file-rev-id\n123456\n25\nN', bytes)
 
574
        ie2 = inv._bytes_to_entry(bytes)
 
575
        self.assertEqual(ie, ie2)
 
576
        self.assertIsInstance(ie2.name, unicode)
 
577
        self.assertEqual(('\xce\xa9name', 'file-id', 'file-rev-id'),
 
578
                         inv._bytes_to_utf8name_key(bytes))
 
579
 
 
580
    def test_dir_entry_to_bytes(self):
 
581
        inv = CHKInventory(None)
 
582
        ie = inventory.InventoryDirectory('dir-id', 'dirname', 'parent-id')
 
583
        ie.revision = 'dir-rev-id'
 
584
        bytes = inv._entry_to_bytes(ie)
 
585
        self.assertEqual('dir: dir-id\nparent-id\ndirname\ndir-rev-id', bytes)
 
586
        ie2 = inv._bytes_to_entry(bytes)
 
587
        self.assertEqual(ie, ie2)
 
588
        self.assertIsInstance(ie2.name, unicode)
 
589
        self.assertEqual(('dirname', 'dir-id', 'dir-rev-id'),
 
590
                         inv._bytes_to_utf8name_key(bytes))
 
591
 
 
592
    def test_dir2_entry_to_bytes(self):
 
593
        inv = CHKInventory(None)
 
594
        ie = inventory.InventoryDirectory('dir-id', u'dir\u03a9name',
 
595
                                          None)
 
596
        ie.revision = 'dir-rev-id'
 
597
        bytes = inv._entry_to_bytes(ie)
 
598
        self.assertEqual('dir: dir-id\n\ndir\xce\xa9name\n'
 
599
                         'dir-rev-id', bytes)
 
600
        ie2 = inv._bytes_to_entry(bytes)
 
601
        self.assertEqual(ie, ie2)
 
602
        self.assertIsInstance(ie2.name, unicode)
 
603
        self.assertIs(ie2.parent_id, None)
 
604
        self.assertEqual(('dir\xce\xa9name', 'dir-id', 'dir-rev-id'),
 
605
                         inv._bytes_to_utf8name_key(bytes))
 
606
 
 
607
    def test_symlink_entry_to_bytes(self):
 
608
        inv = CHKInventory(None)
 
609
        ie = inventory.InventoryLink('link-id', 'linkname', 'parent-id')
 
610
        ie.revision = 'link-rev-id'
 
611
        ie.symlink_target = u'target/path'
 
612
        bytes = inv._entry_to_bytes(ie)
 
613
        self.assertEqual('symlink: link-id\nparent-id\nlinkname\n'
 
614
                         'link-rev-id\ntarget/path', bytes)
 
615
        ie2 = inv._bytes_to_entry(bytes)
 
616
        self.assertEqual(ie, ie2)
 
617
        self.assertIsInstance(ie2.name, unicode)
 
618
        self.assertIsInstance(ie2.symlink_target, unicode)
 
619
        self.assertEqual(('linkname', 'link-id', 'link-rev-id'),
 
620
                         inv._bytes_to_utf8name_key(bytes))
 
621
 
 
622
    def test_symlink2_entry_to_bytes(self):
 
623
        inv = CHKInventory(None)
 
624
        ie = inventory.InventoryLink('link-id', u'link\u03a9name', 'parent-id')
 
625
        ie.revision = 'link-rev-id'
 
626
        ie.symlink_target = u'target/\u03a9path'
 
627
        bytes = inv._entry_to_bytes(ie)
 
628
        self.assertEqual('symlink: link-id\nparent-id\nlink\xce\xa9name\n'
 
629
                         'link-rev-id\ntarget/\xce\xa9path', bytes)
 
630
        ie2 = inv._bytes_to_entry(bytes)
 
631
        self.assertEqual(ie, ie2)
 
632
        self.assertIsInstance(ie2.name, unicode)
 
633
        self.assertIsInstance(ie2.symlink_target, unicode)
 
634
        self.assertEqual(('link\xce\xa9name', 'link-id', 'link-rev-id'),
 
635
                         inv._bytes_to_utf8name_key(bytes))
 
636
 
 
637
    def test_tree_reference_entry_to_bytes(self):
 
638
        inv = CHKInventory(None)
 
639
        ie = inventory.TreeReference('tree-root-id', u'tree\u03a9name',
 
640
                                     'parent-id')
 
641
        ie.revision = 'tree-rev-id'
 
642
        ie.reference_revision = 'ref-rev-id'
 
643
        bytes = inv._entry_to_bytes(ie)
 
644
        self.assertEqual('tree: tree-root-id\nparent-id\ntree\xce\xa9name\n'
 
645
                         'tree-rev-id\nref-rev-id', bytes)
 
646
        ie2 = inv._bytes_to_entry(bytes)
 
647
        self.assertEqual(ie, ie2)
 
648
        self.assertIsInstance(ie2.name, unicode)
 
649
        self.assertEqual(('tree\xce\xa9name', 'tree-root-id', 'tree-rev-id'),
 
650
                         inv._bytes_to_utf8name_key(bytes))