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

62 statements  

« prev     ^ index     » next       coverage.py v7.3.1, created at 2023-09-19 10:04 +0530

1import os 

2import pprint 

3import sys 

4import unittest 

5 

6from .messages import text_type 

7 

8_PY2K = sys.version_info < (3,) 

9_PRIMITIVES = [int, str, bool] 

10if _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 

17else: 

18 _STR_F = str 

19 

20 

21def 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 

46def _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 

53class 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 

93def deserialize_error(serialized_message): 

94 return EqualsAssertionError.deserialize_error(serialized_message)