Browse Source

Improve test coverage; fix some node-related bugs.

* Parameters with non-integer keys can no longer be created with
  showkey=False, nor have the value of this attribute be set to False
  later.
* Calling Template.remove() with a Parameter object that is not part of
  the template now raises ValueError instead of doing nothing.
* Added tests for HTMLEntity._unichr() being called with out-of-range
  codepoints.
* Added tests for Tag.__children__() and Tag.__showtree__() involving
  attributes that have no values.
tags/v0.4
Ben Kurtovic 9 years ago
parent
commit
8bc7ea669d
11 changed files with 140 additions and 114 deletions
  1. +4
    -0
      .coveragerc
  2. +5
    -0
      CHANGELOG
  3. +7
    -0
      docs/changelog.rst
  4. +12
    -1
      mwparserfromhell/nodes/extras/parameter.py
  5. +11
    -11
      mwparserfromhell/nodes/html_entity.py
  6. +5
    -6
      mwparserfromhell/nodes/template.py
  7. +3
    -2
      tests/test_builder.py
  8. +5
    -0
      tests/test_html_entity.py
  9. +3
    -2
      tests/test_parameter.py
  10. +11
    -7
      tests/test_tag.py
  11. +74
    -85
      tests/test_template.py

+ 4
- 0
.coveragerc View File

@@ -2,3 +2,7 @@
exclude_lines = exclude_lines =
pragma: no cover pragma: no cover
raise NotImplementedError() raise NotImplementedError()
partial_branches =
pragma: no branch
if py3k:
if not py3k:

+ 5
- 0
CHANGELOG View File

@@ -10,10 +10,15 @@ v0.4 (unreleased):
option, RECURSE_OTHERS, which recurses over all children except instances of option, RECURSE_OTHERS, which recurses over all children except instances of
'forcetype' (for example, `code.filter_templates(code.RECURSE_OTHERS)` 'forcetype' (for example, `code.filter_templates(code.RECURSE_OTHERS)`
returns all un-nested templates). returns all un-nested templates).
- Calling Template.remove() with a Parameter object that is not part of the
template now raises ValueError instead of doing nothing.
- Parameters with non-integer keys can no longer be created with
'showkey=False', nor have the value of this attribute be set to False later.
- If something goes wrong while parsing, ParserError will now be raised. - If something goes wrong while parsing, ParserError will now be raised.
Previously, the parser would produce an unclear BadRoute exception or allow Previously, the parser would produce an unclear BadRoute exception or allow
an incorrect node tree to be build. an incorrect node tree to be build.
- Fixed a parser bug involving nested tags. - Fixed a parser bug involving nested tags.
- Test coverage has been improved, and some minor related bugs have been fixed.
- Updated and fixed some documentation. - Updated and fixed some documentation.


v0.3.3 (released April 22, 2014): v0.3.3 (released April 22, 2014):


+ 7
- 0
docs/changelog.rst View File

@@ -18,10 +18,17 @@ Unreleased
which recurses over all children except instances of *forcetype* (for which recurses over all children except instances of *forcetype* (for
example, ``code.filter_templates(code.RECURSE_OTHERS)`` returns all un-nested example, ``code.filter_templates(code.RECURSE_OTHERS)`` returns all un-nested
templates). templates).
- Calling :py:meth:`.Template.remove` with a :py:class:`.Parameter` object that
is not part of the template now raises :py:exc:`ValueError` instead of doing
nothing.
- :py:class:`.Parameter`\ s with non-integer keys can no longer be created with
*showkey=False*, nor have the value of this attribute be set to *False*
later.
- If something goes wrong while parsing, :py:exc:`.ParserError` will now be - If something goes wrong while parsing, :py:exc:`.ParserError` will now be
raised. Previously, the parser would produce an unclear :py:exc:`.BadRoute` raised. Previously, the parser would produce an unclear :py:exc:`.BadRoute`
exception or allow an incorrect node tree to be build. exception or allow an incorrect node tree to be build.
- Fixed a parser bug involving nested tags. - Fixed a parser bug involving nested tags.
- Test coverage has been improved, and some minor related bugs have been fixed.
- Updated and fixed some documentation. - Updated and fixed some documentation.


