1
# Copyright (C) 2008, 2009 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 bzrlib.inventory_delta.
19
See doc/developer/inventory.txt for more information.
22
from cStringIO import StringIO
29
from bzrlib.inventory_delta import InventoryDeltaError
30
from bzrlib.inventory import Inventory
31
from bzrlib.revision import NULL_REVISION
32
from bzrlib.tests import TestCase
34
### DO NOT REFLOW THESE TEXTS. NEW LINES ARE SIGNIFICANT. ###
35
empty_lines = """format: bzr inventory delta v1 (bzr 1.14)
42
root_only_lines = """format: bzr inventory delta v1 (bzr 1.14)
44
version: entry-version
47
None\x00/\x00an-id\x00\x00a@e\xc3\xa5ample.com--2004\x00dir
51
root_change_lines = """format: bzr inventory delta v1 (bzr 1.14)
56
/\x00an-id\x00\x00different-version\x00dir
59
corrupt_parent_lines = """format: bzr inventory delta v1 (bzr 1.14)
63
tree_references: false
64
/\x00an-id\x00\x00different-version\x00dir
67
root_only_unversioned = """format: bzr inventory delta v1 (bzr 1.14)
69
version: entry-version
71
tree_references: false
72
None\x00/\x00TREE_ROOT\x00\x00entry-version\x00dir
75
reference_lines = """format: bzr inventory delta v1 (bzr 1.14)
77
version: entry-version
80
None\x00/\x00TREE_ROOT\x00\x00a@e\xc3\xa5ample.com--2004\x00dir
81
None\x00/foo\x00id\x00TREE_ROOT\x00changed\x00tree\x00subtree-version
84
change_tree_lines = """format: bzr inventory delta v1 (bzr 1.14)
88
tree_references: false
89
/foo\x00id\x00TREE_ROOT\x00changed-twice\x00tree\x00subtree-version2
93
class TestDeserialization(TestCase):
94
"""Test InventoryDeltaSerializer.parse_text_bytes."""
96
def test_parse_no_bytes(self):
97
deserializer = inventory_delta.InventoryDeltaDeserializer()
98
err = self.assertRaises(
99
InventoryDeltaError, deserializer.parse_text_bytes, '')
100
self.assertContainsRe(str(err), 'last line not empty')
102
def test_parse_bad_format(self):
103
deserializer = inventory_delta.InventoryDeltaDeserializer()
104
err = self.assertRaises(InventoryDeltaError,
105
deserializer.parse_text_bytes, 'format: foo\n')
106
self.assertContainsRe(str(err), 'unknown format')
108
def test_parse_no_parent(self):
109
deserializer = inventory_delta.InventoryDeltaDeserializer()
110
err = self.assertRaises(InventoryDeltaError,
111
deserializer.parse_text_bytes,
112
'format: bzr inventory delta v1 (bzr 1.14)\n')
113
self.assertContainsRe(str(err), 'missing parent: marker')
115
def test_parse_no_version(self):
116
deserializer = inventory_delta.InventoryDeltaDeserializer()
117
err = self.assertRaises(InventoryDeltaError,
118
deserializer.parse_text_bytes,
119
'format: bzr inventory delta v1 (bzr 1.14)\n'
121
self.assertContainsRe(str(err), 'missing version: marker')
123
def test_parse_duplicate_key_errors(self):
124
deserializer = inventory_delta.InventoryDeltaDeserializer()
125
double_root_lines = \
126
"""format: bzr inventory delta v1 (bzr 1.14)
130
tree_references: true
131
None\x00/\x00an-id\x00\x00a@e\xc3\xa5ample.com--2004\x00dir\x00\x00
132
None\x00/\x00an-id\x00\x00a@e\xc3\xa5ample.com--2004\x00dir\x00\x00
134
err = self.assertRaises(InventoryDeltaError,
135
deserializer.parse_text_bytes, double_root_lines)
136
self.assertContainsRe(str(err), 'duplicate file id')
138
def test_parse_versioned_root_only(self):
139
deserializer = inventory_delta.InventoryDeltaDeserializer()
140
parse_result = deserializer.parse_text_bytes(root_only_lines)
141
expected_entry = inventory.make_entry(
142
'directory', u'', None, 'an-id')
143
expected_entry.revision = 'a@e\xc3\xa5ample.com--2004'
145
('null:', 'entry-version', True, True,
146
[(None, '', 'an-id', expected_entry)]),
149
def test_parse_special_revid_not_valid_last_mod(self):
150
deserializer = inventory_delta.InventoryDeltaDeserializer()
151
root_only_lines = """format: bzr inventory delta v1 (bzr 1.14)
154
versioned_root: false
155
tree_references: true
156
None\x00/\x00TREE_ROOT\x00\x00null:\x00dir\x00\x00
158
err = self.assertRaises(InventoryDeltaError,
159
deserializer.parse_text_bytes, root_only_lines)
160
self.assertContainsRe(str(err), 'special revisionid found')
162
def test_parse_versioned_root_versioned_disabled(self):
163
deserializer = inventory_delta.InventoryDeltaDeserializer()
164
root_only_lines = """format: bzr inventory delta v1 (bzr 1.14)
167
versioned_root: false
168
tree_references: true
169
None\x00/\x00TREE_ROOT\x00\x00a@e\xc3\xa5ample.com--2004\x00dir\x00\x00
171
err = self.assertRaises(InventoryDeltaError,
172
deserializer.parse_text_bytes, root_only_lines)
173
self.assertContainsRe(str(err), 'Versioned root found')
175
def test_parse_unique_root_id_root_versioned_disabled(self):
176
deserializer = inventory_delta.InventoryDeltaDeserializer()
177
root_only_lines = """format: bzr inventory delta v1 (bzr 1.14)
179
version: a@e\xc3\xa5ample.com--2004
180
versioned_root: false
181
tree_references: true
182
None\x00/\x00an-id\x00\x00parent-id\x00dir\x00\x00
184
err = self.assertRaises(InventoryDeltaError,
185
deserializer.parse_text_bytes, root_only_lines)
186
self.assertContainsRe(str(err), 'Versioned root found')
188
def test_parse_unversioned_root_versioning_enabled(self):
189
deserializer = inventory_delta.InventoryDeltaDeserializer()
190
parse_result = deserializer.parse_text_bytes(root_only_unversioned)
191
expected_entry = inventory.make_entry(
192
'directory', u'', None, 'TREE_ROOT')
193
expected_entry.revision = 'entry-version'
195
('null:', 'entry-version', False, False,
196
[(None, u'', 'TREE_ROOT', expected_entry)]),
199
def test_parse_versioned_root_when_disabled(self):
200
deserializer = inventory_delta.InventoryDeltaDeserializer(
201
allow_versioned_root=False)
202
err = self.assertRaises(inventory_delta.IncompatibleInventoryDelta,
203
deserializer.parse_text_bytes, root_only_lines)
204
self.assertEquals("versioned_root not allowed", str(err))
206
def test_parse_tree_when_disabled(self):
207
deserializer = inventory_delta.InventoryDeltaDeserializer(
208
allow_tree_references=False)
209
err = self.assertRaises(inventory_delta.IncompatibleInventoryDelta,
210
deserializer.parse_text_bytes, reference_lines)
211
self.assertEquals("Tree reference not allowed", str(err))
213
def test_parse_tree_when_header_disallows(self):
214
# A deserializer that allows tree_references to be set or unset.
215
deserializer = inventory_delta.InventoryDeltaDeserializer()
216
# A serialised inventory delta with a header saying no tree refs, but
217
# that has a tree ref in its content.
218
lines = """format: bzr inventory delta v1 (bzr 1.14)
220
version: entry-version
221
versioned_root: false
222
tree_references: false
223
None\x00/foo\x00id\x00TREE_ROOT\x00changed\x00tree\x00subtree-version
225
err = self.assertRaises(InventoryDeltaError,
226
deserializer.parse_text_bytes, lines)
227
self.assertContainsRe(str(err), 'Tree reference found')
229
def test_parse_versioned_root_when_header_disallows(self):
230
# A deserializer that allows tree_references to be set or unset.
231
deserializer = inventory_delta.InventoryDeltaDeserializer()
232
# A serialised inventory delta with a header saying no tree refs, but
233
# that has a tree ref in its content.
234
lines = """format: bzr inventory delta v1 (bzr 1.14)
236
version: entry-version
237
versioned_root: false
238
tree_references: false
239
None\x00/\x00TREE_ROOT\x00\x00a@e\xc3\xa5ample.com--2004\x00dir
241
err = self.assertRaises(InventoryDeltaError,
242
deserializer.parse_text_bytes, lines)
243
self.assertContainsRe(str(err), 'Versioned root found')
245
def test_parse_last_line_not_empty(self):
246
"""newpath must start with / if it is not None."""
247
# Trim the trailing newline from a valid serialization
248
lines = root_only_lines[:-1]
249
deserializer = inventory_delta.InventoryDeltaDeserializer()
250
err = self.assertRaises(InventoryDeltaError,
251
deserializer.parse_text_bytes, lines)
252
self.assertContainsRe(str(err), 'last line not empty')
254
def test_parse_invalid_newpath(self):
255
"""newpath must start with / if it is not None."""
257
lines += "None\x00bad\x00TREE_ROOT\x00\x00version\x00dir\n"
258
deserializer = inventory_delta.InventoryDeltaDeserializer()
259
err = self.assertRaises(InventoryDeltaError,
260
deserializer.parse_text_bytes, lines)
261
self.assertContainsRe(str(err), 'newpath invalid')
263
def test_parse_invalid_oldpath(self):
264
"""oldpath must start with / if it is not None."""
265
lines = root_only_lines
266
lines += "bad\x00/new\x00file-id\x00\x00version\x00dir\n"
267
deserializer = inventory_delta.InventoryDeltaDeserializer()
268
err = self.assertRaises(InventoryDeltaError,
269
deserializer.parse_text_bytes, lines)
270
self.assertContainsRe(str(err), 'oldpath invalid')
272
def test_parse_new_file(self):
273
"""a new file is parsed correctly"""
274
lines = root_only_lines
275
fake_sha = "deadbeef" * 5
277
"None\x00/new\x00file-id\x00an-id\x00version\x00file\x00123\x00" +
278
"\x00" + fake_sha + "\n")
279
deserializer = inventory_delta.InventoryDeltaDeserializer()
280
parse_result = deserializer.parse_text_bytes(lines)
281
expected_entry = inventory.make_entry(
282
'file', u'new', 'an-id', 'file-id')
283
expected_entry.revision = 'version'
284
expected_entry.text_size = 123
285
expected_entry.text_sha1 = fake_sha
286
delta = parse_result[4]
288
(None, u'new', 'file-id', expected_entry), delta[-1])
290
def test_parse_delete(self):
291
lines = root_only_lines
293
"/old-file\x00None\x00deleted-id\x00\x00null:\x00deleted\x00\x00\n")
294
deserializer = inventory_delta.InventoryDeltaDeserializer()
295
parse_result = deserializer.parse_text_bytes(lines)
296
delta = parse_result[4]
298
(u'old-file', None, 'deleted-id', None), delta[-1])
301
class TestSerialization(TestCase):
302
"""Tests for InventoryDeltaSerializer.delta_to_lines."""
304
def test_empty_delta_to_lines(self):
305
old_inv = Inventory(None)
306
new_inv = Inventory(None)
307
delta = new_inv._make_delta(old_inv)
308
serializer = inventory_delta.InventoryDeltaSerializer(
309
versioned_root=True, tree_references=True)
310
self.assertEqual(StringIO(empty_lines).readlines(),
311
serializer.delta_to_lines(NULL_REVISION, NULL_REVISION, delta))
313
def test_root_only_to_lines(self):
314
old_inv = Inventory(None)
315
new_inv = Inventory(None)
316
root = new_inv.make_entry('directory', '', None, 'an-id')
317
root.revision = 'a@e\xc3\xa5ample.com--2004'
319
delta = new_inv._make_delta(old_inv)
320
serializer = inventory_delta.InventoryDeltaSerializer(
321
versioned_root=True, tree_references=True)
322
self.assertEqual(StringIO(root_only_lines).readlines(),
323
serializer.delta_to_lines(NULL_REVISION, 'entry-version', delta))
325
def test_unversioned_root(self):
326
old_inv = Inventory(None)
327
new_inv = Inventory(None)
328
root = new_inv.make_entry('directory', '', None, 'TREE_ROOT')
329
# Implicit roots are considered modified in every revision.
330
root.revision = 'entry-version'
332
delta = new_inv._make_delta(old_inv)
333
serializer = inventory_delta.InventoryDeltaSerializer(
334
versioned_root=False, tree_references=False)
335
serialized_lines = serializer.delta_to_lines(
336
NULL_REVISION, 'entry-version', delta)
337
self.assertEqual(StringIO(root_only_unversioned).readlines(),
339
deserializer = inventory_delta.InventoryDeltaDeserializer()
341
(NULL_REVISION, 'entry-version', False, False, delta),
342
deserializer.parse_text_bytes(''.join(serialized_lines)))
344
def test_unversioned_non_root_errors(self):
345
old_inv = Inventory(None)
346
new_inv = Inventory(None)
347
root = new_inv.make_entry('directory', '', None, 'TREE_ROOT')
348
root.revision = 'a@e\xc3\xa5ample.com--2004'
350
non_root = new_inv.make_entry('directory', 'foo', root.file_id, 'id')
351
new_inv.add(non_root)
352
delta = new_inv._make_delta(old_inv)
353
serializer = inventory_delta.InventoryDeltaSerializer(
354
versioned_root=True, tree_references=True)
355
err = self.assertRaises(InventoryDeltaError,
356
serializer.delta_to_lines, NULL_REVISION, 'entry-version', delta)
357
self.assertEqual(str(err), 'no version for fileid id')
359
def test_richroot_unversioned_root_errors(self):
360
old_inv = Inventory(None)
361
new_inv = Inventory(None)
362
root = new_inv.make_entry('directory', '', None, 'TREE_ROOT')
364
delta = new_inv._make_delta(old_inv)
365
serializer = inventory_delta.InventoryDeltaSerializer(
366
versioned_root=True, tree_references=True)
367
err = self.assertRaises(InventoryDeltaError,
368
serializer.delta_to_lines, NULL_REVISION, 'entry-version', delta)
369
self.assertEqual(str(err), 'no version for fileid TREE_ROOT')
371
def test_nonrichroot_versioned_root_errors(self):
372
old_inv = Inventory(None)
373
new_inv = Inventory(None)
374
root = new_inv.make_entry('directory', '', None, 'TREE_ROOT')
375
root.revision = 'a@e\xc3\xa5ample.com--2004'
377
delta = new_inv._make_delta(old_inv)
378
serializer = inventory_delta.InventoryDeltaSerializer(
379
versioned_root=False, tree_references=True)
380
err = self.assertRaises(InventoryDeltaError,
381
serializer.delta_to_lines, NULL_REVISION, 'entry-version', delta)
382
self.assertStartsWith(str(err), 'Version present for / in TREE_ROOT')
384
def test_unknown_kind_errors(self):
385
old_inv = Inventory(None)
386
new_inv = Inventory(None)
387
root = new_inv.make_entry('directory', '', None, 'my-rich-root-id')
388
root.revision = 'changed'
390
non_root = new_inv.make_entry('directory', 'foo', root.file_id, 'id')
391
non_root.revision = 'changed'
392
non_root.kind = 'strangelove'
393
new_inv.add(non_root)
394
delta = new_inv._make_delta(old_inv)
395
serializer = inventory_delta.InventoryDeltaSerializer(
396
versioned_root=True, tree_references=True)
397
# we expect keyerror because there is little value wrapping this.
398
# This test aims to prove that it errors more than how it errors.
399
err = self.assertRaises(KeyError,
400
serializer.delta_to_lines, NULL_REVISION, 'entry-version', delta)
401
self.assertEqual(('strangelove',), err.args)
403
def test_tree_reference_disabled(self):
404
old_inv = Inventory(None)
405
new_inv = Inventory(None)
406
root = new_inv.make_entry('directory', '', None, 'TREE_ROOT')
407
root.revision = 'a@e\xc3\xa5ample.com--2004'
409
non_root = new_inv.make_entry(
410
'tree-reference', 'foo', root.file_id, 'id')
411
non_root.revision = 'changed'
412
non_root.reference_revision = 'subtree-version'
413
new_inv.add(non_root)
414
delta = new_inv._make_delta(old_inv)
415
serializer = inventory_delta.InventoryDeltaSerializer(
416
versioned_root=True, tree_references=False)
417
# we expect keyerror because there is little value wrapping this.
418
# This test aims to prove that it errors more than how it errors.
419
err = self.assertRaises(KeyError,
420
serializer.delta_to_lines, NULL_REVISION, 'entry-version', delta)
421
self.assertEqual(('tree-reference',), err.args)
423
def test_tree_reference_enabled(self):
424
old_inv = Inventory(None)
425
new_inv = Inventory(None)
426
root = new_inv.make_entry('directory', '', None, 'TREE_ROOT')
427
root.revision = 'a@e\xc3\xa5ample.com--2004'
429
non_root = new_inv.make_entry(
430
'tree-reference', 'foo', root.file_id, 'id')
431
non_root.revision = 'changed'
432
non_root.reference_revision = 'subtree-version'
433
new_inv.add(non_root)
434
delta = new_inv._make_delta(old_inv)
435
serializer = inventory_delta.InventoryDeltaSerializer(
436
versioned_root=True, tree_references=True)
437
self.assertEqual(StringIO(reference_lines).readlines(),
438
serializer.delta_to_lines(NULL_REVISION, 'entry-version', delta))
440
def test_to_inventory_root_id_versioned_not_permitted(self):
441
root_entry = inventory.make_entry('directory', '', None, 'TREE_ROOT')
442
root_entry.revision = 'some-version'
443
delta = [(None, '', 'TREE_ROOT', root_entry)]
444
serializer = inventory_delta.InventoryDeltaSerializer(
445
versioned_root=False, tree_references=True)
447
InventoryDeltaError, serializer.delta_to_lines, 'old-version',
448
'new-version', delta)
450
def test_to_inventory_root_id_not_versioned(self):
451
delta = [(None, '', 'an-id', inventory.make_entry(
452
'directory', '', None, 'an-id'))]
453
serializer = inventory_delta.InventoryDeltaSerializer(
454
versioned_root=True, tree_references=True)
456
InventoryDeltaError, serializer.delta_to_lines, 'old-version',
457
'new-version', delta)
459
def test_to_inventory_has_tree_not_meant_to(self):
460
make_entry = inventory.make_entry
461
tree_ref = make_entry('tree-reference', 'foo', 'changed-in', 'ref-id')
462
tree_ref.reference_revision = 'ref-revision'
465
make_entry('directory', '', 'changed-in', 'an-id')),
466
(None, 'foo', 'ref-id', tree_ref)
467
# a file that followed the root move
469
serializer = inventory_delta.InventoryDeltaSerializer(
470
versioned_root=True, tree_references=True)
471
self.assertRaises(InventoryDeltaError, serializer.delta_to_lines,
472
'old-version', 'new-version', delta)
474
def test_to_inventory_torture(self):
475
def make_entry(kind, name, parent_id, file_id, **attrs):
476
entry = inventory.make_entry(kind, name, parent_id, file_id)
477
for name, value in attrs.items():
478
setattr(entry, name, value)
480
# this delta is crafted to have all the following:
484
# - files moved after parent dir was renamed
485
# - files with and without exec bit
488
(None, '', 'new-root-id',
489
make_entry('directory', '', None, 'new-root-id',
490
revision='changed-in')),
492
('', 'old-root', 'TREE_ROOT',
493
make_entry('directory', 'subdir-now', 'new-root-id',
494
'TREE_ROOT', revision='moved-root')),
495
# a file that followed the root move
496
('under-old-root', 'old-root/under-old-root', 'moved-id',
497
make_entry('file', 'under-old-root', 'TREE_ROOT', 'moved-id',
498
revision='old-rev', executable=False, text_size=30,
499
text_sha1='some-sha')),
501
('old-file', None, 'deleted-id', None),
502
# a tree reference moved to the new root
503
('ref', 'ref', 'ref-id',
504
make_entry('tree-reference', 'ref', 'new-root-id', 'ref-id',
505
reference_revision='tree-reference-id',
506
revision='new-rev')),
507
# a symlink now in a deep dir
508
('dir/link', 'old-root/dir/link', 'link-id',
509
make_entry('symlink', 'link', 'deep-id', 'link-id',
510
symlink_target='target', revision='new-rev')),
512
('dir', 'old-root/dir', 'deep-id',
513
make_entry('directory', 'dir', 'TREE_ROOT', 'deep-id',
514
revision='new-rev')),
515
# a file with an exec bit set
516
(None, 'configure', 'exec-id',
517
make_entry('file', 'configure', 'new-root-id', 'exec-id',
518
executable=True, text_size=30, text_sha1='some-sha',
519
revision='old-rev')),
521
serializer = inventory_delta.InventoryDeltaSerializer(
522
versioned_root=True, tree_references=True)
523
lines = serializer.delta_to_lines(NULL_REVISION, 'something', delta)
524
expected = """format: bzr inventory delta v1 (bzr 1.14)
528
tree_references: true
529
/\x00/old-root\x00TREE_ROOT\x00new-root-id\x00moved-root\x00dir
530
/dir\x00/old-root/dir\x00deep-id\x00TREE_ROOT\x00new-rev\x00dir
531
/dir/link\x00/old-root/dir/link\x00link-id\x00deep-id\x00new-rev\x00link\x00target
532
/old-file\x00None\x00deleted-id\x00\x00null:\x00deleted\x00\x00
533
/ref\x00/ref\x00ref-id\x00new-root-id\x00new-rev\x00tree\x00tree-reference-id
534
/under-old-root\x00/old-root/under-old-root\x00moved-id\x00TREE_ROOT\x00old-rev\x00file\x0030\x00\x00some-sha
535
None\x00/\x00new-root-id\x00\x00changed-in\x00dir
536
None\x00/configure\x00exec-id\x00new-root-id\x00old-rev\x00file\x0030\x00Y\x00some-sha
538
serialized = ''.join(lines)
539
self.assertIsInstance(serialized, str)
540
self.assertEqual(expected, serialized)
543
class TestContent(TestCase):
544
"""Test serialization of the content part of a line."""
547
entry = inventory.make_entry('directory', 'a dir', None)
548
self.assertEqual('dir', inventory_delta._directory_content(entry))
550
def test_file_0_short_sha(self):
551
file_entry = inventory.make_entry('file', 'a file', None, 'file-id')
552
file_entry.text_sha1 = ''
553
file_entry.text_size = 0
554
self.assertEqual('file\x000\x00\x00',
555
inventory_delta._file_content(file_entry))
557
def test_file_10_foo(self):
558
file_entry = inventory.make_entry('file', 'a file', None, 'file-id')
559
file_entry.text_sha1 = 'foo'
560
file_entry.text_size = 10
561
self.assertEqual('file\x0010\x00\x00foo',
562
inventory_delta._file_content(file_entry))
564
def test_file_executable(self):
565
file_entry = inventory.make_entry('file', 'a file', None, 'file-id')
566
file_entry.executable = True
567
file_entry.text_sha1 = 'foo'
568
file_entry.text_size = 10
569
self.assertEqual('file\x0010\x00Y\x00foo',
570
inventory_delta._file_content(file_entry))
572
def test_file_without_size(self):
573
file_entry = inventory.make_entry('file', 'a file', None, 'file-id')
574
file_entry.text_sha1 = 'foo'
575
self.assertRaises(InventoryDeltaError,
576
inventory_delta._file_content, file_entry)
578
def test_file_without_sha1(self):
579
file_entry = inventory.make_entry('file', 'a file', None, 'file-id')
580
file_entry.text_size = 10
581
self.assertRaises(InventoryDeltaError,
582
inventory_delta._file_content, file_entry)
584
def test_link_empty_target(self):
585
entry = inventory.make_entry('symlink', 'a link', None)
586
entry.symlink_target = ''
587
self.assertEqual('link\x00',
588
inventory_delta._link_content(entry))
590
def test_link_unicode_target(self):
591
entry = inventory.make_entry('symlink', 'a link', None)
592
entry.symlink_target = ' \xc3\xa5'.decode('utf8')
593
self.assertEqual('link\x00 \xc3\xa5',
594
inventory_delta._link_content(entry))
596
def test_link_space_target(self):
597
entry = inventory.make_entry('symlink', 'a link', None)
598
entry.symlink_target = ' '
599
self.assertEqual('link\x00 ',
600
inventory_delta._link_content(entry))
602
def test_link_no_target(self):
603
entry = inventory.make_entry('symlink', 'a link', None)
604
self.assertRaises(InventoryDeltaError,
605
inventory_delta._link_content, entry)
607
def test_reference_null(self):
608
entry = inventory.make_entry('tree-reference', 'a tree', None)
609
entry.reference_revision = NULL_REVISION
610
self.assertEqual('tree\x00null:',
611
inventory_delta._reference_content(entry))
613
def test_reference_revision(self):
614
entry = inventory.make_entry('tree-reference', 'a tree', None)
615
entry.reference_revision = 'foo@\xc3\xa5b-lah'
616
self.assertEqual('tree\x00foo@\xc3\xa5b-lah',
617
inventory_delta._reference_content(entry))
619
def test_reference_no_reference(self):
620
entry = inventory.make_entry('tree-reference', 'a tree', None)
621
self.assertRaises(InventoryDeltaError,
622
inventory_delta._reference_content, entry)