Completed
Pull Request — master (#2598)
by Lasse
01:56
created

FunctionMetadataTest.test_add_alias()   A

Complexity

Conditions 1

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
c 1
b 0
f 0
dl 0
loc 15
rs 9.4285
1
import unittest
2
3
from coalib.settings.FunctionMetadata import FunctionMetadata
4
from coalib.settings.Section import Section
5
from coalib.settings.Setting import Setting
6
7
8
class TestClass:
9
10
    def __init__(self, param1, param2, param3=5, param4: int=6):
11
        """
12
        Description
13
14
        :param param2: d
15
        :param param4: p4 desc
16
        :return:       ret
17
        """
18
19
    def good_function(self, a_param: int):
20
        pass
21
22
    def bad_function(self, bad_param: "no function"):
23
        pass
24
25
26
class FunctionMetadataTest(unittest.TestCase):
27
28
    def test_construction(self):
29
        self.check_function_metadata_data_set(FunctionMetadata("name"), "name")
30
31
    def test_from_function(self):
32
        uut = FunctionMetadata.from_function(self.test_from_function)
33
        self.check_function_metadata_data_set(uut, "test_from_function")
34
        # setattr on bound methods will fail, vars() will use the dict from
35
        # the unbound method which is ok.
36
        vars(self.test_from_function)["__metadata__"] = (
37
            FunctionMetadata("t"))
38
        uut = FunctionMetadata.from_function(self.test_from_function)
39
        self.check_function_metadata_data_set(uut, "t")
40
41
        uut = FunctionMetadata.from_function(TestClass(5, 5).__init__)
42
        self.check_function_metadata_data_set(
43
            uut,
44
            "__init__",
45
            desc="Description",
46
            retval_desc="ret",
47
            non_optional_params={
48
                "param1": (uut.str_nodesc, None),
49
                "param2": ("d", None)
50
            },
51
            optional_params={
52
                "param3": (uut.str_nodesc + " ("
53
                           + uut.str_optional.format("5") + ")",
54
                           None, 5),
55
                "param4": ("p4 desc ("
56
                           + uut.str_optional.format("6") + ")", int, 6)})
57
58
        uut = FunctionMetadata.from_function(TestClass(5, 5).__init__,
59
                                             omit={"param3", "param2"})
60
        self.check_function_metadata_data_set(
61
            uut,
62
            "__init__",
63
            desc="Description",
64
            retval_desc="ret",
65
            non_optional_params={
66
                "param1": (uut.str_nodesc,
67
                           None)
68
            },
69
            optional_params={
70
                "param4": ("p4 desc (" + uut.str_optional.format("6") + ")",
71
                           int,
72
                           6)})
73
74
    def test_create_params_from_section_invalid(self):
75
        section = Section("name")
76
        section.append(Setting("bad_param", "value"))
77
        uut = FunctionMetadata.from_function(TestClass(5, 5).bad_function)
78
79
        with self.assertRaises(ValueError):
80
            uut.create_params_from_section(section)
81
82
    def test_create_params_from_section_valid(self):
83
        section = Section("name")
84
        section.append(Setting("a_param", "value"))
85
        uut = FunctionMetadata.from_function(TestClass(5, 5).good_function)
86
87
        with self.assertRaises(ValueError):
88
            uut.create_params_from_section(section)
89
90
        section.append(Setting("a_param", "5"))
91
        params = uut.create_params_from_section(section)
92
        self.assertEqual(params['a_param'], 5)
93
94
    def check_function_metadata_data_set(self,
95
                                         metadata,
96
                                         name,
97
                                         desc="",
98
                                         retval_desc="",
99
                                         non_optional_params=None,
100
                                         optional_params=None):
101
        non_optional_params = non_optional_params or {}
102
        optional_params = optional_params or {}
103
104
        self.assertEqual(metadata.name, name)
105
        self.assertEqual(metadata.desc, desc)
106
        self.assertEqual(metadata.retval_desc, retval_desc)
107
        self.assertEqual(metadata.non_optional_params, non_optional_params)
108
        self.assertEqual(metadata.optional_params, optional_params)
109
110
    def test_add_alias(self):
111
        uut = FunctionMetadata(
112
            "test",
113
            non_optional_params={'not_optional': ('desc', str)},
114
            optional_params={'optional': ('desc2', str, 'default')})
115
116
        uut.add_alias('optional', 'old_optional')
117
        uut.add_alias('not_optional', 'old_not_optional')
118
119
        self.assertEqual(uut.non_optional_params,
120
                         {'not_optional': ('desc', str)})
121
        self.assertEqual(uut.optional_params,
122
                         {'optional': ('desc2', str, 'default'),
123
                          'old_optional': ('desc2', str, 'default'),
124
                          'old_not_optional': ('desc', str, None)})
125
126
    def test_merge(self):
127
        metadata1 = FunctionMetadata(
128
            "main",
129
            "Desc of main.\n",
130
            "Returns 0 on success",
131
            {"argc": ("argc desc", None), "argv": ("argv desc", None)},
132
            {"opt": ("opt desc", int, 88)},
133
            {"self", "A"})
134
135
        metadata2 = FunctionMetadata(
136
            "process",
137
            "Desc of process.\n",
138
            "Returns the processed stuff.",
139
            {"argc": ("argc desc from process", int),
140
             "to_process": ("to_process desc", int)},
141
            {"opt2": ("opt2 desc", str, "hello")},
142
            {"self", "B"})
143
144
        metadata3 = FunctionMetadata("nodesc", "", "", {}, {})
145
146
        merged_metadata = FunctionMetadata.merge(metadata1,
147
                                                 metadata2,
148
                                                 metadata3)
149
150
        self.assertEqual(
151
            merged_metadata.name,
152
            "<Merged signature of 'main', 'process', 'nodesc'>")
153
        self.assertEqual(merged_metadata.desc, "Desc of process.\n")
154
        self.assertEqual(merged_metadata.retval_desc,
155
                         "Returns the processed stuff.")
156
        self.assertEqual(
157
            merged_metadata.non_optional_params,
158
            {"argc": ("argc desc from process", int),
159
             "argv": ("argv desc", None),
160
             "to_process": ("to_process desc", int)})
161
        self.assertEqual(
162
            merged_metadata.optional_params,
163
            {"opt": ("opt desc", int, 88),
164
             "opt2": ("opt2 desc", str, "hello")})
165
        self.assertEqual(
166
            merged_metadata.omit,
167
            frozenset({"self", "A", "B"}))
168