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