v0.3.3 v0.3.3


+ 12
- 1
mwparserfromhell/nodes/extras/parameter.py View File

@@ -21,6 +21,7 @@
# SOFTWARE. # SOFTWARE.


from __future__ import unicode_literals from __future__ import unicode_literals
import re


from ...compat import str from ...compat import str
from ...string_mixin import StringMixIn from ...string_mixin import StringMixIn
@@ -39,6 +40,8 @@ class Parameter(StringMixIn):


def __init__(self, name, value, showkey=True): def __init__(self, name, value, showkey=True):
super(Parameter, self).__init__() super(Parameter, self).__init__()
if not showkey and not self.can_hide_key(name):
raise ValueError("key {0!r} cannot be hidden".format(name))
self._name = name self._name = name
self._value = value self._value = value
self._showkey = showkey self._showkey = showkey
@@ -48,6 +51,11 @@ class Parameter(StringMixIn):
return str(self.name) + "=" + str(self.value) return str(self.name) + "=" + str(self.value)
return str(self.value) return str(self.value)


@staticmethod
def can_hide_key(key):
"""Return whether or not the given key can be hidden."""
return re.match(r"[1-9][0-9]*$", str(key).strip())

@property @property
def name(self): def name(self):
"""The name of the parameter as a :py:class:`~.Wikicode` object.""" """The name of the parameter as a :py:class:`~.Wikicode` object."""
@@ -73,4 +81,7 @@ class Parameter(StringMixIn):


@showkey.setter @showkey.setter
def showkey(self, newval): def showkey(self, newval):
self._showkey = bool(newval)
newval = bool(newval)
if not newval and not self.can_hide_key(self.name):
raise ValueError("parameter key cannot be hidden")
self._showkey = newval

+ 11
- 11
mwparserfromhell/nodes/html_entity.py View File

@@ -77,17 +77,17 @@ class HTMLEntity(Node):
# Test whether we're on the wide or narrow Python build. Check # Test whether we're on the wide or narrow Python build. Check
# the length of a non-BMP code point # the length of a non-BMP code point
# (U+1F64A, SPEAK-NO-EVIL MONKEY): # (U+1F64A, SPEAK-NO-EVIL MONKEY):
if len("\U0001F64A") == 2:
# Ensure this is within the range we can encode:
if value > 0x10FFFF:
raise ValueError("unichr() arg not in range(0x110000)")
code = value - 0x10000
if value < 0: # Invalid code point
raise
lead = 0xD800 + (code >> 10)
trail = 0xDC00 + (code % (1 << 10))
return unichr(lead) + unichr(trail)
raise
if len("\U0001F64A") == 1: # pragma: no cover
raise
# Ensure this is within the range we can encode:
if value > 0x10FFFF:
raise ValueError("unichr() arg not in range(0x110000)")
code = value - 0x10000
if value < 0: # Invalid code point
raise
lead = 0xD800 + (code >> 10)
trail = 0xDC00 + (code % (1 << 10))
return unichr(lead) + unichr(trail)


@property @property
def value(self): def value(self):


+ 5
- 6
mwparserfromhell/nodes/template.py View File

@@ -155,6 +155,7 @@ class Template(Node):
else: else:
self.params.pop(i) self.params.pop(i)
return return
raise ValueError(needle)


@property @property
def name(self): def name(self):
@@ -254,21 +255,19 @@ class Template(Node):
return existing return existing


if showkey is None: if showkey is None:
try:
if Parameter.can_hide_key(name):
int_name = int(str(name)) int_name = int(str(name))
except ValueError:
showkey = True
else:
int_keys = set() int_keys = set()
for param in self.params: for param in self.params:
if not param.showkey: if not param.showkey:
if re.match(r"[1-9][0-9]*$", param.name.strip()):
int_keys.add(int(str(param.name)))
int_keys.add(int(str(param.name)))
expected = min(set(range(1, len(int_keys) + 2)) - int_keys) expected = min(set(range(1, len(int_keys) + 2)) - int_keys)
if expected == int_name: if expected == int_name:
showkey = False showkey = False
else: else:
showkey = True showkey = True
else:
showkey = True
if not showkey: if not showkey:
self._surface_escape(value, "=") self._surface_escape(value, "=")




