From 913572c2ef8a4c948bb8b67ff2064d6920e313e7 Mon Sep 17 00:00:00 2001 From: TIGirardi <55336837+TIGirardi@users.noreply.github.com> Date: Mon, 18 May 2020 00:58:10 -0300 Subject: Accept None as a key in pure python module (#42) --- tests/test_none_keys.py | 511 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 511 insertions(+) create mode 100644 tests/test_none_keys.py (limited to 'tests') diff --git a/tests/test_none_keys.py b/tests/test_none_keys.py new file mode 100644 index 0000000..3662e9c --- /dev/null +++ b/tests/test_none_keys.py @@ -0,0 +1,511 @@ +import unittest + +from immutables.map import map_hash, map_mask, Map as PyMap +from tests.test_map import HashKey + + +none_hash = map_hash(None) +assert(none_hash != 1) +assert((none_hash >> 32) == 0) + +not_collision = 0xffffffff & (~none_hash) + +mask = 0x7ffffffff +none_collisions = [none_hash & (mask >> shift) + for shift in reversed(range(0, 32, 5))] +assert(len(none_collisions) == 7) +none_collisions = [h | (not_collision & (mask << shift)) + for shift, h in zip(range(5, 37, 5), none_collisions)] + + +class NoneCollision(HashKey): + def __init__(self, name, level): + if name is None: + raise ValueError("Can't have a NoneCollision with a None value") + super().__init__(none_collisions[level], name) + + def __eq__(self, other): + if other is None: + return False + return super().__eq__(other) + + __hash__ = HashKey.__hash__ + + +class BaseNoneTest: + Map = None + + def test_none_collisions(self): + collisions = [NoneCollision('a', level) for level in range(7)] + indices = [map_mask(none_hash, shift) for shift in range(0, 32, 5)] + + for i, c in enumerate(collisions[:-1], 1): + self.assertNotEqual(c, None) + c_hash = map_hash(c) + self.assertNotEqual(c_hash, none_hash) + for j, idx in enumerate(indices[:i]): + self.assertEqual(map_mask(c_hash, j*5), idx) + for j, idx in enumerate(indices[i:], i): + self.assertNotEqual(map_mask(c_hash, j*5), idx) + + c = collisions[-1] + self.assertNotEqual(c, None) + c_hash = map_hash(c) + self.assertEqual(c_hash, none_hash) + for i, idx in enumerate(indices): + self.assertEqual(map_mask(c_hash, i*5), idx) + + def test_none_as_key(self): + m = self.Map({None: 1}) + + self.assertEqual(len(m), 1) + self.assertTrue(None in m) + self.assertEqual(m[None], 1) + self.assertTrue(repr(m).startswith('