Reorder tests.
authorphilipp <philipp@7aebc617-e5e2-0310-91dc-80fb5f6d2477>
Tue, 2 Feb 2016 21:09:47 +0000 (21:09 +0000)
committerphilipp <philipp@7aebc617-e5e2-0310-91dc-80fb5f6d2477>
Tue, 2 Feb 2016 21:09:47 +0000 (21:09 +0000)
git-svn-id: http://www.winterrodeln.org/svn/wrpylib/trunk@2442 7aebc617-e5e2-0310-91dc-80fb5f6d2477

tests/test_wrvalidators.py

index 034b986ad6830360bfc7e28876bc04fdf1983904..42fc9cbf1d7216c11a72dc112ed2fbd4f4819015 100644 (file)
@@ -13,14 +13,14 @@ from wrpylib.wrvalidators import *
 
 class TestNoGermanConverter(unittest.TestCase):
     def test_from_str(self):
-        self.assertEqual(no_german_from_str('abc'), (True, 'abc'))
-        self.assertEqual(no_german_from_str('Nein'), (False, None))
+        self.assertEqual((True, 'abc'), no_german_from_str('abc'))
+        self.assertEqual((False, None), no_german_from_str('Nein'))
         with self.assertRaises(ValueError):
             no_german_from_str('')
 
     def test_to_str(self):
-        self.assertEqual(no_german_to_str((True, 'abc')), 'abc')
-        self.assertEqual(no_german_to_str((False, None)), 'Nein')
+        self.assertEqual('abc', no_german_to_str((True, 'abc')))
+        self.assertEqual('Nein', no_german_to_str((False, None)))
 
 
 # "optional"/"no" converter
@@ -46,13 +46,57 @@ class TestOptNoGerman(unittest.TestCase):
 # --------------
 
 
-# TODO: enum/"list" converter
+# enum/"list" converter
 # ---------------------
 
+class TestEnumConverter(unittest.TestCase):
+    def test_from_str(self):
+        self.assertEqual([], enum_from_str(''))
+        self.assertEqual(['abc'], enum_from_str('abc'))
+        self.assertEqual(['abc', 'def'], enum_from_str('abc; def'))
+        self.assertEqual(['abc', 'def', 'ghi'], enum_from_str('abc; def;ghi'))
+
+    def test_to_str(self):
+        self.assertEqual('abc; def; ghi', enum_to_str(['abc', 'def', 'ghi']))
+        self.assertEqual('abc', enum_to_str(['abc']))
+        self.assertEqual('', enum_to_str(['']))
+        self.assertEqual('', enum_to_str([]))
+
 
-# TODO: value/comment converter
+# value/comment converter
 # -----------------------
 
+class TestValueCommentConverter(unittest.TestCase):
+    def test_from_str(self):
+        self.assertEqual(('abc', 'defg'), value_comment_from_str('abc (defg)'))
+        self.assertEqual(('abc', ''), value_comment_from_str('abc ()'))
+        self.assertEqual(('', 'def'), value_comment_from_str('(def)'))
+        self.assertEqual(('ab', '(cd)'), value_comment_from_str('ab((cd))'))
+        self.assertEqual(('ab', '(c(d)[(]))'), value_comment_from_str('ab((c(d)[(])))'))
+        self.assertEqual(('ab(', 'cd'), value_comment_from_str('ab((cd)'))
+        self.assertEqual(('abcd', 'ef'), value_comment_from_str('abcd  (ef) '))
+        self.assertEqual(('abc', ''), value_comment_from_str('abc', comment_optional=True))
+        with self.assertRaises(ValueError):
+            value_comment_from_str('abc (')
+        with self.assertRaises(ValueError):
+            value_comment_from_str('abc )')
+        with self.assertRaises(ValueError):
+            value_comment_from_str('abc (def)g')
+        with self.assertRaises(ValueError):
+            value_comment_from_str('abc (b))')
+        with self.assertRaises(ValueError):
+            value_comment_from_str('abc')
+
+    def test_to_str(self):
+        self.assertEqual('abc (defg)', value_comment_to_str(('abc', 'defg')))
+        self.assertEqual('abc ()', value_comment_to_str(('abc', '')))
+        self.assertEqual('(def)', value_comment_to_str(('', 'def')))
+        self.assertEqual('ab ((cd))', value_comment_to_str(('ab', '(cd)')))
+        self.assertEqual('ab ((c(d)[(])))', value_comment_to_str(('ab', '(c(d)[(]))')))
+        self.assertEqual('ab( (cd)', value_comment_to_str(('ab(', 'cd')))
+        self.assertEqual('abcd (ef)', value_comment_to_str(('abcd', 'ef')))
+        self.assertEqual('abc', value_comment_to_str(('abc', ''), comment_optional=True))
+
 
 # string converter
 # ----------------
@@ -87,9 +131,22 @@ class TestOptStr(unittest.TestCase):
         self.assertEqual('', opt_str_to_str(None))
 
 
-# TODO: optional no or string converter
+# optional no or string converter
 # -------------------------------
 
+class TestOptNoOrStr(unittest.TestCase):
+    def test_from_str(self):
+        self.assertEqual((False, None), opt_no_or_str_from_str('Nein'))
+        self.assertEqual((True, 'Nur Wochenende'), opt_no_or_str_from_str('Nur Wochenende'))
+        self.assertEqual((True, 'Ja'), opt_no_or_str_from_str('Ja'))
+        self.assertEqual((None, None), opt_no_or_str_from_str(''))
+
+    def test_to_str(self):
+        self.assertEqual('Nein', opt_no_or_str_to_str((False, None)))
+        self.assertEqual('Nur Wochenende', opt_no_or_str_to_str((True, 'Nur Wochenende')))
+        self.assertEqual('Ja', opt_no_or_str_to_str((True, 'Ja')))
+        self.assertEqual('', opt_no_or_str_to_str((None, None)))
+
 
 # integer converter
 # -----------------
