diff --git a/tests/test_hypothesis.py b/tests/test_hypothesis.py index db62a0a..5642e31 100644 --- a/tests/test_hypothesis.py +++ b/tests/test_hypothesis.py @@ -6,7 +6,7 @@ from bidict import ( OrderedBidirectionalMapping, IGNORE, OVERWRITE, RAISE, bidict, loosebidict, looseorderedbidict, orderedbidict, frozenbidict, frozenorderedbidict) -from bidict.compat import iteritems, viewitems +from bidict.compat import iteritems from collections import OrderedDict from hypothesis import assume, given, settings from hypothesis.strategies import integers, lists, tuples @@ -33,18 +33,12 @@ ondupbehaviors = (IGNORE, OVERWRITE, RAISE) mutable_bidict_types = (bidict, loosebidict, looseorderedbidict, orderedbidict) bidict_types = mutable_bidict_types + (frozenbidict, frozenorderedbidict) mutating_methods_by_arity = { - 0: ('clear', 'popitem',), - 1: ('__delitem__', 'pop', 'setdefault', 'move_to_end',), - 2: ('__setitem__', 'pop', 'put', 'forceput', 'setdefault',), - -1: ('update', 'forceupdate',), + 0: ('clear', 'popitem'), + 1: ('__delitem__', 'pop', 'setdefault', 'move_to_end'), + 2: ('__setitem__', 'pop', 'put', 'forceput', 'setdefault'), + -1: ('update', 'forceupdate'), } immutable = integers() -# To test with more immutable types, can use the following, but it slows down -# the tests without finding more bugs: -# sz = dict(average_size=2) -# immu_atom = none() | booleans() | integers() | floats(allow_nan=False) | text(**sz) | binary(**sz) -# immu_coll = lambda e: frozensets(e, **sz) | lists(e, **sz).map(tuple) -# immutable = recursive(immu_atom, immu_coll) itemlists = lists(tuples(immutable, immutable)) inititems = itemlists.map(prune_dup_vals) @@ -81,7 +75,7 @@ def test_bidirectional_mappings(B, init): assert valsf == valsi -@pytest.mark.parametrize('arity,methodname', +@pytest.mark.parametrize('arity, methodname', [(a, m) for (a, ms) in iteritems(mutating_methods_by_arity) for m in ms]) @pytest.mark.parametrize('B', mutable_bidict_types) @given(init=inititems, arg1=immutable, arg2=immutable, items=itemlists) @@ -89,7 +83,6 @@ def test_consistency_after_mutation(arity, methodname, B, init, arg1, arg2, item method = getattr(B, methodname, None) if not method: return - b = B(init) args = [] if arity == -1: args.append(items) @@ -98,48 +91,18 @@ def test_consistency_after_mutation(arity, methodname, B, init, arg1, arg2, item args.append(arg1) if arity > 1: args.append(arg2) - b0 = b.copy() + b0 = B(init) + b1 = b0.copy() try: - method(b, *args) + method(b1, *args) except: - # All methods should fail clean, reverting any changes made before failure. - assert b == b0 - assert b.inv == b0.inv - else: - assert b == to_inv_odict(iteritems(b.inv)) - assert b.inv == to_inv_odict(iteritems(b)) - - # If b is an orderedbidict and the method is not expected to change the - # ordering, test that the relative ordering of any items that survived - # the mutation is preserved, i.e. if (k1, v1) came before (k2, v2) - # before the mutation, it still does after. - # - # In the case of forceupdate(), order is preserved as much as possible, - # but in some cases it is not preserved completely, e.g.:: - # - # >>> o = orderedbidict([(0, 2), (2, 1)]) - # >>> o.forceupdate([(1, 2), (0, 0), (0, 2)]) - # >>> o - # orderedbidict([(2, 1), (0, 2)]) - # - # So this test is skipped for forceupdate(). - ordered = issubclass(B, OrderedBidirectionalMapping) - if ordered and methodname not in ('move_to_end', 'forceupdate'): - items0 = viewitems(b0) - items1 = viewitems(b) - common = items0 & items1 - if common: - items0 = list(items0) - items1 = list(items1) - for i in common: - idx0 = items0.index(i) - idx1 = items1.index(i) - beforei0 = [j for j in items0[:idx0] if j in common] - beforei1 = [j for j in items1[:idx1] if j in common] - assert beforei0 == beforei1 - afteri0 = [j for j in items0[idx0 + 1:] if j in common] - afteri1 = [j for j in items1[idx1 + 1:] if j in common] - assert afteri0 == afteri1 + # All methods should fail clean. + assert b1 == b0 + assert b1.inv == b0.inv + return + # Method succeeded -> b1 should pass consistency checks. + assert b1 == to_inv_odict(iteritems(b1.inv)) + assert b1.inv == to_inv_odict(iteritems(b1)) @pytest.mark.parametrize('B', mutable_bidict_types)