bidict/tests/test_eq_and_hash.py

89 lines
3.0 KiB
Python

# -*- coding: utf-8 -*-
# Copyright 2018 Joshua Bronson. All Rights Reserved.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""Equality and hashing tests."""
from collections import Counter, Hashable, OrderedDict, Mapping, defaultdict
from itertools import product
import pytest
from bidict import FrozenOrderedBidict, OrderedBidict, bidict, namedbidict, frozenbidict
class _DictSubcls(dict):
pass
class _OrderedBidictSubcls(OrderedBidict):
pass
# pylint: disable=C0103
items = [('a', 1), ('b', 2)] # use int values so makes sense with Counter
itemsreversed = list(reversed(items))
bidict_of_items = bidict(items)
frozenbidict_of_items = frozenbidict(items)
namedbidict_of_items = namedbidict('named', 'keys', 'vals')(items)
orderedbidict_of_items = OrderedBidict(items)
orderedbidict_of_itemsreversed = OrderedBidict(itemsreversed)
orderedbidictsubcls_of_items = _OrderedBidictSubcls(items)
orderedbidictsubcls_of_itemsreversed = _OrderedBidictSubcls(itemsreversed)
frozenorderedbidict_of_items = FrozenOrderedBidict(items)
frozenorderedbidict_of_itemsreversed = FrozenOrderedBidict(itemsreversed)
bidicts = (
bidict_of_items,
frozenbidict_of_items,
namedbidict_of_items,
orderedbidict_of_items,
orderedbidict_of_itemsreversed,
orderedbidictsubcls_of_items,
orderedbidictsubcls_of_itemsreversed,
frozenorderedbidict_of_items,
frozenorderedbidict_of_itemsreversed,
)
dict_of_itemsreversed = dict(itemsreversed)
counter_of_itemsreversed = Counter(dict_of_itemsreversed)
defaultdict_of_itemsreversed = defaultdict(lambda x: None, itemsreversed)
dictsubcls_of_itemsreversed = _DictSubcls(itemsreversed)
ordereddict_of_items = OrderedDict(items)
ordereddict_of_itemsreversed = OrderedDict(itemsreversed)
empty_dict = {}
not_a_mapping = 42
not_bidicts = (
dict_of_itemsreversed,
counter_of_itemsreversed,
defaultdict_of_itemsreversed,
dictsubcls_of_itemsreversed,
ordereddict_of_items,
ordereddict_of_itemsreversed,
empty_dict,
not_a_mapping,
)
@pytest.mark.parametrize('b, other', product(bidicts, bidicts + not_bidicts))
def test_eq_and_hash(b, other):
"""Make sure equality tests and hash results behave as expected."""
if not isinstance(other, Mapping):
assert b != other
elif len(b) != len(other):
assert b != other
else:
should_be_equal = dict(b) == dict(other)
are_equal = b == other
assert are_equal == should_be_equal
both_hashable = isinstance(b, Hashable) and isinstance(other, Hashable)
if are_equal and both_hashable:
assert hash(b) == hash(other)
if hasattr(b, 'equals_order_sensitive') and hasattr(other, '__reversed__'):
are_equal_ordered = b.equals_order_sensitive(other)
should_be_equal_ordered = OrderedDict(b) == OrderedDict(other)
assert are_equal_ordered == should_be_equal_ordered