Coverage for Applications/PyCharm.app/Contents/plugins/python-ce/helpers/pycharm/teamcity/diff_tools.py: 42%

1 import os

2 import pprint

3 import sys

4 import unittest

5

6 from .messages import text_type

7

8 _PY2K = sys.version_info < (3,)

9 _PRIMITIVES = [int, str, bool]

10 if _PY2K:

11 # Not available in py3

12 # noinspection PyUnresolvedReferences

13 _PRIMITIVES.append(unicode) # noqa

14 # Not available in py3

15 # noinspection PyUnresolvedReferences

16 _STR_F = unicode # noqa

17 else:

18 _STR_F = str

19

20

21 def patch_unittest_diff(test_filter=None):

22 """

23 Patches "assertEquals" to throw DiffError.

24

25 @:param test_filter callback to check each test. If not None it should return True to test or EqualsAssertionError will be skipped

26 """

27 if sys.version_info < (2, 7):

28 return

29 old = unittest.TestCase.assertEqual

30

31 def _patched_equals(self, first, second, msg=None):

32 try:

33 old(self, first, second, msg)

34 return

35 except AssertionError as e:

36 if not test_filter or test_filter(self):

37 error = EqualsAssertionError(first, second, msg, real_exception=e)

38 if error.can_be_serialized():

39 from .jb_local_exc_store import store_exception

40 store_exception(error)

41 raise

42

43 unittest.TestCase.assertEqual = _patched_equals

44

45

46 def _format_and_convert(val):

47 if "_JB_PPRINT_PRIMITIVES" in os.environ:

48 return pprint.pformat(val)

49 # No need to pretty-print primitives

50 return val if any(x for x in _PRIMITIVES if isinstance(val, x)) else pprint.pformat(val)

51

52

53 class EqualsAssertionError(AssertionError):

54 MESSAGE_SEP = " :: "

55 NOT_EQ_SEP = " != "

56

57 # Real exception could be provided, but not serialized

58 def __init__(self, expected, actual, msg=None, preformated=False, real_exception=None):

59 self.real_exception = real_exception

60 self.expected = expected

61 self.actual = actual

62 self.msg = text_type(msg)

63

64 if not preformated:

65 self.expected = _format_and_convert(self.expected)

66 self.actual = _format_and_convert(self.actual)

67 self.msg = text_type(msg) if msg else ""

68

69 self.expected = _STR_F(self.expected)

70 self.actual = _STR_F(self.actual)

71

72 def can_be_serialized(self):

73 if any([self.MESSAGE_SEP in s or self.NOT_EQ_SEP in s for s in [self.expected, self.actual, self.msg]]):

74 return False

75 return len(self.actual) + len(self.expected) < 10000

76

77 def __str__(self):

78 return self._serialize()

79

80 def __unicode__(self):

81 return self._serialize()

82

83 def _serialize(self):

84 return self.msg + self.MESSAGE_SEP + self.expected + self.NOT_EQ_SEP + self.actual

85

86 @classmethod

87 def deserialize_error(cls, serialized_message):

88 message, diff = serialized_message.split(cls.MESSAGE_SEP)

89 exp, act = diff.split(cls.NOT_EQ_SEP)

90 return EqualsAssertionError(exp, act, message, preformated=True)

91

92

93 def deserialize_error(serialized_message):

94 return EqualsAssertionError.deserialize_error(serialized_message)