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_merge(self): |
111
|
|
|
metadata1 = FunctionMetadata( |
112
|
|
|
"main", |
113
|
|
|
"Desc of main.\n", |
114
|
|
|
"Returns 0 on success", |
115
|
|
|
{"argc": ("argc desc", None), "argv": ("argv desc", None)}, |
116
|
|
|
{"opt": ("opt desc", int, 88)}, |
|
|
|
|
117
|
|
|
{"self", "A"}) |
118
|
|
|
|
119
|
|
|
metadata2 = FunctionMetadata( |
120
|
|
|
"process", |
121
|
|
|
"Desc of process.\n", |
122
|
|
|
"Returns the processed stuff.", |
123
|
|
|
{"argc": ("argc desc from process", int), |
124
|
|
|
"to_process": ("to_process desc", int)}, |
125
|
|
|
{"opt2": ("opt2 desc", str, "hello")}, |
|
|
|
|
126
|
|
|
{"self", "B"}) |
127
|
|
|
|
128
|
|
|
metadata3 = FunctionMetadata("nodesc", "", "", {}, {}) |
129
|
|
|
|
130
|
|
|
merged_metadata = FunctionMetadata.merge(metadata1, |
|
|
|
|
131
|
|
|
metadata2, |
|
|
|
|
132
|
|
|
metadata3) |
|
|
|
|
133
|
|
|
|
134
|
|
|
self.assertEqual( |
135
|
|
|
merged_metadata.name, |
|
|
|
|
136
|
|
|
"<Merged signature of 'main', 'process', 'nodesc'>") |
137
|
|
|
self.assertEqual(merged_metadata.desc, "Desc of process.\n") |
138
|
|
|
self.assertEqual(merged_metadata.retval_desc, |
139
|
|
|
"Returns the processed stuff.") |
140
|
|
|
self.assertEqual( |
141
|
|
|
merged_metadata.non_optional_params, |
142
|
|
|
{"argc": ("argc desc from process", int), |
143
|
|
|
"argv": ("argv desc", None), |
144
|
|
|
"to_process": ("to_process desc", int)}) |
145
|
|
|
self.assertEqual( |
146
|
|
|
merged_metadata.optional_params, |
147
|
|
|
{"opt": ("opt desc", int, 88), |
148
|
|
|
"opt2": ("opt2 desc", str, "hello")}) |
149
|
|
|
self.assertEqual( |
150
|
|
|
merged_metadata.omit, |
151
|
|
|
frozenset({"self", "A", "B"})) |
152
|
|
|
|