@@ -154,271 +211,190 @@ class TestOptUInt(unittest.TestCase):
         self.assertEqual('', opt_uint_to_str(None))
 
 
-# bool converter
+# TODO: bool converter
 # --------------
 
 
-class TestEnumConverter(unittest.TestCase):
-    def test_from_str(self):
-        self.assertEqual(enum_from_str(''), [])
-        self.assertEqual(enum_from_str('abc'), ['abc'])
-        self.assertEqual(enum_from_str('abc; def'), ['abc', 'def'])
-        self.assertEqual(enum_from_str('abc; def;ghi'), ['abc', 'def', 'ghi'])
-
-    def test_to_str(self):
-        self.assertEqual(enum_to_str(['abc', 'def', 'ghi']), 'abc; def; ghi')
-        self.assertEqual(enum_to_str(['abc']), 'abc')
-        self.assertEqual(enum_to_str(['']), '')
-        self.assertEqual(enum_to_str([]), '')
-
-
-class TestDifficultyGerman(unittest.TestCase):
-    def test_from_str(self):
-        self.assertEqual(difficulty_german_from_str('leicht'), 1)
-        self.assertEqual(difficulty_german_from_str('mittel'), 2)
-        with self.assertRaises(ValueError):
-            difficulty_german_from_str('dontknow')
-        with self.assertRaises(ValueError):
-            difficulty_german_from_str('')
-
-    def test_to_str(self):
-        self.assertEqual(difficulty_german_to_str(1), 'leicht')
-
+# tristate converter
+# ------------------
 
 class TestTristateGerman(unittest.TestCase):
     def test_from_str(self):
-        self.assertEqual(tristate_german_from_str('Ja'), 1.0)
-        self.assertEqual(tristate_german_from_str('Teilweise'), 0.5)
-        self.assertEqual(tristate_german_from_str('Nein'), 0)
+        self.assertEqual(1.0, tristate_german_from_str('Ja'))
+        self.assertEqual(0.5, tristate_german_from_str('Teilweise'))
+        self.assertEqual(0, tristate_german_from_str('Nein'))
         with self.assertRaises(ValueError):
             tristate_german_from_str('')
         with self.assertRaises(ValueError):
             tristate_german_from_str('Vielleicht')
 
     def test_to_str(self):
-        self.assertEqual(tristate_german_to_str(1.0), 'Ja')
-        self.assertEqual(tristate_german_to_str(0.5), 'Teilweise')
-        self.assertEqual(tristate_german_to_str(0.0), 'Nein')
+        self.assertEqual('Ja', tristate_german_to_str(1.0))
+        self.assertEqual('Teilweise', tristate_german_to_str(0.5))
+        self.assertEqual('Nein', tristate_german_to_str(0.0))
 
 
 class TestOptTristateGerman(unittest.TestCase):
     def test_from_str(self):
-        self.assertEqual(opt_tristate_german_from_str('Ja'), 1.0)
-        self.assertEqual(opt_tristate_german_from_str('Teilweise'), 0.5)
-        self.assertEqual(opt_tristate_german_from_str('Nein'), 0)
-        self.assertEqual(opt_tristate_german_from_str(''), None)
+        self.assertEqual(1.0, opt_tristate_german_from_str('Ja'))
+        self.assertEqual(0.5, opt_tristate_german_from_str('Teilweise'))
+        self.assertEqual(0, opt_tristate_german_from_str('Nein'))
+        self.assertEqual(None, opt_tristate_german_from_str(''))
         with self.assertRaises(ValueError):
             opt_tristate_german_from_str('Vielleicht')
 
     def test_to_str(self):
-        self.assertEqual(opt_tristate_german_to_str(1.0), 'Ja')
-        self.assertEqual(opt_tristate_german_to_str(0.5), 'Teilweise')
-        self.assertEqual(opt_tristate_german_to_str(0.0), 'Nein')
-        self.assertEqual(opt_tristate_german_to_str(None), '')
+        self.assertEqual('Ja', opt_tristate_german_to_str(1.0))
+        self.assertEqual('Teilweise', opt_tristate_german_to_str(0.5))
+        self.assertEqual('Nein', opt_tristate_german_to_str(0.0))
+        self.assertEqual('', opt_tristate_german_to_str(None))
+
 
+# tristate with comment converter
+# -------------------------------
 
 class TestOptTristateGermanComment(unittest.TestCase):
     def test_from_str(self):
-        self.assertEqual(opt_tristate_german_comment_from_str('Ja'), (1.0, None))
-        self.assertEqual(opt_tristate_german_comment_from_str('Teilweise'), (0.5, None))
-        self.assertEqual(opt_tristate_german_comment_from_str('Nein'), (0, None))
-        self.assertEqual(opt_tristate_german_comment_from_str('Teilweise (nur ganz oben nicht)'), (0.5, 'nur ganz oben nicht'))
-        self.assertEqual(opt_tristate_german_comment_from_str(''), (None, None))
+        self.assertEqual((1.0, None), opt_tristate_german_comment_from_str('Ja'))
+        self.assertEqual((0.5, None), opt_tristate_german_comment_from_str('Teilweise'))
+        self.assertEqual((0, None), opt_tristate_german_comment_from_str('Nein'))
+        self.assertEqual((0.5, 'nur ganz oben nicht'), opt_tristate_german_comment_from_str('Teilweise (nur ganz oben nicht)'))
+        self.assertEqual((None, None), opt_tristate_german_comment_from_str(''))
         with self.assertRaises(ValueError):
             opt_tristate_german_from_str('Vielleicht')
         with self.assertRaises(ValueError):
             opt_tristate_german_from_str('(Ja)')
 
     def test_to_str(self):
-        self.assertEqual(opt_tristate_german_comment_to_str((1.0, None)), 'Ja')
-        self.assertEqual(opt_tristate_german_comment_to_str((0.5, None)), 'Teilweise')
-        self.assertEqual(opt_tristate_german_comment_to_str((0.0, None)), 'Nein')
-        self.assertEqual(opt_tristate_german_comment_to_str((None, None)), '')
-
-
-class TestLonLat(unittest.TestCase):
-    def test_from_str(self):
-        self.assertEqual(lonlat_from_str('47.076207 N 11.453553 E'), LonLat(11.453553, 47.076207))
-        with self.assertRaises(ValueError):
-            lonlat_from_str('47.076207 N 11.453553')
+        self.assertEqual('Ja', opt_tristate_german_comment_to_str((1.0, None)))
+        self.assertEqual('Teilweise', opt_tristate_german_comment_to_str((0.5, None)))
+        self.assertEqual('Nein', opt_tristate_german_comment_to_str((0.0, None)))
+        self.assertEqual('', opt_tristate_german_comment_to_str((None, None)))
 
-    def test_to_str(self):
-        self.assertEqual(lonlat_to_str(LonLat(11.453553, 47.076207)), '47.076207 N 11.453553 E')
 
+# url converter
+# -------------
 
-class TestValueCommentConverter(unittest.TestCase):
+class TestUrl(unittest.TestCase):
     def test_from_str(self):
-        self.assertEqual(value_comment_from_str('abc (defg)'), ('abc', 'defg'))
-        self.assertEqual(value_comment_from_str('abc ()'), ('abc', ''))
-        self.assertEqual(value_comment_from_str('(def)'), ('', 'def'))
-        self.assertEqual(value_comment_from_str('ab((cd))'), ('ab', '(cd)'))
-        self.assertEqual(value_comment_from_str('ab((c(d)[(])))'), ('ab', '(c(d)[(]))'))
-        self.assertEqual(value_comment_from_str('ab((cd)'), ('ab(', 'cd'))
-        self.assertEqual(value_comment_from_str('abcd  (ef) '), ('abcd', 'ef'))
-        self.assertEqual(value_comment_from_str('abc', comment_optional=True), ('abc', ''))
-        with self.assertRaises(ValueError):
-            value_comment_from_str('abc (')
-        with self.assertRaises(ValueError):
-            value_comment_from_str('abc )')
-        with self.assertRaises(ValueError):
-            value_comment_from_str('abc (def)g')
+        self.assertEqual(url_from_str('http://www.winterrodeln.org/wiki/Arzler_Alm/'), 'http://www.winterrodeln.org/wiki/Arzler_Alm/')
+        self.assertEqual(url_from_str('http://www.winterrodeln.org/wiki/Nösslachhütte/'), 'http://www.winterrodeln.org/wiki/Nösslachhütte/')
+        self.assertEqual(url_from_str('https://www.winterrodeln.org/wiki/Nösslachhütte/'), 'https://www.winterrodeln.org/wiki/Nösslachhütte/')
         with self.assertRaises(ValueError):
-            value_comment_from_str('abc (b))')
+            url_from_str('mailto:office@example.com')
         with self.assertRaises(ValueError):
-            value_comment_from_str('abc')
+            url_from_str('/wiki/Arzler_Alm/')
 
     def test_to_str(self):
-        self.assertEqual(value_comment_to_str(('abc', 'defg')), 'abc (defg)')
-        self.assertEqual(value_comment_to_str(('abc', '')), 'abc ()')
-        self.assertEqual(value_comment_to_str(('', 'def')), '(def)')
-        self.assertEqual(value_comment_to_str(('ab', '(cd)')), 'ab ((cd))')
-        self.assertEqual(value_comment_to_str(('ab', '(c(d)[(]))')), 'ab ((c(d)[(])))')
-        self.assertEqual(value_comment_to_str(('ab(', 'cd')), 'ab( (cd)')
-        self.assertEqual(value_comment_to_str(('abcd', 'ef')), 'abcd (ef)')
-        self.assertEqual(value_comment_to_str(('abc', ''), comment_optional=True), 'abc')
+        self.assertEqual(url_to_str('http://www.winterrodeln.org/wiki/Arzler_Alm/'), 'http://www.winterrodeln.org/wiki/Arzler_Alm/')
+        self.assertEqual(url_to_str('http://www.winterrodeln.org/wiki/Nösslachhütte/'), 'http://www.winterrodeln.org/wiki/Nösslachhütte/')
+        self.assertEqual(url_to_str('https://www.winterrodeln.org/wiki/Nösslachhütte/'), 'https://www.winterrodeln.org/wiki/Nösslachhütte/')
 
 
-class TestLiftGermanValidator(unittest.TestCase):
+# webauskunft converter
+# ---------------------
+
+class TestWebauskunft(unittest.TestCase):
     def test_from_str(self):
-        self.assertEqual(lift_german_from_str(''), None)
-        self.assertEqual(lift_german_from_str('Nein'), [])
-        self.assertEqual(lift_german_from_str('Sessellift'), [('Sessellift', None)])
-        self.assertEqual(lift_german_from_str('Gondel (nur bis zur Hälfte)'), [('Gondel', 'nur bis zur Hälfte')])
-        self.assertEqual(lift_german_from_str('Sessellift; Taxi'), [('Sessellift', None), ('Taxi', None)])
-        self.assertEqual(lift_german_from_str('Sessellift (Wochenende); Taxi (6 Euro)'), [('Sessellift', 'Wochenende'), ('Taxi', '6 Euro')])
+        self.assertEqual(webauskunft_from_str('http://www.example.com/current'), (True, 'http://www.example.com/current'))
+        self.assertEqual(webauskunft_from_str(''), (None, None))
+        self.assertEqual(webauskunft_from_str('Nein'), (False, None))
 
     def test_to_str(self):
