changeset 2400:0c56b1468e78

Merge main.
author Karol 'grzywacz' Nowak <grzywacz@sul.uni.lodz.pl>
date Sun, 15 Jul 2007 23:50:13 +0200
parents 245181ec9fe2 (current diff) a7f4b02f5fdb (diff)
children d2487ea5bcf2
files
diffstat 6 files changed, 70 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/_tests/test_sourcecode.py	Sun Jul 15 23:46:08 2007 +0200
+++ b/MoinMoin/_tests/test_sourcecode.py	Sun Jul 15 23:50:13 2007 +0200
@@ -8,7 +8,7 @@
 @license: MIT licensed
 """
 
-import os, re
+import os, re, time, stat
 
 import pep8
 
@@ -18,8 +18,11 @@
 
 EXCLUDE = [
     '/contrib/DesktopEdition/setup_py2exe.py', # has crlf
+    '/contrib/TWikiDrawPlugin', # 3rd party java stuff
     '/MoinMoin/support', # 3rd party libs or non-broken stdlib stuff
     '/wiki/htdocs/applets/FCKeditor', # 3rd party GUI editor
+    '/tests/wiki', # this is our test wiki
+    '/wiki/htdocs', # this is our dist static stuff
 ]
 
 TRAILING_SPACES = 'nochange' # 'nochange' or 'fix'
@@ -27,6 +30,14 @@
 FIX_TS_RE = re.compile(r' +$', re.M) # 'fix' mode: everything matching the trailing space re will be removed
 
 
+RECENTLY = time.time() - 7 * 24*60*60 # we only check stuff touched recently.
+# After doing a fresh clone, this procedure is recommended:
+# 1. Run the tests once to see if everything is OK (as cloning updates the mtime,
+#    it will test every file).
+# 2. Before starting to make new changes, use "touch" to change all timestamps
+#    to a time before <RECENTLY>.
+# 3. Regularly run the tests, they will run much faster now.
+
 def pep8_error_count(path):
     # process_options initializes some data structures and MUST be called before each Checker().check_all()
     pep8.process_options(['pep8', '--ignore=E202,E221,E222,E241,E301,E302,E401,E501,E701,W391,W601,W602', '--show-source', 'dummy_path'])
@@ -50,15 +61,18 @@
 def test_sourcecode():
     def walk(reldir):
         if reldir in EXCLUDE:
+            #print "Skippping %r..." % reldir
             return
         if reldir:
             path = os.path.join(ROOT, *reldir.split('/'))
         else:
             path = ROOT
-        if os.path.isfile(path):
-            if path.lower().endswith('.py'):
+        st = os.stat(path)
+        mode = st.st_mode
+        if stat.S_ISREG(mode): # is a regular file
+            if path.lower().endswith('.py') and st.st_mtime >= RECENTLY:
                 yield check_py_file, reldir, path
-        elif os.path.isdir(path):
+        elif stat.S_ISDIR(mode): # is a directory
             for entry in os.listdir(path):
                 if not entry.startswith('.'):
                     for _ in walk('%s/%s' % (reldir, entry)):
--- a/MoinMoin/_tests/test_wikiutil.py	Sun Jul 15 23:46:08 2007 +0200
+++ b/MoinMoin/_tests/test_wikiutil.py	Sun Jul 15 23:50:13 2007 +0200
@@ -66,10 +66,10 @@
 
 
 class TestNameQuoting:
-    tests = [(u"", u"''"), # empty
-             (u"test", u"'test'"), # nothing special
-             (u"Sarah O'Connor", u"\"Sarah O'Connor\""), # contains ', quote with "
-             (u'Just "something" quoted', u'\'Just "something" quoted\''), # contains ", quote with '
+    tests = [(u"", u'""'), # empty
+             (u"test", u'"test"'), # nothing special
+             (u"Sarah O'Connor", u"\"Sarah O'Connor\""),
+             (u'Just "something" quoted', u'"Just ""something"" quoted"'),
             ]
     def testQuoteName(self):
         for name, qname in self.tests:
@@ -85,7 +85,13 @@
         tests = [('SomePage', ('Self', 'SomePage', '')),
                  ('OtherWiki:OtherPage', ('OtherWiki', 'OtherPage', '')),
                  ('MoinMoin:"Page with blanks" link title', ("MoinMoin", "Page with blanks", "link title")),
-                 ("MoinMoin:'Page with blanks' link title", ("MoinMoin", "Page with blanks", "link title")),
+                 ('MoinMoin:"Page with blanks"link title', ("MoinMoin", "Page with blanks", "link title")),
+                 ('MoinMoin:"Page with blanks"', ("MoinMoin", "Page with blanks", "")),
+                 ('MoinMoin:"Page with ""quote""" link title', ("MoinMoin", 'Page with "quote"', "link title")),
+                 ('MoinMoin:"Page with """"double-quote"""link title', ("MoinMoin", 'Page with ""double-quote"', "link title")),
+                 ('MoinMoin:"""starts with quote"link title', ("MoinMoin", '"starts with quote', "link title")),
+                 ('MoinMoin:"ends with quote"""link title', ("MoinMoin", 'ends with quote"', "link title")),
+                 ('MoinMoin:"""page with quotes around"""link title', ("MoinMoin", '"page with quotes around"', "link title")),
                  ('attachment:"filename with blanks.txt" other title', ("attachment", "filename with blanks.txt", "other title")),
                 ]
         for markup, (wikiname, pagename, linktext) in tests:
