[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