-        self.assertEqual(lift_german_to_str(None), '')
-        self.assertEqual(lift_german_to_str([]), 'Nein')
-        self.assertEqual(lift_german_to_str([('Sessellift', None)]), 'Sessellift')
-        self.assertEqual(lift_german_to_str([('Gondel', 'nur bis zur Hälfte')]), 'Gondel (nur bis zur Hälfte)')
-        self.assertEqual(lift_german_to_str([('Sessellift', None), ('Taxi', None)]), 'Sessellift; Taxi')
-        self.assertEqual(lift_german_to_str([('Sessellift', 'Wochenende'), ('Taxi', '6 Euro')]), 'Sessellift (Wochenende); Taxi (6 Euro)')
+        self.assertEqual(webauskunft_to_str((True, 'http://www.example.com/current')), 'http://www.example.com/current')
+        self.assertEqual(webauskunft_to_str((None, None)), '')
+        self.assertEqual(webauskunft_to_str((False, None)), 'Nein')
 
 
-class TestNightLightDays(unittest.TestCase):
+# wikipage converter
+# ------------------
+
+class TestWikipage(unittest.TestCase):
     def test_from_str(self):
-        self.assertEqual(nightlightdays_from_str(''), (None, None))
-        self.assertEqual(nightlightdays_from_str('2 (Mo, Di)'), (2, 'Mo, Di'))
-        self.assertEqual(nightlightdays_from_str('7'), (7, None))
-        self.assertEqual(nightlightdays_from_str('0'), (0, None))
-        self.assertEqual(nightlightdays_from_str('(keine Ahnung)'), (None, 'keine Ahnung'))
+        self.assertEqual('[[Birgitzer Alm]]', wikipage_from_str('[[Birgitzer Alm]]'))
         with self.assertRaises(ValueError):
-            nightlightdays_from_str('8')
+            wikipage_from_str('[[')
         with self.assertRaises(ValueError):
-            nightlightdays_from_str('5 (Montag')
+            wikipage_from_str('')
         with self.assertRaises(ValueError):
-            nightlightdays_from_str('5.2')
+            wikipage_from_str('Birgitzer Alm')
 
     def test_to_str(self):
-        self.assertEqual(nightlightdays_to_str((None, None)), '')
-        self.assertEqual(nightlightdays_to_str((2, 'Mo, Di')), '2 (Mo, Di)')
-        self.assertEqual(nightlightdays_to_str((7, None)), '7')
-        self.assertEqual(nightlightdays_to_str((0, None)), '0')
+        self.assertEqual('[[Birgitzer Alm]]', wikipage_to_str('[[Birgitzer Alm]]'))
 
 
-class TestOptStrOptCommentEnum(unittest.TestCase):
+class TestOptWikipageEnum(unittest.TestCase):
     def test_from_str(self):
-        self.assertEqual(opt_str_opt_comment_enum_from_str(''), None)
-        self.assertEqual(opt_str_opt_comment_enum_from_str('Nein'), [])
-        self.assertEqual(opt_str_opt_comment_enum_from_str('Talstation'), [('Talstation', None)])
-        self.assertEqual(opt_str_opt_comment_enum_from_str('Talstation (unten)'), [('Talstation', 'unten')])
-        self.assertEqual(opt_str_opt_comment_enum_from_str('Talstation (unten); Mittelstation'), [('Talstation', 'unten'), ('Mittelstation', None)])
-        with self.assertRaises(ValueError):
-            opt_str_opt_comment_enum_from_str('(unten)')
-        with self.assertRaises(ValueError):
-            opt_str_opt_comment_enum_from_str('Talstation (unten); ; Mittelstation')
+        self.assertEqual(['[[Birgitzer Alm]]', '[[Kemater Alm]]'], opt_wikipage_enum_from_str('[[Birgitzer Alm]]; [[Kemater Alm]]'))
+        self.assertEqual(['[[Birgitzer Alm]]'], opt_wikipage_enum_from_str('[[Birgitzer Alm]]'))
+        self.assertEqual([], opt_wikipage_enum_from_str('Nein'))
+        self.assertEqual(None, opt_wikipage_enum_from_str(''))
 
     def test_to_str(self):
-        self.assertEqual(opt_str_opt_comment_enum_to_str(None), '')
-        self.assertEqual(opt_str_opt_comment_enum_to_str([]), 'Nein')
-        self.assertEqual(opt_str_opt_comment_enum_to_str([('Talstation', None)]), 'Talstation')
-        self.assertEqual(opt_str_opt_comment_enum_to_str([('Talstation', 'unten')]), 'Talstation (unten)')
-        self.assertEqual(opt_str_opt_comment_enum_to_str([('Talstation', 'unten'), ('Mittelstation', None)]), 'Talstation (unten); Mittelstation')
-
-
-class TestNoOrStr(unittest.TestCase):
-    def test_from_str(self):
-        self.assertEqual((False, None), opt_no_or_str_from_str('Nein'))
-        self.assertEqual((True, 'Nur Wochenende'), opt_no_or_str_from_str('Nur Wochenende'))
-        self.assertEqual((True, 'Ja'), opt_no_or_str_from_str('Ja'))
-        self.assertEqual((None, None), opt_no_or_str_from_str(''))
+        self.assertEqual('[[Birgitzer Alm]]; [[Kemater Alm]]', opt_wikipage_enum_to_str(['[[Birgitzer Alm]]', '[[Kemater Alm]]']))
+        self.assertEqual('[[Birgitzer Alm]]', opt_wikipage_enum_to_str(['[[Birgitzer Alm]]']))
+        self.assertEqual('Nein', opt_wikipage_enum_to_str([]))
+        self.assertEqual('', opt_wikipage_enum_to_str(None))
 
