Skip to content

Commit

Permalink
improve hypothesis tests, deps, code formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
jab committed Dec 17, 2015
1 parent 8bf9606 commit abeb01e
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 14 deletions.
2 changes: 2 additions & 0 deletions bidict/_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ def __repr__(self):
return "<%s '%s'>" % (self.__class__.__name__, self)



class KeyExistsException(BidictException):
"""
Guards against replacing an existing mapping whose key matches the given.
Expand All @@ -147,4 +148,5 @@ def __str__(self):
"""Get a "friendly" string representation of this exception."""
return 'Value {1!r} exists with key {0!r}'.format(*self.args[0])


_missing = object()
1 change: 1 addition & 0 deletions bidict/_frozen.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from ._common import BidirectionalMapping
from collections import Hashable


class frozenbidict(BidirectionalMapping, Hashable):
"""Immutable, hashable bidict type."""

Expand Down
35 changes: 21 additions & 14 deletions tests/test_hypothesis.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,59 +2,65 @@
Property-based tests using https://warehouse.python.org/project/hypothesis/
"""

import pytest

from functools import reduce
from math import isnan
from operator import or_

from hypothesis import assume, given, strategy
from hypothesis.specifiers import dictionary
from hypothesis import assume, given
from hypothesis.strategies import dictionaries, none, booleans, integers, floats, text, binary, one_of, frozensets, \
lists, recursive

from bidict import bidict, frozenbidict


def inv(d):
return {v: k for (k, v) in d.items()}


def prune_dup_vals(d):
pruned = inv(inv(d))
assume(len(pruned) >= 0.5 * len(d))
return pruned

immutable_types_ = (None, bool, int, float, str, bytes, tuple(), frozenset())
immutable_types = reduce(or_, map(strategy, immutable_types_))
d = strategy(dictionary(immutable_types, immutable_types)).map(prune_dup_vals)

immutable_types = recursive(one_of(none(), booleans(), integers(), floats(), text(), binary()),
lambda elts: one_of(frozensets(elts), lists(elts).map(tuple)))
d = dictionaries(immutable_types, immutable_types).map(prune_dup_vals)


@given(d)
def test_len(d):
assert len(d) == len(inv(d)) == len(bidict(d))

def isnan_(x):

def _isnan(x):
return isnan(x) if isinstance(x, float) else False

def both_nan(a, b):
return isnan_(a) and isnan_(b)

def _both_nan(a, b):
return _isnan(a) and _isnan(b)


@given(d)
def test_bidirectional_mappings(d):
b = bidict(d)
for k, v in b.items():
v_ = b[k]
k_ = b.inv[v]
assert k == k_ or both_nan(k, k_)
assert v == v_ or both_nan(v, v_)
assert k == k_ or _both_nan(k, k_)
assert v == v_ or _both_nan(v, v_)


@given(d)
def test_inv_identity(d):
b = bidict(d)
assert b is b.inv.inv
assert b.inv is b.inv.inv.inv


# work around https://bitbucket.org/pypy/pypy/issue/1974
nan = float('nan')
WORKAROUND_NAN_BUG = (nan, nan) != (nan, nan)


@given(d)
def test_equality(d):
if WORKAROUND_NAN_BUG:
Expand All @@ -68,6 +74,7 @@ def test_equality(d):
assert not b != d
assert not b.inv != i


@given(d)
def test_frozenbidict_hash(d):
f = frozenbidict(d)
Expand Down

0 comments on commit abeb01e

Please sign in to comment.