robotframework-2.7.7.utest.utils.test_markuputils.py Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of robotframework Show documentation
Show all versions of robotframework Show documentation
High level test automation framework
The newest version!
import unittest
from robot.utils.asserts import assert_equals
from robot.utils.markuputils import html_escape, html_format, attribute_escape
from robot.utils.htmlformatters import TableFormatter
_format_table = TableFormatter()._format_table
def assert_escape_and_format(inp, exp_escape=None, exp_format=None):
if exp_escape is None:
exp_escape = str(inp)
if exp_format is None:
exp_format = exp_escape
exp_format = '%s
' % exp_format.replace('\n', ' ')
escape = html_escape(inp)
format = html_format(inp)
assert_equals(escape, exp_escape,
'ESCAPE:\n%r =!\n%r' % (escape, exp_escape), values=False)
assert_equals(format, exp_format,
'FORMAT:\n%r =!\n%r' % (format, exp_format), values=False)
def assert_format(inp, exp=None, p=False):
exp = exp if exp is not None else inp
if p:
exp = '%s
' % exp
assert_equals(html_format(inp), exp)
def assert_escape(inp, exp=None):
exp = exp if exp is not None else inp
assert_equals(html_escape(inp), exp)
class TestHtmlEscape(unittest.TestCase):
def test_no_changes(self):
for inp in ['', 'nothing to change']:
assert_escape(inp)
def test_newlines_and_paragraphs(self):
for inp in ['Text on first line.\nText on second line.',
'1 line\n2 line\n3 line\n4 line\n5 line\n',
'Para 1 line 1\nP1 L2\n\nP2 L1\nP2 L1\n\nP3 L1\nP3 L2',
'Multiple empty lines\n\n\n\n\nbetween these lines']:
assert_escape(inp)
class TestEntities(unittest.TestCase):
def test_entities(self):
for char, entity in [('<','<'), ('>','>'), ('&','&')]:
for inp, exp in [(char, entity),
('text %s' % char, 'text %s' % entity),
('-%s-%s-' % (char, char),
'-%s-%s-' % (entity, entity)),
('"%s&%s"' % (char, char),
'"%s&%s"' % (entity, entity))]:
assert_escape_and_format(inp, exp)
class TestUrlsToLinks(unittest.TestCase):
def test_not_urls(self):
for no_url in ['http no link', 'http:/no', '123://no',
'1a://no', 'http://', 'http:// no']:
assert_escape_and_format(no_url)
def test_simple_urls(self):
for link in ['http://robot.fi', 'https://r.fi/', 'FTP://x.y.z/p/f.txt',
'a23456://link', 'file:///c:/temp/xxx.yyy']:
exp = '%s' % (link, link)
assert_escape_and_format(link, exp)
for end in [',', '.', ';', ':', '!', '?', '...', '!?!', ' hello' ]:
assert_escape_and_format(link+end, exp+end)
assert_escape_and_format('xxx '+link+end, 'xxx '+exp+end)
for start, end in [('(',')'), ('[',']'), ('"','"'), ("'","'")]:
assert_escape_and_format(start+link+end, start+exp+end)
def test_complex_urls_and_surrounding_content(self):
for inp, exp in [
('hello http://link world',
'hello http://link world'),
('multi\nhttp://link\nline',
'multi\nhttp://link\nline'),
('http://link, ftp://link2.',
'http://link, '
'ftp://link2.'),
('x (git+ssh://yy, z)',
'x (git+ssh://yy, z)'),
('(http://x.com/blah_(wikipedia)#cite-1)',
'(http://x.com/blah_(wikipedia)#cite-1)'),
('x-yojimbo-item://6303,E4C1,6A6E, FOO',
'x-yojimbo-item://6303,E4C1,6A6E, FOO'),
('Hello http://one, ftp://kaksi/; "gopher://3.0"',
'Hello http://one, '
'ftp://kaksi/; '
'"gopher://3.0"')]:
assert_escape_and_format(inp, exp)
def test_image_urls(self):
link = '(%s)'
img = '()'
for ext in ['jpg', 'jpeg', 'png', 'gif', 'bmp']:
url = 'foo://bar/zap.%s' % ext
uprl = url.upper()
inp = '(%s)' % url
assert_escape_and_format(inp, link % (url, url), img % (url, url))
assert_escape_and_format(inp.upper(), link % (uprl, uprl),
img % (uprl, uprl))
def test_url_with_chars_needing_escaping(self):
for items in [
('http://foo"bar',
'http://foo"bar'),
('ftp://<&>/',
'ftp://<&>/'),
('http://x&".png',
'http://x&".png',
'')
]:
assert_escape_and_format(*items)
class TestFormatParagraph(unittest.TestCase):
def test_empty(self):
assert_format('', '')
def test_single_line(self):
assert_format('foo', 'foo
')
def test_multi_line(self):
assert_format('foo\nbar', 'foo bar
')
def test_leading_and_trailing_spaces(self):
assert_format(' foo \n bar', 'foo bar
')
def test_multiple_paragraphs(self):
assert_format('P\n1\n\nP 2', 'P 1
\nP 2
')
def test_leading_empty_line(self):
assert_format('\nP', 'P
')
def test_other_formatted_content_before_paragraph(self):
assert_format('---\nP', '
\nP
')
assert_format('| PRE \nP', '\nPRE\n
\nP
')
def test_other_formatted_content_after_paragraph(self):
assert_format('P\n---', 'P
\n
')
assert_format('P\n| PRE \n', 'P
\n\nPRE\n
')
class TestHtmlFormatBoldAndItalic(unittest.TestCase):
def test_one_word_bold(self):
for inp, exp in [('*bold*', 'bold'),
('*b*', 'b'),
('*many bold words*', 'many bold words'),
(' *bold*', 'bold'),
('*bold* ', 'bold'),
('xx *bold*', 'xx bold'),
('*bold* xx', 'bold xx'),
('***', '*'),
('****', '**'),
('*****', '***')]:
assert_format(inp, exp, p=True)
def test_multiple_word_bold(self):
for inp, exp in [('*bold* *b* not bold *b3* not',
'bold b not bold b3 not'),
('not b *this is b* *more b words here*',
'not b this is b more b words here'),
('*** not *b* ***',
'* not b *')]:
assert_format(inp, exp, p=True)
def test_bold_on_multiple_lines(self):
inp = 'this is *bold*\nand *this*\nand *that*'
exp = 'this is bold and this and that'
assert_format(inp, exp, p=True)
assert_format('this *works\ntoo!*', 'this works too!', p=True)
def test_not_bolded_if_no_content(self):
assert_format('**', p=True)
def test_asterisk_in_the_middle_of_word_is_ignored(self):
for inp, exp in [('aa*notbold*bbb', None),
('*bold*still bold*', 'bold*still bold'),
('a*not*b c*still not*d', None),
('*b*b2* -*n*- *b3*', 'b*b2 -*n*- b3')]:
assert_format(inp, exp, p=True)
def test_asterisk_alone_does_not_start_bolding(self):
for inp, exp in [('*', None),
(' * ', '*'),
('* not *', None),
(' * not * ', '* not *'),
('* not*', None),
('*bold *', 'bold '),
('* *b* *', '* b *'),
('*bold * not*', 'bold not*'),
('*bold * not*not* *b*',
'bold not*not* b')]:
assert_format(inp, exp, p=True)
def test_one_word_italic(self):
for inp, exp in [('_italic_', 'italic'),
('_i_', 'i'),
('_many italic words_', 'many italic words'),
(' _italic_', 'italic'),
('_italic_ ', 'italic'),
('xx _italic_', 'xx italic'),
('_italic_ xx', 'italic xx')]:
assert_format(inp, exp, p=True)
def test_multiple_word_italic(self):
for inp, exp in [('_italic_ _i_ not italic _i3_ not',
'italic i not italic i3 not'),
('not i _this is i_ _more i words here_',
'not i this is i more i words here')]:
assert_format(inp, exp, p=True)
def test_not_italiced_if_no_content(self):
assert_format('__', p=True)
def test_not_italiced_many_underlines(self):
for inp in ['___', '____', '_________', '__len__']:
assert_format(inp, p=True)
def test_underscore_in_the_middle_of_word_is_ignored(self):
for inp, exp in [('aa_notitalic_bbb', None),
('_ital_still ital_', 'ital_still ital'),
('a_not_b c_still not_d', None),
('_b_b2_ -_n_- _b3_', 'b_b2 -_n_- b3')]:
assert_format(inp, exp, p=True)
def test_underscore_alone_does_not_start_italicing(self):
for inp, exp in [('_', None),
(' _ ', '_'),
('_ not _', None),
(' _ not _ ', '_ not _'),
('_ not_', None),
('_italic _', 'italic '),
('_ _b_ _', '_ b _'),
('_italic _ not_', 'italic not_'),
('_italic _ not_not_ _b_',
'italic not_not_ b')]:
assert_format(inp, exp, p=True)
def test_bold_and_italic(self):
for inp, exp in [('*b* _i_', 'b i')]:
assert_format(inp, exp, p=True)
def test_bold_and_italic_works_with_punctuation_marks(self):
for bef, aft in [('(',''), ('"',''), ("'",''), ('(\'"(',''),
('',')'), ('','"'), ('',','), ('','"\').,!?!?:;'),
('(',')'), ('"','"'), ('("\'','\'";)'), ('"','..."')]:
for inp, exp in [('*bold*','bold'),
('_ital_','ital'),
('*b* _i_','b i')]:
assert_format(bef + inp + aft, bef + exp + aft, p=True)
def test_bold_italic(self):
for inp, exp in [('_*bi*_', 'bi'),
('_*bold ital*_', 'bold ital'),
('_*bi* i_', 'bi i'),
('_*bi_ b*', 'bi b'),
('_i *bi*_', 'i bi'),
('*b _bi*_', 'b bi')]:
assert_format(inp, exp, p=True)
class TestHtmlFormatCustomLinks(unittest.TestCase):
def test_text_with_text(self):
assert_format('[link.html|title]', 'title', p=True)
assert_format('[link|t|i|t|l|e]', 't|i|t|l|e', p=True)
def test_text_with_image(self):
assert_format('[link|img.png]',
'',
p=True)
def test_image_with_text(self):
assert_format('[img.png|title]', '', p=True)
assert_format('[img.png|]', '', p=True)
def test_image_with_image(self):
assert_format('[x.png|thumb.png]',
'',
p=True)
def test_link_is_required(self):
assert_format('[|]', '[|]', p=True)
def test_whitespace_is_strip(self):
assert_format('[ link.html | title words ]',
'title words', p=True)
def test_url_and_link(self):
assert_format('http://url [link|title]',
'http://url title',
p=True)
def test_link_as_url(self):
assert_format('[http://url|title]', 'title', p=True)
def test_multiple_links(self):
assert_format('start [link|img.png] middle [link.html|title] end',
'start '
'middle title end', p=True)
def test_multiple_links_and_urls(self):
assert_format('[L|T]ftp://url[X|Y][http://u2]',
'Tftp://url'
'Y[http://u2]', p=True)
def test_escaping(self):
assert_format('["|<&>]', '<&>', p=True)
assert_format('[<".jpg|">]', '', p=True)
def test_formatted_link(self):
assert_format('*[link.html|title]*', 'title', p=True)
def test_link_in_table(self):
assert_format('| [link.html|title] |', '''\
title
''')
class TestHtmlFormatTable(unittest.TestCase):
def test_one_row_table(self):
inp = '| one | two |'
exp = _format_table([['one','two']])
assert_format(inp, exp)
def test_multi_row_table(self):
inp = '| 1.1 | 1.2 | 1.3 |\n| 2.1 | 2.2 |\n| 3.1 | 3.2 | 3.3 |\n'
exp = _format_table([['1.1','1.2','1.3'],
['2.1','2.2'],
['3.1','3.2','3.3']])
assert_format(inp, exp)
def test_table_with_extra_spaces(self):
inp = ' | 1.1 | 1.2 | \n | 2.1 | 2.2 | '
exp = _format_table([['1.1','1.2',],['2.1','2.2']])
assert_format(inp, exp)
def test_table_with_one_space_empty_cells(self):
inp = '''
| 1.1 | 1.2 | |
| 2.1 | | 2.3 |
| | 3.2 | 3.3 |
| 4.1 | | |
| | 5.2 | |
| | | 6.3 |
| | | |
'''[1:-1]
exp = _format_table([['1.1','1.2',''],
['2.1','','2.3'],
['','3.2','3.3'],
['4.1','',''],
['','5.2',''],
['','','6.3'],
['','','']])
assert_format(inp, exp)
def test_one_column_table(self):
inp = '| one column |\n| |\n | | \n| 2 | col |\n| |'
exp = _format_table([['one column'],[''],[''],['2','col'],['']])
assert_format(inp, exp)
def test_table_with_other_content_around(self):
inp = '''before table
| in | table |
| still | in |
after table
'''
exp = 'before table
\n' \
+ _format_table([['in','table'],['still','in']]) \
+ '\nafter table
'
assert_format(inp, exp)
def test_multiple_tables(self):
inp = '''before tables
| table | 1 |
| still | 1 |
between
| table | 2 |
between
| 3.1.1 | 3.1.2 | 3.1.3 |
| 3.2.1 | 3.2.2 | 3.2.3 |
| 3.3.1 | 3.3.2 | 3.3.3 |
| t | 4 |
| | |
after
'''
exp = 'before tables
\n' \
+ _format_table([['table','1'],['still','1']]) \
+ '\nbetween
\n' \
+ _format_table([['table','2']]) \
+ '\nbetween
\n' \
+ _format_table([['3.1.1','3.1.2','3.1.3'],
['3.2.1','3.2.2','3.2.3'],
['3.3.1','3.3.2','3.3.3']]) \
+ '\n' \
+ _format_table([['t','4'],['','']]) \
+ '\nafter
'
assert_format(inp, exp)
def test_ragged_table(self):
inp = '''
| 1.1 | 1.2 | 1.3 |
| 2.1 |
| 3.1 | 3.2 |
'''
exp = _format_table([['1.1','1.2','1.3'],
['2.1','',''],
['3.1','3.2','']])
assert_format(inp, exp)
def test_bold_in_table_cells(self):
inp = '''
| *a* | *b* | *c* |
| *b* | x | y |
| *c* | z | |
| a | x *b* y | *b* *c* |
| *a | b* | |
'''
exp = _format_table([['a','b','c'],
['b','x','y'],
['c','z','']]) + '\n' \
+ _format_table([['a','x b y','b c'],
['*a','b*','']])
assert_format(inp, exp)
def test_italic_in_table_cells(self):
inp = '''
| _a_ | _b_ | _c_ |
| _b_ | x | y |
| _c_ | z | |
| a | x _b_ y | _b_ _c_ |
| _a | b_ | |
'''
exp = _format_table([['a','b','c'],
['b','x','y'],
['c','z','']]) + '\n' \
+ _format_table([['a','x b y','b c'],
['_a','b_','']])
assert_format(inp, exp)
def test_bold_and_italic_in_table_cells(self):
inp = '''
| *a* | *b* | *c* |
| _b_ | x | y |
| _c_ | z | *b* _i_ |
'''
exp = _format_table([['a','b','c'],
['b','x','y'],
['c','z','b i']])
assert_format(inp, exp)
def test_link_in_table_cell(self):
inp = '''
| 1 | http://one |
| 2 | ftp://two/ |
'''
exp = _format_table([['1','FIRST'],
['2','SECOND']]) \
.replace('FIRST', 'http://one') \
.replace('SECOND', 'ftp://two/')
assert_format(inp, exp)
class TestHtmlFormatHr(unittest.TestCase):
def test_hr_is_three_or_more_hyphens(self):
for i in range(3, 10):
hr = '-' * i
spaces = ' ' * i
assert_format(hr, '
')
assert_format(spaces + hr + spaces, '
')
def test_hr_with_other_stuff_around(self):
for inp, exp in [('---\n-', '
\n-
'),
('xx\n---\nxx', 'xx
\n
\nxx
'),
('xx\n\n------\n\nxx', 'xx
\n
\nxx
')]:
assert_format(inp, exp)
def test_multiple_hrs(self):
assert_format('---\n---\n\n---', '
\n
\n
')
def test_not_hr(self):
for inp in ['-', '--', '-- --', '...---...', '===']:
assert_format(inp, p=True)
def test_hr_before_and_after_table(self):
inp = '''
---
| t | a | b | l | e |
---'''
exp = '
\n' + _format_table([['t','a','b','l','e']]) + '\n
'
assert_format(inp, exp)
class TestHtmlFormatList(unittest.TestCase):
def test_not_a_list(self):
for inp in ('-- item', '+ item', '* item', '-item'):
assert_format(inp, inp, p=True)
def test_one_item_list(self):
assert_format('- item', '\n- item
\n
')
assert_format(' - item', '\n- item
\n
')
def test_multi_item_list(self):
assert_format('- 1\n - 2\n- 3',
'\n- 1
\n- 2
\n- 3
\n
')
def test_list_with_formatted_content(self):
assert_format('- *bold* text\n- _italic_\n- [http://url|link]',
'\n- bold text
\n- italic
\n'
'- link
\n
')
def test_indentation_can_be_used_to_continue_list_item(self):
assert_format('''
outside list
- this item
continues
- 2nd item
continues
twice
''', '''\
outside list
- this item continues
- 2nd item continues twice
''')
def test_lists_with_other_content_around(self):
assert_format('''
before
- a
- *b*
between
- c
- d
e
f
---
''', '''\
before
- a
- b
between
- c
- d e f
''')
class TestHtmlFormatPreformatted(unittest.TestCase):
def test_single_line_block(self):
self._assert_preformatted('| some', 'some')
def test_block_without_any_content(self):
self._assert_preformatted('|', '')
def test_first_char_after_pipe_must_be_space(self):
assert_format('|x', p=True)
def test_multi_line_block(self):
self._assert_preformatted('| some\n|\n| quote', 'some\n\nquote')
def test_internal_whitespace_is_preserved(self):
self._assert_preformatted('| so\t\tme ', ' so\t\tme')
def test_spaces_before_leading_pipe_are_ignored(self):
self._assert_preformatted(' | some', 'some')
def test_block_mixed_with_other_content(self):
assert_format('before block:\n| some\n| quote\nafter block',
'before block:
\n\nsome\nquote\n
\nafter block
')
def test_multiple_blocks(self):
assert_format('| some\n| quote\nbetween\n| other block\n\nafter', '''\
some
quote
between
other block
after
''')
def test_block_line_with_other_formatting(self):
self._assert_preformatted('| _some_ formatted\n| text *here*',
'some formatted\ntext here')
def _assert_preformatted(self, inp, exp):
assert_format(inp, '\n' + exp + '\n
')
class TestHtmlFormatHeaders(unittest.TestCase):
def test_no_header(self):
for line in ['', 'hello', '=', '==', '====', '= =', '= =', '== ==',
'= inconsistent levels ==', '==== 4 is too many ====',
'=no spaces=', '=no spaces =', '= no spaces=']:
assert_format(line, p=bool(line))
def test_header(self):
for line, expected in [('= My Header =', 'My Header
'),
('== my == header ==', 'my == header
'),
(' === === === ', '===
')]:
assert_format(line, expected)
class TestFormatTable(unittest.TestCase):
# RIDE needs border="1" because its HTML view doesn't support CSS
_table_start = ''
def test_one_row_table(self):
inp = [['1','2','3']]
exp = self._table_start + '''
1
2
3
'''
assert_equals(_format_table(inp), exp)
def test_multi_row_table(self):
inp = [['1.1','1.2'], ['2.1','2.2'], ['3.1','3.2']]
exp = self._table_start + '''
1.1
1.2
2.1
2.2
3.1
3.2
'''
assert_equals(_format_table(inp), exp)
def test_fix_ragged_table(self):
inp = [['1.1','1.2','1.3'], ['2.1'], ['3.1','3.2']]
exp = self._table_start + '''
1.1
1.2
1.3
2.1
3.1
3.2
'''
assert_equals(_format_table(inp), exp)
class TestAttributeEscape(unittest.TestCase):
def test_nothing_to_escape(self):
for inp in ['', 'whatever', 'nothing here, move along']:
assert_equals(attribute_escape(inp), inp)
def test_html_entities(self):
for inp, exp in [('"', '"'), ('<', '<'), ('>', '>'),
('&', '&'), ('&<">&', '&<">&'),
('Sanity < "check"', 'Sanity < "check"')]:
assert_equals(attribute_escape(inp), exp)
def test_newlines_and_tabs(self):
for inp, exp in [('\n', '
'), ('\t', ' '), ('"\n\t"', '"
"'),
('N1\nN2\n\nT1\tT3\t\t\t', 'N1
N2
T1 T3 ')]:
assert_equals(attribute_escape(inp), exp)
def test_illegal_chars_in_xml(self):
for c in u'\x00\x08\x0B\x0C\x0E\x1F\uFFFE\uFFFF':
assert_equals(attribute_escape(c), '')
if __name__ == '__main__':
unittest.main()