+ 3
- 2
tests/test_builder.py View File

@@ -27,6 +27,7 @@ try:
except ImportError: except ImportError:
import unittest import unittest


from mwparserfromhell.compat import py3k
from mwparserfromhell.nodes import (Argument, Comment, ExternalLink, Heading, from mwparserfromhell.nodes import (Argument, Comment, ExternalLink, Heading,
HTMLEntity, Tag, Template, Text, Wikilink) HTMLEntity, Tag, Template, Text, Wikilink)
from mwparserfromhell.nodes.extras import Attribute, Parameter from mwparserfromhell.nodes.extras import Attribute, Parameter
@@ -422,9 +423,9 @@ class TestBuilder(TreeEqualityTestCase):


def test_parser_error(self): def test_parser_error(self):
"""test whether ParserError gets thrown for bad input""" """test whether ParserError gets thrown for bad input"""
func = self.assertRaisesRegex if py3k else self.assertRaisesRegexp
msg = r"_handle_token\(\) got unexpected TemplateClose" msg = r"_handle_token\(\) got unexpected TemplateClose"
self.assertRaisesRegexp(
ParserError, msg, self.builder.build, [tokens.TemplateClose()])
func(ParserError, msg, self.builder.build, [tokens.TemplateClose()])


if __name__ == "__main__": if __name__ == "__main__":
unittest.main(verbosity=2) unittest.main(verbosity=2)

+ 5
- 0
tests/test_html_entity.py View File

@@ -108,6 +108,7 @@ class TestHTMLEntity(TreeEqualityTestCase):
self.assertRaises(ValueError, setattr, node3, "value", -1) self.assertRaises(ValueError, setattr, node3, "value", -1)
self.assertRaises(ValueError, setattr, node1, "value", 110000) self.assertRaises(ValueError, setattr, node1, "value", 110000)
self.assertRaises(ValueError, setattr, node1, "value", "1114112") self.assertRaises(ValueError, setattr, node1, "value", "1114112")
self.assertRaises(ValueError, setattr, node1, "value", "12FFFF")


def test_named(self): def test_named(self):
"""test getter/setter for the named attribute""" """test getter/setter for the named attribute"""
@@ -163,10 +164,14 @@ class TestHTMLEntity(TreeEqualityTestCase):
node2 = HTMLEntity("107") node2 = HTMLEntity("107")
node3 = HTMLEntity("e9") node3 = HTMLEntity("e9")
node4 = HTMLEntity("1f648") node4 = HTMLEntity("1f648")
node5 = HTMLEntity("-2")
node6 = HTMLEntity("110000", named=False, hexadecimal=True)
self.assertEqual("\xa0", node1.normalize()) self.assertEqual("\xa0", node1.normalize())
self.assertEqual("k", node2.normalize()) self.assertEqual("k", node2.normalize())
self.assertEqual("é", node3.normalize()) self.assertEqual("é", node3.normalize())
self.assertEqual("\U0001F648", node4.normalize()) self.assertEqual("\U0001F648", node4.normalize())
self.assertRaises(ValueError, node5.normalize)
self.assertRaises(ValueError, node6.normalize)


if __name__ == "__main__": if __name__ == "__main__":
unittest.main(verbosity=2) unittest.main(verbosity=2)

+ 3
- 2
tests/test_parameter.py View File

@@ -71,9 +71,10 @@ class TestParameter(TreeEqualityTestCase):
self.assertFalse(node1.showkey) self.assertFalse(node1.showkey)
self.assertTrue(node2.showkey) self.assertTrue(node2.showkey)
node1.showkey = True node1.showkey = True
node2.showkey = ""
self.assertTrue(node1.showkey) self.assertTrue(node1.showkey)
self.assertFalse(node2.showkey)
node1.showkey = ""
self.assertFalse(node1.showkey)
self.assertRaises(ValueError, setattr, node2, "showkey", False)


