Omitted parameter "name" in some functions.
[philipp/winterrodeln/wrpylib.git] / tests / test_wrvalidators.py
1 #!/usr/bin/python3.4
2 # -*- coding: utf-8 -*-
3 import unittest
4 from wrpylib.wrvalidators import *
5
6 # optional converter
7 # ------------------
8
9 class TestOpt(unittest.TestCase):
10     def test_from_str(self):
11         self.assertEqual(None, opt_from_str('', str_from_str))
12         self.assertEqual('abc', opt_from_str('abc', str_from_str))
13         self.assertEqual(None, opt_from_str('', int_from_str))
14         self.assertEqual(4, opt_from_str('4', int_from_str))
15
16     def test_to_str(self):
17         self.assertEqual('', opt_to_str(None, str_to_str))
18         self.assertEqual('abc', opt_to_str('abc', str_to_str))
19         self.assertEqual('', opt_to_str(None, int_to_str))
20         self.assertEqual('4', opt_to_str(4, int_to_str))
21
22
23 # "no" converter
24 # --------------
25
26 class TestNoGermanConverter(unittest.TestCase):
27     def test_from_str(self):
28         self.assertEqual((True, 'abc'), no_german_from_str('abc', req_str_from_str))
29         self.assertEqual((False, None), no_german_from_str('Nein', req_str_from_str))
30         with self.assertRaises(ValueError):
31             no_german_from_str('', req_str_from_str)
32
33     def test_to_str(self):
34         self.assertEqual('abc', no_german_to_str((True, 'abc'), str_to_str))
35         self.assertEqual('Nein', no_german_to_str((False, None), str_to_str))
36
37
38 # "optional"/"no" converter
39 # -------------------------
40
41 class TestOptNoGerman(unittest.TestCase):
42     def test_from_str(self):
43         self.assertEqual((True, 'abc'), opt_no_german_from_str('abc', str_from_str))
44         self.assertEqual((False, None), opt_no_german_from_str('Nein', str_from_str))
45         self.assertEqual((None, None), opt_no_german_from_str('', str_from_str))
46
47     def test_to_str(self):
48         self.assertEqual('abc', opt_no_german_to_str((True, 'abc'), str_to_str))
49         self.assertEqual('Nein', opt_no_german_to_str((False, None), str_to_str))
50         self.assertEqual('', opt_no_german_to_str((None, None), str_to_str))
51
52
53 # choice converter
54 # ----------------
55
56 class TestCoice(unittest.TestCase):
57     def setUp(self):
58         self.choices = ['abc', 'def', 'ghi']
59
60     def test_from_str(self):
61         self.assertEqual('abc', choice_from_str('abc', self.choices))
62         self.assertEqual('ghi', choice_from_str('ghi', self.choices))
63         with self.assertRaises(ValueError):
64             choice_from_str('jkl', self.choices)
65
66
67 # dictkey converter
68 # -----------------
69
70 class TestDictkey(unittest.TestCase):
71     def setUp(self):
72         self.choices = {'abc': '1', 'def': '2', 'ghi': '3'}
73
74     def test_from_str(self):
75         self.assertEqual('abc', dictkey_from_str('1', self.choices))
76         self.assertEqual('ghi', dictkey_from_str('3', self.choices))
77         with self.assertRaises(ValueError):
78             dictkey_from_str('4', self.choices)
79
80     def test_to_str(self):
81         self.assertEqual('1', dictkey_to_str('abc', self.choices))
82         self.assertEqual('3', dictkey_to_str('ghi', self.choices))
83
84
85 # enum/"list" converter
86 # ---------------------
87
88 class TestEnumConverter(unittest.TestCase):
89     def test_from_str(self):
90         self.assertEqual([], enum_from_str('', str_from_str))
91         self.assertEqual(['abc'], enum_from_str('abc', str_from_str))
92         self.assertEqual(['abc', 'def'], enum_from_str('abc; def', str_from_str))
93         self.assertEqual(['abc', 'def', 'ghi'], enum_from_str('abc; def;ghi', str_from_str))
94
95     def test_to_str(self):
96         self.assertEqual('abc; def; ghi', enum_to_str(['abc', 'def', 'ghi'], str_to_str))
97         self.assertEqual('abc', enum_to_str(['abc'], str_to_str))
98         self.assertEqual('', enum_to_str([''], str_to_str))
99         self.assertEqual('', enum_to_str([], str_to_str))
100
101
102 # value/comment converter
103 # -----------------------
104
105 class TestValueCommentConverter(unittest.TestCase):
106     def test_from_str(self):
107         self.assertEqual(('abc', 'defg'), value_comment_from_str('abc (defg)', str_from_str, str_from_str))
108         self.assertEqual(('abc', ''), value_comment_from_str('abc ()', str_from_str, str_from_str))
109         self.assertEqual(('', 'def'), value_comment_from_str('(def)', str_from_str, str_from_str))
110         self.assertEqual(('ab', '(cd)'), value_comment_from_str('ab ((cd))', str_from_str, str_from_str))
111         self.assertEqual(('ab', '(c(d)[(]))'), value_comment_from_str('ab ((c(d)[(])))', str_from_str, str_from_str))
112         self.assertEqual(('ab(', 'cd'), value_comment_from_str('ab( (cd)', str_from_str, str_from_str))
113         self.assertEqual(('abcd ', 'ef'), value_comment_from_str('abcd  (ef)', str_from_str, str_from_str))
114         self.assertEqual(('abc', ''), value_comment_from_str('abc', str_from_str, str_from_str, comment_optional=True))
115         self.assertEqual(('a(bc)de', 'fg'), value_comment_from_str('a(bc)de (fg)', str_from_str, str_from_str))
116         self.assertEqual(('a(bc)de', 'fg'), value_comment_from_str('a(bc)de (fg)', str_from_str, str_from_str, comment_optional=True))
117         self.assertEqual(('a(bc)de', 'f(g)'), value_comment_from_str('a(bc)de (f(g))', str_from_str, str_from_str))
118         self.assertEqual(('a(bc)de', 'f(g)'), value_comment_from_str('a(bc)de (f(g))', str_from_str, str_from_str, comment_optional=True))
119         self.assertEqual(('a(bc)de', None), value_comment_from_str('a(bc)de', str_from_str, opt_str_from_str, comment_optional=True))
120         with self.assertRaises(ValueError):
121             value_comment_from_str('abc (', str_from_str, str_from_str)
122         with self.assertRaises(ValueError):
123             value_comment_from_str('abc )', str_from_str, str_from_str)
124         with self.assertRaises(ValueError):
125             value_comment_from_str('abc (def)g', str_from_str, str_from_str)
126         with self.assertRaises(ValueError):
127             value_comment_from_str('abc (b))', str_from_str, str_from_str)
128         with self.assertRaises(ValueError):
129             value_comment_from_str('abc', str_from_str, str_from_str)
130         with self.assertRaises(ValueError):
131             value_comment_from_str('abc(def)', str_from_str, str_from_str)
132
133     def test_to_str(self):
134         self.assertEqual('abc (defg)', value_comment_to_str(('abc', 'defg'), str_to_str, str_to_str))
135         self.assertEqual('abc ()', value_comment_to_str(('abc', ''), str_to_str, str_to_str))
136         self.assertEqual('(def)', value_comment_to_str(('', 'def'), str_to_str, str_to_str))
137         self.assertEqual('ab ((cd))', value_comment_to_str(('ab', '(cd)'), str_to_str, str_to_str))
138         self.assertEqual('ab ((c(d)[(])))', value_comment_to_str(('ab', '(c(d)[(]))'), str_to_str, str_to_str))
139         self.assertEqual('ab( (cd)', value_comment_to_str(('ab(', 'cd'), str_to_str, str_to_str))
140         self.assertEqual('abcd (ef)', value_comment_to_str(('abcd', 'ef'), str_to_str, str_to_str))
141         self.assertEqual('abc', value_comment_to_str(('abc', ''), str_to_str, str_to_str, comment_optional=True))
142         self.assertEqual('a(bc)de (fg)', value_comment_to_str(('a(bc)de', 'fg'), str_to_str, str_to_str))
143         self.assertEqual('a(bc)de (fg)', value_comment_to_str(('a(bc)de', 'fg'), str_to_str, str_to_str, comment_optional=True))
144         self.assertEqual('a(bc)de (f(g))', value_comment_to_str(('a(bc)de', 'f(g)'), str_to_str, str_to_str))
145         self.assertEqual('a(bc)de (f(g))', value_comment_to_str(('a(bc)de', 'f(g)'), str_to_str, str_to_str, comment_optional=True))
146         self.assertEqual('a(bc)de', value_comment_to_str(('a(bc)de', None), str_to_str, opt_str_to_str, comment_optional=True))
147
148
149 # string converter
150 # ----------------
151
152 class TestStr(unittest.TestCase):
153     def test_from_str(self):
154         self.assertEqual('', str_from_str(''))
155         self.assertEqual('abc', str_from_str('abc'))
156
157     def test_to_str(self):
158         self.assertEqual('', str_to_str(''))
159         self.assertEqual('abc', str_to_str('abc'))
160
161
162 class TestReqStr(unittest.TestCase):
163     def test_from_str(self):
164         self.assertEqual('abc', req_str_from_str('abc'))
165         self.assertEqual(' ', req_str_from_str(' '))
166         with self.assertRaises(ValueError):
167             req_str_from_str('')
168
169
170 class TestOptStr(unittest.TestCase):
171     def test_from_str(self):
172         self.assertEqual('abc', opt_str_from_str('abc'))
173         self.assertEqual(' ', opt_str_from_str(' '))
174         self.assertEqual(None, opt_str_from_str(''))
175
176     def test_to_str(self):
177         self.assertEqual('abc', opt_str_to_str('abc'))
178         self.assertEqual(' ', opt_str_to_str(' '))
179         self.assertEqual('', opt_str_to_str(None))
180
181
182 # optional no or string converter
183 # -------------------------------
184
185 class TestOptNoOrStr(unittest.TestCase):
186     def test_from_str(self):
187         self.assertEqual((False, None), opt_no_or_str_from_str('Nein'))
188         self.assertEqual((True, 'Nur Wochenende'), opt_no_or_str_from_str('Nur Wochenende'))
189         self.assertEqual((True, 'Ja'), opt_no_or_str_from_str('Ja'))
190         self.assertEqual((None, None), opt_no_or_str_from_str(''))
191
192     def test_to_str(self):
193         self.assertEqual('Nein', opt_no_or_str_to_str((False, None)))
194         self.assertEqual('Nur Wochenende', opt_no_or_str_to_str((True, 'Nur Wochenende')))
195         self.assertEqual('Ja', opt_no_or_str_to_str((True, 'Ja')))
196         self.assertEqual('', opt_no_or_str_to_str((None, None)))
197
198
199 # integer converter
200 # -----------------
201
202 class TestInt(unittest.TestCase):
203     def test_from_str(self):
204         self.assertEqual(42, int_from_str('42'))
205         self.assertEqual(42, int_from_str('+42'))
206         self.assertEqual(-20, int_from_str('-20'))
207         self.assertEqual(0, int_from_str('0', min=0))
208         self.assertEqual(10, int_from_str('10', max=10))
209         with self.assertRaises(ValueError):
210             int_from_str('abc')
211         with self.assertRaises(ValueError):
212             int_from_str('')
213         with self.assertRaises(ValueError):
214             int_from_str('-1', min=0)
215         with self.assertRaises(ValueError):
216             int_from_str('11', max=10)
217         with self.assertRaises(ValueError):
218             int_from_str('10.0')
219         with self.assertRaises(ValueError):
220             int_from_str('0d')
221
222     def test_to_str(self):
223         self.assertEqual('20', int_to_str(20))
224         self.assertEqual('-20', int_to_str(-20))
225         self.assertEqual('0', int_to_str(0))
226
227
228 class TestOptInt(unittest.TestCase):
229     def test_from_str(self):
230         self.assertEqual(42, opt_int_from_str('42'))
231         self.assertEqual(42, opt_int_from_str('+42'))
232         self.assertEqual(-20, opt_int_from_str('-20'))
233         self.assertEqual(None, opt_int_from_str(''))
234         with self.assertRaises(ValueError):
235             opt_int_from_str('abc')
236         with self.assertRaises(ValueError):
237             opt_int_from_str('10.0')
238         with self.assertRaises(ValueError):
239             opt_int_from_str('0d')
240
241     def test_to_str(self):
242         self.assertEqual('20', opt_int_to_str(20))
243         self.assertEqual('-20', opt_int_to_str(-20))
244         self.assertEqual('0', opt_int_to_str(0))
245         self.assertEqual('', opt_int_to_str(None))
246
247
248 class TestOptUInt(unittest.TestCase):
249     def test_from_str(self):
250         self.assertEqual(42, opt_uint_from_str('42'))
251         self.assertEqual(0, opt_uint_from_str('0'))
252         self.assertEqual(None, opt_uint_from_str(''))
253         with self.assertRaises(ValueError):
254             opt_uint_from_str('-1')
255
256     def test_to_str(self):
257         self.assertEqual('20', opt_uint_to_str(20))
258         self.assertEqual('0', opt_uint_to_str(0))
259         self.assertEqual('', opt_uint_to_str(None))
260
261
262 # bool converter
263 # --------------
264
265 class TestBoolGerman(unittest.TestCase):
266     def test_from_str(self):
267         self.assertEqual(True, bool_german_from_str('Ja'))
268         self.assertEqual(True, opt_bool_german_from_str('Ja'))
269         self.assertEqual(False, bool_german_from_str('Nein'))
270         self.assertEqual(False, opt_bool_german_from_str('Nein'))
271         self.assertEqual(None, opt_bool_german_from_str(''))
272         with self.assertRaises(ValueError):
273             bool_german_from_str('Vielleicht')
274             opt_bool_german_from_str('Vielleicht')
275             bool_german_from_str('')
276
277     def test_to_str(self):
278         self.assertEqual('Ja', bool_german_to_str(True))
279         self.assertEqual('Ja', opt_bool_german_to_str(True))
280         self.assertEqual('Nein', bool_german_to_str(False))
281         self.assertEqual('Nein', opt_bool_german_to_str(False))
282         self.assertEqual('', opt_bool_german_to_str(None))
283
284
285 # tristate converter
286 # ------------------
287
288 class TestTristateGerman(unittest.TestCase):
289     def test_from_str(self):
290         self.assertEqual(1.0, tristate_german_from_str('Ja'))
291         self.assertEqual(0.5, tristate_german_from_str('Teilweise'))
292         self.assertEqual(0, tristate_german_from_str('Nein'))
293         with self.assertRaises(ValueError):
294             tristate_german_from_str('')
295         with self.assertRaises(ValueError):
296             tristate_german_from_str('Vielleicht')
297
298     def test_to_str(self):
299         self.assertEqual('Ja', tristate_german_to_str(1.0))
300         self.assertEqual('Teilweise', tristate_german_to_str(0.5))
301         self.assertEqual('Nein', tristate_german_to_str(0.0))
302
303
304 class TestOptTristateGerman(unittest.TestCase):
305     def test_from_str(self):
306         self.assertEqual(1.0, opt_tristate_german_from_str('Ja'))
307         self.assertEqual(0.5, opt_tristate_german_from_str('Teilweise'))
308         self.assertEqual(0, opt_tristate_german_from_str('Nein'))
309         self.assertEqual(None, opt_tristate_german_from_str(''))
310         with self.assertRaises(ValueError):
311             opt_tristate_german_from_str('Vielleicht')
312
313     def test_to_str(self):
314         self.assertEqual('Ja', opt_tristate_german_to_str(1.0))
315         self.assertEqual('Teilweise', opt_tristate_german_to_str(0.5))
316         self.assertEqual('Nein', opt_tristate_german_to_str(0.0))
317         self.assertEqual('', opt_tristate_german_to_str(None))
318
319
320 # tristate with comment converter
321 # -------------------------------
322
323 class TestOptTristateGermanComment(unittest.TestCase):
324     def test_from_str(self):
325         self.assertEqual((1.0, None), opt_tristate_german_comment_from_str('Ja'))
326         self.assertEqual((0.5, None), opt_tristate_german_comment_from_str('Teilweise'))
327         self.assertEqual((0, None), opt_tristate_german_comment_from_str('Nein'))
328         self.assertEqual((0.5, 'nur ganz oben nicht'), opt_tristate_german_comment_from_str('Teilweise (nur ganz oben nicht)'))
329         self.assertEqual((None, None), opt_tristate_german_comment_from_str(''))
330         with self.assertRaises(ValueError):
331             opt_tristate_german_from_str('Vielleicht')
332         with self.assertRaises(ValueError):
333             opt_tristate_german_from_str('(Ja)')
334
335     def test_to_str(self):
336         self.assertEqual('Ja', opt_tristate_german_comment_to_str((1.0, None)))
337         self.assertEqual('Teilweise', opt_tristate_german_comment_to_str((0.5, None)))
338         self.assertEqual('Nein', opt_tristate_german_comment_to_str((0.0, None)))
339         self.assertEqual('', opt_tristate_german_comment_to_str((None, None)))
340
341
342 # url converter
343 # -------------
344
345 class TestUrl(unittest.TestCase):
346     def test_from_str(self):
347         self.assertEqual('http://www.winterrodeln.org/wiki/Arzler_Alm/', url_from_str('http://www.winterrodeln.org/wiki/Arzler_Alm/'))
348         self.assertEqual('http://www.winterrodeln.org/wiki/Nösslachhütte/', url_from_str('http://www.winterrodeln.org/wiki/Nösslachhütte/'))
349         self.assertEqual('https://www.winterrodeln.org/wiki/Nösslachhütte/', url_from_str('https://www.winterrodeln.org/wiki/Nösslachhütte/'))
350         with self.assertRaises(ValueError):
351             url_from_str('mailto:office@example.com')
352         with self.assertRaises(ValueError):
353             url_from_str('/wiki/Arzler_Alm/')
354
355     def test_to_str(self):
356         self.assertEqual('http://www.winterrodeln.org/wiki/Arzler_Alm/', url_to_str('http://www.winterrodeln.org/wiki/Arzler_Alm/'))
357         self.assertEqual('http://www.winterrodeln.org/wiki/Nösslachhütte/', url_to_str('http://www.winterrodeln.org/wiki/Nösslachhütte/'))
358         self.assertEqual('https://www.winterrodeln.org/wiki/Nösslachhütte/', url_to_str('https://www.winterrodeln.org/wiki/Nösslachhütte/'))
359
360
361 # webauskunft converter
362 # ---------------------
363
364 class TestWebauskunft(unittest.TestCase):
365     def test_from_str(self):
366         self.assertEqual((True, 'http://www.example.com/current'), webauskunft_from_str('http://www.example.com/current'))
367         self.assertEqual((None, None), webauskunft_from_str(''))
368         self.assertEqual((False, None), webauskunft_from_str('Nein'))
369
370     def test_to_str(self):
371         self.assertEqual('http://www.example.com/current', webauskunft_to_str((True, 'http://www.example.com/current')))
372         self.assertEqual('', webauskunft_to_str((None, None)))
373         self.assertEqual('Nein', webauskunft_to_str((False, None)))
374
375
376 # wikipage converter
377 # ------------------
378
379 class TestWikipage(unittest.TestCase):
380     def test_from_str(self):
381         self.assertEqual('[[Birgitzer Alm]]', wikipage_from_str('[[Birgitzer Alm]]'))
382         with self.assertRaises(ValueError):
383             wikipage_from_str('[[')
384         with self.assertRaises(ValueError):
385             wikipage_from_str('')
386         with self.assertRaises(ValueError):
387             wikipage_from_str('Birgitzer Alm')
388
389     def test_to_str(self):
390         self.assertEqual('[[Birgitzer Alm]]', wikipage_to_str('[[Birgitzer Alm]]'))
391
392
393 class TestOptWikipageEnum(unittest.TestCase):
394     def test_from_str(self):
395         self.assertEqual(['[[Birgitzer Alm]]', '[[Kemater Alm]]'], opt_wikipage_enum_from_str('[[Birgitzer Alm]]; [[Kemater Alm]]'))
396         self.assertEqual(['[[Birgitzer Alm]]'], opt_wikipage_enum_from_str('[[Birgitzer Alm]]'))
397         self.assertEqual([], opt_wikipage_enum_from_str('Nein'))
398         self.assertEqual(None, opt_wikipage_enum_from_str(''))
399
400     def test_to_str(self):
401         self.assertEqual('[[Birgitzer Alm]]; [[Kemater Alm]]', opt_wikipage_enum_to_str(['[[Birgitzer Alm]]', '[[Kemater Alm]]']))
402         self.assertEqual('[[Birgitzer Alm]]', opt_wikipage_enum_to_str(['[[Birgitzer Alm]]']))
403         self.assertEqual('Nein', opt_wikipage_enum_to_str([]))
404         self.assertEqual('', opt_wikipage_enum_to_str(None))
405
406
407 # email converter
408 # ---------------
409
410 class TestEmail(unittest.TestCase):
411     def setUp(self):
412         self.good_addresses = ['office@example.com', 'winter+rodeln@localhost', 'joe.doe@exämple.com']
413         self.bad_addresses = ['öffice@example.com', 'winter rodeln@localhost', 'www.winterrodeln.org', 'mailto:info@example.com', 'info@example.com.']
414
415     def test_from_str(self):
416         for value in self.good_addresses:
417             self.assertEqual(value, email_from_str(value))
418         for value in self.bad_addresses:
419             with self.assertRaises(ValueError):
420                 email_from_str(value)
421
422     def test_to_str(self):
423         for value in self.good_addresses:
424             self.assertEqual(value, email_to_str(value))
425
426
427 class TestMaskedEmail(unittest.TestCase):
428     def test_from_str(self):
429         self.assertEqual(('office@example.com', False), masked_email_from_str('office@example.com'))
430         self.assertEqual(('office@example.com', True), masked_email_from_str('office(at)example.com'))
431         with self.assertRaises(ValueError):
432             masked_email_from_str('office@example.com', masked_only=True)
433         with self.assertRaises(ValueError):
434             masked_email_from_str('off ice@example.com')
435
436     def test_to_str(self):
437         self.assertEqual('office@example.com', masked_email_to_str(('office@example.com', False)))
438         self.assertEqual('office(at)example.com', masked_email_to_str(('office@example.com', True)))
439         self.assertEqual('office()example.com', masked_email_to_str(('office@example.com', True), '()'))
440
441
442 class TestEmails(unittest.TestCase):
443     def test_from_str(self):
444         self.assertEqual(None, emails_from_str(''))
445         self.assertEqual([], emails_from_str('Nein'))
446         self.assertEqual([(('info@example.com', False), None)], emails_from_str('info@example.com'))
447         self.assertEqual([(('info@example.com', True), None)], emails_from_str('info(at)example.com'))
448         self.assertEqual([(('info@example.com', False), 'Office')], emails_from_str('info@example.com (Office)'))
449         self.assertEqual([(('info@example.com', False), None), (('home@example.com', False), 'Privat')], emails_from_str('info@example.com; home@example.com (Privat)'))
450         with self.assertRaises(ValueError):
451             emails_from_str('nein')
452         with self.assertRaises(ValueError):
453             emails_from_str('info@example.com; ho me@example.com (Privat)')
454
455     def test_to_str(self):
456         self.assertEqual('', emails_to_str(None))
457         self.assertEqual('Nein', emails_to_str([]))
458         self.assertEqual('info@example.com', emails_to_str([(('info@example.com', False), None)]))
459         self.assertEqual('info@example.com (Office)', emails_to_str([(('info@example.com', False), 'Office')]))
460         self.assertEqual('info@example.com; home@example.com (Privat)', emails_to_str([(('info@example.com', False), None), (('home@example.com', False), 'Privat')]))
461
462
463 # phone converter
464 # ---------------
465
466 class TestPhoneNumber(unittest.TestCase):
467     def test_from_str(self):
468         self.assertEqual('+43-699-123456789', phone_number_from_str('+43-699-123456789'))
469         self.assertEqual('+43-69945', phone_number_from_str('+43-69945'))
470         self.assertEqual('+43-512-507-6418', phone_number_from_str('+43-512-507-6418'))
471         with self.assertRaises(ValueError):
472             phone_number_from_str('+43-')
473         with self.assertRaises(ValueError):
474             phone_number_from_str('0512123456789')
475
476     def test_to_str(self):
477         self.assertEqual('+43-699-123456789', phone_number_to_str('+43-699-123456789'))
478         self.assertEqual('+43-69945', phone_number_to_str('+43-69945'))
479         self.assertEqual('+43-512-507-6418', phone_number_to_str('+43-512-507-6418'))
480
481
482 class TestOptPhoneCommentEnum(unittest.TestCase):
483     def test_from_str(self):
484         self.assertEqual(opt_phone_comment_enum_from_str(''), None)
485         self.assertEqual([], opt_phone_comment_enum_from_str('Nein'))
486         self.assertEqual([('+43-512-123456', 'untertags')], opt_phone_comment_enum_from_str('+43-512-123456 (untertags)'))
487         self.assertEqual([('+43-512-1234', 'untertags'), ('+43-664-123456', 'Alm')], opt_phone_comment_enum_from_str('+43-512-1234 (untertags); +43-664-123456 (Alm)'))
488         self.assertEqual([('+43-512-1234', None), ('+43-664-123456', 'Sommer')], opt_phone_comment_enum_from_str('+43-512-1234; +43-664-123456 (Sommer)', True))
489         with self.assertRaises(ValueError):
490             opt_phone_comment_enum_from_str('+43-512-123456+ (untertags)')
491         with self.assertRaises(ValueError):
492             opt_phone_comment_enum_from_str('+43-512-123456')
493
494     def test_to_str(self):
495         self.assertEqual('', opt_phone_comment_enum_to_str(None))
496         self.assertEqual('Nein', opt_phone_comment_enum_to_str([]))
497         self.assertEqual('+43-512-123456 (untertags)', opt_phone_comment_enum_to_str([('+43-512-123456', 'untertags')]))
498         self.assertEqual('+43-512-1234 (untertags); +43-664-123456 (Alm)', opt_phone_comment_enum_to_str([('+43-512-1234', 'untertags'), ('+43-664-123456', 'Alm')]))
499         self.assertEqual('+43-512-1234; +43-664-123456 (Sommer)', opt_phone_comment_enum_to_str([('+43-512-1234', None), ('+43-664-123456', 'Sommer')], True))
500
501
502 # longitude/latitude converter
503 # ----------------------------
504
505 class TestLonLat(unittest.TestCase):
506     def test_from_str(self):
507         self.assertEqual(LonLat(11.453553, 47.076207), lonlat_from_str('47.076207 N 11.453553 E'))
508         with self.assertRaises(ValueError):
509             lonlat_from_str('47.076207 N 11.453553')
510
511     def test_to_str(self):
512         self.assertEqual('47.076207 N 11.453553 E', lonlat_to_str(LonLat(11.453553, 47.076207)))
513
514
515 # difficulty converter
516 # --------------------
517
518 class TestDifficultyGerman(unittest.TestCase):
519     def test_from_str(self):
520         self.assertEqual(1, difficulty_german_from_str('leicht'))
521         self.assertEqual(2, difficulty_german_from_str('mittel'))
522         with self.assertRaises(ValueError):
523             difficulty_german_from_str('dontknow')
524         with self.assertRaises(ValueError):
525             difficulty_german_from_str('')
526
527     def test_to_str(self):
528         self.assertEqual('leicht', difficulty_german_to_str(1))
529
530
531 # avalanches converter
532 # --------------------
533
534 class TestAvalancesGermanConverter(unittest.TestCase):
535     def test_from_str(self):
536         self.assertEqual(1, avalanches_german_from_str('kaum'))
537         self.assertEqual(1, opt_avalanches_german_from_str('kaum'))
538         self.assertEqual(2, avalanches_german_from_str('selten'))
539         self.assertEqual(2, opt_avalanches_german_from_str('selten'))
540         self.assertEqual(3, avalanches_german_from_str('gelegentlich'))
541         self.assertEqual(3, opt_avalanches_german_from_str('gelegentlich'))
542         self.assertEqual(4, avalanches_german_from_str('häufig'))
543         self.assertEqual(4, opt_avalanches_german_from_str('häufig'))
544         self.assertEqual(None, opt_avalanches_german_from_str(''))
545         with self.assertRaises(ValueError):
546             avalanches_german_from_str('immer')
547         with self.assertRaises(ValueError):
548             opt_avalanches_german_from_str('immer')
549         with self.assertRaises(ValueError):
550             avalanches_german_from_str('')
551
552     def test_to_str(self):
553         self.assertEqual('kaum', avalanches_german_to_str(1))
554         self.assertEqual('kaum', opt_avalanches_german_to_str(1))
555         self.assertEqual('selten', avalanches_german_to_str(2))
556         self.assertEqual('selten', opt_avalanches_german_to_str(2))
557         self.assertEqual('gelegentlich', avalanches_german_to_str(3))
558         self.assertEqual('gelegentlich', opt_avalanches_german_to_str(3))
559         self.assertEqual('häufig', avalanches_german_to_str(4))
560         self.assertEqual('häufig', opt_avalanches_german_to_str(4))
561         self.assertEqual('', opt_avalanches_german_to_str(None))
562
563
564 # lift converter
565 # --------------
566
567 class TestLiftGermanValidator(unittest.TestCase):
568     def test_from_str(self):
569         self.assertEqual(lift_german_from_str(''), None)
570         self.assertEqual([], lift_german_from_str('Nein'))
571         self.assertEqual([('Sessellift', None)], lift_german_from_str('Sessellift'))
572         self.assertEqual([('Gondel', 'nur bis zur Hälfte')], lift_german_from_str('Gondel (nur bis zur Hälfte)'))
573         self.assertEqual([('Sessellift', None), ('Taxi', None)], lift_german_from_str('Sessellift; Taxi'))
574         self.assertEqual([('Sessellift', 'Wochenende'), ('Taxi', '6 Euro')], lift_german_from_str('Sessellift (Wochenende); Taxi (6 Euro)'))
575
576     def test_to_str(self):
577         self.assertEqual('', lift_german_to_str(None))
578         self.assertEqual('Nein', lift_german_to_str([]))
579         self.assertEqual('Sessellift', lift_german_to_str([('Sessellift', None)]))
580         self.assertEqual('Gondel (nur bis zur Hälfte)', lift_german_to_str([('Gondel', 'nur bis zur Hälfte')]))
581         self.assertEqual('Sessellift; Taxi', lift_german_to_str([('Sessellift', None), ('Taxi', None)]))
582         self.assertEqual('Sessellift (Wochenende); Taxi (6 Euro)', lift_german_to_str([('Sessellift', 'Wochenende'), ('Taxi', '6 Euro')]))
583
584
585 # public transport converter
586 # --------------------------
587
588 class TestPublicTransportGerman(unittest.TestCase):
589     def test_from_str(self):
590         self.assertEqual(1, public_transport_german_from_str('Sehr gut'))
591         self.assertEqual(1, opt_public_transport_german_from_str('Sehr gut'))
592         self.assertEqual(2, public_transport_german_from_str('Gut'))
593         self.assertEqual(2, opt_public_transport_german_from_str('Gut'))
594         self.assertEqual(3, public_transport_german_from_str('Mittelmäßig'))
595         self.assertEqual(3, opt_public_transport_german_from_str('Mittelmäßig'))
596         self.assertEqual(4, public_transport_german_from_str('Schlecht'))
597         self.assertEqual(4, opt_public_transport_german_from_str('Schlecht'))
598         self.assertEqual(5, public_transport_german_from_str('Nein'))
599         self.assertEqual(5, opt_public_transport_german_from_str('Nein'))
600         self.assertEqual(6, public_transport_german_from_str('Ja'))
601         self.assertEqual(6, opt_public_transport_german_from_str('Ja'))
602         self.assertEqual(None, opt_public_transport_german_from_str(''))
603         with self.assertRaises(ValueError):
604             public_transport_german_from_str('')
605         with self.assertRaises(ValueError):
606             public_transport_german_from_str('Naja')
607         with self.assertRaises(ValueError):
608             opt_public_transport_german_from_str('Naja')
609
610     def test_to_str(self):
611         self.assertEqual('Sehr gut', public_transport_german_to_str(1))
612         self.assertEqual('Sehr gut', opt_public_transport_german_to_str(1))
613         self.assertEqual('Gut', public_transport_german_to_str(2))
614         self.assertEqual('Gut', opt_public_transport_german_to_str(2))
615         self.assertEqual('Mittelmäßig', public_transport_german_to_str(3))
616         self.assertEqual('Mittelmäßig', opt_public_transport_german_to_str(3))
617         self.assertEqual('Schlecht', public_transport_german_to_str(4))
618         self.assertEqual('Schlecht', opt_public_transport_german_to_str(4))
619         self.assertEqual('Nein', public_transport_german_to_str(5))
620         self.assertEqual('Nein', opt_public_transport_german_to_str(5))
621         self.assertEqual('Ja', public_transport_german_to_str(6))
622         self.assertEqual('Ja', opt_public_transport_german_to_str(6))
623         self.assertEqual('', opt_public_transport_german_to_str(None))
624
625
626 # cachet converter
627 # ----------------
628
629 class TestSingleCachet(unittest.TestCase):
630     def test_from_str(self):
631         self.assertEqual(('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel'), single_cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 2009 mittel'))
632         self.assertEqual(('Tiroler Naturrodelbahn-Gütesiegel', '2013', 'schwer'), single_cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 2013 schwer'))
633         with self.assertRaises(ValueError):
634             single_cachet_german_from_str('')
635         with self.assertRaises(ValueError):
636             single_cachet_german_from_str('Salzburger Naturrodelbahn-Gütesiegel 2013 schwer')
637         with self.assertRaises(ValueError):
638             single_cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 4013 schwer')
639         with self.assertRaises(ValueError):
640             single_cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 13 schwer')
641         with self.assertRaises(ValueError):
642             single_cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 2013 schwerer')
643
644     def test_to_str(self):
645         self.assertEqual('Tiroler Naturrodelbahn-Gütesiegel 2009 mittel', single_cachet_german_to_str(('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel')))
646         self.assertEqual('Tiroler Naturrodelbahn-Gütesiegel 2013 schwer', single_cachet_german_to_str(('Tiroler Naturrodelbahn-Gütesiegel', '2013', 'schwer')))
647
648
649 class TestCachetGerman(unittest.TestCase):
650     def test_from_str(self):
651         self.assertEqual(cachet_german_from_str(''), None)
652         self.assertEqual([], cachet_german_from_str('Nein'))
653         self.assertEqual([('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel')], cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 2009 mittel'))
654         self.assertEqual([('Tiroler Naturrodelbahn-Gütesiegel', '2013', 'schwer'), ('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel')], 
655                          cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 2013 schwer; Tiroler Naturrodelbahn-Gütesiegel 2009 mittel'))
656         with self.assertRaises(ValueError):
657             cachet_german_from_str('Ja')
658         with self.assertRaises(ValueError):
659             cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 2013 schwer Tiroler Naturrodelbahn-Gütesiegel 2009 mittel')
660
661     def test_to_str(self):
662         self.assertEqual('', cachet_german_to_str(None))
663         self.assertEqual('Nein', cachet_german_to_str([]))
664         self.assertEqual('Tiroler Naturrodelbahn-Gütesiegel 2009 mittel', cachet_german_to_str([('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel')]))
665         self.assertEqual('Tiroler Naturrodelbahn-Gütesiegel 2013 schwer; Tiroler Naturrodelbahn-Gütesiegel 2009 mittel', cachet_german_to_str([('Tiroler Naturrodelbahn-Gütesiegel', '2013', 'schwer'), ('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel')]))
666
667
668 # night light days converter
669 # --------------------------
670
671 class TestNightLightDays(unittest.TestCase):
672     def test_from_str(self):
673         self.assertEqual((None, None), nightlightdays_from_str(''))
674         self.assertEqual((2, 'Mo, Di'), nightlightdays_from_str('2 (Mo, Di)'))
675         self.assertEqual((7, None), nightlightdays_from_str('7'))
676         self.assertEqual((0, None), nightlightdays_from_str('0'))
677         self.assertEqual((None, 'keine Ahnung'), nightlightdays_from_str('(keine Ahnung)'))
678         with self.assertRaises(ValueError):
679             nightlightdays_from_str('8')
680         with self.assertRaises(ValueError):
681             nightlightdays_from_str('5 (Montag')
682         with self.assertRaises(ValueError):
683             nightlightdays_from_str('5.2')
684
685     def test_to_str(self):
686         self.assertEqual('', nightlightdays_to_str((None, None)))
687         self.assertEqual('2 (Mo, Di)', nightlightdays_to_str((2, 'Mo, Di')))
688         self.assertEqual('7', nightlightdays_to_str((7, None)))
689         self.assertEqual('0', nightlightdays_to_str((0, None)))
690
691
692 # string with optional comment enum/list converter
693 # ------------------------------------------------
694
695 class TestOptStrOptCommentEnum(unittest.TestCase):
696     def test_from_str(self):
697         self.assertEqual(None, opt_str_opt_comment_enum_from_str(''))
698         self.assertEqual([], opt_str_opt_comment_enum_from_str('Nein'))
699         self.assertEqual([('Talstation', None)], opt_str_opt_comment_enum_from_str('Talstation'))
700         self.assertEqual([('Talstation', 'unten')], opt_str_opt_comment_enum_from_str('Talstation (unten)'))
701         self.assertEqual([('Talstation', 'unten'), ('Mittelstation', None)], opt_str_opt_comment_enum_from_str('Talstation (unten); Mittelstation'))
702         with self.assertRaises(ValueError):
703             opt_str_opt_comment_enum_from_str('(unten)')
704         with self.assertRaises(ValueError):
705             opt_str_opt_comment_enum_from_str('Talstation (unten); ; Mittelstation')
706
707     def test_to_str(self):
708         self.assertEqual('', opt_str_opt_comment_enum_to_str(None))
709         self.assertEqual('Nein', opt_str_opt_comment_enum_to_str([]))
710         self.assertEqual('Talstation', opt_str_opt_comment_enum_to_str([('Talstation', None)]))
711         self.assertEqual('Talstation (unten)', opt_str_opt_comment_enum_to_str([('Talstation', 'unten')]))
712         self.assertEqual('Talstation (unten); Mittelstation', opt_str_opt_comment_enum_to_str([('Talstation', 'unten'), ('Mittelstation', None)]))
713
714
715 # wikibox converter
716 # -----------------
717
718 class TestWikibox(unittest.TestCase):
719     def test_from_str(self):
720         value = '{{MyTemplate|apple=2|banana=5}}'
721         converter_dict = OrderedDict([('apple', opt_uint_converter), ('banana', opt_uint_converter)])
722         result = wikibox_from_str(value, 'MyTemplate', converter_dict)
723         self.assertEqual(2, result['apple'])
724         self.assertEqual(5, result['banana'])
725
726         value = '{{MyTemplate\n | apple = 2 \n| banana = 5 }}'
727         result = wikibox_from_str(value, 'MyTemplate', converter_dict)
728         self.assertEqual(2, result['apple'])
729         self.assertEqual(5, result['banana'])
730
731         with self.assertRaises(ValueError):
732             wikibox_from_str(value, 'myTemplate', converter_dict)
733         with self.assertRaises(ValueError):
734             value = '{{MyTemplate|apple=2|banana=five}}'
735             wikibox_from_str(value, 'MyTemplate', converter_dict)
736         with self.assertRaises(ValueError):
737             value = '{{MyTemplate|apple=2}}'
738             wikibox_from_str(value, 'MyTemplate', converter_dict)
739         with self.assertRaises(ValueError):
740             value = '{{MyTemplate|apple=2|banana=5|cherry=6}}'
741             wikibox_from_str(value, 'MyTemplate', converter_dict)
742
743     def test_to_str(self):
744         value = OrderedDict([('apple', 2), ('banana', 5)])
745         converter_dict = OrderedDict([('apple', opt_uint_converter), ('banana', opt_uint_converter)])
746         result = wikibox_to_str(value, 'MyTemplate', converter_dict)
747         self.assertEqual('{{MyTemplate|apple=2|banana=5}}', result)
748
749
750 # Rodelbahnbox converter
751 # ----------------------
752
753 class TestRodelbahnbox(unittest.TestCase):
754     def setUp(self):
755         self.maxDiff = None
756         self.value = \
757 '''{{Rodelbahnbox
758 | Position             = 46.807218 N 12.806522 E
759 | Position oben        = 46.799014 N 12.818658 E
760 | Höhe oben            = 1046
761 | Position unten       =
762 | Höhe unten           =
763 | Länge                = 3500
764 | Schwierigkeit        = mittel
765 | Lawinen              = kaum
766 | Betreiber            = Bringungsgemeinschaft Kreithof-Dolomitenhütte
767 | Öffentliche Anreise  = Schlecht
768 | Aufstieg möglich     = Ja
769 | Aufstieg getrennt    = Teilweise
770 | Gehzeit              = 75
771 | Aufstiegshilfe       = Taxi; Sonstige (PKW bis Kreithof)
772 | Beleuchtungsanlage   = Ja
773 | Beleuchtungstage     = 7
774 | Rodelverleih         = Nein
775 | Gütesiegel           = Tiroler Naturrodelbahn-Gütesiegel 2009 mittel
776 | Webauskunft          = http://www.lienzerdolomiten.info/at/tobogorpt.html
777 | Telefonauskunft      = +43-664-2253782 (Dolomitenhütte)
778 | Bild                 = Dolomitenrodelbahn Tristach 2011-12-22 oberer Bereich.jpg
779 | In Übersichtskarte   = Ja
780 | Forumid              = 139
781 }}'''
782
783     def test_from_str(self):
784         value = rodelbahnbox_from_str(self.value)
785         self.assertEqual(LonLat(12.806522, 46.807218), value['Position'])
786         self.assertEqual(LonLat(12.818658, 46.799014), value['Position oben'])
787         self.assertEqual(1046, value['Höhe oben'])
788         self.assertEqual(LonLat(None, None), value['Position unten'])
789         self.assertEqual(None, value['Höhe unten'])
790         self.assertEqual(3500, value['Länge'])
791         self.assertEqual(2, value['Schwierigkeit'])
792         self.assertEqual(1, value['Lawinen'])
793         self.assertEqual('Bringungsgemeinschaft Kreithof-Dolomitenhütte', value['Betreiber'])
794         self.assertEqual(4, value['Öffentliche Anreise'])
795         self.assertEqual(True, value['Aufstieg möglich'])
796         self.assertEqual((0.5, None), value['Aufstieg getrennt'])
797         self.assertEqual(75, value['Gehzeit'])
798         self.assertEqual([('Taxi', None), ('Sonstige', 'PKW bis Kreithof')], value['Aufstiegshilfe'])
799         self.assertEqual((1.0, None), value['Beleuchtungsanlage'])
800         self.assertEqual((7, None), value['Beleuchtungstage'])
801         self.assertEqual([], value['Rodelverleih'])
802         self.assertEqual([('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel')], value['Gütesiegel'])
803         self.assertEqual((True, 'http://www.lienzerdolomiten.info/at/tobogorpt.html'), value['Webauskunft'])
804         self.assertEqual([('+43-664-2253782', 'Dolomitenhütte')], value['Telefonauskunft'])
805         self.assertEqual('Dolomitenrodelbahn Tristach 2011-12-22 oberer Bereich.jpg', value['Bild'])
806         self.assertEqual(True, value['In Übersichtskarte'])
807         self.assertEqual(139, value['Forumid'])
808
809     def test_to_str(self):
810         value = OrderedDict([
811             ('Position', LonLat(12.806522, 46.807218)),
812             ('Position oben', LonLat(12.818658, 46.799014)),
813             ('Höhe oben', 1046),
814             ('Position unten', LonLat(None, None)),
815             ('Höhe unten', None),
816             ('Länge', 3500),
817             ('Schwierigkeit', 2),
818             ('Lawinen', 1),
819             ('Betreiber', 'Bringungsgemeinschaft Kreithof-Dolomitenhütte'),
820             ('Öffentliche Anreise', 4),
821             ('Aufstieg möglich', True),
822             ('Aufstieg getrennt', (0.5, None)),
823             ('Gehzeit', 75),
824             ('Aufstiegshilfe', [('Taxi', None), ('Sonstige', 'PKW bis Kreithof')]),
825             ('Beleuchtungsanlage', (1.0, None)),
826             ('Beleuchtungstage', (7, None)),
827             ('Rodelverleih', []),
828             ('Gütesiegel', [('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel')]),
829             ('Webauskunft', (True, 'http://www.lienzerdolomiten.info/at/tobogorpt.html')),
830             ('Telefonauskunft', [('+43-664-2253782', 'Dolomitenhütte')]),
831             ('Bild', 'Dolomitenrodelbahn Tristach 2011-12-22 oberer Bereich.jpg'),
832             ('In Übersichtskarte', True),
833             ('Forumid', 139)])
834         self.assertEqual(self.value, rodelbahnbox_to_str(value))
835
836
837 # Gasthausbox converter
838 # ---------------------
839
840 class TestGasthausbox(unittest.TestCase):
841     def setUp(self):
842         self.maxDiff = None
843         self.value = \
844 """{{Gasthausbox
845 | Position          = 47.123456 N 11.123456 E
846 | Höhe              = 1808
847 | Betreiber         = Max Mustermann
848 | Sitzplätze        = 50
849 | Übernachtung      = 20 Matrazenlager, 3 Doppelzimmer
850 | Rauchfrei         = Ja
851 | Rodelverleih      = 2 Euro (Ausweis erforderlich)
852 | Handyempfang      = A1; T-Mobile A
853 | Homepage          = http://www.birgitzeralm.at/
854 | E-Mail            = Nein
855 | Telefon           = +43-664-5487520; +43-512-123456 (wenn geschlossen)
856 | Bild              = Gasthaus_Birgitzer_Alm_03.jpg
857 | Rodelbahnen       = [[Birgitzer Alm (vom Adelshof)]]; [[Birgitzer Alm (von Birgitz)]]
858 }}"""
859
860     def test_from_str(self):
861         value = gasthausbox_from_str(self.value)
862         self.assertEqual(LonLat(11.123456, 47.123456), value['Position'])
863         self.assertEqual(1808, value['Höhe'])
864         self.assertEqual('Max Mustermann', value['Betreiber'])
865         self.assertEqual(50, value['Sitzplätze'])
866         self.assertEqual((True, '20 Matrazenlager, 3 Doppelzimmer'), value['Übernachtung'])
867         self.assertEqual((True, '2 Euro (Ausweis erforderlich)'), value['Rodelverleih'])
868         self.assertEqual(1.0, value['Rauchfrei'])
869         self.assertEqual([('A1', None), ('T-Mobile A', None)], value['Handyempfang'])
870         self.assertEqual((True, 'http://www.birgitzeralm.at/'), value['Homepage'])
871         self.assertEqual([], value['E-Mail'])
872         self.assertEqual([('+43-664-5487520', None), ('+43-512-123456', 'wenn geschlossen')], value['Telefon'])
873         self.assertEqual('Gasthaus_Birgitzer_Alm_03.jpg', value['Bild'])
874         self.assertEqual(['[[Birgitzer Alm (vom Adelshof)]]', '[[Birgitzer Alm (von Birgitz)]]'], value['Rodelbahnen'])
875
876     def test_to_str(self):
877         value = OrderedDict([
878             ('Position', LonLat(11.123456, 47.123456)),
879             ('Höhe', 1808),
880             ('Betreiber', 'Max Mustermann'),
881             ('Sitzplätze', 50),
882             ('Übernachtung', (True, '20 Matrazenlager, 3 Doppelzimmer')),
883             ('Rodelverleih', (True, '2 Euro (Ausweis erforderlich)')),
884             ('Rauchfrei', 1.0),
885             ('Handyempfang', [('A1', None), ('T-Mobile A', None)]),
886             ('Homepage', (True, 'http://www.birgitzeralm.at/')),
887             ('E-Mail', []),
888             ('Telefon', [('+43-664-5487520', None), ('+43-512-123456', 'wenn geschlossen')]),
889             ('Bild', 'Gasthaus_Birgitzer_Alm_03.jpg'),
890             ('Rodelbahnen', ['[[Birgitzer Alm (vom Adelshof)]]', '[[Birgitzer Alm (von Birgitz)]]'])])
891         self.assertEqual(self.value, gasthausbox_to_str(value))