e678709eb199b4fed2fbaef86f523037ff107488
[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 formencode
6 import unittest
7 from wrpylib.wrvalidators import *
8
9
10 class TestConverter(unittest.TestCase):
11     def test_from_str(self):
12         self.assertEqual(Converter.from_str('abc'), 'abc')
13         self.assertEqual(Converter.from_str(''), '')
14
15     def test_to_str(self):
16         self.assertEqual(Converter.to_str('abc'), 'abc')
17         self.assertEqual(Converter.to_str(''), '')
18         self.assertEqual(Converter.to_str(42), '42')
19
20
21 class TestInt(unittest.TestCase):
22     def test_from_str(self):
23         self.assertEqual(int_from_str('42'), 42)
24         self.assertEqual(int_from_str('+42'), 42)
25         self.assertEqual(int_from_str('-20'), -20)
26         self.assertEqual(int_from_str('0', min=0), 0)
27         self.assertEqual(int_from_str('10', max=10), 10)
28         with self.assertRaises(ValueError):
29             int_from_str('abc')
30         with self.assertRaises(ValueError):
31             int_from_str('')
32         with self.assertRaises(ValueError):
33             int_from_str('-1', min=0)
34         with self.assertRaises(ValueError):
35             int_from_str('11', max=10)
36         with self.assertRaises(ValueError):
37             int_from_str('10.0')
38         with self.assertRaises(ValueError):
39             int_from_str('0d')
40
41     def test_to_str(self):
42         self.assertEqual(int_to_str(20), '20')
43         self.assertEqual(int_to_str(-20), '-20')
44         self.assertEqual(int_to_str(0), '0')
45
46
47 class TestOptInt(unittest.TestCase):
48     def test_from_str(self):
49         self.assertEqual(opt_int_from_str('42'), 42)
50         self.assertEqual(opt_int_from_str('+42'), 42)
51         self.assertEqual(opt_int_from_str('-20'), -20)
52         self.assertEqual(opt_int_from_str(''), None)
53         with self.assertRaises(ValueError):
54             opt_int_from_str('abc')
55         with self.assertRaises(ValueError):
56             opt_int_from_str('10.0')
57         with self.assertRaises(ValueError):
58             opt_int_from_str('0d')
59
60     def test_to_str(self):
61         self.assertEqual(opt_int_to_str(20), '20')
62         self.assertEqual(opt_int_to_str(-20), '-20')
63         self.assertEqual(opt_int_to_str(0), '0')
64         self.assertEqual(opt_int_to_str(None), '')
65
66
67 class TestEnumConverter(unittest.TestCase):
68     def test_from_str(self):
69         self.assertEqual(enum_from_str(''), [])
70         self.assertEqual(enum_from_str('abc'), ['abc'])
71         self.assertEqual(enum_from_str('abc; def'), ['abc', 'def'])
72         self.assertEqual(enum_from_str('abc; def;ghi'), ['abc', 'def', 'ghi'])
73
74     def test_to_str(self):
75         self.assertEqual(enum_to_str(['abc', 'def', 'ghi']), 'abc; def; ghi')
76         self.assertEqual(enum_to_str(['abc']), 'abc')
77         self.assertEqual(enum_to_str(['']), '')
78         self.assertEqual(enum_to_str([]), '')
79
80
81 class TestDateTime(unittest.TestCase):
82     def test_from_str(self):
83         self.assertEqual(DateTime.from_str('2015-12-31 23:07:42'), datetime.datetime(2015, 12, 31, 23, 7, 42))
84
85     def test_to_str(self):
86         self.assertEqual(DateTime.to_str(datetime.datetime(2015, 12, 31, 23, 7, 42)), '2015-12-31 23:07:42')
87
88
89 class TestDifficultyGerman(unittest.TestCase):
90     def test_from_str(self):
91         self.assertEqual(difficulty_german_from_str('leicht'), 1)
92         self.assertEqual(difficulty_german_from_str('mittel'), 2)
93         with self.assertRaises(ValueError):
94             difficulty_german_from_str('dontknow')
95         with self.assertRaises(ValueError):
96             difficulty_german_from_str('')
97
98     def test_to_str(self):
99         self.assertEqual(difficulty_german_to_str(1), 'leicht')
100
101
102 class TestTristateGerman(unittest.TestCase):
103     def test_from_str(self):
104         self.assertEqual(tristate_german_from_str('Ja'), 1.0)
105         self.assertEqual(tristate_german_from_str('Teilweise'), 0.5)
106         self.assertEqual(tristate_german_from_str('Nein'), 0)
107         with self.assertRaises(ValueError):
108             tristate_german_from_str('')
109         with self.assertRaises(ValueError):
110             tristate_german_from_str('Vielleicht')
111
112     def test_to_str(self):
113         self.assertEqual(tristate_german_to_str(1.0), 'Ja')
114         self.assertEqual(tristate_german_to_str(0.5), 'Teilweise')
115         self.assertEqual(tristate_german_to_str(0.0), 'Nein')
116
117
118 class TestOptTristateGerman(unittest.TestCase):
119     def test_from_str(self):
120         self.assertEqual(opt_tristate_german_from_str('Ja'), 1.0)
121         self.assertEqual(opt_tristate_german_from_str('Teilweise'), 0.5)
122         self.assertEqual(opt_tristate_german_from_str('Nein'), 0)
123         self.assertEqual(opt_tristate_german_from_str(''), None)
124         with self.assertRaises(ValueError):
125             opt_tristate_german_from_str('Vielleicht')
126
127     def test_to_str(self):
128         self.assertEqual(opt_tristate_german_to_str(1.0), 'Ja')
129         self.assertEqual(opt_tristate_german_to_str(0.5), 'Teilweise')
130         self.assertEqual(opt_tristate_german_to_str(0.0), 'Nein')
131         self.assertEqual(opt_tristate_german_to_str(None), '')
132
133
134 class TestOptTristateGermanComment(unittest.TestCase):
135     def test_from_str(self):
136         self.assertEqual(opt_tristate_german_comment_from_str('Ja'), (1.0, None))
137         self.assertEqual(opt_tristate_german_comment_from_str('Teilweise'), (0.5, None))
138         self.assertEqual(opt_tristate_german_comment_from_str('Nein'), (0, None))
139         self.assertEqual(opt_tristate_german_comment_from_str('Teilweise (nur ganz oben nicht)'), (0.5, 'nur ganz oben nicht'))
140         self.assertEqual(opt_tristate_german_comment_from_str(''), (None, None))
141         with self.assertRaises(ValueError):
142             opt_tristate_german_from_str('Vielleicht')
143         with self.assertRaises(ValueError):
144             opt_tristate_german_from_str('(Ja)')
145
146     def test_to_str(self):
147         self.assertEqual(opt_tristate_german_comment_to_str((1.0, None)), 'Ja')
148         self.assertEqual(opt_tristate_german_comment_to_str((0.5, None)), 'Teilweise')
149         self.assertEqual(opt_tristate_german_comment_to_str((0.0, None)), 'Nein')
150         self.assertEqual(opt_tristate_german_comment_to_str((None, None)), '')
151
152
153 class TestLonLat(unittest.TestCase):
154     def test_from_str(self):
155         self.assertEqual(lonlat_from_str('47.076207 N 11.453553 E'), LonLat(11.453553, 47.076207))
156         with self.assertRaises(ValueError):
157             lonlat_from_str('47.076207 N 11.453553')
158
159     def test_to_str(self):
160         self.assertEqual(lonlat_to_str(LonLat(11.453553, 47.076207)), '47.076207 N 11.453553 E')
161
162
163 class TestValueCommentConverter(unittest.TestCase):
164     def test_from_str(self):
165         self.assertEqual(value_comment_from_str('abc (defg)'), ('abc', 'defg'))
166         self.assertEqual(value_comment_from_str('abc ()'), ('abc', ''))
167         self.assertEqual(value_comment_from_str('(def)'), ('', 'def'))
168         self.assertEqual(value_comment_from_str('ab((cd))'), ('ab', '(cd)'))
169         self.assertEqual(value_comment_from_str('ab((c(d)[(])))'), ('ab', '(c(d)[(]))'))
170         self.assertEqual(value_comment_from_str('ab((cd)'), ('ab(', 'cd'))
171         self.assertEqual(value_comment_from_str('abcd  (ef) '), ('abcd', 'ef'))
172         self.assertEqual(value_comment_from_str('abc', comment_optional=True), ('abc', ''))
173         with self.assertRaises(ValueError):
174             value_comment_from_str('abc (')
175         with self.assertRaises(ValueError):
176             value_comment_from_str('abc )')
177         with self.assertRaises(ValueError):
178             value_comment_from_str('abc (def)g')
179         with self.assertRaises(ValueError):
180             value_comment_from_str('abc (b))')
181         with self.assertRaises(ValueError):
182             value_comment_from_str('abc')
183
184     def test_to_str(self):
185         self.assertEqual(value_comment_to_str(('abc', 'defg')), 'abc (defg)')
186         self.assertEqual(value_comment_to_str(('abc', '')), 'abc ()')
187         self.assertEqual(value_comment_to_str(('', 'def')), '(def)')
188         self.assertEqual(value_comment_to_str(('ab', '(cd)')), 'ab ((cd))')
189         self.assertEqual(value_comment_to_str(('ab', '(c(d)[(]))')), 'ab ((c(d)[(])))')
190         self.assertEqual(value_comment_to_str(('ab(', 'cd')), 'ab( (cd)')
191         self.assertEqual(value_comment_to_str(('abcd', 'ef')), 'abcd (ef)')
192         self.assertEqual(value_comment_to_str(('abc', ''), comment_optional=True), 'abc')
193
194
195 class TestNoGermanConverter(unittest.TestCase):
196     def test_from_str(self):
197         self.assertEqual(no_german_from_str('abc'), (True, 'abc'))
198         self.assertEqual(no_german_from_str('Nein'), (False, None))
199         with self.assertRaises(ValueError):
200             no_german_from_str('')
201
202     def test_to_str(self):
203         self.assertEqual(no_german_to_str((True, 'abc')), 'abc')
204         self.assertEqual(no_german_to_str((False, None)), 'Nein')
205
206
207 class TestOptNoGerman(unittest.TestCase):
208     def test_from_str(self):
209         self.assertEqual(opt_no_german_from_str('abc'), (True, 'abc'))
210         self.assertEqual(opt_no_german_from_str('Nein'), (False, None))
211         self.assertEqual(opt_no_german_from_str(''), (None, None))
212
213     def test_to_str(self):
214         self.assertEqual(opt_no_german_to_str((True, 'abc')), 'abc')
215         self.assertEqual(opt_no_german_to_str((False, None)), 'Nein')
216         self.assertEqual(opt_no_german_to_str((None, None)), '')
217
218
219 class TestLiftGermanValidator(unittest.TestCase):
220     def test_from_str(self):
221         self.assertEqual(lift_german_from_str(''), None)
222         self.assertEqual(lift_german_from_str('Nein'), [])
223         self.assertEqual(lift_german_from_str('Sessellift'), [('Sessellift', None)])
224         self.assertEqual(lift_german_from_str('Gondel (nur bis zur Hälfte)'), [('Gondel', 'nur bis zur Hälfte')])
225         self.assertEqual(lift_german_from_str('Sessellift; Taxi'), [('Sessellift', None), ('Taxi', None)])
226         self.assertEqual(lift_german_from_str('Sessellift (Wochenende); Taxi (6 Euro)'), [('Sessellift', 'Wochenende'), ('Taxi', '6 Euro')])
227
228     def test_to_str(self):
229         self.assertEqual(lift_german_to_str(None), '')
230         self.assertEqual(lift_german_to_str([]), 'Nein')
231         self.assertEqual(lift_german_to_str([('Sessellift', None)]), 'Sessellift')
232         self.assertEqual(lift_german_to_str([('Gondel', 'nur bis zur Hälfte')]), 'Gondel (nur bis zur Hälfte)')
233         self.assertEqual(lift_german_to_str([('Sessellift', None), ('Taxi', None)]), 'Sessellift; Taxi')
234         self.assertEqual(lift_german_to_str([('Sessellift', 'Wochenende'), ('Taxi', '6 Euro')]), 'Sessellift (Wochenende); Taxi (6 Euro)')
235
236
237 class TestNightLightDays(unittest.TestCase):
238     def test_from_str(self):
239         self.assertEqual(nightlightdays_from_str(''), (None, None))
240         self.assertEqual(nightlightdays_from_str('2 (Mo, Di)'), (2, 'Mo, Di'))
241         self.assertEqual(nightlightdays_from_str('7'), (7, None))
242         self.assertEqual(nightlightdays_from_str('0'), (0, None))
243         self.assertEqual(nightlightdays_from_str('(keine Ahnung)'), (None, 'keine Ahnung'))
244         with self.assertRaises(ValueError):
245             nightlightdays_from_str('8')
246         with self.assertRaises(ValueError):
247             nightlightdays_from_str('5 (Montag')
248         with self.assertRaises(ValueError):
249             nightlightdays_from_str('5.2')
250
251     def test_to_str(self):
252         self.assertEqual(nightlightdays_to_str((None, None)), '')
253         self.assertEqual(nightlightdays_to_str((2, 'Mo, Di')), '2 (Mo, Di)')
254         self.assertEqual(nightlightdays_to_str((7, None)), '7')
255         self.assertEqual(nightlightdays_to_str((0, None)), '0')
256
257
258 class TestSledRental(unittest.TestCase):
259     def test_from_str(self):
260         self.assertEqual(sledrental_from_str(''), None)
261         self.assertEqual(sledrental_from_str('Nein'), [])
262         self.assertEqual(sledrental_from_str('Talstation'), [('Talstation', None)])
263         self.assertEqual(sledrental_from_str('Talstation (unten)'), [('Talstation', 'unten')])
264         self.assertEqual(sledrental_from_str('Talstation (unten); Mittelstation'), [('Talstation', 'unten'), ('Mittelstation', None)])
265         with self.assertRaises(ValueError):
266             sledrental_from_str('(unten)')
267         with self.assertRaises(ValueError):
268             sledrental_from_str('Talstation (unten); ; Mittelstation')
269
270     def test_to_str(self):
271         self.assertEqual(sledrental_to_str(None), '')
272         self.assertEqual(sledrental_to_str([]), 'Nein')
273         self.assertEqual(sledrental_to_str([('Talstation', None)]), 'Talstation')
274         self.assertEqual(sledrental_to_str([('Talstation', 'unten')]), 'Talstation (unten)')
275         self.assertEqual(sledrental_to_str([('Talstation', 'unten'), ('Mittelstation', None)]), 'Talstation (unten); Mittelstation')
276
277
278 class TestSingleCachet(unittest.TestCase):
279     def test_from_str(self):
280         self.assertEqual(single_cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 2009 mittel'), ('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel'))
281         self.assertEqual(single_cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 2013 schwer'), ('Tiroler Naturrodelbahn-Gütesiegel', '2013', 'schwer'))
282         with self.assertRaises(ValueError):
283             single_cachet_german_from_str('')
284         with self.assertRaises(ValueError):
285             single_cachet_german_from_str('Salzburger Naturrodelbahn-Gütesiegel 2013 schwer')
286         with self.assertRaises(ValueError):
287             single_cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 4013 schwer')
288         with self.assertRaises(ValueError):
289             single_cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 13 schwer')
290         with self.assertRaises(ValueError):
291             single_cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 2013 schwerer')
292
293     def test_to_str(self):
294         self.assertEqual(single_cachet_german_to_str(('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel')), 'Tiroler Naturrodelbahn-Gütesiegel 2009 mittel')
295         self.assertEqual(single_cachet_german_to_str(('Tiroler Naturrodelbahn-Gütesiegel', '2013', 'schwer')), 'Tiroler Naturrodelbahn-Gütesiegel 2013 schwer')
296
297
298 class TestCachetGerman(unittest.TestCase):
299     def test_from_str(self):
300         self.assertEqual(cachet_german_from_str(''), None)
301         self.assertEqual(cachet_german_from_str('Nein'), [])
302         self.assertEqual(cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 2009 mittel'), [('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel')])
303         self.assertEqual(cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 2013 schwer; Tiroler Naturrodelbahn-Gütesiegel 2009 mittel'),
304             [('Tiroler Naturrodelbahn-Gütesiegel', '2013', 'schwer'), ('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel')])
305         with self.assertRaises(ValueError):
306             cachet_german_from_str('Ja')
307         with self.assertRaises(ValueError):
308             cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 2013 schwer Tiroler Naturrodelbahn-Gütesiegel 2009 mittel')
309
310     def test_to_str(self):
311         self.assertEqual(cachet_german_to_str(None), '')
312         self.assertEqual(cachet_german_to_str([]), 'Nein')
313         self.assertEqual(cachet_german_to_str([('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel')]), 'Tiroler Naturrodelbahn-Gütesiegel 2009 mittel')
314         self.assertEqual(cachet_german_to_str([('Tiroler Naturrodelbahn-Gütesiegel', '2013', 'schwer'), ('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel')]),
315             'Tiroler Naturrodelbahn-Gütesiegel 2013 schwer; Tiroler Naturrodelbahn-Gütesiegel 2009 mittel')
316
317
318 class TestUrl(unittest.TestCase):
319     def test_from_str(self):
320         self.assertEqual(url_from_str('http://www.winterrodeln.org/wiki/Arzler_Alm/'), 'http://www.winterrodeln.org/wiki/Arzler_Alm/')
321         self.assertEqual(url_from_str('http://www.winterrodeln.org/wiki/Nösslachhütte/'), 'http://www.winterrodeln.org/wiki/Nösslachhütte/')
322         self.assertEqual(url_from_str('https://www.winterrodeln.org/wiki/Nösslachhütte/'), 'https://www.winterrodeln.org/wiki/Nösslachhütte/')
323         with self.assertRaises(ValueError):
324             url_from_str('mailto:office@example.com')
325         with self.assertRaises(ValueError):
326             url_from_str('/wiki/Arzler_Alm/')
327
328     def test_to_str(self):
329         self.assertEqual(url_to_str('http://www.winterrodeln.org/wiki/Arzler_Alm/'), 'http://www.winterrodeln.org/wiki/Arzler_Alm/')
330         self.assertEqual(url_to_str('http://www.winterrodeln.org/wiki/Nösslachhütte/'), 'http://www.winterrodeln.org/wiki/Nösslachhütte/')
331         self.assertEqual(url_to_str('https://www.winterrodeln.org/wiki/Nösslachhütte/'), 'https://www.winterrodeln.org/wiki/Nösslachhütte/')
332
333
334 class TestWebauskunft(unittest.TestCase):
335     def test_from_str(self):
336         self.assertEqual(webauskunft_from_str('http://www.example.com/current'), (True, 'http://www.example.com/current'))
337         self.assertEqual(webauskunft_from_str(''), (None, None))
338         self.assertEqual(webauskunft_from_str('Nein'), (False, None))
339
340     def test_to_str(self):
341         self.assertEqual(webauskunft_to_str((True, 'http://www.example.com/current')), 'http://www.example.com/current')
342         self.assertEqual(webauskunft_to_str((None, None)), '')
343         self.assertEqual(webauskunft_to_str((False, None)), 'Nein')
344
345
346 class TestPhoneNumber(unittest.TestCase):
347     def test_from_str(self):
348         self.assertEqual(phone_number_from_str('+43-699-123456789'), '+43-699-123456789')
349         self.assertEqual(phone_number_from_str('+43-69945'), '+43-69945')
350         self.assertEqual(phone_number_from_str('+43-512-507-6418'), '+43-512-507-6418')
351         with self.assertRaises(ValueError):
352             phone_number_from_str('+43-')
353         with self.assertRaises(ValueError):
354             phone_number_from_str('0512123456789')
355
356     def test_to_str(self):
357         self.assertEqual(phone_number_to_str('+43-699-123456789'), '+43-699-123456789')
358         self.assertEqual(phone_number_to_str('+43-69945'), '+43-69945')
359         self.assertEqual(phone_number_to_str('+43-512-507-6418'), '+43-512-507-6418')
360
361
362 class TestTelefonauskunft(unittest.TestCase):
363     def test_from_str(self):
364         self.assertEqual(telefonauskunft_from_str(''), None)
365         self.assertEqual(telefonauskunft_from_str('Nein'), [])
366         self.assertEqual(telefonauskunft_from_str('+43-512-123456 (untertags)'), [('+43-512-123456', 'untertags')])
367         self.assertEqual(telefonauskunft_from_str('+43-512-1234 (untertags); +43-664-123456 (Alm)'), [('+43-512-1234', 'untertags'), ('+43-664-123456', 'Alm')])
368         with self.assertRaises(ValueError):
369             telefonauskunft_from_str('+43-512-123456+ (untertags)')
370         with self.assertRaises(ValueError):
371             telefonauskunft_from_str('+43-512-123456')
372
373     def test_to_str(self):
374         self.assertEqual(telefonauskunft_to_str(None), '')
375         self.assertEqual(telefonauskunft_to_str([]), 'Nein')
376         self.assertEqual(telefonauskunft_to_str([('+43-512-123456', 'untertags')]), '+43-512-123456 (untertags)')
377         self.assertEqual(telefonauskunft_to_str([('+43-512-1234', 'untertags'), ('+43-664-123456', 'Alm')]), '+43-512-1234 (untertags); +43-664-123456 (Alm)')
378
379
380 class TestEmail(unittest.TestCase):
381     def setUp(self):
382         self.good_addresses = ['office@example.com', 'winter+rodeln@localhost', 'joe.doe@exämple.com']
383         self.bad_addresses = ['öffice@example.com', 'winter rodeln@localhost', 'www.winterrodeln.org', 'mailto:info@example.com', 'info@example.com.']
384
385     def test_from_str(self):
386         for value in self.good_addresses:
387             self.assertEqual(value, email_from_str(value))
388         for value in self.bad_addresses:
389             with self.assertRaises(ValueError):
390                 email_from_str(value)
391
392     def test_to_str(self):
393         for value in self.good_addresses:
394             self.assertEqual(value, email_to_str(value))
395
396
397 class TestMaskedEmail(unittest.TestCase):
398     def test_from_str(self):
399         self.assertEqual(('office@example.com', False), masked_email_from_str('office@example.com'))
400         self.assertEqual(('office@example.com', True), masked_email_from_str('office(at)example.com'))
401         with self.assertRaises(ValueError):
402             masked_email_from_str('office@example.com', masked_only=True)
403         with self.assertRaises(ValueError):
404             masked_email_from_str('off ice@example.com')
405
406     def test_to_str(self):
407         self.assertEqual('office@example.com', masked_email_to_str(('office@example.com', False)))
408         self.assertEqual('office(at)example.com', masked_email_to_str(('office@example.com', True)))
409         self.assertEqual('office()example.com', masked_email_to_str(('office@example.com', True), '()'))
410
411
412 class TestBox(unittest.TestCase):
413     def test_from_str(self):
414         value = '{{MyTemplate|apple=2|banana=5}}'
415         converter_dict = OrderedDict([('apple', opt_int_converter), ('banana', opt_int_converter)])
416         result = box_from_str(value, 'MyTemplate', converter_dict)
417         self.assertEqual(result['apple'], 2)
418         self.assertEqual(result['banana'], 5)
419
420         value = '{{MyTemplate\n | apple = 2 \n| banana = 5 }}'
421         result = box_from_str(value, 'MyTemplate', converter_dict)
422         self.assertEqual(result['apple'], 2)
423         self.assertEqual(result['banana'], 5)
424
425         with self.assertRaises(ValueError):
426             box_from_str(value, 'myTemplate', converter_dict)
427         with self.assertRaises(ValueError):
428             value = '{{MyTemplate|apple=2|banana=five}}'
429             box_from_str(value, 'MyTemplate', converter_dict)
430         with self.assertRaises(ValueError):
431             value = '{{MyTemplate|apple=2}}'
432             box_from_str(value, 'MyTemplate', converter_dict)
433         with self.assertRaises(ValueError):
434             value = '{{MyTemplate|apple=2|banana=5|cherry=6}}'
435             box_from_str(value, 'MyTemplate', converter_dict)
436
437     def test_to_str(self):
438         value = OrderedDict([('apple', 2), ('banana', 5)])
439         converter_dict = OrderedDict([('apple', opt_int_converter), ('banana', opt_int_converter)])
440         result = box_to_str(value, 'MyTemplate', converter_dict)
441         self.assertEqual(result, '{{MyTemplate|apple=2|banana=5}}')
442
443
444 class TestRodelbahnbox(unittest.TestCase):
445     def setUp(self):
446         self.maxDiff = None
447         self.value = \
448 '''{{Rodelbahnbox
449 | Position             = 46.807218 N 12.806522 E
450 | Position oben        = 46.799014 N 12.818658 E
451 | Höhe oben            = 1046
452 | Position unten       =
453 | Höhe unten           =
454 | Länge                = 3500
455 | Schwierigkeit        = mittel
456 | Lawinen              = kaum
457 | Betreiber            = Bringungsgemeinschaft Kreithof-Dolomitenhütte
458 | Öffentliche Anreise  = Schlecht
459 | Aufstieg möglich     = Ja
460 | Aufstieg getrennt    = Teilweise
461 | Gehzeit              = 75
462 | Aufstiegshilfe       = Taxi; Sonstige (PKW bis Kreithof)
463 | Beleuchtungsanlage   = Ja
464 | Beleuchtungstage     = 7
465 | Rodelverleih         = Nein
466 | Gütesiegel           = Tiroler Naturrodelbahn-Gütesiegel 2009 mittel
467 | Webauskunft          = http://www.lienzerdolomiten.info/at/tobogorpt.html
468 | Telefonauskunft      = +43-664-2253782 (Dolomitenhütte)
469 | Bild                 = Dolomitenrodelbahn Tristach 2011-12-22 oberer Bereich.jpg
470 | In Übersichtskarte   = Ja
471 | Forumid              = 139
472 }}'''
473
474     def test_from_str(self):
475         value = rodelbahnbox_from_str(self.value)
476         self.assertEqual(value['Position'], LonLat(12.806522, 46.807218))
477         self.assertEqual(value['Position oben'], LonLat(12.818658, 46.799014))
478         self.assertEqual(value['Höhe oben'], 1046)
479         self.assertEqual(value['Position unten'], LonLat(None, None))
480         self.assertEqual(value['Höhe unten'], None)
481         self.assertEqual(value['Länge'], 3500)
482         self.assertEqual(value['Schwierigkeit'], 2)
483         self.assertEqual(value['Lawinen'], 1)
484         self.assertEqual(value['Betreiber'], 'Bringungsgemeinschaft Kreithof-Dolomitenhütte')
485         self.assertEqual(value['Öffentliche Anreise'], 4)
486         self.assertEqual(value['Aufstieg möglich'], True)
487         self.assertEqual(value['Aufstieg getrennt'], (0.5, None))
488         self.assertEqual(value['Gehzeit'], 75)
489         self.assertEqual(value['Aufstiegshilfe'], [('Taxi', None), ('Sonstige', 'PKW bis Kreithof')])
490         self.assertEqual(value['Beleuchtungsanlage'], (1.0, None))
491         self.assertEqual(value['Beleuchtungstage'], (7, None))
492         self.assertEqual(value['Rodelverleih'], [])
493         self.assertEqual(value['Gütesiegel'], [('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel')])
494         self.assertEqual(value['Webauskunft'], (True, 'http://www.lienzerdolomiten.info/at/tobogorpt.html'))
495         self.assertEqual(value['Telefonauskunft'], [('+43-664-2253782', 'Dolomitenhütte')])
496         self.assertEqual(value['Bild'], 'Dolomitenrodelbahn Tristach 2011-12-22 oberer Bereich.jpg')
497         self.assertEqual(value['In Übersichtskarte'], True)
498         self.assertEqual(value['Forumid'], 139)
499
500     def test_to_str(self):
501         value = OrderedDict([
502             ('Position', LonLat(12.806522, 46.807218)),
503             ('Position oben', LonLat(12.818658, 46.799014)),
504             ('Höhe oben', 1046),
505             ('Position unten', LonLat(None, None)),
506             ('Höhe unten', None),
507             ('Länge', 3500),
508             ('Schwierigkeit', 2),
509             ('Lawinen', 1),
510             ('Betreiber', 'Bringungsgemeinschaft Kreithof-Dolomitenhütte'),
511             ('Öffentliche Anreise', 4),
512             ('Aufstieg möglich', True),
513             ('Aufstieg getrennt', (0.5, None)),
514             ('Gehzeit', 75),
515             ('Aufstiegshilfe', [('Taxi', None), ('Sonstige', 'PKW bis Kreithof')]),
516             ('Beleuchtungsanlage', (1.0, None)),
517             ('Beleuchtungstage', (7, None)),
518             ('Rodelverleih', []),
519             ('Gütesiegel', [('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel')]),
520             ('Webauskunft', (True, 'http://www.lienzerdolomiten.info/at/tobogorpt.html')),
521             ('Telefonauskunft', [('+43-664-2253782', 'Dolomitenhütte')]),
522             ('Bild', 'Dolomitenrodelbahn Tristach 2011-12-22 oberer Bereich.jpg'),
523             ('In Übersichtskarte', True),
524             ('Forumid', 139)])
525         self.assertEqual(rodelbahnbox_to_str(value), self.value)
526
527
528 class TestWrValidators(unittest.TestCase):
529     def test_ValueCommentListNeinLoopNone(self):
530         v = wrpylib.wrvalidators.ValueCommentListNeinLoopNone()
531         assert v.to_python('') == None
532         assert v.to_python('Nein') == 'Nein'
533         assert v.to_python('T-Mobile (gut); A1') == 'T-Mobile (gut); A1'
534         assert v.from_python(None) == ''
535         assert v.from_python('Nein') == 'Nein'
536         assert v.from_python('T-Mobile (gut); A1') == 'T-Mobile (gut); A1'
537
538
539     def test_PhoneCommentListNeinLoopNone(self):
540         v = wrpylib.wrvalidators.PhoneCommentListNeinLoopNone(comments_are_optional=True)
541         assert v.to_python('') == None
542         assert v.to_python('Nein') == 'Nein'
543         assert v.to_python('+43-699-1234567 (nicht nach 20:00 Uhr); +43-512-123456') == '+43-699-1234567 (nicht nach 20:00 Uhr); +43-512-123456'
544         assert v.from_python(None) == ''
545         assert v.from_python('Nein') == 'Nein'
546         assert v.from_python('+43-699-1234567 (nicht nach 20:00 Uhr); +43-512-123456') == '+43-699-1234567 (nicht nach 20:00 Uhr); +43-512-123456'
547
548
549     def test_MaskedEmail(self):
550         v = wrpylib.wrvalidators.MaskedEmail()
551         assert v.to_python('') == (None, None)
552         assert v.to_python('abc.def@example.com') == ('abc.def@example.com', False)
553         assert v.to_python('abc.def(at)example.com') == ('abc.def@example.com', True)
554         assert v.from_python((None, None)) == ''
555         assert v.from_python(('abc.def@example.com', False)) == 'abc.def@example.com'
556         assert v.from_python(('abc.def@example.com', True)) == 'abc.def(at)example.com'
557
558
559     def test_EmailCommentListNeinLoopNone(self):
560         v = wrpylib.wrvalidators.EmailCommentListNeinLoopNone()
561         assert v.to_python('') == None
562         assert v.to_python('Nein') == 'Nein'
563         assert v.to_python('first@example.com') == 'first@example.com'
564         assert v.to_python('first@example.com (Nur Winter); second@example.com') == 'first@example.com (Nur Winter); second@example.com'
565         assert v.from_python(None) == ''
566         assert v.from_python('Nein') == 'Nein'
567         assert v.from_python('first@example.com') == 'first@example.com'
568         assert v.from_python('first@example.com (Nur Winter); second@example.com') == 'first@example.com (Nur Winter); second@example.com'
569         testvalue = 'abc.def(at)example.com (comment)'
570         try:
571             v.to_python(testvalue)
572             assert False
573         except formencode.Invalid:
574             pass
575         try:
576             v.from_python(testvalue)
577             assert False
578         except formencode.Invalid:
579             pass
580         v = wrpylib.wrvalidators.EmailCommentListNeinLoopNone(allow_masked_email=True)
581         assert v.to_python(testvalue) == testvalue
582         assert v.from_python(testvalue) == testvalue
583
584
585     def test_WikiPageListLoopNone(self):
586         v = wrpylib.wrvalidators.WikiPageListLoopNone()
587         assert v.to_python('') == None
588         assert v.to_python('[[Birgitzer Alm]]; [[Kemater Alm]]') == '[[Birgitzer Alm]]; [[Kemater Alm]]'
589         assert v.from_python(None) == ''
590         assert v.from_python('[[Birgitzer Alm]]; [[Kemater Alm]]') == '[[Birgitzer Alm]]; [[Kemater Alm]]'
591
592
593     def test_GasthausboxDictValidator(self):
594         v = wrpylib.wrvalidators.GasthausboxDictValidator()
595         other = collections.OrderedDict([
596             ('Position', '47.295549 N 9.986970 E'),
597             ('Höhe', '1250'),
598             ('Betreiber', ''),
599             ('Sitzplätze', ''),
600             ('Übernachtung', ''),
601             ('Rauchfrei', 'Nein'),
602             ('Rodelverleih', ''),
603             ('Handyempfang', 'A1; T-Mobile/Telering'),
604             ('Homepage', 'http://www.bergkristallhuette.com/'),
605             ('E-Mail', 'bergkristallhuette@gmx.at'),
606             ('Telefon', '+43-664-1808482'),
607             ('Bild', 'Bergkritsallhütte 2009-02-07.JPG'),
608             ('Rodelbahnen', '[[Bergkristallhütte]]')])
609         python = v.to_python(other, None)
610         other2 = v.from_python(python, None)
611         assert other == other2