if __name__ == "__main__": if __name__ == "__main__":
unittest.main(verbosity=2) unittest.main(verbosity=2)

+ 11
- 7
tests/test_tag.py View File

@@ -33,6 +33,7 @@ from mwparserfromhell.nodes.extras import Attribute
from ._test_tree_equality import TreeEqualityTestCase, wrap, wraptext from ._test_tree_equality import TreeEqualityTestCase, wrap, wraptext


agen = lambda name, value: Attribute(wraptext(name), wraptext(value)) agen = lambda name, value: Attribute(wraptext(name), wraptext(value))
agennv = lambda name: Attribute(wraptext(name))
agennq = lambda name, value: Attribute(wraptext(name), wraptext(value), False) agennq = lambda name, value: Attribute(wraptext(name), wraptext(value), False)
agenp = lambda name, v, a, b, c: Attribute(wraptext(name), v, True, a, b, c) agenp = lambda name, v, a, b, c: Attribute(wraptext(name), v, True, a, b, c)
agenpnv = lambda name, a, b, c: Attribute(wraptext(name), None, True, a, b, c) agenpnv = lambda name, a, b, c: Attribute(wraptext(name), None, True, a, b, c)
@@ -74,10 +75,10 @@ class TestTag(TreeEqualityTestCase):
node1 = Tag(wraptext("ref"), wraptext("foobar")) node1 = Tag(wraptext("ref"), wraptext("foobar"))
# '''bold text''' # '''bold text'''
node2 = Tag(wraptext("b"), wraptext("bold text"), wiki_markup="'''") node2 = Tag(wraptext("b"), wraptext("bold text"), wiki_markup="'''")
# <img id="foo" class="bar" />
# <img id="foo" class="bar" selected />
node3 = Tag(wraptext("img"), node3 = Tag(wraptext("img"),
attrs=[Attribute(wraptext("id"), wraptext("foo")),
Attribute(wraptext("class"), wraptext("bar"))],
attrs=[agen("id", "foo"), agen("class", "bar"),
agennv("selected")],
self_closing=True, padding=" ") self_closing=True, padding=" ")


gen1 = node1.__children__() gen1 = node1.__children__()
@@ -89,6 +90,7 @@ class TestTag(TreeEqualityTestCase):
self.assertEqual(node3.attributes[0].value, next(gen3)) self.assertEqual(node3.attributes[0].value, next(gen3))
self.assertEqual(node3.attributes[1].name, next(gen3)) self.assertEqual(node3.attributes[1].name, next(gen3))
self.assertEqual(node3.attributes[1].value, next(gen3)) self.assertEqual(node3.attributes[1].value, next(gen3))
self.assertEqual(node3.attributes[2].name, next(gen3))
self.assertEqual(node1.contents, next(gen1)) self.assertEqual(node1.contents, next(gen1))
self.assertEqual(node2.contents, next(gen2)) self.assertEqual(node2.contents, next(gen2))
self.assertEqual(node1.closing_tag, next(gen1)) self.assertEqual(node1.closing_tag, next(gen1))
@@ -113,7 +115,8 @@ class TestTag(TreeEqualityTestCase):
getter, marker = object(), object() getter, marker = object(), object()
get = lambda code: output.append((getter, code)) get = lambda code: output.append((getter, code))
mark = lambda: output.append(marker) mark = lambda: output.append(marker)
node1 = Tag(wraptext("ref"), wraptext("text"), [agen("name", "foo")])
node1 = Tag(wraptext("ref"), wraptext("text"),
[agen("name", "foo"), agennv("selected")])
node2 = Tag(wraptext("br"), self_closing=True, padding=" ") node2 = Tag(wraptext("br"), self_closing=True, padding=" ")
node3 = Tag(wraptext("br"), self_closing=True, invalid=True, node3 = Tag(wraptext("br"), self_closing=True, invalid=True,
implicit=True, padding=" ") implicit=True, padding=" ")
@@ -122,9 +125,10 @@ class TestTag(TreeEqualityTestCase):
node3.__showtree__(output.append, get, mark) node3.__showtree__(output.append, get, mark)
valid = [ valid = [
"<", (getter, node1.tag), (getter, node1.attributes[0].name), "<", (getter, node1.tag), (getter, node1.attributes[0].name),
" = ", marker, (getter, node1.attributes[0].value), ">",
(getter, node1.contents), "</", (getter, node1.closing_tag), ">",
"<", (getter, node2.tag), "/>", "</", (getter, node3.tag), ">"]
" = ", marker, (getter, node1.attributes[0].value),
(getter, node1.attributes[1].name), ">", (getter, node1.contents),
"</", (getter, node1.closing_tag), ">", "<", (getter, node2.tag),
"/>", "</", (getter, node3.tag), ">"]
self.assertEqual(valid, output) self.assertEqual(valid, output)


def test_tag(self): def test_tag(self):


+ 74
- 85
tests/test_template.py View File

@@ -130,6 +130,8 @@ class TestTemplate(TreeEqualityTestCase):
self.assertTrue(node4.has("b", False)) self.assertTrue(node4.has("b", False))
self.assertTrue(node3.has("b", True)) self.assertTrue(node3.has("b", True))
self.assertFalse(node4.has("b", True)) self.assertFalse(node4.has("b", True))
self.assertFalse(node1.has_param("foobar", False))
self.assertTrue(node2.has_param(1, False))


def test_get(self): def test_get(self):
"""test Template.get()""" """test Template.get()"""
@@ -176,52 +178,41 @@ class TestTemplate(TreeEqualityTestCase):
pgens("b ", " c\n"), pgens("\nd ", " e"), pgens("\nf ", "g ")]) pgens("b ", " c\n"), pgens("\nd ", " e"), pgens("\nf ", "g ")])
node16 = Template(wraptext("a"), [ node16 = Template(wraptext("a"), [
pgens("\nb ", " c"), pgens("\nd ", " e"), pgens("\nf ", " g")]) pgens("\nb ", " c"), pgens("\nd ", " e"), pgens("\nf ", " g")])
node17 = Template(wraptext("a"), [
pgens("\nb ", " c"), pgens("\nd ", " e"), pgens("\nf ", " g")])
node18 = Template(wraptext("a\n"), [
pgens("b ", "c\n"), pgens("d ", " e"), pgens("f ", "g\n"),
pgens("h ", " i\n")])
node19 = Template(wraptext("a"), [
pgens("b ", " c\n"), pgens("\nd ", " e"), pgens("\nf ", "g ")])
node20 = Template(wraptext("a"), [
pgens("\nb ", " c"), pgens("\nd ", " e"), pgens("\nf ", " g")])
node21 = Template(wraptext("a"), [pgenh("1", "b")])
node22 = Template(wraptext("a"), [pgenh("1", "b")])
node23 = Template(wraptext("a"), [pgenh("1", "b")])
node24 = Template(wraptext("a"), [pgenh("1", "b"), pgenh("2", "c"),
node17 = Template(wraptext("a"), [pgenh("1", "b")])
node18 = Template(wraptext("a"), [pgenh("1", "b")])
node19 = Template(wraptext("a"), [pgenh("1", "b")])
node20 = Template(wraptext("a"), [pgenh("1", "b"), pgenh("2", "c"),
pgenh("3", "d"), pgenh("4", "e")]) pgenh("3", "d"), pgenh("4", "e")])
node25 = Template(wraptext("a"), [pgenh("1", "b"), pgenh("2", "c"),
node21 = Template(wraptext("a"), [pgenh("1", "b"), pgenh("2", "c"),
pgens("4", "d"), pgens("5", "e")]) pgens("4", "d"), pgens("5", "e")])
node26 = Template(wraptext("a"), [pgenh("1", "b"), pgenh("2", "c"),
node22 = Template(wraptext("a"), [pgenh("1", "b"), pgenh("2", "c"),
pgens("4", "d"), pgens("5", "e")]) pgens("4", "d"), pgens("5", "e")])
node23 = Template(wraptext("a"), [pgenh("1", "b")])
node24 = Template(wraptext("a"), [pgenh("1", "b")])
node25 = Template(wraptext("a"), [pgens("b", "c")])
node26 = Template(wraptext("a"), [pgenh("1", "b")])
node27 = Template(wraptext("a"), [pgenh("1", "b")]) node27 = Template(wraptext("a"), [pgenh("1", "b")])
node28 = Template(wraptext("a"), [pgenh("1", "b")])
node29 = Template(wraptext("a"), [pgens("b", "c")])
node30 = Template(wraptext("a"), [pgenh("1", "b")])
node31 = Template(wraptext("a"), [pgenh("1", "b")])
node32 = Template(wraptext("a"), [pgens("1", "b")])
node33 = Template(wraptext("a"), [
node28 = Template(wraptext("a"), [pgens("1", "b")])
node29 = Template(wraptext("a"), [
pgens("\nb ", " c"), pgens("\nd ", " e"), pgens("\nf ", " g")]) pgens("\nb ", " c"), pgens("\nd ", " e"), pgens("\nf ", " g")])
node34 = Template(wraptext("a\n"), [
node30 = Template(wraptext("a\n"), [
pgens("b ", "c\n"), pgens("d ", " e"), pgens("f ", "g\n"), pgens("b ", "c\n"), pgens("d ", " e"), pgens("f ", "g\n"),
pgens("h ", " i\n")]) pgens("h ", " i\n")])
node35 = Template(wraptext("a"), [
node31 = Template(wraptext("a"), [
pgens("b ", " c\n"), pgens("\nd ", " e"), pgens("\nf ", "g ")]) pgens("b ", " c\n"), pgens("\nd ", " e"), pgens("\nf ", "g ")])
node36 = Template(wraptext("a"), [
node32 = Template(wraptext("a"), [
pgens("\nb ", " c "), pgens("\nd ", " e "), pgens("\nf ", " g ")]) pgens("\nb ", " c "), pgens("\nd ", " e "), pgens("\nf ", " g ")])
node37 = Template(wraptext("a"), [pgens("b", "c"), pgens("d", "e"),
pgens("b", "f"), pgens("b", "h"),
pgens("i", "j")])
node37 = Template(wraptext("a"), [pgens("b", "c"), pgens("d", "e"),
node33 = Template(wraptext("a"), [pgens("b", "c"), pgens("d", "e"),
pgens("b", "f"), pgens("b", "h"), pgens("b", "f"), pgens("b", "h"),
pgens("i", "j")]) pgens("i", "j")])
node38 = Template(wraptext("a"), [pgens("1", "b"), pgens("x", "y"),
node34 = Template(wraptext("a"), [pgens("1", "b"), pgens("x", "y"),
pgens("1", "c"), pgens("2", "d")]) pgens("1", "c"), pgens("2", "d")])
node39 = Template(wraptext("a"), [pgens("1", "b"), pgens("x", "y"),
node35 = Template(wraptext("a"), [pgens("1", "b"), pgens("x", "y"),
pgenh("1", "c"), pgenh("2", "d")]) pgenh("1", "c"), pgenh("2", "d")])
node40 = Template(wraptext("a"), [pgens("b", "c"), pgens("d", "e"),
node36 = Template(wraptext("a"), [pgens("b", "c"), pgens("d", "e"),
pgens("f", "g")]) pgens("f", "g")])
node41 = Template(wraptext("a"), [pgenh("1", "")])
node37 = Template(wraptext("a"), [pgenh("1", "")])
node38 = Template(wraptext("abc"))


node1.add("e", "f", showkey=True) node1.add("e", "f", showkey=True)
node2.add(2, "g", showkey=False) node2.add(2, "g", showkey=False)
@@ -241,31 +232,29 @@ class TestTemplate(TreeEqualityTestCase):
node14.add("j", "k", showkey=True) node14.add("j", "k", showkey=True)
node15.add("h", "i", showkey=True) node15.add("h", "i", showkey=True)
node16.add("h", "i", showkey=True, preserve_spacing=False) node16.add("h", "i", showkey=True, preserve_spacing=False)
node17.add("h", "i", showkey=False)
node18.add("j", "k", showkey=False)
node19.add("h", "i", showkey=False)
node20.add("h", "i", showkey=False, preserve_spacing=False)
node21.add("2", "c")
node22.add("3", "c")
node23.add("c", "d")
node24.add("5", "f")
node25.add("3", "f")
node26.add("6", "f")
node27.add("c", "foo=bar")
node28.add("2", "foo=bar")
node29.add("b", "d")
node30.add("1", "foo=bar")
node31.add("1", "foo=bar", showkey=True)
node32.add("1", "foo=bar", showkey=False)
node33.add("d", "foo")
node34.add("f", "foo")
node35.add("f", "foo")
node36.add("d", "foo", preserve_spacing=False)
node37.add("b", "k")
node38.add("1", "e")
node39.add("1", "e")
node40.add("d", "h", before="b")
node41.add(1, "b")
node17.add("2", "c")
node18.add("3", "c")
node19.add("c", "d")
node20.add("5", "f")
node21.add("3", "f")
node22.add("6", "f")
node23.add("c", "foo=bar")
node24.add("2", "foo=bar")
node25.add("b", "d")
node26.add("1", "foo=bar")
node27.add("1", "foo=bar", showkey=True)
node28.add("1", "foo=bar", showkey=False)
node29.add("d", "foo")
node30.add("f", "foo")
node31.add("f", "foo")
node32.add("d", "foo", preserve_spacing=False)
node33.add("b", "k")
node34.add("1", "e")
node35.add("1", "e")
node36.add("d", "h", before="b")
node37.add(1, "b")
node38.add("1", "foo")
self.assertRaises(ValueError, node38.add, "z", "bar", showkey=False)


self.assertEqual("{{a|b=c|d|e=f}}", node1) self.assertEqual("{{a|b=c|d|e=f}}", node1)
self.assertEqual("{{a|b=c|d|g}}", node2) self.assertEqual("{{a|b=c|d|g}}", node2)
@@ -285,34 +274,31 @@ class TestTemplate(TreeEqualityTestCase):
self.assertEqual("{{a\n|b =c\n|d = e|f =g\n|h = i\n|j =k\n}}", node14) self.assertEqual("{{a\n|b =c\n|d = e|f =g\n|h = i\n|j =k\n}}", node14)
self.assertEqual("{{a|b = c\n|\nd = e|\nf =g |h =i}}", node15) self.assertEqual("{{a|b = c\n|\nd = e|\nf =g |h =i}}", node15)
self.assertEqual("{{a|\nb = c|\nd = e|\nf = g|h=i}}", node16) self.assertEqual("{{a|\nb = c|\nd = e|\nf = g|h=i}}", node16)
self.assertEqual("{{a|\nb = c|\nd = e|\nf = g| i}}", node17)
self.assertEqual("{{a\n|b =c\n|d = e|f =g\n|h = i\n|k\n}}", node18)
self.assertEqual("{{a|b = c\n|\nd = e|\nf =g |i}}", node19)
self.assertEqual("{{a|\nb = c|\nd = e|\nf = g|i}}", node20)
self.assertEqual("{{a|b|c}}", node21)
self.assertEqual("{{a|b|3=c}}", node22)
self.assertEqual("{{a|b|c=d}}", node23)
self.assertEqual("{{a|b|c|d|e|f}}", node24)
self.assertEqual("{{a|b|c|4=d|5=e|f}}", node25)
self.assertEqual("{{a|b|c|4=d|5=e|6=f}}", node26)
self.assertEqual("{{a|b|c=foo=bar}}", node27)
self.assertEqual("{{a|b|foo&#61;bar}}", node28)
self.assertIsInstance(node28.params[1].value.get(1), HTMLEntity)
self.assertEqual("{{a|b=d}}", node29)
self.assertEqual("{{a|foo&#61;bar}}", node30)
self.assertIsInstance(node30.params[0].value.get(1), HTMLEntity)
self.assertEqual("{{a|1=foo=bar}}", node31)
self.assertEqual("{{a|foo&#61;bar}}", node32)
self.assertIsInstance(node32.params[0].value.get(1), HTMLEntity)
self.assertEqual("{{a|\nb = c|\nd = foo|\nf = g}}", node33)
self.assertEqual("{{a\n|b =c\n|d = e|f =foo\n|h = i\n}}", node34)
self.assertEqual("{{a|b = c\n|\nd = e|\nf =foo }}", node35)
self.assertEqual("{{a|\nb = c |\nd =foo|\nf = g }}", node36)
self.assertEqual("{{a|b=k|d=e|i=j}}", node37)
self.assertEqual("{{a|1=e|x=y|2=d}}", node38)
self.assertEqual("{{a|x=y|e|d}}", node39)
self.assertEqual("{{a|b=c|d=h|f=g}}", node40)
self.assertEqual("{{a|b}}", node41)
self.assertEqual("{{a|b|c}}", node17)
self.assertEqual("{{a|b|3=c}}", node18)
self.assertEqual("{{a|b|c=d}}", node19)
self.assertEqual("{{a|b|c|d|e|f}}", node20)
self.assertEqual("{{a|b|c|4=d|5=e|f}}", node21)
self.assertEqual("{{a|b|c|4=d|5=e|6=f}}", node22)
self.assertEqual("{{a|b|c=foo=bar}}", node23)
self.assertEqual("{{a|b|foo&#61;bar}}", node24)
self.assertIsInstance(node24.params[1].value.get(1), HTMLEntity)
self.assertEqual("{{a|b=d}}", node25)
self.assertEqual("{{a|foo&#61;bar}}", node26)
self.assertIsInstance(node26.params[0].value.get(1), HTMLEntity)
self.assertEqual("{{a|1=foo=bar}}", node27)
self.assertEqual("{{a|foo&#61;bar}}", node28)
self.assertIsInstance(node28.params[0].value.get(1), HTMLEntity)
self.assertEqual("{{a|\nb = c|\nd = foo|\nf = g}}", node29)
self.assertEqual("{{a\n|b =c\n|d = e|f =foo\n|h = i\n}}", node30)
self.assertEqual("{{a|b = c\n|\nd = e|\nf =foo }}", node31)
self.assertEqual("{{a|\nb = c |\nd =foo|\nf = g }}", node32)
self.assertEqual("{{a|b=k|d=e|i=j}}", node33)
self.assertEqual("{{a|1=e|x=y|2=d}}", node34)
self.assertEqual("{{a|x=y|e|d}}", node35)
self.assertEqual("{{a|b=c|d=h|f=g}}", node36)
self.assertEqual("{{a|b}}", node37)
self.assertEqual("{{abc|foo}}", node38)


def test_remove(self): def test_remove(self):
"""test Template.remove()""" """test Template.remove()"""
@@ -373,6 +359,8 @@ class TestTemplate(TreeEqualityTestCase):
node26 = Template(wraptext("foo"), [ node26 = Template(wraptext("foo"), [
pgens("a", "b"), pgens("c", "d"), pgens("e", "f"), pgens("a", "b"), pgens("a", "b"), pgens("c", "d"), pgens("e", "f"), pgens("a", "b"),
pgens("a", "b")]) pgens("a", "b")])
node27 = Template(wraptext("foo"), [pgenh("1", "bar")])
node28 = Template(wraptext("foo"), [pgenh("1", "bar")])


node2.remove("1") node2.remove("1")
node2.remove("abc") node2.remove("abc")
@@ -430,6 +418,7 @@ class TestTemplate(TreeEqualityTestCase):
self.assertEqual("{{foo|a=|c=d|e=f|a=b|a=b}}", node24) self.assertEqual("{{foo|a=|c=d|e=f|a=b|a=b}}", node24)
self.assertEqual("{{foo|a=b|c=d|e=f|a=b}}", node25) self.assertEqual("{{foo|a=b|c=d|e=f|a=b}}", node25)
self.assertEqual("{{foo|a=b|c=d|e=f|a=|a=b}}", node26) self.assertEqual("{{foo|a=b|c=d|e=f|a=|a=b}}", node26)
self.assertRaises(ValueError, node27.remove, node28.get(1))


if __name__ == "__main__": if __name__ == "__main__":
unittest.main(verbosity=2) unittest.main(verbosity=2)

Loading…
Cancel
Save