[py-svn] r21180 - in py/dist/py/rest: . testing

jan at codespeak.net jan at codespeak.net
Thu Dec 15 15:57:44 CET 2005


Author: jan
Date: Thu Dec 15 15:57:42 2005
New Revision: 21180

Modified:
   py/dist/py/rest/rst.py
   py/dist/py/rest/testing/test_rst.py
Log:
more ReST tags



Modified: py/dist/py/rest/rst.py
==============================================================================
--- py/dist/py/rest/rst.py	(original)
+++ py/dist/py/rest/rst.py	Thu Dec 15 15:57:42 2005
@@ -1,9 +1,8 @@
 import py
 from py.xml import Namespace, Tag
-from py.__.xmlobj.visit import SimpleUnicodeVisitor
-from py.__.xmlobj.html import HtmlVisitor
+#from py.__.xmlobj.visit import SimpleUnicodeVisitor
+#from py.__.xmlobj.html import HtmlVisitor
 
-import textwrap
 
 def itertext(text):
     """ Generator: like string.split, but ''.join(itertext(t)) == t
@@ -68,13 +67,15 @@
                    line and not line[-1].isspace():
                 line += w
                 continue
+            if not line and w == ' '*len(w):
+                continue
             if len(line) + len(w) > self.width:
                 if line != '':
                     self.lines.append(line)
                 line = w.lstrip()
                 continue
             line += w
-                
+
         self.lines.append(line)
         return self   
     
@@ -93,11 +94,11 @@
         self.write_literal(join.join(
             [indent + line
              for line in out.render().splitlines(keepends)]))
-        #self.write_literal(indent + line)
 
     def extend(self, out_list, indent = '', infix = ' ',
                join = '', literal = False):
         l = list(out_list)
+        if not l: return
         for out in l[:-1]:
             self.append(out, indent, join=join)
             self.write(infix, literal=literal)
@@ -109,10 +110,12 @@
     def render(self):
         return '\n'.join(self.lines)
 
+
 class RestTag(Tag):
     start_string = ''
     end_string = ''
     sep = ''
+    write_literal = False
     
     def __init__(self, *args, **kwargs):
         super(RestTag, self).__init__(*args, **kwargs)
@@ -143,18 +146,47 @@
             if isinstance(child, RestTag):
                 child.__rest__(child_out)
             else:
-                child_out.write(child)
+                child_out.write(child, literal = self.write_literal)
             outs.append(child_out)
         return outs
 
+class DirectiveMetaclass(type): 
+    def __getattr__(self, name): 
+        if name[:1] == '_': 
+            raise AttributeError(name)
+        # convert '_' to '-'
+        name = name.replace('_','-')
+        classattr = {'name': name}
+        cls = type(name, (self.__tagclass__,), classattr) 
+        setattr(self, name, cls) 
+        return cls 
+
+class UniversalDirective(RestTag):
+    sep = '\n\n'
+    start_string = '.. '
+
+    def write_children(self, out, child_outs):
+        out.write(self.name)
+        out.write(':: ')
+        out.writeln(child_outs[0].render())
+        keys = [attr for attr in dir(self.attr) if not attr.startswith('__')]
+        keys.sort()
+        for key in keys:
+            value = str(getattr(self.attr, key))
+            out.write_literal(' ' * len(self.start_string) +':%s: %s\n' \
+                              % (key,value))
+            
+        if len(child_outs) > 1:
+            # directive block
+            out.writeln(' ' * len(self.start_string))
+            out.extend(child_outs[1:], indent = ' ' * len(self.start_string))
+    
+
 
 class rest(Namespace):
     __tagclass__ = RestTag
     __stickname__ = True
 
-    class paragraph(RestTag):
-        sep = '\n\n'
-
     class emph(RestTag):
         start_string = '*'
         end_string = start_string
@@ -177,6 +209,9 @@
             if self.role:
                 self.start_string = ':%s:%s' % (self.role, self.start_string)
 
+    class paragraph(RestTag):
+        sep = '\n\n'
+
     class explicit_markup(RestTag):
         sep = '\n\n'
         start_string = '.. '
@@ -210,7 +245,7 @@
 
         def parse_options(self, attr):
             self.start_string = getattr(attr, 'bullet', '*') + ' '
-            if  getattr(attr, 'enumerate', False):
+            if  getattr(attr, 'auto_enumerate', False):
                 self.start_string = '#. '
             
         def write_children(self, out, child_outs):
@@ -222,9 +257,16 @@
         indent = '  '
         quote = '  '
         quotes = """! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ ` { | } ~""".split() + [' ']
+        write_literal = True
         
         def parse_options(self, attr):
             self.quote = getattr(attr, 'quote', '  ')
 
         def write_children(self, out, child_outs):
-            out.extend(child_outs, indent = self.quote)
+            out.extend(child_outs, indent = self.quote, infix ='', literal = True)
+
+    unidirective = UniversalDirective
+
+    class directive:
+        __metaclass__ = DirectiveMetaclass
+        __tagclass__ = UniversalDirective

Modified: py/dist/py/rest/testing/test_rst.py
==============================================================================
--- py/dist/py/rest/testing/test_rst.py	(original)
+++ py/dist/py/rest/testing/test_rst.py	Thu Dec 15 15:57:42 2005
@@ -6,6 +6,7 @@
 #temp = py.path.local.mkdtemp()
 
 def check_rest(content, include_dir = None):
+    " try to convert content to html "
     if isinstance(content, RestTag):
         content = content.text()
     content = unicode(content)
@@ -27,8 +28,17 @@
     return True
 
 def render_xml(arg):
+    'try to generate a xml representation of arg'
     return arg.unicode()
 
+def strip_lines(line_list):
+    'filter line_list and remove trailing whitespaces'
+    return [line.rstrip() for line in line_list if line.strip()]
+
+def print_lines(line_list):
+    'pretty print line_list'
+    py.std.pprint.pprint(strip_lines(line_list))
+
 class TestSplit:
 
     def test_empyt_string(self):
@@ -131,6 +141,12 @@
 
         assert len(root_out.lines) == 2
 
+    def test_extend_empty_list(self):
+        out = Out()
+        text = out.render()
+        out.extend([])
+        assert text == out.render()
+
     def test_max_length(self):
         out = Out()
         out.write('1234567890')
@@ -144,7 +160,10 @@
     def setup_method(self, method):
         self.text = {}
 
-        self.text['paragraph'] = "Paragraphs consist of blocks of left-aligned text with no markup indicating any other body element. Blank lines separate paragraphs from each other and from other body elements. Paragraphs may contain inline markup."
+        self.text['paragraph'] = "Paragraphs consist of blocks of "
+        "left-aligned text with no markup indicating any other body "
+        "element. Blank lines separate paragraphs from each other and "
+        "from other body elements. Paragraphs may contain inline markup."
        
     def test_paragraph(self):
         para = rest.paragraph(self.text['paragraph'])
@@ -154,22 +173,29 @@
         assert text[0] == '\n'
         assert text[-1] == '\n'
         
+    def test_paragraph_with_whitespaces(self):
+        phrase =  "Perhaps if we wrote                 programs from "
+        "childhood on, as                 adults                     "
+        "               we'd be able to read them."
+        para = rest.paragraph(phrase)
+        check_rest(para)
+        assert True not in [line.startswith(' ') for line in para.text().splitlines()]
+        
     def test_emph(self):
         emph = rest.emph('strong')
         assert emph.text() == '*strong*'
         assert check_rest(emph.text())
 
-    def test_add_whitespace(self):
+    def test_paragraph_adds_whitespace(self):
         para = rest.paragraph('Starttext', rest.emph('EMPHASIS'), 'endtext')
-        assert para.text() == '\n\nStarttext *EMPHASIS* endtext\n\n'
+        assert para.text() == para.sep +'Starttext *EMPHASIS* endtext'+ para.sep
 
     def test_nested_emph(self):
-        "Nested Inline Markup not allowed in ReST"
+        "Nested Inline Markup not allowed in ReST, don't try at home ;-)"
         emph = rest.emph('start', rest.emph('middle'), 'end')
         check_rest(emph.text())
         assert emph.text() == '*start *middle* end*'
     
-
     def test_strongemph(self):
         phrase = 'failure is not an option'
         emph = rest.strongemph(phrase)
@@ -192,10 +218,6 @@
 ##     assert check_rest(subtitle)
     
 
-    def test_paragraph(self):
-        phrase =  "Perhaps if we wrote programs from childhood on, as adults we'd be able to read them."
-        para = rest.paragraph(phrase)
-        assert check_rest(para)
 
     def test_list_item(self):
         item_text = 'A short item.'
@@ -207,8 +229,12 @@
     def test_list_item_multiline(self):
         item_text = '01234567890 1234567890'
         item = rest.list_item(item_text)
-        assert len(item.text(width=15).splitlines()) == 5
-        check_rest(item.text(width=15))
+        text = item.text(width = 15)
+        assert len([l for l in text.splitlines() if l.strip()]) == 2
+        check_rest(text)
+        out = Out(width = 15)
+        item.__rest__(out)
+        assert out.max_length() <= 15
 
     def test_list_item_custom_bullet(self):
         item_text = '12345678901234567890'
@@ -218,26 +244,27 @@
 
     def test_auto_enumerated_list(self):
         item_text = '12345678901234567890'
-        item = rest.list_item(item_text, enumerate = True)
+        item = rest.list_item(item_text, auto_enumerate = True)
         assert item.text().strip()[0:2] == '#.'
         check_rest(item)
 
     def test_literal_block(self):
-        block_text = '''\
+        text = '''\
         This line is only 45 characters wide.
-          This one is even longer (two spaces).
+          This one is even longer (two spaces).\
         '''
-
-        block = rest.literal_block(block_text)
-        assert block.text()[:6] == '\n\n::\n\n'
+        block = rest.literal_block(text)
+        assert block.text()[:6] == block.sep + '::' + block.sep
         out = Out()
         block.__rest__(out)
-        assert out.max_length() == len(block.quote) + max([len(l) for l in block_text.splitlines()])
+        assert out.max_length() == len(block.quote) + max([len(l) for l in text.splitlines()])
         check_rest(block)
-
-        block = rest.literal_block(block_text, quote= rest.literal_block.quotes[3])
+        
+        block = rest.literal_block(text, quote= rest.literal_block.quotes[3])
         assert block.text().strip()[4] == rest.literal_block.quotes[3]
-
+        check_rest(block)
+        
+        
 
     def test_interpreted_text(self):
 
@@ -247,42 +274,95 @@
         assert itext_role.text().startswith(':red:`just')
 
     def test_directive(self):
