Coverage for /home/runner/work/zserio/zserio/compiler/extensions/python/runtime/tests/test_hashcode.py: 100%
148 statements
« prev ^ index » next coverage.py v6.5.0, created at 2024-12-05 10:43 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2024-12-05 10:43 +0000
1import enum
2import unittest
4from zserio.array import Array, SignedBitFieldArrayTraits
5from zserio.bitbuffer import BitBuffer
6from zserio.hashcode import (
7 HASH_SEED,
8 HASH_PRIME_NUMBER,
9 calc_hashcode_bool,
10 calc_hashcode_int32,
11 calc_hashcode_int64,
12 calc_hashcode_float32,
13 calc_hashcode_float64,
14 calc_hashcode_bytes,
15 calc_hashcode_string,
16 calc_hashcode_object,
17 calc_hashcode_bool_array,
18 calc_hashcode_int_array,
19 calc_hashcode_float32_array,
20 calc_hashcode_float64_array,
21 calc_hashcode_bytes_array,
22 calc_hashcode_string_array,
23 calc_hashcode_object_array,
24)
25from zserio.float import float_to_uint32, float_to_uint64
28class Color(enum.Enum):
29 NONE = 0
30 RED = 2
31 BLUE = 3
32 BLACK = 7
34 def __hash__(self):
35 result = HASH_SEED
36 result = calc_hashcode_int32(result, self.value)
37 return result
40class Permissions:
41 def __init__(self, value):
42 self._value = value
44 def __hash__(self):
45 result = HASH_SEED
46 result = calc_hashcode_int32(result, self.value)
47 return result
49 @property
50 def value(self):
51 return self._value
53 class Values:
54 READ = None
55 WRITE = None
56 CREATE = None
59Permissions.Values.READ = Permissions(1)
60Permissions.Values.WRITE = Permissions(2)
61Permissions.Values.CREATE = Permissions(4)
64class DummyObject:
65 def __init__(self, hash_code):
66 self._hash_code = hash_code
68 def __hash__(self):
69 return self._hash_code
72class HashCodeTest(unittest.TestCase):
74 def test_bool_type(self):
75 hash_seed = 1
76 bool_value = True
77 self.assertEqual(HASH_PRIME_NUMBER + 1, calc_hashcode_bool(hash_seed, bool_value))
79 self.assertEqual(HASH_PRIME_NUMBER, calc_hashcode_bool(hash_seed, None))
81 def test_int_type(self):
82 hash_seed = 1
83 int_value = 10
84 self.assertEqual(HASH_PRIME_NUMBER + 10, calc_hashcode_int32(hash_seed, int_value))
86 int_value = -1
87 self.assertEqual(HASH_PRIME_NUMBER - 1, calc_hashcode_int32(hash_seed, int_value))
88 self.assertEqual(HASH_PRIME_NUMBER, calc_hashcode_int64(hash_seed, int_value))
90 self.assertEqual(HASH_PRIME_NUMBER, calc_hashcode_int32(hash_seed, None))
91 self.assertEqual(HASH_PRIME_NUMBER, calc_hashcode_int64(hash_seed, None))
93 def test_float32_type(self):
94 hash_seed = 1
95 float_value = 10.0
96 self.assertEqual(
97 HASH_PRIME_NUMBER + float_to_uint32(float_value),
98 calc_hashcode_float32(hash_seed, float_value),
99 )
101 self.assertEqual(HASH_PRIME_NUMBER, calc_hashcode_float32(hash_seed, None))
103 def test_float64_type(self):
104 hash_seed = 1
105 float_value = 10.0
106 uint64_value = float_to_uint64(float_value)
107 expected_hash_code = (
108 HASH_PRIME_NUMBER + ((uint64_value & 0xFFFFFFFF) ^ ((uint64_value & 0xFFFFFFFFFFFFFFFF) >> 32))
109 ) & 0xFFFFFFFF
110 self.assertEqual(expected_hash_code, calc_hashcode_float64(hash_seed, float_value))
112 self.assertEqual(HASH_PRIME_NUMBER, calc_hashcode_float64(hash_seed, None))
114 def test_bytes_type(self):
115 hash_seed = 1
116 bytes_value = bytearray([1])
117 self.assertEqual(HASH_PRIME_NUMBER + 1, calc_hashcode_bytes(hash_seed, bytes_value))
119 self.assertEqual(HASH_PRIME_NUMBER, calc_hashcode_bytes(hash_seed, None))
121 def test_string_type(self):
122 hash_seed = 1
123 string_value = "0"
124 self.assertEqual(HASH_PRIME_NUMBER + ord("0"), calc_hashcode_string(hash_seed, string_value))
126 self.assertEqual(HASH_PRIME_NUMBER, calc_hashcode_string(hash_seed, None))
128 def test_bitbuffer_type(self):
129 hash_seed = 1
130 bitbuffer_value = BitBuffer(bytes())
131 self.assertEqual(
132 HASH_PRIME_NUMBER + HASH_SEED,
133 calc_hashcode_object(hash_seed, bitbuffer_value),
134 )
136 def test_enum_type(self):
137 hash_seed = 1
138 self.assertEqual(
139 HASH_PRIME_NUMBER + (HASH_PRIME_NUMBER * HASH_SEED + Color.NONE.value),
140 calc_hashcode_object(hash_seed, Color.NONE),
141 )
142 self.assertEqual(
143 HASH_PRIME_NUMBER + (HASH_PRIME_NUMBER * HASH_SEED + Color.RED.value),
144 calc_hashcode_object(hash_seed, Color.RED),
145 )
146 self.assertEqual(
147 HASH_PRIME_NUMBER + (HASH_PRIME_NUMBER * HASH_SEED + Color.BLUE.value),
148 calc_hashcode_object(hash_seed, Color.BLUE),
149 )
150 self.assertEqual(
151 HASH_PRIME_NUMBER + (HASH_PRIME_NUMBER * HASH_SEED + Color.BLACK.value),
152 calc_hashcode_object(hash_seed, Color.BLACK),
153 )
155 def test_bitmask_type(self):
156 hash_seed = 1
157 self.assertEqual(
158 HASH_PRIME_NUMBER + (HASH_PRIME_NUMBER * HASH_SEED + Permissions.Values.READ.value),
159 calc_hashcode_object(hash_seed, Permissions.Values.READ),
160 )
161 self.assertEqual(
162 HASH_PRIME_NUMBER + (HASH_PRIME_NUMBER * HASH_SEED + Permissions.Values.WRITE.value),
163 calc_hashcode_object(hash_seed, Permissions.Values.WRITE),
164 )
165 self.assertEqual(
166 HASH_PRIME_NUMBER + (HASH_PRIME_NUMBER * HASH_SEED + Permissions.Values.CREATE.value),
167 calc_hashcode_object(hash_seed, Permissions.Values.CREATE),
168 )
170 def test_object_type(self):
171 hash_seed = 1
172 object_value = DummyObject(10)
173 self.assertEqual(HASH_PRIME_NUMBER + 10, calc_hashcode_object(hash_seed, object_value))
175 self.assertEqual(HASH_PRIME_NUMBER, calc_hashcode_object(hash_seed, None))
177 def test_array_type(self):
178 hash_seed = 1
179 array_value = Array(SignedBitFieldArrayTraits(32), [3, 7])
181 raw_array_hash_code = (HASH_PRIME_NUMBER * HASH_SEED + 3) * HASH_PRIME_NUMBER + 7
182 self.assertEqual(
183 HASH_PRIME_NUMBER + raw_array_hash_code,
184 calc_hashcode_object(hash_seed, array_value),
185 )
187 def test_bool_array_type(self):
188 hash_seed = 1
189 bool_array_value = [False, True]
190 self.assertEqual(
191 (HASH_PRIME_NUMBER + 0) * HASH_PRIME_NUMBER + 1,
192 calc_hashcode_bool_array(hash_seed, bool_array_value),
193 )
195 self.assertEqual(HASH_PRIME_NUMBER, calc_hashcode_bool_array(hash_seed, None))
197 def test_int_array_type(self):
198 hash_seed = 1
199 int_array_value = [3, 7]
200 self.assertEqual(
201 (HASH_PRIME_NUMBER + 3) * HASH_PRIME_NUMBER + 7,
202 calc_hashcode_int_array(hash_seed, int_array_value),
203 )
205 self.assertEqual(HASH_PRIME_NUMBER, calc_hashcode_int_array(hash_seed, None))
207 def test_float32_array_type(self):
208 hash_seed = 1
209 float32_array_value = [10.0]
210 self.assertEqual(
211 HASH_PRIME_NUMBER + float_to_uint32(float32_array_value[0]),
212 calc_hashcode_float32_array(hash_seed, float32_array_value),
213 )
215 self.assertEqual(HASH_PRIME_NUMBER, calc_hashcode_float32_array(hash_seed, None))
217 def test_float64_array_type(self):
218 hash_seed = 1
219 float64_array_value = [10.0]
220 uint64_value = float_to_uint64(float64_array_value[0])
221 expected_hash_code = (
222 HASH_PRIME_NUMBER + ((uint64_value & 0xFFFFFFFF) ^ ((uint64_value & 0xFFFFFFFFFFFFFFFF) >> 32))
223 ) & 0xFFFFFFFF
224 self.assertEqual(
225 expected_hash_code,
226 calc_hashcode_float64_array(hash_seed, float64_array_value),
227 )
229 self.assertEqual(HASH_PRIME_NUMBER, calc_hashcode_float64_array(hash_seed, None))
231 def test_bytes_array_type(self):
232 hash_seed = 1
233 bytes_value = [bytearray([1])]
234 self.assertEqual(HASH_PRIME_NUMBER + 1, calc_hashcode_bytes_array(hash_seed, bytes_value))
236 self.assertEqual(HASH_PRIME_NUMBER, calc_hashcode_bytes_array(hash_seed, None))
238 def test_str_array_type(self):
239 hash_seed = 1
240 str_array_value = ["0"]
241 self.assertEqual(
242 HASH_PRIME_NUMBER + ord(str_array_value[0]),
243 calc_hashcode_string_array(hash_seed, str_array_value),
244 )
246 self.assertEqual(HASH_PRIME_NUMBER, calc_hashcode_string_array(hash_seed, None))
248 def test_bitbuffer_array_type(self):
249 hash_seed = 1
250 bitbuffer_array_value = [BitBuffer(bytes())]
251 self.assertEqual(
252 HASH_PRIME_NUMBER + HASH_SEED,
253 calc_hashcode_object_array(hash_seed, bitbuffer_array_value),
254 )
256 def test_enum_array_type(self):
257 hash_seed = 1
258 enum_array_value = [Color.NONE]
259 self.assertEqual(
260 HASH_PRIME_NUMBER + (HASH_PRIME_NUMBER * HASH_SEED + Color.NONE.value),
261 calc_hashcode_object_array(hash_seed, enum_array_value),
262 )
264 def test_bitmask_array_type(self):
265 hash_seed = 1
266 bitmask_array_value = [Permissions.Values.READ]
267 self.assertEqual(
268 HASH_PRIME_NUMBER + (HASH_PRIME_NUMBER * HASH_SEED + Permissions.Values.READ.value),
269 calc_hashcode_object_array(hash_seed, bitmask_array_value),
270 )
272 def test_object_array_type(self):
273 hash_seed = 1
274 object_array_value = [DummyObject(3), DummyObject(7)]
275 self.assertEqual(
276 (HASH_PRIME_NUMBER + 3) * HASH_PRIME_NUMBER + 7,
277 calc_hashcode_object_array(hash_seed, object_array_value),
278 )
280 self.assertEqual(HASH_PRIME_NUMBER, calc_hashcode_object_array(hash_seed, None))