--- a/MoinMoin/formatter/text_html.py	Sun Jul 15 23:46:08 2007 +0200
+++ b/MoinMoin/formatter/text_html.py	Sun Jul 15 23:50:13 2007 +0200
@@ -510,7 +510,8 @@
         """
         @keyword title: override using the interwiki wikiname as title
         """
-        wikitag, wikiurl, wikitail, wikitag_bad = wikiutil.resolve_wiki(self.request, '%s:"%s"' % (interwiki, pagename))
+        quoted = '%s:%s' % (interwiki, wikiutil.quoteName(pagename))
+        wikitag, wikiurl, wikitail, wikitag_bad = wikiutil.resolve_wiki(self.request, quoted)
         wikiurl = wikiutil.mapURL(self.request, wikiurl)
         if wikitag == 'Self': # for own wiki, do simple links
             if '#' in wikitail:
--- a/MoinMoin/parser/_tests/test_text_moin_wiki.py	Sun Jul 15 23:46:08 2007 +0200
+++ b/MoinMoin/parser/_tests/test_text_moin_wiki.py	Sun Jul 15 23:50:13 2007 +0200
@@ -586,11 +586,26 @@
         ('MoinMoin:"with space"',     '<a class="interwiki" href="http://moinmoin.wikiwikiweb.de/with%20space" title="MoinMoin">with space</a>'),
         ('RFC:"1 2 3"',               '<a class="interwiki" href="http://www.ietf.org/rfc/rfc1%202%203" title="RFC">1 2 3</a>'),
         ("RFC:'something else'",      "RFC:'something else'"),
+        ('["with "" quote"]',         '<a class="nonexistent" href="./with%20%22%20quote">with " quote</a>'),
+        ('MoinMoin:"with "" quote"',  '<a class="interwiki" href="http://moinmoin.wikiwikiweb.de/with%20%22%20quote" title="MoinMoin">with " quote</a>'),
         )
 
     def testTextFormating(self):
         """ parser.wiki: text formating """
+        together_test = []
+        together_expected = []
         for test, expected in self._tests:
             html = self.parse(self.text % test)
             result = self.needle.search(html).group(1)
             assert result == expected
+            together_test.append(test)
+            together_expected.append(expected)
+
+        # now test all together to make sure one quoting doesn't
+        # "leak" into the next
+        for joint in ('', 'lala " lala ', 'lala "" lala '):
+            test = joint.join(together_test)
+            expected = joint.join(together_expected)
+            html = self.parse(self.text % test)
+            result = self.needle.search(html).group(1)
+            assert result == expected
--- a/MoinMoin/parser/text_moin_wiki.py	Sun Jul 15 23:46:08 2007 +0200
+++ b/MoinMoin/parser/text_moin_wiki.py	Sun Jul 15 23:50:13 2007 +0200
@@ -33,9 +33,7 @@
     # quoted strings (we require that there is at least one char (that is not the quoting char)
     # inside to not confuse stuff like '''Contact:''' (just a bold Contact:) with interwiki markup
     # OtherWiki:'Page with blanks'
