diff options
Diffstat (limited to 'bzrlib/tests/test_inventory_delta.py')
-rw-r--r-- | bzrlib/tests/test_inventory_delta.py | 622 |
1 files changed, 622 insertions, 0 deletions
diff --git a/bzrlib/tests/test_inventory_delta.py b/bzrlib/tests/test_inventory_delta.py new file mode 100644 index 0000000..b44e493 --- /dev/null +++ b/bzrlib/tests/test_inventory_delta.py @@ -0,0 +1,622 @@ +# Copyright (C) 2009, 2010, 2011 Canonical Ltd +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +"""Tests for bzrlib.inventory_delta. + +See doc/developer/inventory.txt for more information. +""" + +from cStringIO import StringIO + +from bzrlib import ( + inventory, + inventory_delta, + ) +from bzrlib.inventory_delta import InventoryDeltaError +from bzrlib.inventory import Inventory +from bzrlib.revision import NULL_REVISION +from bzrlib.tests import TestCase + +### DO NOT REFLOW THESE TEXTS. NEW LINES ARE SIGNIFICANT. ### +empty_lines = """format: bzr inventory delta v1 (bzr 1.14) +parent: null: +version: null: +versioned_root: true +tree_references: true +""" + +root_only_lines = """format: bzr inventory delta v1 (bzr 1.14) +parent: null: +version: entry-version +versioned_root: true +tree_references: true +None\x00/\x00an-id\x00\x00a@e\xc3\xa5ample.com--2004\x00dir +""" + + +root_change_lines = """format: bzr inventory delta v1 (bzr 1.14) +parent: entry-version +version: changed-root +versioned_root: true +tree_references: true +/\x00an-id\x00\x00different-version\x00dir +""" + +corrupt_parent_lines = """format: bzr inventory delta v1 (bzr 1.14) +parent: entry-version +version: changed-root +versioned_root: false +tree_references: false +/\x00an-id\x00\x00different-version\x00dir +""" + +root_only_unversioned = """format: bzr inventory delta v1 (bzr 1.14) +parent: null: +version: entry-version +versioned_root: false +tree_references: false +None\x00/\x00TREE_ROOT\x00\x00entry-version\x00dir +""" + +reference_lines = """format: bzr inventory delta v1 (bzr 1.14) +parent: null: +version: entry-version +versioned_root: true +tree_references: true +None\x00/\x00TREE_ROOT\x00\x00a@e\xc3\xa5ample.com--2004\x00dir +None\x00/foo\x00id\x00TREE_ROOT\x00changed\x00tree\x00subtree-version +""" + +change_tree_lines = """format: bzr inventory delta v1 (bzr 1.14) +parent: entry-version +version: change-tree +versioned_root: false +tree_references: false +/foo\x00id\x00TREE_ROOT\x00changed-twice\x00tree\x00subtree-version2 +""" + + +class TestDeserialization(TestCase): + """Test InventoryDeltaSerializer.parse_text_bytes.""" + + def test_parse_no_bytes(self): + deserializer = inventory_delta.InventoryDeltaDeserializer() + err = self.assertRaises( + InventoryDeltaError, deserializer.parse_text_bytes, '') + self.assertContainsRe(str(err), 'last line not empty') + + def test_parse_bad_format(self): + deserializer = inventory_delta.InventoryDeltaDeserializer() + err = self.assertRaises(InventoryDeltaError, + deserializer.parse_text_bytes, 'format: foo\n') + self.assertContainsRe(str(err), 'unknown format') + + def test_parse_no_parent(self): + deserializer = inventory_delta.InventoryDeltaDeserializer() + err = self.assertRaises(InventoryDeltaError, + deserializer.parse_text_bytes, + 'format: bzr inventory delta v1 (bzr 1.14)\n') + self.assertContainsRe(str(err), 'missing parent: marker') + + def test_parse_no_version(self): + deserializer = inventory_delta.InventoryDeltaDeserializer() + err = self.assertRaises(InventoryDeltaError, + deserializer.parse_text_bytes, + 'format: bzr inventory delta v1 (bzr 1.14)\n' + 'parent: null:\n') + self.assertContainsRe(str(err), 'missing version: marker') + + def test_parse_duplicate_key_errors(self): + deserializer = inventory_delta.InventoryDeltaDeserializer() + double_root_lines = \ +"""format: bzr inventory delta v1 (bzr 1.14) +parent: null: +version: null: +versioned_root: true +tree_references: true +None\x00/\x00an-id\x00\x00a@e\xc3\xa5ample.com--2004\x00dir\x00\x00 +None\x00/\x00an-id\x00\x00a@e\xc3\xa5ample.com--2004\x00dir\x00\x00 +""" + err = self.assertRaises(InventoryDeltaError, + deserializer.parse_text_bytes, double_root_lines) + self.assertContainsRe(str(err), 'duplicate file id') + + def test_parse_versioned_root_only(self): + deserializer = inventory_delta.InventoryDeltaDeserializer() + parse_result = deserializer.parse_text_bytes(root_only_lines) + expected_entry = inventory.make_entry( + 'directory', u'', None, 'an-id') + expected_entry.revision = 'a@e\xc3\xa5ample.com--2004' + self.assertEqual( + ('null:', 'entry-version', True, True, + [(None, '', 'an-id', expected_entry)]), + parse_result) + + def test_parse_special_revid_not_valid_last_mod(self): + deserializer = inventory_delta.InventoryDeltaDeserializer() + root_only_lines = """format: bzr inventory delta v1 (bzr 1.14) +parent: null: +version: null: +versioned_root: false +tree_references: true +None\x00/\x00TREE_ROOT\x00\x00null:\x00dir\x00\x00 +""" + err = self.assertRaises(InventoryDeltaError, + deserializer.parse_text_bytes, root_only_lines) + self.assertContainsRe(str(err), 'special revisionid found') + + def test_parse_versioned_root_versioned_disabled(self): + deserializer = inventory_delta.InventoryDeltaDeserializer() + root_only_lines = """format: bzr inventory delta v1 (bzr 1.14) +parent: null: +version: null: +versioned_root: false +tree_references: true +None\x00/\x00TREE_ROOT\x00\x00a@e\xc3\xa5ample.com--2004\x00dir\x00\x00 +""" + err = self.assertRaises(InventoryDeltaError, + deserializer.parse_text_bytes, root_only_lines) + self.assertContainsRe(str(err), 'Versioned root found') + + def test_parse_unique_root_id_root_versioned_disabled(self): + deserializer = inventory_delta.InventoryDeltaDeserializer() + root_only_lines = """format: bzr inventory delta v1 (bzr 1.14) +parent: parent-id +version: a@e\xc3\xa5ample.com--2004 +versioned_root: false +tree_references: true +None\x00/\x00an-id\x00\x00parent-id\x00dir\x00\x00 +""" + err = self.assertRaises(InventoryDeltaError, + deserializer.parse_text_bytes, root_only_lines) + self.assertContainsRe(str(err), 'Versioned root found') + + def test_parse_unversioned_root_versioning_enabled(self): + deserializer = inventory_delta.InventoryDeltaDeserializer() + parse_result = deserializer.parse_text_bytes(root_only_unversioned) + expected_entry = inventory.make_entry( + 'directory', u'', None, 'TREE_ROOT') + expected_entry.revision = 'entry-version' + self.assertEqual( + ('null:', 'entry-version', False, False, + [(None, u'', 'TREE_ROOT', expected_entry)]), + parse_result) + + def test_parse_versioned_root_when_disabled(self): + deserializer = inventory_delta.InventoryDeltaDeserializer( + allow_versioned_root=False) + err = self.assertRaises(inventory_delta.IncompatibleInventoryDelta, + deserializer.parse_text_bytes, root_only_lines) + self.assertEquals("versioned_root not allowed", str(err)) + + def test_parse_tree_when_disabled(self): + deserializer = inventory_delta.InventoryDeltaDeserializer( + allow_tree_references=False) + err = self.assertRaises(inventory_delta.IncompatibleInventoryDelta, + deserializer.parse_text_bytes, reference_lines) + self.assertEquals("Tree reference not allowed", str(err)) + + def test_parse_tree_when_header_disallows(self): + # A deserializer that allows tree_references to be set or unset. + deserializer = inventory_delta.InventoryDeltaDeserializer() + # A serialised inventory delta with a header saying no tree refs, but + # that has a tree ref in its content. + lines = """format: bzr inventory delta v1 (bzr 1.14) +parent: null: +version: entry-version +versioned_root: false +tree_references: false +None\x00/foo\x00id\x00TREE_ROOT\x00changed\x00tree\x00subtree-version +""" + err = self.assertRaises(InventoryDeltaError, + deserializer.parse_text_bytes, lines) + self.assertContainsRe(str(err), 'Tree reference found') + + def test_parse_versioned_root_when_header_disallows(self): + # A deserializer that allows tree_references to be set or unset. + deserializer = inventory_delta.InventoryDeltaDeserializer() + # A serialised inventory delta with a header saying no tree refs, but + # that has a tree ref in its content. + lines = """format: bzr inventory delta v1 (bzr 1.14) +parent: null: +version: entry-version +versioned_root: false +tree_references: false +None\x00/\x00TREE_ROOT\x00\x00a@e\xc3\xa5ample.com--2004\x00dir +""" + err = self.assertRaises(InventoryDeltaError, + deserializer.parse_text_bytes, lines) + self.assertContainsRe(str(err), 'Versioned root found') + + def test_parse_last_line_not_empty(self): + """newpath must start with / if it is not None.""" + # Trim the trailing newline from a valid serialization + lines = root_only_lines[:-1] + deserializer = inventory_delta.InventoryDeltaDeserializer() + err = self.assertRaises(InventoryDeltaError, + deserializer.parse_text_bytes, lines) + self.assertContainsRe(str(err), 'last line not empty') + + def test_parse_invalid_newpath(self): + """newpath must start with / if it is not None.""" + lines = empty_lines + lines += "None\x00bad\x00TREE_ROOT\x00\x00version\x00dir\n" + deserializer = inventory_delta.InventoryDeltaDeserializer() + err = self.assertRaises(InventoryDeltaError, + deserializer.parse_text_bytes, lines) + self.assertContainsRe(str(err), 'newpath invalid') + + def test_parse_invalid_oldpath(self): + """oldpath must start with / if it is not None.""" + lines = root_only_lines + lines += "bad\x00/new\x00file-id\x00\x00version\x00dir\n" + deserializer = inventory_delta.InventoryDeltaDeserializer() + err = self.assertRaises(InventoryDeltaError, + deserializer.parse_text_bytes, lines) + self.assertContainsRe(str(err), 'oldpath invalid') + + def test_parse_new_file(self): + """a new file is parsed correctly""" + lines = root_only_lines + fake_sha = "deadbeef" * 5 + lines += ( + "None\x00/new\x00file-id\x00an-id\x00version\x00file\x00123\x00" + + "\x00" + fake_sha + "\n") + deserializer = inventory_delta.InventoryDeltaDeserializer() + parse_result = deserializer.parse_text_bytes(lines) + expected_entry = inventory.make_entry( + 'file', u'new', 'an-id', 'file-id') + expected_entry.revision = 'version' + expected_entry.text_size = 123 + expected_entry.text_sha1 = fake_sha + delta = parse_result[4] + self.assertEqual( + (None, u'new', 'file-id', expected_entry), delta[-1]) + + def test_parse_delete(self): + lines = root_only_lines + lines += ( + "/old-file\x00None\x00deleted-id\x00\x00null:\x00deleted\x00\x00\n") + deserializer = inventory_delta.InventoryDeltaDeserializer() + parse_result = deserializer.parse_text_bytes(lines) + delta = parse_result[4] + self.assertEqual( + (u'old-file', None, 'deleted-id', None), delta[-1]) + + +class TestSerialization(TestCase): + """Tests for InventoryDeltaSerializer.delta_to_lines.""" + + def test_empty_delta_to_lines(self): + old_inv = Inventory(None) + new_inv = Inventory(None) + delta = new_inv._make_delta(old_inv) + serializer = inventory_delta.InventoryDeltaSerializer( + versioned_root=True, tree_references=True) + self.assertEqual(StringIO(empty_lines).readlines(), + serializer.delta_to_lines(NULL_REVISION, NULL_REVISION, delta)) + + def test_root_only_to_lines(self): + old_inv = Inventory(None) + new_inv = Inventory(None) + root = new_inv.make_entry('directory', '', None, 'an-id') + root.revision = 'a@e\xc3\xa5ample.com--2004' + new_inv.add(root) + delta = new_inv._make_delta(old_inv) + serializer = inventory_delta.InventoryDeltaSerializer( + versioned_root=True, tree_references=True) + self.assertEqual(StringIO(root_only_lines).readlines(), + serializer.delta_to_lines(NULL_REVISION, 'entry-version', delta)) + + def test_unversioned_root(self): + old_inv = Inventory(None) + new_inv = Inventory(None) + root = new_inv.make_entry('directory', '', None, 'TREE_ROOT') + # Implicit roots are considered modified in every revision. + root.revision = 'entry-version' + new_inv.add(root) + delta = new_inv._make_delta(old_inv) + serializer = inventory_delta.InventoryDeltaSerializer( + versioned_root=False, tree_references=False) + serialized_lines = serializer.delta_to_lines( + NULL_REVISION, 'entry-version', delta) + self.assertEqual(StringIO(root_only_unversioned).readlines(), + serialized_lines) + deserializer = inventory_delta.InventoryDeltaDeserializer() + self.assertEqual( + (NULL_REVISION, 'entry-version', False, False, delta), + deserializer.parse_text_bytes(''.join(serialized_lines))) + + def test_unversioned_non_root_errors(self): + old_inv = Inventory(None) + new_inv = Inventory(None) + root = new_inv.make_entry('directory', '', None, 'TREE_ROOT') + root.revision = 'a@e\xc3\xa5ample.com--2004' + new_inv.add(root) + non_root = new_inv.make_entry('directory', 'foo', root.file_id, 'id') + new_inv.add(non_root) + delta = new_inv._make_delta(old_inv) + serializer = inventory_delta.InventoryDeltaSerializer( + versioned_root=True, tree_references=True) + err = self.assertRaises(InventoryDeltaError, + serializer.delta_to_lines, NULL_REVISION, 'entry-version', delta) + self.assertEqual(str(err), 'no version for fileid id') + + def test_richroot_unversioned_root_errors(self): + old_inv = Inventory(None) + new_inv = Inventory(None) + root = new_inv.make_entry('directory', '', None, 'TREE_ROOT') + new_inv.add(root) + delta = new_inv._make_delta(old_inv) + serializer = inventory_delta.InventoryDeltaSerializer( + versioned_root=True, tree_references=True) + err = self.assertRaises(InventoryDeltaError, + serializer.delta_to_lines, NULL_REVISION, 'entry-version', delta) + self.assertEqual(str(err), 'no version for fileid TREE_ROOT') + + def test_nonrichroot_versioned_root_errors(self): + old_inv = Inventory(None) + new_inv = Inventory(None) + root = new_inv.make_entry('directory', '', None, 'TREE_ROOT') + root.revision = 'a@e\xc3\xa5ample.com--2004' + new_inv.add(root) + delta = new_inv._make_delta(old_inv) + serializer = inventory_delta.InventoryDeltaSerializer( + versioned_root=False, tree_references=True) + err = self.assertRaises(InventoryDeltaError, + serializer.delta_to_lines, NULL_REVISION, 'entry-version', delta) + self.assertStartsWith(str(err), 'Version present for / in TREE_ROOT') + + def test_unknown_kind_errors(self): + old_inv = Inventory(None) + new_inv = Inventory(None) + root = new_inv.make_entry('directory', '', None, 'my-rich-root-id') + root.revision = 'changed' + new_inv.add(root) + class StrangeInventoryEntry(inventory.InventoryEntry): + kind = 'strange' + non_root = StrangeInventoryEntry('id', 'foo', root.file_id) + non_root.revision = 'changed' + new_inv.add(non_root) + delta = new_inv._make_delta(old_inv) + serializer = inventory_delta.InventoryDeltaSerializer( + versioned_root=True, tree_references=True) + # we expect keyerror because there is little value wrapping this. + # This test aims to prove that it errors more than how it errors. + err = self.assertRaises(KeyError, + serializer.delta_to_lines, NULL_REVISION, 'entry-version', delta) + self.assertEqual(('strange',), err.args) + + def test_tree_reference_disabled(self): + old_inv = Inventory(None) + new_inv = Inventory(None) + root = new_inv.make_entry('directory', '', None, 'TREE_ROOT') + root.revision = 'a@e\xc3\xa5ample.com--2004' + new_inv.add(root) + non_root = new_inv.make_entry( + 'tree-reference', 'foo', root.file_id, 'id') + non_root.revision = 'changed' + non_root.reference_revision = 'subtree-version' + new_inv.add(non_root) + delta = new_inv._make_delta(old_inv) + serializer = inventory_delta.InventoryDeltaSerializer( + versioned_root=True, tree_references=False) + # we expect keyerror because there is little value wrapping this. + # This test aims to prove that it errors more than how it errors. + err = self.assertRaises(KeyError, + serializer.delta_to_lines, NULL_REVISION, 'entry-version', delta) + self.assertEqual(('tree-reference',), err.args) + + def test_tree_reference_enabled(self): + old_inv = Inventory(None) + new_inv = Inventory(None) + root = new_inv.make_entry('directory', '', None, 'TREE_ROOT') + root.revision = 'a@e\xc3\xa5ample.com--2004' + new_inv.add(root) + non_root = new_inv.make_entry( + 'tree-reference', 'foo', root.file_id, 'id') + non_root.revision = 'changed' + non_root.reference_revision = 'subtree-version' + new_inv.add(non_root) + delta = new_inv._make_delta(old_inv) + serializer = inventory_delta.InventoryDeltaSerializer( + versioned_root=True, tree_references=True) + self.assertEqual(StringIO(reference_lines).readlines(), + serializer.delta_to_lines(NULL_REVISION, 'entry-version', delta)) + + def test_to_inventory_root_id_versioned_not_permitted(self): + root_entry = inventory.make_entry('directory', '', None, 'TREE_ROOT') + root_entry.revision = 'some-version' + delta = [(None, '', 'TREE_ROOT', root_entry)] + serializer = inventory_delta.InventoryDeltaSerializer( + versioned_root=False, tree_references=True) + self.assertRaises( + InventoryDeltaError, serializer.delta_to_lines, 'old-version', + 'new-version', delta) + + def test_to_inventory_root_id_not_versioned(self): + delta = [(None, '', 'an-id', inventory.make_entry( + 'directory', '', None, 'an-id'))] + serializer = inventory_delta.InventoryDeltaSerializer( + versioned_root=True, tree_references=True) + self.assertRaises( + InventoryDeltaError, serializer.delta_to_lines, 'old-version', + 'new-version', delta) + + def test_to_inventory_has_tree_not_meant_to(self): + make_entry = inventory.make_entry + tree_ref = make_entry('tree-reference', 'foo', 'changed-in', 'ref-id') + tree_ref.reference_revision = 'ref-revision' + delta = [ + (None, '', 'an-id', + make_entry('directory', '', 'changed-in', 'an-id')), + (None, 'foo', 'ref-id', tree_ref) + # a file that followed the root move + ] + serializer = inventory_delta.InventoryDeltaSerializer( + versioned_root=True, tree_references=True) + self.assertRaises(InventoryDeltaError, serializer.delta_to_lines, + 'old-version', 'new-version', delta) + + def test_to_inventory_torture(self): + def make_entry(kind, name, parent_id, file_id, **attrs): + entry = inventory.make_entry(kind, name, parent_id, file_id) + for name, value in attrs.items(): + setattr(entry, name, value) + return entry + # this delta is crafted to have all the following: + # - deletes + # - renamed roots + # - deep dirs + # - files moved after parent dir was renamed + # - files with and without exec bit + delta = [ + # new root: + (None, '', 'new-root-id', + make_entry('directory', '', None, 'new-root-id', + revision='changed-in')), + # an old root: + ('', 'old-root', 'TREE_ROOT', + make_entry('directory', 'subdir-now', 'new-root-id', + 'TREE_ROOT', revision='moved-root')), + # a file that followed the root move + ('under-old-root', 'old-root/under-old-root', 'moved-id', + make_entry('file', 'under-old-root', 'TREE_ROOT', 'moved-id', + revision='old-rev', executable=False, text_size=30, + text_sha1='some-sha')), + # a deleted path + ('old-file', None, 'deleted-id', None), + # a tree reference moved to the new root + ('ref', 'ref', 'ref-id', + make_entry('tree-reference', 'ref', 'new-root-id', 'ref-id', + reference_revision='tree-reference-id', + revision='new-rev')), + # a symlink now in a deep dir + ('dir/link', 'old-root/dir/link', 'link-id', + make_entry('symlink', 'link', 'deep-id', 'link-id', + symlink_target='target', revision='new-rev')), + # a deep dir + ('dir', 'old-root/dir', 'deep-id', + make_entry('directory', 'dir', 'TREE_ROOT', 'deep-id', + revision='new-rev')), + # a file with an exec bit set + (None, 'configure', 'exec-id', + make_entry('file', 'configure', 'new-root-id', 'exec-id', + executable=True, text_size=30, text_sha1='some-sha', + revision='old-rev')), + ] + serializer = inventory_delta.InventoryDeltaSerializer( + versioned_root=True, tree_references=True) + lines = serializer.delta_to_lines(NULL_REVISION, 'something', delta) + expected = """format: bzr inventory delta v1 (bzr 1.14) +parent: null: +version: something +versioned_root: true +tree_references: true +/\x00/old-root\x00TREE_ROOT\x00new-root-id\x00moved-root\x00dir +/dir\x00/old-root/dir\x00deep-id\x00TREE_ROOT\x00new-rev\x00dir +/dir/link\x00/old-root/dir/link\x00link-id\x00deep-id\x00new-rev\x00link\x00target +/old-file\x00None\x00deleted-id\x00\x00null:\x00deleted\x00\x00 +/ref\x00/ref\x00ref-id\x00new-root-id\x00new-rev\x00tree\x00tree-reference-id +/under-old-root\x00/old-root/under-old-root\x00moved-id\x00TREE_ROOT\x00old-rev\x00file\x0030\x00\x00some-sha +None\x00/\x00new-root-id\x00\x00changed-in\x00dir +None\x00/configure\x00exec-id\x00new-root-id\x00old-rev\x00file\x0030\x00Y\x00some-sha +""" + serialized = ''.join(lines) + self.assertIsInstance(serialized, str) + self.assertEqual(expected, serialized) + + +class TestContent(TestCase): + """Test serialization of the content part of a line.""" + + def test_dir(self): + entry = inventory.make_entry('directory', 'a dir', None) + self.assertEqual('dir', inventory_delta._directory_content(entry)) + + def test_file_0_short_sha(self): + file_entry = inventory.make_entry('file', 'a file', None, 'file-id') + file_entry.text_sha1 = '' + file_entry.text_size = 0 + self.assertEqual('file\x000\x00\x00', + inventory_delta._file_content(file_entry)) + + def test_file_10_foo(self): + file_entry = inventory.make_entry('file', 'a file', None, 'file-id') + file_entry.text_sha1 = 'foo' + file_entry.text_size = 10 + self.assertEqual('file\x0010\x00\x00foo', + inventory_delta._file_content(file_entry)) + + def test_file_executable(self): + file_entry = inventory.make_entry('file', 'a file', None, 'file-id') + file_entry.executable = True + file_entry.text_sha1 = 'foo' + file_entry.text_size = 10 + self.assertEqual('file\x0010\x00Y\x00foo', + inventory_delta._file_content(file_entry)) + + def test_file_without_size(self): + file_entry = inventory.make_entry('file', 'a file', None, 'file-id') + file_entry.text_sha1 = 'foo' + self.assertRaises(InventoryDeltaError, + inventory_delta._file_content, file_entry) + + def test_file_without_sha1(self): + file_entry = inventory.make_entry('file', 'a file', None, 'file-id') + file_entry.text_size = 10 + self.assertRaises(InventoryDeltaError, + inventory_delta._file_content, file_entry) + + def test_link_empty_target(self): + entry = inventory.make_entry('symlink', 'a link', None) + entry.symlink_target = '' + self.assertEqual('link\x00', + inventory_delta._link_content(entry)) + + def test_link_unicode_target(self): + entry = inventory.make_entry('symlink', 'a link', None) + entry.symlink_target = ' \xc3\xa5'.decode('utf8') + self.assertEqual('link\x00 \xc3\xa5', + inventory_delta._link_content(entry)) + + def test_link_space_target(self): + entry = inventory.make_entry('symlink', 'a link', None) + entry.symlink_target = ' ' + self.assertEqual('link\x00 ', + inventory_delta._link_content(entry)) + + def test_link_no_target(self): + entry = inventory.make_entry('symlink', 'a link', None) + self.assertRaises(InventoryDeltaError, + inventory_delta._link_content, entry) + + def test_reference_null(self): + entry = inventory.make_entry('tree-reference', 'a tree', None) + entry.reference_revision = NULL_REVISION + self.assertEqual('tree\x00null:', + inventory_delta._reference_content(entry)) + + def test_reference_revision(self): + entry = inventory.make_entry('tree-reference', 'a tree', None) + entry.reference_revision = 'foo@\xc3\xa5b-lah' + self.assertEqual('tree\x00foo@\xc3\xa5b-lah', + inventory_delta._reference_content(entry)) + + def test_reference_no_reference(self): + entry = inventory.make_entry('tree-reference', 'a tree', None) + self.assertRaises(InventoryDeltaError, + inventory_delta._reference_content, entry) |