add milestones to Config
[utils.git] / src / budget_sync / test / test_config.py
1 import unittest
2 import io
3 from budget_sync.config import Config, ConfigParseError
4
5
6 class TestConfig(unittest.TestCase):
7 def test_config_parsing(self):
8 def check_error(text: str, expected_error_text: str):
9 with self.assertRaises(ConfigParseError) as e:
10 Config.from_str(text)
11 self.assertEqual(str(e.exception), expected_error_text)
12
13 def check(text: str, expected_repr_text: str):
14 self.assertEqual(repr(Config.from_str(text)), expected_repr_text)
15
16 check_error(
17 "bad-toml=",
18 "TOML parse error: Empty value is invalid "
19 "(line 1 column 1 char 0)")
20 check_error(
21 """
22 """,
23 "`bugzilla_url` field is missing")
24 check_error(
25 """
26 [bugzilla_url]
27 """,
28 "`bugzilla_url` must be a string")
29 check_error(
30 """
31 bugzilla_url = ""
32 """,
33 "`people` table is missing")
34 check_error(
35 """
36 blah = ""
37 """,
38 "unknown config entry: `blah`")
39 check_error(
40 """
41 bugzilla_url = ""
42 people = []
43 """,
44 "`people` field must be a table")
45 check_error(
46 """
47 bugzilla_url = ""
48 [people]
49 person1 = 1
50 """,
51 "person entry for 'person1' must be a table")
52 check_error(
53 """
54 bugzilla_url = ""
55 [people."person1"]
56 aliases = ""
57 """,
58 "`aliases` field in person entry for 'person1' must be a list "
59 "of strings")
60 check_error(
61 """
62 bugzilla_url = ""
63 [people."person1"]
64 aliases = [1]
65 """,
66 "`aliases` field in person entry for 'person1' must be a list "
67 "of strings")
68 check_error(
69 """
70 bugzilla_url = ""
71 [people."person1"]
72 aliases = ["a", "a"]
73 """,
74 "duplicate alias in person entry for 'person1': 'a'")
75 check_error(
76 """
77 bugzilla_url = ""
78 [people]
79 """,
80 "`milestones` table is missing")
81 check(
82 """
83 bugzilla_url = ""
84 [milestones]
85 [people."person1"]
86 aliases = ["a"]
87 [people."person2"]
88 aliases = ["b"]
89 """,
90 "Config(bugzilla_url='', people={"
91 "'person1': Person(config=..., identifier='person1', "
92 "aliases={'a'}, email=None), "
93 "'person2': Person(config=..., identifier='person2', "
94 "aliases={'b'}, email=None)}, milestones={})")
95 check_error(
96 """
97 bugzilla_url = ""
98 [people."person1"]
99 email = 123
100 """,
101 "`email` field in person entry for 'person1' must be a string")
102 check(
103 """
104 bugzilla_url = ""
105 [people]
106 [milestones]
107 """,
108 "Config(bugzilla_url='', people={}, milestones={})")
109 check(
110 """
111 bugzilla_url = ""
112 [milestones]
113 [people."person1"]
114 email = "email@example.com"
115 """,
116 "Config(bugzilla_url='', people={"
117 "'person1': Person(config=..., identifier='person1', "
118 "aliases=set(), email='email@example.com')}, milestones={})")
119 check_error(
120 """
121 bugzilla_url = ""
122 [people."person1"]
123 blah = 123
124 """,
125 "unknown field in person entry for 'person1': `blah`")
126 check_error(
127 """
128 bugzilla_url = ""
129 [milestones]
130 [people."person1"]
131 [people."person2"]
132 aliases = ["person1"]
133 """,
134 "alias is not allowed to be the same as any person's identifier: "
135 "in person entry for 'person2': 'person1' is also the identifier "
136 "for person 'person1'")
137 check_error(
138 """
139 bugzilla_url = ""
140 [milestones]
141 [people."person1"]
142 aliases = ["a"]
143 [people."person2"]
144 aliases = ["a"]
145 """,
146 "alias is not allowed to be the same as another person's alias: "
147 "in person entry for 'person2': 'a' is also an alias for person "
148 "'person1'")
149 check_error(
150 """
151 bugzilla_url = ""
152 [milestones]
153 "abc" = 1
154 [people]
155 """,
156 "milestones entry for 'abc' must be a table")
157 check_error(
158 """
159 bugzilla_url = ""
160 [milestones]
161 "abc" = { canonical_bug_id = "abc" }
162 [people]
163 """,
164 "`canonical_bug_id` field in milestones entry for 'abc' must "
165 "be an integer")
166 check_error(
167 """
168 bugzilla_url = ""
169 [milestones]
170 "abc" = { blah = "def" }
171 [people]
172 """,
173 "unknown field in milestones entry for 'abc': `blah`")
174 check_error(
175 """
176 bugzilla_url = ""
177 [milestones]
178 "abc" = {}
179 [people]
180 """,
181 "`canonical_bug_id` field is missing in milestones entry for 'abc'")
182 check_error(
183 """
184 bugzilla_url = ""
185 milestones = 1
186 [people]
187 """,
188 "`milestones` field must be a table")
189 check_error(
190 """
191 bugzilla_url = ""
192 [milestones]
193 "abc" = { canonical_bug_id = 1 }
194 "def" = { canonical_bug_id = 1 }
195 [people]
196 """,
197 "canonical_bug_id is not allowed to be the same as another "
198 "milestone's canonical_bug_id: in milestone entry for 'def': "
199 "1 is also the canonical_bug_id for milestone 'abc'")
200
201 def test_all_names(self):
202 config = Config.from_str(
203 """
204 bugzilla_url = ""
205 [milestones]
206 [people."person1"]
207 aliases = ["person1_alias1", "alias1"]
208 [people."person2"]
209 aliases = ["person2_alias2", "alias2"]
210 """)
211 person1 = config.people['person1']
212 person2 = config.people['person2']
213 self.assertEqual(config.all_names,
214 {
215 'person1': person1,
216 'person1_alias1': person1,
217 'alias1': person1,
218 'person2': person2,
219 'person2_alias2': person2,
220 'alias2': person2,
221 })
222
223 def test_canonical_bug_ids(self):
224 config = Config.from_str(
225 """
226 bugzilla_url = ""
227 [people]
228 [milestones]
229 "Milestone 1" = { canonical_bug_id = 1 }
230 "Milestone 2" = { canonical_bug_id = 2 }
231 """)
232 milestone1 = config.milestones['Milestone 1']
233 milestone2 = config.milestones['Milestone 2']
234 self.assertEqual(config.canonical_bug_ids,
235 {
236 1: milestone1,
237 2: milestone2,
238 })
239
240 def test_from_file(self):
241 def load(text):
242 with io.StringIO(text) as file:
243 return Config.from_file(file)
244
245 with self.assertRaisesRegex(TypeError,
246 "^list is not a valid file or path$"):
247 Config.from_file([])
248
249 with self.assertRaisesRegex(
250 ConfigParseError,
251 "^TOML parse error: Empty value is invalid"):
252 load("""bad-toml=""")
253
254 self.assertEqual(str(load(
255 """
256 bugzilla_url = "https://bugzilla.example.com/"
257 [people."person1"]
258 email = "person1@example.com"
259 aliases = ["alias1"]
260 [milestones]
261 "Milestone 1" = { canonical_bug_id = 123 }
262 """)),
263 "Config(bugzilla_url='https://bugzilla.example.com/', "
264 "people={'person1': Person(config=..., identifier='person1', "
265 "aliases={'alias1'}, email='person1@example.com')}, "
266 "milestones={'Milestone 1': Milestone(config=..., "
267 "identifier='Milestone 1', canonical_bug_id=123)})")
268
269
270 if __name__ == "__main__":
271 unittest.main()