-        pass
-
+        dir = rest.directive.image('img.png')
+        assert dir.text() == dir.sep + '.. image:: img.png\n' + dir.sep
+        check_rest(dir.text())
+
+    def test_directive_with_options(self):
+        expected = """\
+.. figure:: picture.png
+   :alt: map to buried treasure
+   :scale: 50
 
-# create texts with rest objects
+   This is the caption of the figure (a simple paragraph).
 
-    def test_block_quote(self):
-        block ="""\
-This is an ordinary paragraph, introducing a block quote.
+   The legend consists of all elements after the caption.  In this
+   case, the legend consists of this paragraph."""
 
-    "It is my business to know things.  That is my trade."
+        legend = """ The legend consists of all elements after the caption.  In this\n case, the legend consists of this paragraph."""
+        
+        figure = rest.directive.figure('picture.png', rest.paragraph('This is the caption of the figure (a simple paragraph).'), rest.paragraph(legend), scale=50, alt= 'map to buried treasure')
+             
+        check_rest(expected)
+        check_rest(figure.text())
+        print_lines(expected.splitlines())
+        print_lines(figure.text().splitlines())
 
-    -- Sherlock Holmes
-    """
-        assert check_rest(block)
+        assert strip_lines(expected.splitlines()) == strip_lines(figure.text().splitlines())
+        
+        
+    def test_directive_replace_underscore_in_directive_name(self):
+        expected = '''\
+.. csv-table:: Frozen Delights!
+   :header: "Treat", "Quantity", "Description"
+   :widths: 15, 10, 30
+
+   Albatross,2.99,On a stick!
+   Crunchy Frog,1.49,"If we took the bones out, it wouldn't be crunchy,
+   now would it?"
+   Gannet Ripple,1.99,On a stick!
+''' #"
+
+        data =[["Albatross", 2.99, "On a stick!"],
+               ["Crunchy Frog", 1.49, "If we took the bones out, it wouldn't be crunchy, now would it?"],
+               ["Gannet Ripple", 1.99, "On a stick!"]
+               ]
+
+        out = Out(width = None)
+        py.std.csv.writer(out).writerows(data)
+        text = out.render()
+        table = rest.directive.csv_table('Frozen Delights!', text,
+                                         header = '"Treat", "Quantity", "Description"',
+                                         widths = "15, 10, 30")
+
+        print_lines(expected.splitlines())
+        print_lines(table.text().splitlines())
+        check_rest(expected)
+        check_rest(table.text())
+        assert strip_lines(expected.splitlines()) == strip_lines(table.text().splitlines())
+
+
+##     def test_block_quote(self):
+##         block ="""\
+## This is an ordinary paragraph, introducing a block quote.
+
+##     "It is my business to know things.  That is my trade."
+
+##     -- Sherlock Holmes
+##     """
+##         assert check_rest(block)
 
 
     
