diff --git a/pytest_mock.py b/pytest_mock.py index b893acc..f4c1c25 100644 --- a/pytest_mock.py +++ b/pytest_mock.py @@ -1,6 +1,7 @@ from pprint import pformat import inspect +import py import pytest try: @@ -8,6 +9,8 @@ except ImportError: import unittest.mock as mock_module +u = py.builtin._totext + version = '1.2' @@ -152,12 +155,12 @@ def mock(mocker): _mock_module_originals = {} -DETAILED_ASSERTION = """{original!s} +DETAILED_ASSERTION = u("""{original!s} ... pytest introspection follows: {detailed!s} -""" -FULL_ANY_CALLS_DIFF = "{call} in {calls_list}" +""") +FULL_ANY_CALLS_DIFF = u("{call} in {calls_list}") def pytest_assertrepr_compare(config, op, left, right): @@ -187,12 +190,12 @@ def safe_unpack_args(call): try: assert largs == rargs except AssertionError as e: - msg.extend(['args introspection:', str(e)]) + msg.extend(['args introspection:', u(e)]) try: assert lkwargs == rkwargs except AssertionError as e: - msg.extend(['kwargs introspection:', str(e)]) + msg.extend(['kwargs introspection:', u(e)]) return msg if (isinstance(left, tuple) and @@ -216,8 +219,8 @@ def assert_wrapper(__wrapped_mock_method__, *args, **kwargs): assert assert_call == __mock_self.call_args except AssertionError as diff: # raise a new detailed exception, appending to existing - msg = DETAILED_ASSERTION.format(original=e, detailed=diff) - err = AssertionError(msg.encode().decode('unicode_escape')) + msg = DETAILED_ASSERTION.format(original=u(e), detailed=u(diff)) + err = AssertionError(msg.replace('\\n', '\n').encode('unicode_escape').decode('unicode_escape')) err._msg_updated = True raise err raise AssertionError(*e.args) diff --git a/test_pytest_mock.py b/test_pytest_mock.py index 925f2c3..6e373a0 100644 --- a/test_pytest_mock.py +++ b/test_pytest_mock.py @@ -1,12 +1,15 @@ +# coding=utf-8 import os import platform import sys from contextlib import contextmanager +import py import py.code import pytest +u = py.builtin._totext pytest_plugins = 'pytester' # could not make some of the tests work on PyPy, patches are welcome! @@ -561,3 +564,38 @@ def test_assertion_error_is_descriptive(mocker): assert mocker_any_call.startswith(mock_error_message) assert "assert call(1, 2) in [call(" in mocker_any_call + + +def test_assertion_wrap_unicode(mocker): + """Verify assert_wrapper properly handles unicode call parts""" + mocker_mock = mocker.patch('os.remove') + mocker_mock(u('א', 'utf-8'), b=u('ב', 'utf-8')) + + # arguments assertion for last call + try: + mocker_mock.assert_called_with(u('ג', 'utf-8'), b=u('ד', 'utf-8')) + except AssertionError as e: + called_with_msg = e.msg + + verbose = any(a.startswith('-v') for a in sys.argv) + if verbose: + assert u("('ג',) == ('א',)", 'utf-8') in called_with_msg + assert u("assert {'b': 'ד'} == {'b': 'ב'}", 'utf-8') in called_with_msg + assert u("Use -v to get the full diff", 'utf-8') not in called_with_msg + else: + assert ( + (u("Expected call: remove(u'\\u05d2', b=u'\\u05d3')", 'utf-8') in called_with_msg) or + (u("Expected call: remove('\u05d2', b='\u05d3')", 'utf-8') in called_with_msg) + ) + assert u("assert {'b': 'ד'} == {'b': 'ב'}", 'utf-8') in called_with_msg + assert u('Use -v to get the full diff', 'utf-8') in called_with_msg + + try: + mocker_mock.assert_any_call(1, 2) + except AssertionError as e: + any_call_msg = e.msg + + assert ( + u("assert call(1, 2) in [call(u'\\u05d0'", 'utf-8') in any_call_msg or + u("assert call(1, 2) in [call('\u05d0'", 'utf-8') in any_call_msg + )