Back to index

moin  1.9.0~rc2
test_wikiutil.py
Go to the documentation of this file.
00001 # -*- coding: iso-8859-1 -*-
00002 """
00003     MoinMoin - MoinMoin.wikiutil Tests
00004 
00005     @copyright: 2003-2004 by Juergen Hermann <jh@web.de>,
00006                 2007 by MoinMoin:ThomasWaldmann
00007     @license: GNU GPL, see COPYING for details.
00008 """
00009 
00010 import py
00011 
00012 from MoinMoin import config, wikiutil
00013 
00014 from werkzeug import MultiDict
00015 
00016 
00017 class TestQueryStringSupport:
00018     tests = [
00019         ('', {}, {}),
00020         ('key1=value1', {'key1': 'value1'}, {'key1': u'value1'}),
00021         ('key1=value1&key2=value2', {'key1': 'value1', 'key2': 'value2'}, {'key1': u'value1', 'key2': u'value2'}),
00022         ('rc_de=Aktuelle%C3%84nderungen', {'rc_de': 'Aktuelle\xc3\x84nderungen'}, {'rc_de': u'Aktuelle\xc4nderungen'}),
00023     ]
00024     def testParseQueryString(self):
00025         for qstr, expected_str, expected_unicode in self.tests:
00026             assert wikiutil.parseQueryString(qstr) == MultiDict(expected_unicode)
00027             assert wikiutil.parseQueryString(unicode(qstr)) == MultiDict(expected_unicode)
00028 
00029     def testMakeQueryString(self):
00030         for qstr, in_str, in_unicode in self.tests:
00031             assert wikiutil.parseQueryString(wikiutil.makeQueryString(in_unicode)) == MultiDict(in_unicode)
00032             assert wikiutil.parseQueryString(wikiutil.makeQueryString(in_str)) == MultiDict(in_unicode)
00033 
00034 
00035 class TestTickets:
00036     def testTickets(self):
00037         from MoinMoin.Page import Page
00038         # page name with double quotes
00039         self.request.page = Page(self.request, u'bla"bla')
00040         ticket1 = wikiutil.createTicket(self.request)
00041         assert wikiutil.checkTicket(self.request, ticket1)
00042         # page name with non-ASCII chars
00043         self.request.page = Page(self.request, u'\xc4rger')
00044         ticket2 = wikiutil.createTicket(self.request)
00045         assert wikiutil.checkTicket(self.request, ticket2)
00046         # same page with another action
00047         self.request.page = Page(self.request, u'\xc4rger')
00048         self.request.action = 'another'
00049         ticket3 = wikiutil.createTicket(self.request)
00050         assert wikiutil.checkTicket(self.request, ticket3)
00051 
00052         assert ticket1 != ticket2
00053         assert ticket2 != ticket3
00054 
00055 
00056 class TestCleanInput:
00057     def testCleanInput(self):
00058         tests = [(u"", u""), # empty
00059                  (u"aaa\r\n\tbbb", u"aaa   bbb"), # ws chars -> blanks
00060                  (u"aaa\x00\x01bbb", u"aaabbb"), # strip weird chars
00061                  (u"a"*500, u""), # too long
00062                 ]
00063         for instr, outstr in tests:
00064             assert wikiutil.clean_input(instr) == outstr
00065 
00066 
00067 class TestInterWiki:
00068     def testSplitWiki(self):
00069         tests = [('SomePage', ('Self', 'SomePage')),
00070                  ('OtherWiki:OtherPage', ('OtherWiki', 'OtherPage')),
00071                  (':OtherPage', ('', 'OtherPage')),
00072                  # broken ('/OtherPage', ('Self', '/OtherPage')),
00073                  # wrong interpretation ('MainPage/OtherPage', ('Self', 'MainPage/OtherPage')),
00074                 ]
00075         for markup, (wikiname, pagename) in tests:
00076             assert wikiutil.split_wiki(markup) == (wikiname, pagename)
00077 
00078     def testJoinWiki(self):
00079         tests = [(('http://example.org/', u'SomePage'), 'http://example.org/SomePage'),
00080                  (('http://example.org/?page=$PAGE&action=show', u'SomePage'), 'http://example.org/?page=SomePage&action=show'),
00081                  (('http://example.org/', u'Aktuelle\xc4nderungen'), 'http://example.org/Aktuelle%C3%84nderungen'),
00082                  (('http://example.org/$PAGE/show', u'Aktuelle\xc4nderungen'), 'http://example.org/Aktuelle%C3%84nderungen/show'),
00083                 ]
00084         for (baseurl, pagename), url in tests:
00085             assert wikiutil.join_wiki(baseurl, pagename) == url
00086 
00087 
00088 class TestSystemPage:
00089     systemPages = (
00090         'RecentChanges',
00091         'TitleIndex',
00092         )
00093     notSystemPages = (
00094         'NoSuchPageYetAndWillNeverBe',
00095         )
00096 
00097     def testSystemPage(self):
00098         """wikiutil: good system page names accepted, bad rejected"""
00099         for name in self.systemPages:
00100             assert wikiutil.isSystemPage(self.request, name)
00101         for name in self.notSystemPages:
00102             assert not  wikiutil.isSystemPage(self.request, name)
00103 
00104 
00105 class TestTemplatePage:
00106     good = (
00107         'aTemplate',
00108         'MyTemplate',
00109     )
00110     bad = (
00111         'Template',
00112         'I want a Template',
00113         'TemplateInFront',
00114         'xTemplateInFront',
00115         'XTemplateInFront',
00116     )
00117 
00118     def testTemplatePage(self):
00119         """wikiutil: good template names accepted, bad rejected"""
00120         for name in self.good:
00121             assert  wikiutil.isTemplatePage(self.request, name)
00122         for name in self.bad:
00123             assert not wikiutil.isTemplatePage(self.request, name)
00124 
00125 
00126 class TestParmeterParser:
00127 
00128     def testParameterParser(self):
00129         tests = [
00130             # trivial
00131             ('', '', 0, {}),
00132 
00133             # fixed
00134             ('%s%i%f%b', '"test",42,23.0,True', 4, {0: 'test', 1: 42, 2: 23.0, 3: True}),
00135 
00136             # fixed and named
00137             ('%s%(x)i%(y)i', '"test"', 1, {0: 'test', 'x': None, 'y': None}),
00138             ('%s%(x)i%(y)i', '"test",1', 1, {0: 'test', 'x': 1, 'y': None}),
00139             ('%s%(x)i%(y)i', '"test",1,2', 1, {0: 'test', 'x': 1, 'y': 2}),
00140             ('%s%(x)i%(y)i', '"test",x=1', 1, {0: 'test', 'x': 1, 'y': None}),
00141             ('%s%(x)i%(y)i', '"test",x=1,y=2', 1, {0: 'test', 'x': 1, 'y': 2}),
00142             ('%s%(x)i%(y)i', '"test",y=2', 1, {0: 'test', 'x': None, 'y': 2}),
00143 
00144             # test mixed acceptance
00145             ("%ifs", '100', 1, {0: 100}),
00146             ("%ifs", '100.0', 1, {0: 100.0}),
00147             ("%ifs", '"100"', 1, {0: "100"}),
00148 
00149             # boolean
00150             ("%(t)b%(f)b", '', 0, {'t': None, 'f': None}),
00151             ("%(t)b%(f)b", 't=1', 0, {'t': True, 'f': None}),
00152             ("%(t)b%(f)b", 'f=False', 0, {'t': None, 'f': False}),
00153             ("%(t)b%(f)b", 't=True, f=0', 0, {'t': True, 'f': False}),
00154 
00155             # integer
00156             ("%(width)i%(height)i", '', 0, {'width': None, 'height': None}),
00157             ("%(width)i%(height)i", 'width=100', 0, {'width': 100, 'height': None}),
00158             ("%(width)i%(height)i", 'height=200', 0, {'width': None, 'height': 200}),
00159             ("%(width)i%(height)i", 'width=100, height=200', 0, {'width': 100, 'height': 200}),
00160 
00161             # float
00162             ("%(width)f%(height)f", '', 0, {'width': None, 'height': None}),
00163             ("%(width)f%(height)f", 'width=100.0', 0, {'width': 100.0, 'height': None}),
00164             ("%(width)f%(height)f", 'height=2.0E2', 0, {'width': None, 'height': 200.0}),
00165             ("%(width)f%(height)f", 'width=1000.0E-1, height=200.0', 0, {'width': 100.0, 'height': 200.0}),
00166 
00167             # string
00168             ("%(width)s%(height)s", '', 0, {'width': None, 'height': None}),
00169             ("%(width)s%(height)s", 'width="really wide"', 0, {'width': 'really wide', 'height': None}),
00170             ("%(width)s%(height)s", 'height="not too high"', 0, {'width': None, 'height': 'not too high'}),
00171             ("%(width)s%(height)s", 'width="really wide", height="not too high"', 0, {'width': 'really wide', 'height': 'not too high'}),
00172             # conversion from given type to expected type
00173             ("%(width)s%(height)s", 'width=100', 0, {'width': '100', 'height': None}),
00174             ("%(width)s%(height)s", 'width=100, height=200', 0, {'width': '100', 'height': '200'}),
00175 
00176             # complex test
00177             ("%i%sf%s%ifs%(a)s|%(b)s", ' 4,"DI\'NG", b=retry, a="DING"', 2, {0: 4, 1: "DI'NG", 'a': 'DING', 'b': 'retry'}),
00178 
00179             ]
00180         for format, args, expected_fixed_count, expected_dict in tests:
00181             argParser = wikiutil.ParameterParser(format)
00182             fixed_count, arg_dict = argParser.parse_parameters(args)
00183             assert (fixed_count, arg_dict) == (expected_fixed_count, expected_dict)
00184 
00185     def testTooMuchWantedArguments(self):
00186         args = 'width=100, height=200, alt=Example'
00187         argParser = wikiutil.ParameterParser("%(width)s%(height)s")
00188         py.test.raises(ValueError, argParser.parse_parameters, args)
00189 
00190     def testMalformedArguments(self):
00191         args = '='
00192         argParser = wikiutil.ParameterParser("%(width)s%(height)s")
00193         py.test.raises(ValueError, argParser.parse_parameters, args)
00194 
00195     def testWrongTypeFixedPosArgument(self):
00196         args = '0.0'
00197         argParser = wikiutil.ParameterParser("%b")
00198         py.test.raises(ValueError, argParser.parse_parameters, args)
00199 
00200     def testWrongTypeNamedArgument(self):
00201         args = 'flag=0.0'
00202         argParser = wikiutil.ParameterParser("%(flag)b")
00203         py.test.raises(ValueError, argParser.parse_parameters, args)
00204 
00205 
00206 class TestParamParsing:
00207     def testMacroArgs(self):
00208         abcd = [u'a', u'b', u'c', u'd']
00209         abcd_dict = {u'a': u'1', u'b': u'2', u'c': u'3', u'd': u'4'}
00210         tests = [
00211                   # regular and quoting tests
00212                   (u'd = 4,c=3,b=2,a= 1 ',    ([], abcd_dict, [])),
00213                   (u'a,b,c,d',                (abcd, {}, [])),
00214                   (u' a , b , c , d ',        (abcd, {}, [])),
00215                   (u'   a   ',                ([u'a'], {}, [])),
00216                   (u'"  a  "',                ([u'  a  '], {}, [])),
00217                   (u'a,b,c,d, "a,b,c,d"',     (abcd+[u'a,b,c,d'], {}, [])),
00218                   (u'quote " :), b',          ([u'quote " :)', u'b'], {}, [])),
00219                   (u'"quote "" :)", b',       ([u'quote " :)', u'b'], {}, [])),
00220                   (u'=7',                     ([], {u'': u'7'}, [])),
00221                   (u',,',                     ([None, None, None], {}, [])),
00222                   (u',"",',                   ([None, u'', None], {}, [])),
00223                   (u',"", ""',                ([None, u'', u''], {}, [])),
00224                   (u'  ""  ,"", ""',          ([u'', u'', u''], {}, [])),
00225                   # some name=value test
00226                   (u'd = 4,c=3,b=2,a= 1 ',    ([], abcd_dict, [])),
00227                   (u'd=d,e="a,b,c,d"',        ([], {u'd': u'd',
00228                                                     u'e': u'a,b,c,d'}, [])),
00229                   (u'd = d,e = "a,b,c,d"',    ([], {u'd': u'd',
00230                                                     u'e': u'a,b,c,d'}, [])),
00231                   (u'd = d, e = "a,b,c,d"',   ([], {u'd': u'd',
00232                                                     u'e': u'a,b,c,d'}, [])),
00233                   (u'd = , e = "a,b,c,d"',    ([], {u'd': None,
00234                                                     u'e': u'a,b,c,d'}, [])),
00235                   (u'd = "", e = "a,b,c,d"',  ([], {u'd': u'',
00236                                                     u'e': u'a,b,c,d'}, [])),
00237                   (u'd = "", e = ',           ([], {u'd': u'', u'e': None},
00238                                                [])),
00239                   (u'd=""',                   ([], {u'd': u''}, [])),
00240                   (u'd = "", e = ""',         ([], {u'd': u'', u'e': u''},
00241                                                [])),
00242                   # no, None as key isn't accepted
00243                   (u' = "",  e = ""',         ([], {u'': u'', u'e': u''},
00244                                                [])),
00245                   # can quote both name and value:
00246                   (u'd = d," e "= "a,b,c,d"', ([], {u'd': u'd',
00247                                                     u' e ': u'a,b,c,d'}, [])),
00248                   # trailing args
00249                   (u'1,2,a=b,3,4',            ([u'1', u'2'], {u'a': u'b'},
00250                                                [u'3', u'4'])),
00251                   # can quote quotes:
00252                   (u'd = """d"',              ([], {u'd': u'"d'}, [])),
00253                   (u'd = """d"""',            ([], {u'd': u'"d"'}, [])),
00254                   (u'd = "d"" ", e=7',        ([], {u'd': u'd" ', u'e': u'7'},
00255                                                [])),
00256                   (u'd = "d""", e=8',         ([], {u'd': u'd"', u'e': u'8'},
00257                                                [])),
00258                 ]
00259         for args, expected in tests:
00260             result = wikiutil.parse_quoted_separated(args)
00261             assert expected == result
00262             for val in result[0]:
00263                 assert val is None or isinstance(val, unicode)
00264             for val in result[1].keys():
00265                 assert val is None or isinstance(val, unicode)
00266             for val in result[1].values():
00267                 assert val is None or isinstance(val, unicode)
00268             for val in result[2]:
00269                 assert val is None or isinstance(val, unicode)
00270 
00271     def testLimited(self):
00272         tests = [
00273                   # regular and quoting tests
00274                   (u'd = 4,c=3,b=2,a= 1 ',    ([], {u'd': u'4',
00275                                                     u'c': u'3,b=2,a= 1'}, [])),
00276                   (u'a,b,c,d',                ([u'a', u'b,c,d'], {}, [])),
00277                   (u'a=b,b,c,d',              ([], {u'a': u'b'}, [u'b,c,d'])),
00278                 ]
00279         for args, expected in tests:
00280             result = wikiutil.parse_quoted_separated(args, seplimit=1)
00281             assert expected == result
00282             for val in result[0]:
00283                 assert val is None or isinstance(val, unicode)
00284             for val in result[1].keys():
00285                 assert val is None or isinstance(val, unicode)
00286             for val in result[1].values():
00287                 assert val is None or isinstance(val, unicode)
00288             for val in result[2]:
00289                 assert val is None or isinstance(val, unicode)
00290 
00291     def testDoubleNameValueSeparator(self):
00292         tests = [
00293                   # regular and quoting tests
00294                   (u'd==4,=3 ',    ([], {u'd': u'=4', u'': u'3'}, [])),
00295                   (u'===a,b,c,d',  ([], {u'': u'==a'}, [u'b', u'c', u'd'])),
00296                   (u'a,b,===,c,d', ([u'a', u'b'], {u'': u'=='}, [u'c', u'd'])),
00297                 ]
00298 
00299         def _check(a, e):
00300             r = wikiutil.parse_quoted_separated(a)
00301             assert r == e
00302 
00303         for args, expected in tests:
00304             yield _check, args, expected
00305 
00306     def testNoNameValue(self):
00307         abcd = [u'a', u'b', u'c', u'd']
00308         tests = [
00309                   # regular and quoting tests
00310                   (u'd = 4,c=3,b=2,a= 1 ',    [u'd = 4', u'c=3',
00311                                                u'b=2', u'a= 1']),
00312                   (u'a,b,c,d',                abcd),
00313                   (u' a , b , c , d ',        abcd),
00314                   (u'   a   ',                [u'a']),
00315                   (u'"  a  "',                [u'  a  ']),
00316                   (u'a,b,c,d, "a,b,c,d"',     abcd + [u'a,b,c,d']),
00317                   (u'quote " :), b',          [u'quote " :)', u'b']),
00318                   (u'"quote "" :)", b',       [u'quote " :)', u'b']),
00319                   (u'"unended quote',         [u'"unended quote']),
00320                   (u'"',                      [u'"']),
00321                   (u'd=d,e="a,b,c,d"',        [u'd=d', u'e="a', u'b',
00322                                                u'c', u'd"']),
00323                 ]
00324         for args, expected in tests:
00325             result = wikiutil.parse_quoted_separated(args, name_value=False)
00326             assert expected == result
00327             for val in result:
00328                 assert val is None or isinstance(val, unicode)
00329 
00330     def testUnitArgument(self):
00331         result = wikiutil.UnitArgument('7mm', float, ['%', 'mm'])
00332         assert result.get_default() ==  (7.0, 'mm')
00333         assert result.parse_argument('8%') == (8.0, '%')
00334         py.test.raises(ValueError, result.parse_argument,  u'7m')
00335         py.test.raises(ValueError, result.parse_argument,  u'7')
00336         py.test.raises(ValueError, result.parse_argument,  u'mm')
00337 
00338     def testExtendedParser(self):
00339         tests = [
00340             (u'"a", "b", "c"', u',', None, [u'a', u'b', u'c']),
00341             (u'a:b, b:c, c:d', u',', u':', [(u'a', u'b'), (u'b', u'c'), (u'c', u'd')]),
00342             (u'a:b, b:c, c:d', u',', None, [u'a:b', u'b:c', u'c:d']),
00343             (u'a=b, b=c, c=d', u',', None, [u'a=b', u'b=c', u'c=d']),
00344             (u'a=b, b=c, c=d', u',', u'=', [(u'a', u'b'), (u'b', u'c'), (u'c', u'd')]),
00345             (u'"a"; "b"; "c"', u';', None, [u'a', u'b', u'c']),
00346             (u'a:b; b:c; c:d', u';', u':', [(u'a', u'b'), (u'b', u'c'), (u'c', u'd')]),
00347             (u'a:b; b:c; c:d', u';', None, [u'a:b', u'b:c', u'c:d']),
00348             (u'a=b; b=c; c=d', u';', None, [u'a=b', u'b=c', u'c=d']),
00349             (u'a=b; b=c; c=d', u';', u'=', [(u'a', u'b'), (u'b', u'c'), (u'c', u'd')]),
00350             (u'"a" "b" "c"', None, None, [u'a', u'b', u'c']),
00351             (u'" a " "b" "c"', None, None, [u' a ', u'b', u'c']),
00352             (u'"a  " "b" "c"', None, None, [u'a  ', u'b', u'c']),
00353             (u'"  a" "b" "c"', None, None, [u'  a', u'b', u'c']),
00354             (u'"  a" "b" "c"', None, u':', [u'  a', u'b', u'c']),
00355             (u'"a:a" "b:b" "c:b"', None, u':', [u'a:a', u'b:b', u'c:b']),
00356             (u'   a:a  ', None, u':', [None, None, None, (u'a', u'a'), None, None]),
00357             (u'a a: a', None, u':', [u'a', (u'a', None), u'a']),
00358             (u'a a:"b c d" a', None, u':', [u'a', (u'a', u'b c d'), u'a']),
00359             (u'a a:"b "" d" a', None, u':', [u'a', (u'a', u'b " d'), u'a']),
00360             (u'title:Help* dog cat', None, u':', [(u'title', u'Help*'), u'dog', u'cat']),
00361             (u'title:Help* "dog cat"', None, u':', [(u'title', u'Help*'), u'dog cat']),
00362             (u'a:b:c d:e:f', None, u':', [(u'a', u'b:c'), (u'd', 'e:f')]),
00363             (u'a:b:c:d', None, u':', [(u'a', u'b:c:d')]),
00364         ]
00365 
00366         def _check(args, sep, kwsep, expected):
00367             res = wikiutil.parse_quoted_separated_ext(args, sep, kwsep)
00368             assert res == expected
00369 
00370         for test in tests:
00371             yield [_check] + list(test)
00372 
00373     def testExtendedParserBracketing(self):
00374         tests = [
00375             (u'"a", "b", "c"', u',', None, [u'a', u'b', u'c']),
00376             (u'("a", "b", "c")', u',', None, [[u'(', u'a', u'b', u'c']]),
00377             (u'("a"("b", "c"))', u',', None, [[u'(', u'a', [u'(', u'b', u'c']]]),
00378             (u'("a"("b)))", "c"))', u',', None, [[u'(', u'a', [u'(', u'b)))', u'c']]]),
00379             (u'("a"("b>>> ( ab )>", "c"))', u',', None, [[u'(', u'a', [u'(', u'b>>> ( ab )>', u'c']]]),
00380             (u'("a" ("b" "c"))', None, None, [[u'(', u'a', [u'(', u'b', u'c']]]),
00381             (u'("a"("b", "c") ) ', u',', None, [[u'(', u'a', [u'(', u'b', u'c']]]),
00382             (u'("a", <"b", ("c")>)', u',', None, [[u'(', u'a', [u'<', u'b', [u'(', u'c']]]]),
00383             (u',,,(a, b, c)', u',', None, [None, None, None, [u'(', u'a', u'b', u'c']]),
00384         ]
00385 
00386         def _check(args, sep, kwsep, expected):
00387             res = wikiutil.parse_quoted_separated_ext(args, sep, kwsep, brackets=(u'<>', u'()'))
00388             assert res == expected
00389 
00390         for test in tests:
00391             yield [_check] + list(test)
00392 
00393     def testExtendedParserQuoting(self):
00394         tests = [
00395             (u'"a b" -a b-', u'"', [u'a b', u'-a', u'b-']),
00396             (u'"a b" -a b-', u"-", [u'"a', u'b"', u'a b']),
00397             (u'"a b" -a b-', u'"-', [u'a b', u'a b']),
00398             (u'"a- b" -a b-', u'"-', [u'a- b', u'a b']),
00399             (u'"a- b" -a" b-', u'"-', [u'a- b', u'a" b']),
00400         ]
00401 
00402         def _check(args, quotes, expected):
00403             res = wikiutil.parse_quoted_separated_ext(args, quotes=quotes)
00404             assert res == expected
00405 
00406         for test in tests:
00407             yield [_check] + list(test)
00408 
00409     def testExtendedParserMultikey(self):
00410         tests = [
00411             (u'"a", "b", "c"', u',', None, [u'a', u'b', u'c']),
00412             (u'a:b, b:c, c:d', u',', u':', [(u'a', u'b'), (u'b', u'c'), (u'c', u'd')]),
00413             (u'a:b, b:c, c:d', u',', None, [u'a:b', u'b:c', u'c:d']),
00414             (u'a=b, b=c, c=d', u',', None, [u'a=b', u'b=c', u'c=d']),
00415             (u'a=b, b=c, c=d', u',', u'=', [(u'a', u'b'), (u'b', u'c'), (u'c', u'd')]),
00416             (u'"a"; "b"; "c"', u';', None, [u'a', u'b', u'c']),
00417             (u'a:b; b:c; c:d', u';', u':', [(u'a', u'b'), (u'b', u'c'), (u'c', u'd')]),
00418             (u'a:b; b:c; c:d', u';', None, [u'a:b', u'b:c', u'c:d']),
00419             (u'a=b; b=c; c=d', u';', None, [u'a=b', u'b=c', u'c=d']),
00420             (u'a=b; b=c; c=d', u';', u'=', [(u'a', u'b'), (u'b', u'c'), (u'c', u'd')]),
00421             (u'"a" "b" "c"', None, None, [u'a', u'b', u'c']),
00422             (u'" a " "b" "c"', None, None, [u' a ', u'b', u'c']),
00423             (u'"a  " "b" "c"', None, None, [u'a  ', u'b', u'c']),
00424             (u'"  a" "b" "c"', None, None, [u'  a', u'b', u'c']),
00425             (u'"  a" "b" "c"', None, u':', [u'  a', u'b', u'c']),
00426             (u'"a:a" "b:b" "c:b"', None, u':', [u'a:a', u'b:b', u'c:b']),
00427             (u'   a:a  ', None, u':', [None, None, None, (u'a', u'a'), None, None]),
00428             (u'a a: a', None, u':', [u'a', (u'a', None), u'a']),
00429             (u'a a:"b c d" a', None, u':', [u'a', (u'a', u'b c d'), u'a']),
00430             (u'a a:"b "" d" a', None, u':', [u'a', (u'a', u'b " d'), u'a']),
00431             (u'title:Help* dog cat', None, u':', [(u'title', u'Help*'), u'dog', u'cat']),
00432             (u'title:Help* "dog cat"', None, u':', [(u'title', u'Help*'), u'dog cat']),
00433             (u'a:b:c d:e:f', None, u':', [(u'a', u'b', u'c'), (u'd', 'e', u'f')]),
00434             (u'a:b:c:d', None, u':', [(u'a', u'b', u'c', u'd')]),
00435             (u'a:"b:c":d', None, u':', [(u'a', u'b:c', u'd')]),
00436         ]
00437 
00438         def _check(args, sep, kwsep, expected):
00439             res = wikiutil.parse_quoted_separated_ext(args, sep, kwsep, multikey=True)
00440             assert res == expected
00441 
00442         for test in tests:
00443             yield [_check] + list(test)
00444 
00445     def testExtendedParserPrefix(self):
00446         P = wikiutil.ParserPrefix('+')
00447         M = wikiutil.ParserPrefix('-')
00448         tests = [
00449             (u'"a", "b", "c"', u',', None, [u'a', u'b', u'c']),
00450             (u'a:b, b:c, c:d', u',', u':', [(u'a', u'b'), (u'b', u'c'), (u'c', u'd')]),
00451             (u'a:b, b:c, c:d', u',', None, [u'a:b', u'b:c', u'c:d']),
00452             (u'a=b, b=c, c=d', u',', None, [u'a=b', u'b=c', u'c=d']),
00453             (u'a=b, b=c, c=d', u',', u'=', [(u'a', u'b'), (u'b', u'c'), (u'c', u'd')]),
00454             (u'"a"; "b"; "c"', u';', None, [u'a', u'b', u'c']),
00455             (u'a:b; b:c; c:d', u';', u':', [(u'a', u'b'), (u'b', u'c'), (u'c', u'd')]),
00456             (u'a:b; b:c; c:d', u';', None, [u'a:b', u'b:c', u'c:d']),
00457             (u'a=b; b=c; c=d', u';', None, [u'a=b', u'b=c', u'c=d']),
00458             (u'a=b; b=c; c=d', u';', u'=', [(u'a', u'b'), (u'b', u'c'), (u'c', u'd')]),
00459             (u'"a" "b" "c"', None, None, [u'a', u'b', u'c']),
00460             (u'" a " "b" "c"', None, None, [u' a ', u'b', u'c']),
00461             (u'"a  " "b" "c"', None, None, [u'a  ', u'b', u'c']),
00462             (u'"  a" "b" "c"', None, None, [u'  a', u'b', u'c']),
00463             (u'"  a" "b" "c"', None, u':', [u'  a', u'b', u'c']),
00464             (u'"a:a" "b:b" "c:b"', None, u':', [u'a:a', u'b:b', u'c:b']),
00465             (u'   a:a  ', None, u':', [None, None, None, (u'a', u'a'), None, None]),
00466             (u'a a: a', None, u':', [u'a', (u'a', None), u'a']),
00467             (u'a a:"b c d" a', None, u':', [u'a', (u'a', u'b c d'), u'a']),
00468             (u'a a:"b "" d" a', None, u':', [u'a', (u'a', u'b " d'), u'a']),
00469             (u'title:Help* dog cat', None, u':', [(u'title', u'Help*'), u'dog', u'cat']),
00470             (u'title:Help* "dog cat"', None, u':', [(u'title', u'Help*'), u'dog cat']),
00471             (u'a:b:c d:e:f', None, u':', [(u'a', u'b', u'c'), (u'd', 'e', u'f')]),
00472             (u'a:b:c:d', None, u':', [(u'a', u'b', u'c', u'd')]),
00473             (u'a:"b:c":d', None, u':', [(u'a', u'b:c', u'd')]),
00474 
00475             (u'-a:b:d', None, u':', [(M, u'a', u'b', u'd')]),
00476             (u'"-a:b:d"', None, u':', [(u'-a:b:d')]),
00477             (u'-"a:b:d"', None, u':', [(M, u'a:b:d')]),
00478             (u'-a:"b:c":"d e f g"', None, u':', [(M, u'a', u'b:c', u'd e f g')]),
00479             (u'+-a:b:d', None, u':', [(P, u'-a', u'b', u'd')]),
00480             (u'-"+a:b:d"', None, u':', [(M, u'+a:b:d')]),
00481             # bit of a weird case...
00482             (u'-+"a:b:d"', None, u':', [(M, u'+"a', u'b', u'd"')]),
00483             (u'-a:"b:c" a +b', None, u':', [(M, u'a', u'b:c'), u'a', (P, u'b')]),
00484         ]
00485 
00486         def _check(args, sep, kwsep, expected):
00487             res = wikiutil.parse_quoted_separated_ext(args, sep, kwsep, multikey=True, prefixes='-+')
00488             assert res == expected
00489 
00490         for test in tests:
00491             yield [_check] + list(test)
00492 
00493     def testExtendedParserBracketingErrors(self):
00494         UCE = wikiutil.BracketUnexpectedCloseError
00495         MCE = wikiutil.BracketMissingCloseError
00496         tests = [
00497             (u'("a", "b", "c"', u',', None, MCE),
00498             (u'("a"("b", "c")', u',', None, MCE),
00499             (u'("a"<"b", "c")>', u',', None, UCE),
00500             (u')("a" ("b" "c"))', None, None, UCE),
00501             (u'("a", ("b", "c">))', u',', None, UCE),
00502             (u'("a", ("b", <"c">>))', u',', None, UCE),
00503             (u'(<(<)>)>', u',', None, UCE),
00504         ]
00505 
00506         def _check(args, sep, kwsep, err):
00507             py.test.raises(err,
00508                            wikiutil.parse_quoted_separated_ext,
00509                            args, sep, kwsep,
00510                            brackets=(u'<>', u'()'))
00511 
00512         for test in tests:
00513             yield [_check] + list(test)
00514 
00515 class TestArgGetters:
00516     def testGetBoolean(self):
00517         tests = [
00518             # default testing for None value
00519             (None, None, None, None),
00520             (None, None, False, False),
00521             (None, None, True, True),
00522 
00523             # some real values
00524             (u'0', None, None, False),
00525             (u'1', None, None, True),
00526             (u'false', None, None, False),
00527             (u'true', None, None, True),
00528             (u'FALSE', None, None, False),
00529             (u'TRUE', None, None, True),
00530             (u'no', None, None, False),
00531             (u'yes', None, None, True),
00532             (u'NO', None, None, False),
00533             (u'YES', None, None, True),
00534         ]
00535         for arg, name, default, expected in tests:
00536             assert wikiutil.get_bool(self.request, arg, name, default) == expected
00537 
00538     def testGetBooleanRaising(self):
00539         # wrong default type
00540         py.test.raises(AssertionError, wikiutil.get_bool, self.request, None, None, 42)
00541 
00542         # anything except None or unicode raises TypeError
00543         py.test.raises(TypeError, wikiutil.get_bool, self.request, True)
00544         py.test.raises(TypeError, wikiutil.get_bool, self.request, 42)
00545         py.test.raises(TypeError, wikiutil.get_bool, self.request, 42.0)
00546         py.test.raises(TypeError, wikiutil.get_bool, self.request, '')
00547         py.test.raises(TypeError, wikiutil.get_bool, self.request, tuple())
00548         py.test.raises(TypeError, wikiutil.get_bool, self.request, [])
00549         py.test.raises(TypeError, wikiutil.get_bool, self.request, {})
00550 
00551         # any value not convertable to boolean raises ValueError
00552         py.test.raises(ValueError, wikiutil.get_bool, self.request, u'')
00553         py.test.raises(ValueError, wikiutil.get_bool, self.request, u'42')
00554         py.test.raises(ValueError, wikiutil.get_bool, self.request, u'wrong')
00555         py.test.raises(ValueError, wikiutil.get_bool, self.request, u'"True"') # must not be quoted!
00556 
00557     def testGetInt(self):
00558         tests = [
00559             # default testing for None value
00560             (None, None, None, None),
00561             (None, None, -23, -23),
00562             (None, None, 42, 42),
00563 
00564             # some real values
00565             (u'0', None, None, 0),
00566             (u'42', None, None, 42),
00567             (u'-23', None, None, -23),
00568         ]
00569         for arg, name, default, expected in tests:
00570             assert wikiutil.get_int(self.request, arg, name, default) == expected
00571 
00572     def testGetIntRaising(self):
00573         # wrong default type
00574         py.test.raises(AssertionError, wikiutil.get_int, self.request, None, None, 42.23)
00575 
00576         # anything except None or unicode raises TypeError
00577         py.test.raises(TypeError, wikiutil.get_int, self.request, True)
00578         py.test.raises(TypeError, wikiutil.get_int, self.request, 42)
00579         py.test.raises(TypeError, wikiutil.get_int, self.request, 42.0)
00580         py.test.raises(TypeError, wikiutil.get_int, self.request, '')
00581         py.test.raises(TypeError, wikiutil.get_int, self.request, tuple())
00582         py.test.raises(TypeError, wikiutil.get_int, self.request, [])
00583         py.test.raises(TypeError, wikiutil.get_int, self.request, {})
00584 
00585         # any value not convertable to int raises ValueError
00586         py.test.raises(ValueError, wikiutil.get_int, self.request, u'')
00587         py.test.raises(ValueError, wikiutil.get_int, self.request, u'23.42')
00588         py.test.raises(ValueError, wikiutil.get_int, self.request, u'wrong')
00589         py.test.raises(ValueError, wikiutil.get_int, self.request, u'"4711"') # must not be quoted!
00590 
00591     def testGetFloat(self):
00592         tests = [
00593             # default testing for None value
00594             (None, None, None, None),
00595             (None, None, -23.42, -23.42),
00596             (None, None, 42.23, 42.23),
00597 
00598             # some real values
00599             (u'0', None, None, 0),
00600             (u'42.23', None, None, 42.23),
00601             (u'-23.42', None, None, -23.42),
00602             (u'-23.42E3', None, None, -23.42E3),
00603             (u'23.42E-3', None, None, 23.42E-3),
00604         ]
00605         for arg, name, default, expected in tests:
00606             assert wikiutil.get_float(self.request, arg, name, default) == expected
00607 
00608     def testGetFloatRaising(self):
00609         # wrong default type
00610         py.test.raises(AssertionError, wikiutil.get_float, self.request, None, None, u'42')
00611 
00612         # anything except None or unicode raises TypeError
00613         py.test.raises(TypeError, wikiutil.get_float, self.request, True)
00614         py.test.raises(TypeError, wikiutil.get_float, self.request, 42)
00615         py.test.raises(TypeError, wikiutil.get_float, self.request, 42.0)
00616         py.test.raises(TypeError, wikiutil.get_float, self.request, '')
00617         py.test.raises(TypeError, wikiutil.get_float, self.request, tuple())
00618         py.test.raises(TypeError, wikiutil.get_float, self.request, [])
00619         py.test.raises(TypeError, wikiutil.get_float, self.request, {})
00620 
00621         # any value not convertable to int raises ValueError
00622         py.test.raises(ValueError, wikiutil.get_float, self.request, u'')
00623         py.test.raises(ValueError, wikiutil.get_float, self.request, u'wrong')
00624         py.test.raises(ValueError, wikiutil.get_float, self.request, u'"47.11"') # must not be quoted!
00625 
00626     def testGetComplex(self):
00627         tests = [
00628             # default testing for None value
00629             (None, None, None, None),
00630             (None, None, -23.42, -23.42),
00631             (None, None, 42.23, 42.23),
00632 
00633             # some real values
00634             (u'0', None, None, 0),
00635             (u'42.23', None, None, 42.23),
00636             (u'-23.42', None, None, -23.42),
00637             (u'-23.42E3', None, None, -23.42E3),
00638             (u'23.42E-3', None, None, 23.42E-3),
00639             (u'23.42E-3+3.04j', None, None, 23.42E-3+3.04j),
00640             (u'3.04j', None, None, 3.04j),
00641             (u'-3.04j', None, None, -3.04j),
00642             (u'23.42E-3+3.04i', None, None, 23.42E-3+3.04j),
00643             (u'3.04i', None, None, 3.04j),
00644             (u'-3.04i', None, None, -3.04j),
00645             (u'-3', None, None, -3L),
00646             (u'-300000000000000000000', None, None, -300000000000000000000L),
00647         ]
00648         for arg, name, default, expected in tests:
00649             assert wikiutil.get_complex(self.request, arg, name, default) == expected
00650 
00651     def testGetComplexRaising(self):
00652         # wrong default type
00653         py.test.raises(AssertionError, wikiutil.get_complex, self.request, None, None, u'42')
00654 
00655         # anything except None or unicode raises TypeError
00656         py.test.raises(TypeError, wikiutil.get_complex, self.request, True)
00657         py.test.raises(TypeError, wikiutil.get_complex, self.request, 42)
00658         py.test.raises(TypeError, wikiutil.get_complex, self.request, 42.0)
00659         py.test.raises(TypeError, wikiutil.get_complex, self.request, 3j)
00660         py.test.raises(TypeError, wikiutil.get_complex, self.request, '')
00661         py.test.raises(TypeError, wikiutil.get_complex, self.request, tuple())
00662         py.test.raises(TypeError, wikiutil.get_complex, self.request, [])
00663         py.test.raises(TypeError, wikiutil.get_complex, self.request, {})
00664 
00665         # any value not convertable to int raises ValueError
00666         py.test.raises(ValueError, wikiutil.get_complex, self.request, u'')
00667         py.test.raises(ValueError, wikiutil.get_complex, self.request, u'3jj')
00668         py.test.raises(ValueError, wikiutil.get_complex, self.request, u'3Ij')
00669         py.test.raises(ValueError, wikiutil.get_complex, self.request, u'3i-3i')
00670         py.test.raises(ValueError, wikiutil.get_complex, self.request, u'wrong')
00671         py.test.raises(ValueError, wikiutil.get_complex, self.request, u'"47.11"') # must not be quoted!
00672 
00673     def testGetUnicode(self):
00674         tests = [
00675             # default testing for None value
00676             (None, None, None, None),
00677             (None, None, u'', u''),
00678             (None, None, u'abc', u'abc'),
00679 
00680             # some real values
00681             (u'', None, None, u''),
00682             (u'abc', None, None, u'abc'),
00683             (u'"abc"', None, None, u'"abc"'),
00684         ]
00685         for arg, name, default, expected in tests:
00686             assert wikiutil.get_unicode(self.request, arg, name, default) == expected
00687 
00688     def testGetUnicodeRaising(self):
00689         # wrong default type
00690         py.test.raises(AssertionError, wikiutil.get_unicode, self.request, None, None, 42)
00691 
00692         # anything except None or unicode raises TypeError
00693         py.test.raises(TypeError, wikiutil.get_unicode, self.request, True)
00694         py.test.raises(TypeError, wikiutil.get_unicode, self.request, 42)
00695         py.test.raises(TypeError, wikiutil.get_unicode, self.request, 42.0)
00696         py.test.raises(TypeError, wikiutil.get_unicode, self.request, '')
00697         py.test.raises(TypeError, wikiutil.get_unicode, self.request, tuple())
00698         py.test.raises(TypeError, wikiutil.get_unicode, self.request, [])
00699         py.test.raises(TypeError, wikiutil.get_unicode, self.request, {})
00700 
00701 
00702 class TestExtensionInvoking:
00703     def _test_invoke_bool(self, b=bool):
00704         assert b is False
00705 
00706     def _test_invoke_bool_def(self, v=bool, b=False):
00707         assert b == v
00708         assert isinstance(b, bool)
00709         assert isinstance(v, bool)
00710 
00711     def _test_invoke_int_None(self, i=int):
00712         assert i == 1 or i is None
00713 
00714     def _test_invoke_float_None(self, i=float):
00715         assert i == 1.4 or i is None
00716 
00717     def _test_invoke_float_required(self, i=wikiutil.required_arg(float)):
00718         assert i == 1.4
00719 
00720     def _test_invoke_choice(self, a, choice=[u'a', u'b', u'c']):
00721         assert a == 7
00722         assert choice == u'a'
00723 
00724     def _test_invoke_choicet(self, a, choice=(u'a', u'b', u'c')):
00725         assert a == 7
00726         assert choice == u'a'
00727 
00728     def _test_invoke_choice_required(self, i=wikiutil.required_arg((u'b', u'a'))):
00729         assert i == u'a'
00730 
00731     def _test_trailing(self, a, _trailing_args=[]):
00732         assert _trailing_args == [u'a']
00733 
00734     def _test_arbitrary_kw(self, expect, _kwargs={}):
00735         assert _kwargs == expect
00736 
00737     def testInvoke(self):
00738         def _test_invoke_int(i=int):
00739             assert i == 1
00740 
00741         def _test_invoke_int_fixed(a, b, i=int):
00742             assert a == 7
00743             assert b == 8
00744             assert i == 1 or i is None
00745 
00746         ief = wikiutil.invoke_extension_function
00747         ief(self.request, self._test_invoke_bool, u'False')
00748         ief(self.request, self._test_invoke_bool, u'b=False')
00749         ief(self.request, _test_invoke_int, u'1')
00750         ief(self.request, _test_invoke_int, u'i=1')
00751         ief(self.request, self._test_invoke_bool_def, u'False, False')
00752         ief(self.request, self._test_invoke_bool_def, u'b=False, v=False')
00753         ief(self.request, self._test_invoke_bool_def, u'False')
00754         ief(self.request, self._test_invoke_int_None, u'i=1')
00755         ief(self.request, self._test_invoke_int_None, u'i=')
00756         ief(self.request, self._test_invoke_int_None, u'')
00757         py.test.raises(ValueError, ief, self.request,
00758                        self._test_invoke_int_None, u'x')
00759         py.test.raises(ValueError, ief, self.request,
00760                        self._test_invoke_int_None, u'""')
00761         py.test.raises(ValueError, ief, self.request,
00762                        self._test_invoke_int_None, u'i=""')
00763         py.test.raises(ValueError, ief, self.request,
00764                        _test_invoke_int_fixed, u'a=7', [7, 8])
00765         ief(self.request, _test_invoke_int_fixed, u'i=1', [7, 8])
00766         py.test.raises(ValueError, ief, self.request,
00767                        _test_invoke_int_fixed, u'i=""', [7, 8])
00768         ief(self.request, _test_invoke_int_fixed, u'i=', [7, 8])
00769 
00770         for choicefn in (self._test_invoke_choice, self._test_invoke_choicet):
00771             ief(self.request, choicefn, u'', [7])
00772             ief(self.request, choicefn, u'choice=a', [7])
00773             ief(self.request, choicefn, u'choice=', [7])
00774             ief(self.request, choicefn, u'choice="a"', [7])
00775             py.test.raises(ValueError, ief, self.request,
00776                            choicefn, u'x', [7])
00777             py.test.raises(ValueError, ief, self.request,
00778                            choicefn, u'choice=x', [7])
00779 
00780         ief(self.request, self._test_invoke_float_None, u'i=1.4')
00781         ief(self.request, self._test_invoke_float_None, u'i=')
00782         ief(self.request, self._test_invoke_float_None, u'')
00783         ief(self.request, self._test_invoke_float_None, u'1.4')
00784         py.test.raises(ValueError, ief, self.request,
00785                        self._test_invoke_float_None, u'x')
00786         py.test.raises(ValueError, ief, self.request,
00787                        self._test_invoke_float_None, u'""')
00788         py.test.raises(ValueError, ief, self.request,
00789                        self._test_invoke_float_None, u'i=""')
00790         ief(self.request, self._test_trailing, u'a=7, a')
00791         ief(self.request, self._test_trailing, u'7, a')
00792         ief(self.request, self._test_arbitrary_kw, u'test=x, \xc3=test',
00793             [{u'\xc3': 'test', 'test': u'x'}])
00794         ief(self.request, self._test_arbitrary_kw, u'test=x, "\xc3"=test',
00795             [{u'\xc3': 'test', 'test': u'x'}])
00796         ief(self.request, self._test_arbitrary_kw, u'test=x, "7 \xc3"=test',
00797             [{u'7 \xc3': 'test', 'test': u'x'}])
00798         ief(self.request, self._test_arbitrary_kw, u'test=x, 7 \xc3=test',
00799             [{u'7 \xc3': 'test', 'test': u'x'}])
00800         ief(self.request, self._test_arbitrary_kw, u'7 \xc3=test, test= x ',
00801             [{u'7 \xc3': 'test', 'test': u'x'}])
00802         py.test.raises(ValueError, ief, self.request,
00803                        self._test_invoke_float_required, u'')
00804         ief(self.request, self._test_invoke_float_required, u'1.4')
00805         ief(self.request, self._test_invoke_float_required, u'i=1.4')
00806         py.test.raises(ValueError, ief, self.request,
00807                        self._test_invoke_choice_required, u'')
00808         ief(self.request, self._test_invoke_choice_required, u'a')
00809         ief(self.request, self._test_invoke_choice_required, u'i=a')
00810         py.test.raises(ValueError, ief, self.request,
00811                        self._test_invoke_float_required, u',')
00812 
00813     def testConstructors(self):
00814         ief = wikiutil.invoke_extension_function
00815 
00816         # new style class
00817         class TEST1(object):
00818             def __init__(self, a=int):
00819                 self.constructed = True
00820                 assert a == 7
00821 
00822         class TEST2(TEST1):
00823             pass
00824 
00825         obj = ief(self.request, TEST1, u'a=7')
00826         assert isinstance(obj, TEST1)
00827         assert obj.constructed
00828         py.test.raises(ValueError, ief, self.request, TEST1, u'b')
00829 
00830         obj = ief(self.request, TEST2, u'a=7')
00831         assert isinstance(obj, TEST1)
00832         assert isinstance(obj, TEST2)
00833         assert obj.constructed
00834         py.test.raises(ValueError, ief, self.request, TEST2, u'b')
00835 
00836         # old style class
00837         class TEST3:
00838             def __init__(self, a=int):
00839                 self.constructed = True
00840                 assert a == 7
00841 
00842         class TEST4(TEST3):
00843             pass
00844 
00845         obj = ief(self.request, TEST3, u'a=7')
00846         assert isinstance(obj, TEST3)
00847         assert obj.constructed
00848         py.test.raises(ValueError, ief, self.request, TEST3, u'b')
00849 
00850         obj = ief(self.request, TEST4, u'a=7')
00851         assert isinstance(obj, TEST3)
00852         assert isinstance(obj, TEST4)
00853         assert obj.constructed
00854         py.test.raises(ValueError, ief, self.request, TEST4, u'b')
00855 
00856     def testFailing(self):
00857         ief = wikiutil.invoke_extension_function
00858 
00859         py.test.raises(TypeError, ief, self.request, hex, u'15')
00860         py.test.raises(TypeError, ief, self.request, cmp, u'15')
00861         py.test.raises(AttributeError, ief, self.request, unicode, u'15')
00862 
00863     def testAllDefault(self):
00864         ief = wikiutil.invoke_extension_function
00865 
00866         def has_many_defaults(a=1, b=2, c=3, d=4):
00867             assert a == 1
00868             assert b == 2
00869             assert c == 3
00870             assert d == 4
00871             return True
00872 
00873         assert ief(self.request, has_many_defaults, u'1, 2, 3, 4')
00874         assert ief(self.request, has_many_defaults, u'2, 3, 4', [1])
00875         assert ief(self.request, has_many_defaults, u'3, 4', [1, 2])
00876         assert ief(self.request, has_many_defaults, u'4', [1, 2, 3])
00877         assert ief(self.request, has_many_defaults, u'', [1, 2, 3, 4])
00878         assert ief(self.request, has_many_defaults, u'd=4,c=3,b=2,a=1')
00879         assert ief(self.request, has_many_defaults, u'd=4,c=3,b=2', [1])
00880         assert ief(self.request, has_many_defaults, u'd=4,c=3', [1, 2])
00881         assert ief(self.request, has_many_defaults, u'd=4', [1, 2, 3])
00882 
00883     def testInvokeComplex(self):
00884         ief = wikiutil.invoke_extension_function
00885 
00886         def has_complex(a=complex, b=complex):
00887             assert a == b
00888             return True
00889 
00890         assert ief(self.request, has_complex, u'3-3i, 3-3j')
00891         assert ief(self.request, has_complex, u'2i, 2j')
00892         assert ief(self.request, has_complex, u'b=2i, a=2j')
00893         assert ief(self.request, has_complex, u'2.007, 2.007')
00894         assert ief(self.request, has_complex, u'2.007', [2.007])
00895         assert ief(self.request, has_complex, u'b=2.007', [2.007])
00896 
00897 
00898 class TestAnchorNames:
00899     def test_anchor_name_encoding(self):
00900         tests = [
00901             # text                    expected output
00902             (u'\xf6\xf6ll\xdf\xdf',   'A.2BAPYA9g-ll.2BAN8A3w-'),
00903             (u'level 2',              'level_2'),
00904             (u'level_2',              'level_2'),
00905             (u'',                     'A'),
00906             (u'123',                  'A123'),
00907             # make sure that a valid anchor is not modified:
00908             (u'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789:_.-',
00909              u'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789:_.-')
00910         ]
00911         for text, expected in tests:
00912             yield self._check, text, expected
00913 
00914     def _check(self, text, expected):
00915         encoded = wikiutil.anchor_name_from_text(text)
00916         assert expected == encoded
00917 
00918 class TestPageLinkMarkup:
00919     def test_pagelinkmarkup(self):
00920         tests = [
00921             # pagename (no link text), expected markup
00922             (('SomePage', ), 'SomePage'),
00923             (('Somepage', ), '[[Somepage]]'),
00924             (('somepage', ), '[[somepage]]'),
00925             (('Some Page', ), '[[Some Page]]'),
00926             # with link text
00927             (('SomePage', 'SomePage'), 'SomePage'),
00928             (('SomePage', 'some page'), '[[SomePage|some page]]'),
00929             (('Some Page', 'Some Page'), '[[Some Page]]'),
00930             (('Some Page', 'some Page'), '[[Some Page|some Page]]'),
00931         ]
00932         for params, expected in tests:
00933             yield self._check, params, expected
00934 
00935     def _check(self, params, expected):
00936         assert expected == wikiutil.pagelinkmarkup(*params)
00937 
00938 class TestRelativeTools:
00939     tests = [
00940         # test                      expected output
00941         # CHILD_PREFIX
00942         (('MainPage', '/SubPage1'), 'MainPage/SubPage1'),
00943         (('MainPage', '/SubPage1/SubPage2'), 'MainPage/SubPage1/SubPage2'),
00944         (('MainPage/SubPage1', '/SubPage2/SubPage3'), 'MainPage/SubPage1/SubPage2/SubPage3'),
00945         (('', '/OtherMainPage'), 'OtherMainPage'), # strange
00946         # PARENT_PREFIX
00947         (('MainPage/SubPage', '../SisterPage'), 'MainPage/SisterPage'),
00948         (('MainPage/SubPage1/SubPage2', '../SisterPage'), 'MainPage/SubPage1/SisterPage'),
00949         (('MainPage/SubPage1/SubPage2', '../../SisterPage'), 'MainPage/SisterPage'),
00950         (('MainPage', '../SisterPage'), 'SisterPage'), # strange
00951     ]
00952     def test_abs_pagename(self):
00953         for (current_page, relative_page), absolute_page in self.tests:
00954             yield self._check_abs_pagename, current_page, relative_page, absolute_page
00955 
00956     def _check_abs_pagename(self, current_page, relative_page, absolute_page):
00957         assert absolute_page == wikiutil.AbsPageName(current_page, relative_page)
00958 
00959     def test_rel_pagename(self):
00960         for (current_page, relative_page), absolute_page in self.tests:
00961             yield self._check_rel_pagename, current_page, absolute_page, relative_page
00962 
00963     def _check_rel_pagename(self, current_page, absolute_page, relative_page):
00964         assert relative_page == wikiutil.RelPageName(current_page, absolute_page)
00965 
00966 
00967 class TestNormalizePagename(object):
00968 
00969     def testPageInvalidChars(self):
00970         """ request: normalize pagename: remove invalid unicode chars
00971 
00972         Assume the default setting
00973         """
00974         test = u'\u0000\u202a\u202b\u202c\u202d\u202e'
00975         expected = u''
00976         result = wikiutil.normalize_pagename(test, self.request.cfg)
00977         assert result == expected
00978 
00979     def testNormalizeSlashes(self):
00980         """ request: normalize pagename: normalize slashes """
00981         cases = (
00982             (u'/////', u''),
00983             (u'/a', u'a'),
00984             (u'a/', u'a'),
00985             (u'a/////b/////c', u'a/b/c'),
00986             (u'a b/////c d/////e f', u'a b/c d/e f'),
00987             )
00988         for test, expected in cases:
00989             result = wikiutil.normalize_pagename(test, self.request.cfg)
00990             assert result == expected
00991 
00992     def testNormalizeWhitespace(self):
00993         """ request: normalize pagename: normalize whitespace """
00994         cases = (
00995             (u'         ', u''),
00996             (u'    a', u'a'),
00997             (u'a    ', u'a'),
00998             (u'a     b     c', u'a b c'),
00999             (u'a   b  /  c    d  /  e   f', u'a b/c d/e f'),
01000             # All 30 unicode spaces
01001             (config.chars_spaces, u''),
01002             )
01003         for test, expected in cases:
01004             result = wikiutil.normalize_pagename(test, self.request.cfg)
01005             assert result == expected
01006 
01007     def testUnderscoreTestCase(self):
01008         """ request: normalize pagename: underscore convert to spaces and normalized
01009 
01010         Underscores should convert to spaces, then spaces should be
01011         normalized, order is important!
01012         """
01013         cases = (
01014             (u'         ', u''),
01015             (u'  a', u'a'),
01016             (u'a  ', u'a'),
01017             (u'a  b  c', u'a b c'),
01018             (u'a  b  /  c  d  /  e  f', u'a b/c d/e f'),
01019             )
01020         for test, expected in cases:
01021             result = wikiutil.normalize_pagename(test, self.request.cfg)
01022             assert result == expected
01023 
01024 class TestGroupPages(object):
01025 
01026     def testNormalizeGroupName(self):
01027         """ request: normalize pagename: restrict groups to alpha numeric Unicode
01028 
01029         Spaces should normalize after invalid chars removed!
01030         """
01031         cases = (
01032             # current acl chars
01033             (u'Name,:Group', u'NameGroup'),
01034             # remove than normalize spaces
01035             (u'Name ! @ # $ % ^ & * ( ) + Group', u'Name Group'),
01036             )
01037         for test, expected in cases:
01038             # validate we are testing valid group names
01039             if wikiutil.isGroupPage(test, self.request.cfg):
01040                 result = wikiutil.normalize_pagename(test, self.request.cfg)
01041                 assert result == expected
01042 
01043 class TestVersion(object):
01044     def test_Version(self):
01045         Version = wikiutil.Version
01046         # test properties
01047         assert Version(1, 2, 3).major == 1
01048         assert Version(1, 2, 3).minor == 2
01049         assert Version(1, 2, 3).release == 3
01050         assert Version(1, 2, 3, '4.5alpha6').additional == '4.5alpha6'
01051         # test Version init and Version to str conversion
01052         assert str(Version(1)) == "1.0.0"
01053         assert str(Version(1, 2)) == "1.2.0"
01054         assert str(Version(1, 2, 3)) == "1.2.3"
01055         assert str(Version(1, 2, 3, '4.5alpha6')) == "1.2.3-4.5alpha6"
01056         assert str(Version(version='1.2.3')) == "1.2.3"
01057         assert str(Version(version='1.2.3-4.5alpha6')) == "1.2.3-4.5alpha6"
01058         # test Version comparison, trivial cases
01059         assert Version() == Version()
01060         assert Version(1) == Version(1)
01061         assert Version(1, 2) == Version(1, 2)
01062         assert Version(1, 2, 3) == Version(1, 2, 3)
01063         assert Version(1, 2, 3, 'foo') == Version(1, 2, 3, 'foo')
01064         assert Version(1) != Version(2)
01065         assert Version(1, 2) != Version(1, 3)
01066         assert Version(1, 2, 3) != Version(1, 2, 4)
01067         assert Version(1, 2, 3, 'foo') != Version(1, 2, 3, 'bar')
01068         assert Version(1) < Version(2)
01069         assert Version(1, 2) < Version(1, 3)
01070         assert Version(1, 2, 3) < Version(1, 2, 4)
01071         assert Version(1, 2, 3, 'bar') < Version(1, 2, 3, 'foo')
01072         assert Version(2) > Version(1)
01073         assert Version(1, 3) > Version(1, 2)
01074         assert Version(1, 2, 4) > Version(1, 2, 3)
01075         assert Version(1, 2, 3, 'foo') > Version(1, 2, 3, 'bar')
01076         # test Version comparison, more delicate cases
01077         assert Version(1, 12) > Version(1, 9)
01078         assert Version(1, 12) > Version(1, 1, 2)
01079         assert Version(1, 0, 0, '0.0a2') > Version(1, 0, 0, '0.0a1')
01080         assert Version(1, 0, 0, '0.0b1') > Version(1, 0, 0, '0.0a9')
01081         assert Version(1, 0, 0, '0.0b2') > Version(1, 0, 0, '0.0b1')
01082         assert Version(1, 0, 0, '0.0c1') > Version(1, 0, 0, '0.0b9')
01083         assert Version(1, 0, 0, '1') > Version(1, 0, 0, '0.0c9')
01084         # test Version playing nice with tuples
01085         assert Version(1, 2, 3) == (1, 2, 3, '')
01086         assert Version(1, 2, 4) > (1, 2, 3)
01087 
01088 
01089 coverage_modules = ['MoinMoin.wikiutil']
01090