-    def test_quoted_line_block(self):
-        text = """\
-Take it away, Eric the Orchestra Leader!
-
-    | A one, two, a one two three four
-    |
-    | Half a bee, philosophically,
-    |     must, *ipso facto*, half not be.
-    | But half the bee has got to be,
-    |     *vis a vis* its entity.  D'you see?
-    |
-    | But can a bee be said to be
-    |     or not to be an entire bee,
-    |         when half the bee is not a bee,
-    |             due to some ancient injury?
-    |
-    | Singing...
-    """
-        assert check_rest(text)
+##     def test_quoted_line_block(self):
+##         text = """\
+## Take it away, Eric the Orchestra Leader!
+
+##     | A one, two, a one two three four
+##     |
+##     | Half a bee, philosophically,
+##     |     must, *ipso facto*, half not be.
+##     | But half the bee has got to be,
+##     |     *vis a vis* its entity.  D'you see?
+##     |
+##     | But can a bee be said to be
+##     |     or not to be an entire bee,
+##     |         when half the bee is not a bee,
+##     |             due to some ancient injury?
+##     |
+##     | Singing...
+##     """
+##         assert check_rest(text)
 
 #def test_temdir_output():
 #    py.test.skip('tempdir is %s' % temp)



More information about the pytest-commit mailing list