edq.testing.unittest

 1import typing
 2import unittest
 3
 4import edq.util.json
 5import edq.util.reflection
 6
 7FORMAT_STR: str = "\n--- Expected ---\n%s\n--- Actual ---\n%s\n---\n"
 8
 9class BaseTest(unittest.TestCase):
10    """
11    A base class for unit tests.
12    """
13
14    maxDiff = None
15    """ Don't limit the size of diffs. """
16
17    def assertJSONEqual(self, a: typing.Any, b: typing.Any, message: typing.Union[str, None] = None) -> None:  # pylint: disable=invalid-name
18        """
19        Like unittest.TestCase.assertEqual(),
20        but uses a default assertion message containing the full JSON representation of the arguments.
21        """
22
23        a_json = edq.util.json.dumps(a, indent = 4)
24        b_json = edq.util.json.dumps(b, indent = 4)
25
26        if (message is None):
27            message = FORMAT_STR % (a_json, b_json)
28
29        super().assertEqual(a, b, msg = message)
30
31    def assertJSONDictEqual(self, a: typing.Any, b: typing.Any, message: typing.Union[str, None] = None) -> None:  # pylint: disable=invalid-name
32        """
33        Like unittest.TestCase.assertDictEqual(),
34        but will try to convert each comparison argument to a dict if it is not already,
35        and uses a default assertion message containing the full JSON representation of the arguments.
36        """
37
38        if (not isinstance(a, dict)):
39            if (isinstance(a, edq.util.json.DictConverter)):
40                a = a.to_dict()
41            else:
42                a = vars(a)
43
44        if (not isinstance(b, dict)):
45            if (isinstance(b, edq.util.json.DictConverter)):
46                b = b.to_dict()
47            else:
48                b = vars(b)
49
50        a_json = edq.util.json.dumps(a, indent = 4)
51        b_json = edq.util.json.dumps(b, indent = 4)
52
53        if (message is None):
54            message = FORMAT_STR % (a_json, b_json)
55
56        super().assertDictEqual(a, b, msg = message)
57
58    def assertJSONListEqual(self, a: typing.List[typing.Any], b: typing.List[typing.Any], message: typing.Union[str, None] = None) -> None:  # pylint: disable=invalid-name
59        """
60        Call assertDictEqual(), but supply a default message containing the full JSON representation of the arguments.
61        """
62
63        a_json = edq.util.json.dumps(a, indent = 4)
64        b_json = edq.util.json.dumps(b, indent = 4)
65
66        if (message is None):
67            message = FORMAT_STR % (a_json, b_json)
68
69        super().assertListEqual(a, b, msg = message)
70
71    def format_error_string(self, ex: typing.Union[BaseException, None]) -> str:
72        """
73        Format an error string from an exception so it can be checked for testing.
74        The type of the error will be included,
75        and any nested errors will be joined together.
76        """
77
78        parts = []
79
80        while (ex is not None):
81            type_name = edq.util.reflection.get_qualified_name(ex)
82            message = str(ex)
83
84            parts.append(f"{type_name}: {message}")
85
86            ex = ex.__cause__
87
88        return "; ".join(parts)
FORMAT_STR: str = '\n--- Expected ---\n%s\n--- Actual ---\n%s\n---\n'
class BaseTest(unittest.case.TestCase):
10class BaseTest(unittest.TestCase):
11    """
12    A base class for unit tests.
13    """
14
15    maxDiff = None
16    """ Don't limit the size of diffs. """
17
18    def assertJSONEqual(self, a: typing.Any, b: typing.Any, message: typing.Union[str, None] = None) -> None:  # pylint: disable=invalid-name
19        """
20        Like unittest.TestCase.assertEqual(),
21        but uses a default assertion message containing the full JSON representation of the arguments.
22        """
23
24        a_json = edq.util.json.dumps(a, indent = 4)
25        b_json = edq.util.json.dumps(b, indent = 4)
26
27        if (message is None):
28            message = FORMAT_STR % (a_json, b_json)
29
30        super().assertEqual(a, b, msg = message)
31
32    def assertJSONDictEqual(self, a: typing.Any, b: typing.Any, message: typing.Union[str, None] = None) -> None:  # pylint: disable=invalid-name
33        """
34        Like unittest.TestCase.assertDictEqual(),
35        but will try to convert each comparison argument to a dict if it is not already,
36        and uses a default assertion message containing the full JSON representation of the arguments.
37        """
38
39        if (not isinstance(a, dict)):
40            if (isinstance(a, edq.util.json.DictConverter)):
41                a = a.to_dict()
42            else:
43                a = vars(a)
44
45        if (not isinstance(b, dict)):
46            if (isinstance(b, edq.util.json.DictConverter)):
47                b = b.to_dict()
48            else:
49                b = vars(b)
50
51        a_json = edq.util.json.dumps(a, indent = 4)
52        b_json = edq.util.json.dumps(b, indent = 4)
53
54        if (message is None):
55            message = FORMAT_STR % (a_json, b_json)
56
57        super().assertDictEqual(a, b, msg = message)
58
59    def assertJSONListEqual(self, a: typing.List[typing.Any], b: typing.List[typing.Any], message: typing.Union[str, None] = None) -> None:  # pylint: disable=invalid-name
60        """
61        Call assertDictEqual(), but supply a default message containing the full JSON representation of the arguments.
62        """
63
64        a_json = edq.util.json.dumps(a, indent = 4)
65        b_json = edq.util.json.dumps(b, indent = 4)
66
67        if (message is None):
68            message = FORMAT_STR % (a_json, b_json)
69
70        super().assertListEqual(a, b, msg = message)
71
72    def format_error_string(self, ex: typing.Union[BaseException, None]) -> str:
73        """
74        Format an error string from an exception so it can be checked for testing.
75        The type of the error will be included,
76        and any nested errors will be joined together.
77        """
78
79        parts = []
80
81        while (ex is not None):
82            type_name = edq.util.reflection.get_qualified_name(ex)
83            message = str(ex)
84
85            parts.append(f"{type_name}: {message}")
86
87            ex = ex.__cause__
88
89        return "; ".join(parts)

