finish adding Config parsing and tests
[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(
76 """
77 bugzilla_url = ""
78 [people."person1"]
79 aliases = ["a"]
80 [people."person2"]
81 aliases = ["b"]
82 """,
83 "Config(bugzilla_url='', people={"
84 "'person1': Person(config=..., identifier='person1', "
85 "aliases={'a'}, email=None), "
86 "'person2': Person(config=..., identifier='person2', "
87 "aliases={'b'}, email=None)})")
88 check_error(
89 """
90 bugzilla_url = ""
91 [people."person1"]
92 email = 123
93 """,
94 "`email` field in person entry for 'person1' must be a string")
95 check(
96 """
97 bugzilla_url = ""
98 [people]
99 """,
100 "Config(bugzilla_url='', people={})")
101 check(
102 """
103 bugzilla_url = ""
104 [people."person1"]
105 email = "email@example.com"
106 """,
107 "Config(bugzilla_url='', people={"
108 "'person1': Person(config=..., identifier='person1', "
109 "aliases=set(), email='email@example.com')})")
110 check_error(
111 """
112 bugzilla_url = ""
113 [people."person1"]
114 blah = 123
115 """,
116 "unknown field in person entry for 'person1': `blah`")
117 check_error(
118 """
119 bugzilla_url = ""
120 [people."person1"]
121 [people."person2"]
122 aliases = ["person1"]
123 """,
124 "alias is not allowed to be the same as any person's identifier: "
125 "in person entry for 'person2': 'person1' is also the identifier "
126 "for person 'person1'")
127 check_error(
128 """
129 bugzilla_url = ""
130 [people."person1"]
131 aliases = ["a"]
132 [people."person2"]
133 aliases = ["a"]
134 """,
135 "alias is not allowed to be the same as another person's alias: "
136 "in person entry for 'person2': 'a' is also an alias for person "
137 "'person1'")
138
139 def test_all_names(self):
140 config = Config.from_str(
141 """
142 bugzilla_url = ""
143 [people."person1"]
144 aliases = ["person1_alias1", "alias1"]
145 [people."person2"]
146 aliases = ["person2_alias2", "alias2"]
147 """)
148 person1 = config.people['person1']
149 person2 = config.people['person2']
150 self.assertEqual(config.all_names,
151 {
152 'person1': person1,
153 'person1_alias1': person1,
154 'alias1': person1,
155 'person2': person2,
156 'person2_alias2': person2,
157 'alias2': person2,
158 })
159
160 def test_from_file(self):
161 def load(text):
162 with io.StringIO(text) as file:
163 return Config.from_file(file)
164
165 with self.assertRaisesRegex(TypeError,
166 "^list is not a valid file or path$"):
167 Config.from_file([])
168
169 with self.assertRaisesRegex(
170 ConfigParseError,
171 "^TOML parse error: Empty value is invalid"):
172 load("""bad-toml=""")
173
174
175 if __name__ == "__main__":
176 unittest.main()