| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- # test_object_format.py -- tests for object_format.py
- # Copyright (C) 2025 Jelmer Vernooij <jelmer@jelmer.uk>
- #
- # SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
- # Dulwich is dual-licensed under the Apache License, Version 2.0 and the GNU
- # General Public License as published by the Free Software Foundation; version 2.0
- # or (at your option) any later version. You can redistribute it and/or
- # modify it under the terms of either of these two licenses.
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- #
- # You should have received a copy of the licenses; if not, see
- # <http://www.gnu.org/licenses/> for a copy of the GNU General Public License
- # and <http://www.apache.org/licenses/LICENSE-2.0> for a copy of the Apache
- # License, Version 2.0.
- #
- """Tests for object_format module."""
- from dulwich.object_format import (
- DEFAULT_OBJECT_FORMAT,
- OBJECT_FORMAT_TYPE_NUMS,
- OBJECT_FORMATS,
- SHA1,
- SHA256,
- get_object_format,
- verify_same_object_format,
- )
- from . import TestCase
- class ObjectFormatTests(TestCase):
- """Tests for ObjectFormat class."""
- def test_sha1_attributes(self) -> None:
- """Test SHA1 object format attributes."""
- self.assertEqual("sha1", SHA1.name)
- self.assertEqual(1, SHA1.type_num)
- self.assertEqual(20, SHA1.oid_length)
- self.assertEqual(40, SHA1.hex_length)
- def test_sha256_attributes(self) -> None:
- """Test SHA256 object format attributes."""
- self.assertEqual("sha256", SHA256.name)
- self.assertEqual(20, SHA256.type_num)
- self.assertEqual(32, SHA256.oid_length)
- self.assertEqual(64, SHA256.hex_length)
- def test_str_representation(self) -> None:
- """Test __str__ method returns format name."""
- self.assertEqual("sha1", str(SHA1))
- self.assertEqual("sha256", str(SHA256))
- def test_repr_representation(self) -> None:
- """Test __repr__ method."""
- self.assertEqual("ObjectFormat('sha1')", repr(SHA1))
- self.assertEqual("ObjectFormat('sha256')", repr(SHA256))
- def test_new_hash(self) -> None:
- """Test new_hash creates a hash object."""
- sha1_hash = SHA1.new_hash()
- self.assertEqual("sha1", sha1_hash.name)
- sha256_hash = SHA256.new_hash()
- self.assertEqual("sha256", sha256_hash.name)
- def test_hash_object(self) -> None:
- """Test hash_object returns binary digest."""
- data = b"test data"
- # Test SHA1
- sha1_digest = SHA1.hash_object(data)
- self.assertIsInstance(sha1_digest, bytes)
- self.assertEqual(20, len(sha1_digest))
- # Verify it matches expected hash
- import hashlib
- expected_sha1 = hashlib.sha1(data).digest()
- self.assertEqual(expected_sha1, sha1_digest)
- # Test SHA256
- sha256_digest = SHA256.hash_object(data)
- self.assertIsInstance(sha256_digest, bytes)
- self.assertEqual(32, len(sha256_digest))
- expected_sha256 = hashlib.sha256(data).digest()
- self.assertEqual(expected_sha256, sha256_digest)
- def test_hash_object_hex(self) -> None:
- """Test hash_object_hex returns hexadecimal digest."""
- data = b"test data"
- # Test SHA1
- sha1_hex = SHA1.hash_object_hex(data)
- self.assertIsInstance(sha1_hex, bytes)
- self.assertEqual(40, len(sha1_hex))
- # Verify it matches expected hash
- import hashlib
- expected_sha1_hex = hashlib.sha1(data).hexdigest().encode("ascii")
- self.assertEqual(expected_sha1_hex, sha1_hex)
- # Test SHA256
- sha256_hex = SHA256.hash_object_hex(data)
- self.assertIsInstance(sha256_hex, bytes)
- self.assertEqual(64, len(sha256_hex))
- expected_sha256_hex = hashlib.sha256(data).hexdigest().encode("ascii")
- self.assertEqual(expected_sha256_hex, sha256_hex)
- class ObjectFormatMappingTests(TestCase):
- """Tests for object format mappings."""
- def test_object_formats_dict(self) -> None:
- """Test OBJECT_FORMATS dictionary."""
- self.assertEqual(SHA1, OBJECT_FORMATS["sha1"])
- self.assertEqual(SHA256, OBJECT_FORMATS["sha256"])
- def test_object_format_type_nums_dict(self) -> None:
- """Test OBJECT_FORMAT_TYPE_NUMS dictionary."""
- self.assertEqual(SHA1, OBJECT_FORMAT_TYPE_NUMS[1])
- self.assertEqual(SHA256, OBJECT_FORMAT_TYPE_NUMS[2])
- def test_default_object_format(self) -> None:
- """Test DEFAULT_OBJECT_FORMAT is SHA1."""
- self.assertEqual(SHA1, DEFAULT_OBJECT_FORMAT)
- class GetObjectFormatTests(TestCase):
- """Tests for get_object_format function."""
- def test_get_object_format_none(self) -> None:
- """Test get_object_format with None returns default."""
- result = get_object_format(None)
- self.assertEqual(DEFAULT_OBJECT_FORMAT, result)
- def test_get_object_format_sha1(self) -> None:
- """Test get_object_format with 'sha1'."""
- result = get_object_format("sha1")
- self.assertEqual(SHA1, result)
- def test_get_object_format_sha256(self) -> None:
- """Test get_object_format with 'sha256'."""
- result = get_object_format("sha256")
- self.assertEqual(SHA256, result)
- def test_get_object_format_case_insensitive(self) -> None:
- """Test get_object_format is case insensitive."""
- self.assertEqual(SHA1, get_object_format("SHA1"))
- self.assertEqual(SHA1, get_object_format("Sha1"))
- self.assertEqual(SHA256, get_object_format("SHA256"))
- self.assertEqual(SHA256, get_object_format("Sha256"))
- def test_get_object_format_invalid(self) -> None:
- """Test get_object_format with invalid name raises ValueError."""
- with self.assertRaises(ValueError) as cm:
- get_object_format("md5")
- self.assertEqual("Unsupported object format: md5", str(cm.exception))
- class VerifySameObjectFormatTests(TestCase):
- """Tests for verify_same_object_format function."""
- def test_verify_single_format(self) -> None:
- """Test verify_same_object_format with single format."""
- result = verify_same_object_format(SHA1)
- self.assertEqual(SHA1, result)
- def test_verify_multiple_same_formats(self) -> None:
- """Test verify_same_object_format with multiple same formats."""
- result = verify_same_object_format(SHA1, SHA1, SHA1)
- self.assertEqual(SHA1, result)
- result = verify_same_object_format(SHA256, SHA256)
- self.assertEqual(SHA256, result)
- def test_verify_no_formats(self) -> None:
- """Test verify_same_object_format with no formats raises ValueError."""
- with self.assertRaises(ValueError) as cm:
- verify_same_object_format()
- self.assertEqual(
- "At least one object format must be provided", str(cm.exception)
- )
- def test_verify_different_formats(self) -> None:
- """Test verify_same_object_format with different formats raises ValueError."""
- with self.assertRaises(ValueError) as cm:
- verify_same_object_format(SHA1, SHA256)
- self.assertEqual("Object format mismatch: sha1 != sha256", str(cm.exception))
- def test_verify_multiple_different_formats(self) -> None:
- """Test verify_same_object_format fails on first mismatch."""
- with self.assertRaises(ValueError) as cm:
- verify_same_object_format(SHA1, SHA1, SHA256, SHA1)
- self.assertEqual("Object format mismatch: sha1 != sha256", str(cm.exception))
|