A base class for unit tests.

maxDiff = None

Don't limit the size of diffs.

def assertJSONEqual(self, a: Any, b: Any, message: Optional[str] = None) -> None:
18    def assertJSONEqual(self, a: typing.Any, b: typing.Any, message: typing.Union[str, None] = None) -> None:  # pylint: disable=invalid-name
19        """
20        Like unittest.TestCase.assertEqual(),
21        but uses a default assertion message containing the full JSON representation of the arguments.
22        """
23
24        a_json = edq.util.json.dumps(a, indent = 4)
25        b_json = edq.util.json.dumps(b, indent = 4)
26
27        if (message is None):
28            message = FORMAT_STR % (a_json, b_json)
29
30        super().assertEqual(a, b, msg = message)

Like unittest.TestCase.assertEqual(), but uses a default assertion message containing the full JSON representation of the arguments.

def assertJSONDictEqual(self, a: Any, b: Any, message: Optional[str] = None) -> None:
32    def assertJSONDictEqual(self, a: typing.Any, b: typing.Any, message: typing.Union[str, None] = None) -> None:  # pylint: disable=invalid-name
33        """
34        Like unittest.TestCase.assertDictEqual(),
35        but will try to convert each comparison argument to a dict if it is not already,
36        and uses a default assertion message containing the full JSON representation of the arguments.
37        """
38
39        if (not isinstance(a, dict)):
40            if (isinstance(a, edq.util.json.DictConverter)):
41                a = a.to_dict()
42            else:
43                a = vars(a)
44
45        if (not isinstance(b, dict)):
46            if (isinstance(b, edq.util.json.DictConverter)):
47                b = b.to_dict()
48            else:
49                b = vars(b)
50
51        a_json = edq.util.json.dumps(a, indent = 4)
52        b_json = edq.util.json.dumps(b, indent = 4)
53
54        if (message is None):
55            message = FORMAT_STR % (a_json, b_json)
56
57        super().assertDictEqual(a, b, msg = message)

Like unittest.TestCase.assertDictEqual(), but will try to convert each comparison argument to a dict if it is not already, and uses a default assertion message containing the full JSON representation of the arguments.

def assertJSONListEqual(self, a: List[Any], b: List[Any], message: Optional[str] = None) -> None:
59    def assertJSONListEqual(self, a: typing.List[typing.Any], b: typing.List[typing.Any], message: typing.Union[str, None] = None) -> None:  # pylint: disable=invalid-name
60        """
61        Call assertDictEqual(), but supply a default message containing the full JSON representation of the arguments.
62        """
63
64        a_json = edq.util.json.dumps(a, indent = 4)
65        b_json = edq.util.json.dumps(b, indent = 4)
66
67        if (message is None):
68            message = FORMAT_STR % (a_json, b_json)
69
70        super().assertListEqual(a, b, msg = message)

Call assertDictEqual(), but supply a default message containing the full JSON representation of the arguments.

def format_error_string(self, ex: Optional[BaseException]) -> str:
72    def format_error_string(self, ex: typing.Union[BaseException, None]) -> str:
73        """
74        Format an error string from an exception so it can be checked for testing.
75        The type of the error will be included,
76        and any nested errors will be joined together.
77        """
78
79        parts = []
80
81        while (ex is not None):
82            type_name = edq.util.reflection.get_qualified_name(ex)
83            message = str(ex)
84
85            parts.append(f"{type_name}: {message}")
86
87            ex = ex.__cause__
88
89        return "; ".join(parts)

Format an error string from an exception so it can be checked for testing. The type of the error will be included, and any nested errors will be joined together.