Attachment 'name.py'
Download 1 # -*- coding: utf8 -*-
2 """
3 Normalize page names
4
5 See http://moinmoin.wikiwikiweb.de/MoinMoinBugs/CanCreateBadNames
6 """
7
8 import unittest
9
10 class InvalidPageNameError(Exception): pass
11
12
13 def normalizePageName(candidate):
14 """ Normalize page name
15
16 Normalaized page name contain only alpha numeric Unicode characters with
17 optional one space between words, and no empty path components.
18
19 Leading, traling or multiple spaces in names are considered a user error
20 and fixed quitely without any error mesages.
21
22 Empty path components are ignored just like the shell does.
23
24 @param candidate: Unicode string with candidate name
25 @return: normalized name
26 @rtype: Unicode string
27 """
28 # Validate input
29 if candidate == '':
30 raise InvalidPageNameError(candidate)
31
32 # Split sub pages and normalize each component
33 validComponents = []
34 pages = candidate.split('/')
35 for pageName in pages:
36 # Split words removing multiple white space between and around words
37 pageWords = pageName.split()
38 # Ignore empty names in the path e.g. '/ /Name/' - > 'Name'
39 if not pageWords:
40 continue
41
42 for word in pageWords:
43 for character in word:
44 if not character.isalnum():
45 raise InvalidPageNameError(candidate)
46
47 # All words are valid, return valid name using one space between words
48 pageName = ' '.join(pageWords)
49 validComponents.append(pageName)
50
51 # Join normalized components
52 normalizedName = '/'.join(validComponents)
53
54 # Do not allow empty names after normalization
55 if normalizedName == '':
56 raise InvalidPageNameError(candidate)
57 return normalizedName
58
59
60 class ValidNamesTestCase(unittest.TestCase):
61
62 TESTS = (
63 # name, normalized name
64 # Remove empty components
65 (u'/Page////Page//', u'Page/Page'),
66 # Remove extra White Space
67 (u' Page \t Name / SubPage ', u'Page Name/SubPage'),
68 # German umlauts
69 (u'Jürgen Hermann', u'Jürgen Hermann'),
70 # Hebrew
71 (u'\u05d0\u05d1 \u05d2', u'\u05d0\u05d1 \u05d2'),
72 # Add more tests
73 )
74
75 def testNormalizePageName(self):
76 """ wikiutil: normalize page names """
77 for test, expected in self.TESTS:
78 result = normalizePageName(test)
79 self.failUnlessEqual(result, expected,
80 'expected "%(expected)s" but got "%(result)s"' % locals())
81
82
83 class InvalidNamesTestCase(unittest.TestCase):
84 TESTS = (
85 # Empty
86 u'',
87 # White Space only
88 u' \t\n ',
89 # Special Unicode white space
90 u' \u200f ',
91 # Sub pages with empty pages or white space
92 u'///', u' / / / / ', u'\u200f/ / '
93 # Non alpha numeric
94 u'.', u'-', u'|', u'%', u'&', u'?', u'@', u'!', u'$', u'*', u'(', u')',
95 u'<', u'>', u'\u202a',
96 # Mix
97 u'\u202a/ValidComponent',
98 # Add more tests
99 )
100
101 def testInvalidPageNames(self):
102 """ wikiutil: invalid page name raise exception """
103 for test in self.TESTS:
104 self.failUnlessRaises(InvalidPageNameError, normalizePageName, test)
105
106
107 if __name__ == '__main__':
108 suite = unittest.TestSuite()
109 suite.addTest(unittest.makeSuite(ValidNamesTestCase))
110 suite.addTest(unittest.makeSuite(InvalidNamesTestCase))
111 unittest.TextTestRunner(verbosity=2).run(suite)
112
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.