-    def test_to_str(self):
-        self.assertEqual('Nein', opt_no_or_str_to_str((False, None)))
-        self.assertEqual('Nur Wochenende', opt_no_or_str_to_str((True, 'Nur Wochenende')))
-        self.assertEqual('Ja', opt_no_or_str_to_str((True, 'Ja')))
-        self.assertEqual('', opt_no_or_str_to_str((None, None)))
 
+# email converter
+# ---------------
 
+class TestEmail(unittest.TestCase):
+    def setUp(self):
+        self.good_addresses = ['office@example.com', 'winter+rodeln@localhost', 'joe.doe@exämple.com']
+        self.bad_addresses = ['öffice@example.com', 'winter rodeln@localhost', 'www.winterrodeln.org', 'mailto:info@example.com', 'info@example.com.']
 
-class TestSingleCachet(unittest.TestCase):
     def test_from_str(self):
-        self.assertEqual(single_cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 2009 mittel'), ('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel'))
-        self.assertEqual(single_cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 2013 schwer'), ('Tiroler Naturrodelbahn-Gütesiegel', '2013', 'schwer'))
-        with self.assertRaises(ValueError):
-            single_cachet_german_from_str('')
-        with self.assertRaises(ValueError):
-            single_cachet_german_from_str('Salzburger Naturrodelbahn-Gütesiegel 2013 schwer')
-        with self.assertRaises(ValueError):
-            single_cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 4013 schwer')
-        with self.assertRaises(ValueError):
-            single_cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 13 schwer')
-        with self.assertRaises(ValueError):
-            single_cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 2013 schwerer')
+        for value in self.good_addresses:
+            self.assertEqual(value, email_from_str(value))
+        for value in self.bad_addresses:
+            with self.assertRaises(ValueError):
+                email_from_str(value)
 
     def test_to_str(self):
-        self.assertEqual(single_cachet_german_to_str(('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel')), 'Tiroler Naturrodelbahn-Gütesiegel 2009 mittel')
-        self.assertEqual(single_cachet_german_to_str(('Tiroler Naturrodelbahn-Gütesiegel', '2013', 'schwer')), 'Tiroler Naturrodelbahn-Gütesiegel 2013 schwer')
+        for value in self.good_addresses:
+            self.assertEqual(value, email_to_str(value))
 
 
-class TestCachetGerman(unittest.TestCase):
+class TestMaskedEmail(unittest.TestCase):
     def test_from_str(self):
-        self.assertEqual(cachet_german_from_str(''), None)
-        self.assertEqual(cachet_german_from_str('Nein'), [])
-        self.assertEqual(cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 2009 mittel'), [('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel')])
-        self.assertEqual(cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 2013 schwer; Tiroler Naturrodelbahn-Gütesiegel 2009 mittel'),
-            [('Tiroler Naturrodelbahn-Gütesiegel', '2013', 'schwer'), ('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel')])
+        self.assertEqual(('office@example.com', False), masked_email_from_str('office@example.com'))
+        self.assertEqual(('office@example.com', True), masked_email_from_str('office(at)example.com'))
         with self.assertRaises(ValueError):
-            cachet_german_from_str('Ja')
+            masked_email_from_str('office@example.com', masked_only=True)
         with self.assertRaises(ValueError):
-            cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 2013 schwer Tiroler Naturrodelbahn-Gütesiegel 2009 mittel')
+            masked_email_from_str('off ice@example.com')
 
     def test_to_str(self):
-        self.assertEqual(cachet_german_to_str(None), '')
-        self.assertEqual(cachet_german_to_str([]), 'Nein')
-        self.assertEqual(cachet_german_to_str([('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel')]), 'Tiroler Naturrodelbahn-Gütesiegel 2009 mittel')
-        self.assertEqual(cachet_german_to_str([('Tiroler Naturrodelbahn-Gütesiegel', '2013', 'schwer'), ('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel')]),
-            'Tiroler Naturrodelbahn-Gütesiegel 2013 schwer; Tiroler Naturrodelbahn-Gütesiegel 2009 mittel')
+        self.assertEqual('office@example.com', masked_email_to_str(('office@example.com', False)))
+        self.assertEqual('office(at)example.com', masked_email_to_str(('office@example.com', True)))
+        self.assertEqual('office()example.com', masked_email_to_str(('office@example.com', True), '()'))
 
 
-class TestUrl(unittest.TestCase):
+class TestEmails(unittest.TestCase):
     def test_from_str(self):
-        self.assertEqual(url_from_str('http://www.winterrodeln.org/wiki/Arzler_Alm/'), 'http://www.winterrodeln.org/wiki/Arzler_Alm/')
-        self.assertEqual(url_from_str('http://www.winterrodeln.org/wiki/Nösslachhütte/'), 'http://www.winterrodeln.org/wiki/Nösslachhütte/')
-        self.assertEqual(url_from_str('https://www.winterrodeln.org/wiki/Nösslachhütte/'), 'https://www.winterrodeln.org/wiki/Nösslachhütte/')
+        self.assertEqual(None, emails_from_str(''))
+        self.assertEqual([], emails_from_str('Nein'))
+        self.assertEqual([(('info@example.com', False), None)], emails_from_str('info@example.com'))
+        # self.assertEqual([(('info@example.com', True), None)], emails_from_str('info(at)example.com'))
+        self.assertEqual([(('info@example.com', False), 'Office')], emails_from_str('info@example.com (Office)'))
+        self.assertEqual([(('info@example.com', False), None), (('home@example.com', False), 'Privat')], emails_from_str('info@example.com; home@example.com (Privat)'))
         with self.assertRaises(ValueError):
-            url_from_str('mailto:office@example.com')
+            emails_from_str('nein')
         with self.assertRaises(ValueError):
-            url_from_str('/wiki/Arzler_Alm/')
+            emails_from_str('info@example.com; ho me@example.com (Privat)')
 
     def test_to_str(self):
-        self.assertEqual(url_to_str('http://www.winterrodeln.org/wiki/Arzler_Alm/'), 'http://www.winterrodeln.org/wiki/Arzler_Alm/')
-        self.assertEqual(url_to_str('http://www.winterrodeln.org/wiki/Nösslachhütte/'), 'http://www.winterrodeln.org/wiki/Nösslachhütte/')
-        self.assertEqual(url_to_str('https://www.winterrodeln.org/wiki/Nösslachhütte/'), 'https://www.winterrodeln.org/wiki/Nösslachhütte/')
-
-
-class TestWebauskunft(unittest.TestCase):
-    def test_from_str(self):
-        self.assertEqual(webauskunft_from_str('http://www.example.com/current'), (True, 'http://www.example.com/current'))
-        self.assertEqual(webauskunft_from_str(''), (None, None))
-        self.assertEqual(webauskunft_from_str('Nein'), (False, None))
+        self.assertEqual('', emails_to_str(None))
+        self.assertEqual('Nein', emails_to_str([]))
+        self.assertEqual('info@example.com', emails_to_str([(('info@example.com', False), None)]))
+        self.assertEqual('info@example.com (Office)', emails_to_str([(('info@example.com', False), 'Office')]))
+        self.assertEqual('info@example.com; home@example.com (Privat)', emails_to_str([(('info@example.com', False), None), (('home@example.com', False), 'Privat')]))
 
-    def test_to_str(self):
-        self.assertEqual(webauskunft_to_str((True, 'http://www.example.com/current')), 'http://www.example.com/current')
-        self.assertEqual(webauskunft_to_str((None, None)), '')
-        self.assertEqual(webauskunft_to_str((False, None)), 'Nein')
 
+# phone converter
+# ---------------
 
 class TestPhoneNumber(unittest.TestCase):
     def test_from_str(self):
@@ -436,7 +412,7 @@ class TestPhoneNumber(unittest.TestCase):
         self.assertEqual(phone_number_to_str('+43-512-507-6418'), '+43-512-507-6418')
 
 
-class TestTelefonauskunft(unittest.TestCase):
+class TestOptPhoneCommentEnum(unittest.TestCase):
     def test_from_str(self):
         self.assertEqual(opt_phone_comment_enum_from_str(''), None)
         self.assertEqual(opt_phone_comment_enum_from_str('Nein'), [])
@@ -454,88 +430,159 @@ class TestTelefonauskunft(unittest.TestCase):
         self.assertEqual(opt_phone_comment_enum_to_str([('+43-512-1234', 'untertags'), ('+43-664-123456', 'Alm')]), '+43-512-1234 (untertags); +43-664-123456 (Alm)')
 
 
-class TestEmail(unittest.TestCase):
-    def setUp(self):
-        self.good_addresses = ['office@example.com', 'winter+rodeln@localhost', 'joe.doe@exämple.com']
-        self.bad_addresses = ['öffice@example.com', 'winter rodeln@localhost', 'www.winterrodeln.org', 'mailto:info@example.com', 'info@example.com.']
+# longitude/latitude converter
+# ----------------------------
 
+class TestLonLat(unittest.TestCase):
     def test_from_str(self):
-        for value in self.good_addresses:
-            self.assertEqual(value, email_from_str(value))
-        for value in self.bad_addresses:
-            with self.assertRaises(ValueError):
-                email_from_str(value)
+        self.assertEqual(LonLat(11.453553, 47.076207), lonlat_from_str('47.076207 N 11.453553 E'))
+        with self.assertRaises(ValueError):
+            lonlat_from_str('47.076207 N 11.453553')
 
     def test_to_str(self):
-        for value in self.good_addresses:
-            self.assertEqual(value, email_to_str(value))
+        self.assertEqual('47.076207 N 11.453553 E', lonlat_to_str(LonLat(11.453553, 47.076207)))
 
 
-class TestMaskedEmail(unittest.TestCase):
+# difficulty converter
+# --------------------
+
+class TestDifficultyGerman(unittest.TestCase):
     def test_from_str(self):
-        self.assertEqual(('office@example.com', False), masked_email_from_str('office@example.com'))
-        self.assertEqual(('office@example.com', True), masked_email_from_str('office(at)example.com'))
+        self.assertEqual(1, difficulty_german_from_str('leicht'))
+        self.assertEqual(2, difficulty_german_from_str('mittel'))
         with self.assertRaises(ValueError):
-            masked_email_from_str('office@example.com', masked_only=True)
+            difficulty_german_from_str('dontknow')
         with self.assertRaises(ValueError):
-            masked_email_from_str('off ice@example.com')
+            difficulty_german_from_str('')
 
     def test_to_str(self):
-        self.assertEqual('office@example.com', masked_email_to_str(('office@example.com', False)))
-        self.assertEqual('office(at)example.com', masked_email_to_str(('office@example.com', True)))
-        self.assertEqual('office()example.com', masked_email_to_str(('office@example.com', True), '()'))
+        self.assertEqual('leicht', difficulty_german_to_str(1))
 
 
-class TestEmails(unittest.TestCase):
+# TODO: avalanches converter
+# --------------------
+
+
+
+# lift converter
+# --------------
+
+class TestLiftGermanValidator(unittest.TestCase):
     def test_from_str(self):
-        self.assertEqual(None, emails_from_str(''))
-        self.assertEqual([], emails_from_str('Nein'))
-        self.assertEqual([(('info@example.com', False), None)], emails_from_str('info@example.com'))
-        # self.assertEqual([(('info@example.com', True), None)], emails_from_str('info(at)example.com'))
-        self.assertEqual([(('info@example.com', False), 'Office')], emails_from_str('info@example.com (Office)'))
-        self.assertEqual([(('info@example.com', False), None), (('home@example.com', False), 'Privat')], emails_from_str('info@example.com; home@example.com (Privat)'))
+        self.assertEqual(lift_german_from_str(''), None)
+        self.assertEqual([], lift_german_from_str('Nein'))
+        self.assertEqual([('Sessellift', None)], lift_german_from_str('Sessellift'))
+        self.assertEqual([('Gondel', 'nur bis zur Hälfte')], lift_german_from_str('Gondel (nur bis zur Hälfte)'))
+        self.assertEqual([('Sessellift', None), ('Taxi', None)], lift_german_from_str('Sessellift; Taxi'))
+        self.assertEqual([('Sessellift', 'Wochenende'), ('Taxi', '6 Euro')], lift_german_from_str('Sessellift (Wochenende); Taxi (6 Euro)'))
+
+    def test_to_str(self):
+        self.assertEqual('', lift_german_to_str(None))
+        self.assertEqual('Nein', lift_german_to_str([]))
+        self.assertEqual('Sessellift', lift_german_to_str([('Sessellift', None)]))
+        self.assertEqual('Gondel (nur bis zur Hälfte)', lift_german_to_str([('Gondel', 'nur bis zur Hälfte')]))
+        self.assertEqual('Sessellift; Taxi', lift_german_to_str([('Sessellift', None), ('Taxi', None)]))
+        self.assertEqual('Sessellift (Wochenende); Taxi (6 Euro)', lift_german_to_str([('Sessellift', 'Wochenende'), ('Taxi', '6 Euro')]))
+
+
+# TODO: public transport converter
+# --------------------------
+
+
+# cachet converter
+# ----------------
+
+class TestSingleCachet(unittest.TestCase):
+    def test_from_str(self):
+        self.assertEqual(single_cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 2009 mittel'), ('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel'))
+        self.assertEqual(single_cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 2013 schwer'), ('Tiroler Naturrodelbahn-Gütesiegel', '2013', 'schwer'))
         with self.assertRaises(ValueError):
-            emails_from_str('nein')
+            single_cachet_german_from_str('')
         with self.assertRaises(ValueError):
-            emails_from_str('info@example.com; ho me@example.com (Privat)')
+            single_cachet_german_from_str('Salzburger Naturrodelbahn-Gütesiegel 2013 schwer')
+        with self.assertRaises(ValueError):
+            single_cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 4013 schwer')
+        with self.assertRaises(ValueError):
+            single_cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 13 schwer')
+        with self.assertRaises(ValueError):
+            single_cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 2013 schwerer')
 
     def test_to_str(self):
-        self.assertEqual('', emails_to_str(None))
-        self.assertEqual('Nein', emails_to_str([]))
-        self.assertEqual('info@example.com', emails_to_str([(('info@example.com', False), None)]))
-        self.assertEqual('info@example.com (Office)', emails_to_str([(('info@example.com', False), 'Office')]))
-        self.assertEqual('info@example.com; home@example.com (Privat)', emails_to_str([(('info@example.com', False), None), (('home@example.com', False), 'Privat')]))
+        self.assertEqual(single_cachet_german_to_str(('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel')), 'Tiroler Naturrodelbahn-Gütesiegel 2009 mittel')
+        self.assertEqual(single_cachet_german_to_str(('Tiroler Naturrodelbahn-Gütesiegel', '2013', 'schwer')), 'Tiroler Naturrodelbahn-Gütesiegel 2013 schwer')
 
 
-class TestWikipage(unittest.TestCase):
+class TestCachetGerman(unittest.TestCase):
     def test_from_str(self):
-        self.assertEqual('[[Birgitzer Alm]]', wikipage_from_str('[[Birgitzer Alm]]'))
+        self.assertEqual(cachet_german_from_str(''), None)
+        self.assertEqual(cachet_german_from_str('Nein'), [])
+        self.assertEqual(cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 2009 mittel'), [('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel')])
+        self.assertEqual(cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 2013 schwer; Tiroler Naturrodelbahn-Gütesiegel 2009 mittel'),
+            [('Tiroler Naturrodelbahn-Gütesiegel', '2013', 'schwer'), ('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel')])
         with self.assertRaises(ValueError):
-            wikipage_from_str('[[')
+            cachet_german_from_str('Ja')
         with self.assertRaises(ValueError):
-            wikipage_from_str('')
+            cachet_german_from_str('Tiroler Naturrodelbahn-Gütesiegel 2013 schwer Tiroler Naturrodelbahn-Gütesiegel 2009 mittel')
+
+    def test_to_str(self):
+        self.assertEqual(cachet_german_to_str(None), '')
+        self.assertEqual(cachet_german_to_str([]), 'Nein')
+        self.assertEqual(cachet_german_to_str([('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel')]), 'Tiroler Naturrodelbahn-Gütesiegel 2009 mittel')
+        self.assertEqual(cachet_german_to_str([('Tiroler Naturrodelbahn-Gütesiegel', '2013', 'schwer'), ('Tiroler Naturrodelbahn-Gütesiegel', '2009', 'mittel')]),
+            'Tiroler Naturrodelbahn-Gütesiegel 2013 schwer; Tiroler Naturrodelbahn-Gütesiegel 2009 mittel')
+
+
+# night light days converter
+# --------------------------
+
+class TestNightLightDays(unittest.TestCase):
+    def test_from_str(self):
+        self.assertEqual((None, None), nightlightdays_from_str(''))
+        self.assertEqual((2, 'Mo, Di'), nightlightdays_from_str('2 (Mo, Di)'))
+        self.assertEqual((7, None), nightlightdays_from_str('7'))
+        self.assertEqual((0, None), nightlightdays_from_str('0'))
+        self.assertEqual((None, 'keine Ahnung'), nightlightdays_from_str('(keine Ahnung)'))
         with self.assertRaises(ValueError):
-            wikipage_from_str('Birgitzer Alm')
+            nightlightdays_from_str('8')
+        with self.assertRaises(ValueError):
+            nightlightdays_from_str('5 (Montag')
+        with self.assertRaises(ValueError):
+            nightlightdays_from_str('5.2')
 
     def test_to_str(self):
-        self.assertEqual('[[Birgitzer Alm]]', wikipage_to_str('[[Birgitzer Alm]]'))
+        self.assertEqual('', nightlightdays_to_str((None, None)))
+        self.assertEqual('2 (Mo, Di)', nightlightdays_to_str((2, 'Mo, Di')))
+        self.assertEqual('7', nightlightdays_to_str((7, None)))
+        self.assertEqual('0', nightlightdays_to_str((0, None)))
 
 
-class TestOptWikipageEnum(unittest.TestCase):
+# string with optional comment enum/list converter
+# ------------------------------------------------
+
+class TestOptStrOptCommentEnum(unittest.TestCase):
     def test_from_str(self):
-        self.assertEqual(['[[Birgitzer Alm]]', '[[Kemater Alm]]'], opt_wikipage_enum_from_str('[[Birgitzer Alm]]; [[Kemater Alm]]'))
-        self.assertEqual(['[[Birgitzer Alm]]'], opt_wikipage_enum_from_str('[[Birgitzer Alm]]'))
-        self.assertEqual([], opt_wikipage_enum_from_str('Nein'))
-        self.assertEqual(None, opt_wikipage_enum_from_str(''))
+        self.assertEqual(opt_str_opt_comment_enum_from_str(''), None)
+        self.assertEqual(opt_str_opt_comment_enum_from_str('Nein'), [])
+        self.assertEqual(opt_str_opt_comment_enum_from_str('Talstation'), [('Talstation', None)])
+        self.assertEqual(opt_str_opt_comment_enum_from_str('Talstation (unten)'), [('Talstation', 'unten')])
+        self.assertEqual(opt_str_opt_comment_enum_from_str('Talstation (unten); Mittelstation'), [('Talstation', 'unten'), ('Mittelstation', None)])
+        with self.assertRaises(ValueError):
+            opt_str_opt_comment_enum_from_str('(unten)')
+        with self.assertRaises(ValueError):
+            opt_str_opt_comment_enum_from_str('Talstation (unten); ; Mittelstation')
 
     def test_to_str(self):
-        self.assertEqual('[[Birgitzer Alm]]; [[Kemater Alm]]', opt_wikipage_enum_to_str(['[[Birgitzer Alm]]', '[[Kemater Alm]]']))
-        self.assertEqual('[[Birgitzer Alm]]', opt_wikipage_enum_to_str(['[[Birgitzer Alm]]']))
-        self.assertEqual('Nein', opt_wikipage_enum_to_str([]))
-        self.assertEqual('', opt_wikipage_enum_to_str(None))
+        self.assertEqual(opt_str_opt_comment_enum_to_str(None), '')
+        self.assertEqual(opt_str_opt_comment_enum_to_str([]), 'Nein')
+        self.assertEqual(opt_str_opt_comment_enum_to_str([('Talstation', None)]), 'Talstation')
+        self.assertEqual(opt_str_opt_comment_enum_to_str([('Talstation', 'unten')]), 'Talstation (unten)')
+        self.assertEqual(opt_str_opt_comment_enum_to_str([('Talstation', 'unten'), ('Mittelstation', None)]), 'Talstation (unten); Mittelstation')
 
 
-class TestBox(unittest.TestCase):
+# wikibox converter
+# -----------------
+
+class TestWikibox(unittest.TestCase):
     def test_from_str(self):
         value = '{{MyTemplate|apple=2|banana=5}}'
         converter_dict = OrderedDict([('apple', opt_uint_converter), ('banana', opt_uint_converter)])
@@ -567,6 +614,9 @@ class TestBox(unittest.TestCase):
         self.assertEqual(result, '{{MyTemplate|apple=2|banana=5}}')
 
 
+# Rodelbahnbox converter
+# ----------------------
+
 class TestRodelbahnbox(unittest.TestCase):
     def setUp(self):
         self.maxDiff = None
@@ -651,16 +701,8 @@ class TestRodelbahnbox(unittest.TestCase):
         self.assertEqual(rodelbahnbox_to_str(value), self.value)
 
 
-class TestWrValidators(unittest.TestCase):
-    def test_ValueCommentListNeinLoopNone(self):
-        v = wrpylib.wrvalidators.ValueCommentListNeinLoopNone()
-        assert v.to_python('') == None
-        assert v.to_python('Nein') == 'Nein'
-        assert v.to_python('T-Mobile (gut); A1') == 'T-Mobile (gut); A1'
-        assert v.from_python(None) == ''
-        assert v.from_python('Nein') == 'Nein'
-        assert v.from_python('T-Mobile (gut); A1') == 'T-Mobile (gut); A1'
-
+# TODO: Gasthausbox converter
+# ---------------------
 
 class TestGasthausbox(unittest.TestCase):
     def test_GasthausboxDictValidator(self):