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