-    sq_string = ur"('[^']+?')" # single quoted string
-    dq_string = ur"(\"[^\"]+?\")" # double quoted string
-    q_string = ur"(%s|%s)" % (sq_string, dq_string) # quoted string
+    dq_string = ur'("([^"]|"")+?"(?!"))' # double quoted string
     attachment_schemas = ["attachment", "inline", "drawing"]
     punct_pattern = re.escape(u'''"\'}]|:,.)?!''')
     punct_no_quote_pattern = re.escape(u'''}]|:,.)?!''')
@@ -50,12 +48,12 @@
         'subpages': wikiutil.CHILD_PREFIX + '?',
         'parent': ur'(?:%s)?' % re.escape(PARENT_PREFIX),
     }
-    url_rule = ur'%(url_guard)s(%(url)s)\:(([^\s\<%(punct)s]|([%(punctnq)s][^\s\<%(punct)s]))+|%(q_string)s)' % {
+    url_rule = ur'%(url_guard)s(%(url)s)\:(([^\s\<%(punct)s]|([%(punctnq)s][^\s\<%(punct)s]))+|%(dq_string)s)' % {
         'url_guard': ur'(^|(?<!\w))',
         'url': url_pattern,
         'punct': punct_pattern,
         'punctnq': punct_no_quote_pattern,
-        'q_string': q_string,
+        'dq_string': dq_string,
     }
 
     ol_rule = ur"^\s+(?:[0-9]+|[aAiI])\.(?:#\d+)?\s"
@@ -405,16 +403,10 @@
 
     def _wikiname_bracket_repl(self, text):
         """Handle special-char wikinames with link text, like:
-           ["Jim O'Brian" Jim's home page] or ['Hello "world"!' a page with doublequotes]i
+           ["Jim O'Brian" Jim's home page] or ["Hello ""world""!" a page with doublequotes]
         """
         word = text[1:-1] # strip brackets
-        first_char = word[0]
-        if first_char in wikiutil.QUOTE_CHARS:
-            # split on closing quote
-            target, linktext = word[1:].split(first_char, 1)
-        else: # not quoted
-            # split on whitespace
-            target, linktext = word.split(None, 1)
+        empty, target, linktext = wikiutil.split_wiki(':%s' % word)
         if target:
             linktext = linktext.strip()
             return self._word_repl(target, linktext)
--- a/MoinMoin/wikiutil.py	Sun Jul 15 23:46:08 2007 +0200
+++ b/MoinMoin/wikiutil.py	Sun Jul 15 23:50:13 2007 +0200
@@ -482,23 +482,19 @@
 
 # Quoting of wiki names, file names, etc. (in the wiki markup) -----------------------------------
 
+# don't ever change this
 QUOTE_CHARS = u'"'
 
 def quoteName(name):
     """ put quotes around a given name """
-    for quote_char in QUOTE_CHARS:
-        if quote_char not in name:
-            return u"%s%s%s" % (quote_char, name, quote_char)
-    else:
-        return name # XXX we need to be able to escape the quote char for worst case
+    return '"%s"' % name.replace('"', '""')
 
 def unquoteName(name):
     """ if there are quotes around the name, strip them """
     if not name:
         return name
-    for quote_char in QUOTE_CHARS:
-        if quote_char == name[0] == name[-1]:
-            return name[1:-1]
+    if '"' == name[0] == name[-1]:
+        return name[1:-1].replace('""', '"')
     else:
         return name
 
@@ -610,9 +606,21 @@
         except ValueError:
             wikiname, rest = 'Self', wikiurl
     if rest:
-        first_char = rest[0]
-        if first_char in QUOTE_CHARS: # quoted pagename
-            pagename_linktext = rest[1:].split(first_char, 1)
+        if rest[0] == '"': # quoted pagename
+            idx = 1
+            max = len(rest)
+            while idx < max:
+                if idx + 1 < max:
+                    next = rest[idx + 1]
+                else:
+                    next = None
+                if next == rest[idx] == '"':
+                    idx += 2
+                    continue
+                if next != '"' and rest[idx] == '"':
+                    break
+                idx += 1
+            pagename_linktext = rest[1:idx].replace('""', '"'), rest[idx+1:]
         else: # not quoted, split on whitespace
             pagename_linktext = rest.split(None, 1)
     else: