diff --git a/_pytest/assertion/util.py b/_pytest/assertion/util.py index a0cff6b18..611b330c0 100644 --- a/_pytest/assertion/util.py +++ b/_pytest/assertion/util.py @@ -1,6 +1,10 @@ """Utilities for assertion debugging""" import py +try: + from collections.abc import Sequence +except ImportError: + from collections import Sequence BuiltinAssertionError = py.builtin.builtins.AssertionError @@ -91,7 +95,8 @@ def assertrepr_compare(config, op, left, right): right_repr = py.io.saferepr(right, maxsize=width-len(left_repr)) summary = '%s %s %s' % (left_repr, op, right_repr) - issequence = lambda x: isinstance(x, (list, tuple)) + issequence = lambda x: (isinstance(x, (list, tuple, Sequence)) + and not isinstance(x, basestring)) istext = lambda x: isinstance(x, basestring) isdict = lambda x: isinstance(x, dict) isset = lambda x: isinstance(x, (set, frozenset)) @@ -198,7 +203,7 @@ def _compare_eq_dict(left, right, verbose=False): common = set(left).intersection(set(right)) same = dict((k, left[k]) for k in common if left[k] == right[k]) if same and not verbose: - explanation += ['Hiding %s identical items, use -v to show' % + explanation += ['Omitting %s identical items, use -v to show' % len(same)] elif same: explanation += ['Common items:'] diff --git a/testing/test_assertion.py b/testing/test_assertion.py index ff633b534..4ebb80305 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -3,6 +3,11 @@ import sys import py, pytest import _pytest.assertion as plugin from _pytest.assertion import reinterpret, util +try: + from collections.abc import MutableSequence +except ImportError: + from collections import MutableSequence + needsnewassert = pytest.mark.skipif("sys.version_info < (2,6)") @@ -95,13 +100,48 @@ class TestAssert_reprcompare: expl = callequal({'a': 0}, {'a': 1}) assert len(expl) > 1 + def test_dict_omitting(self): + lines = callequal({'a': 0, 'b': 1}, {'a': 1, 'b': 1}) + assert lines[1].startswith('Omitting 1 identical item') + assert 'Common items' not in lines + for line in lines[1:]: + assert 'b' not in line + + def test_dict_omitting_verbose(self): + lines = callequal({'a': 0, 'b': 1}, {'a': 1, 'b': 1}, verbose=True) + assert lines[1].startswith('Common items:') + assert 'Omitting' not in lines[1] + assert lines[2] == "{'b': 1}" + def test_set(self): expl = callequal(set([0, 1]), set([0, 2])) assert len(expl) > 1 def test_frozenzet(self): expl = callequal(frozenset([0, 1]), set([0, 2])) - print (expl) + assert len(expl) > 1 + + def test_Sequence(self): + class TestSequence(MutableSequence): # works with a Sequence subclass + def __init__(self, iterable): + self.elements = list(iterable) + + def __getitem__(self, item): + return self.elements[item] + + def __len__(self): + return len(self.elements) + + def __setitem__(self, item, value): + pass + + def __delitem__(self, item): + pass + + def insert(self, item, index): + pass + + expl = callequal(TestSequence([0, 1]), list([0, 2])) assert len(expl) > 1 def test_list_tuples(self):