* 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
| @@ -2,3 +2,7 @@ | |||
| exclude_lines = | |||
| pragma: no cover | |||
| raise NotImplementedError() | |||
| partial_branches = | |||
| pragma: no branch | |||
| if py3k: | |||
| if not py3k: | |||
| @@ -10,10 +10,15 @@ v0.4 (unreleased): | |||
| option, RECURSE_OTHERS, which recurses over all children except instances of | |||
| 'forcetype' (for example, `code.filter_templates(code.RECURSE_OTHERS)` | |||
| 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. | |||
| Previously, the parser would produce an unclear BadRoute exception or allow | |||
| an incorrect node tree to be build. | |||
| - 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. | |||
| v0.3.3 (released April 22, 2014): | |||
| @@ -18,10 +18,17 @@ Unreleased | |||
| which recurses over all children except instances of *forcetype* (for | |||
| example, ``code.filter_templates(code.RECURSE_OTHERS)`` returns all un-nested | |||
| 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 | |||
| raised. Previously, the parser would produce an unclear :py:exc:`.BadRoute` | |||
| exception or allow an incorrect node tree to be build. | |||
| - 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. | |||
| v0.3.3 | |||
| @@ -21,6 +21,7 @@ | |||
| # SOFTWARE. | |||
| from __future__ import unicode_literals | |||
| import re | |||
| from ...compat import str | |||
| from ...string_mixin import StringMixIn | |||
| @@ -39,6 +40,8 @@ class Parameter(StringMixIn): | |||
| def __init__(self, name, value, showkey=True): | |||
| 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._value = value | |||
| self._showkey = showkey | |||
| @@ -48,6 +51,11 @@ class Parameter(StringMixIn): | |||
| return str(self.name) + "=" + 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 | |||
| def name(self): | |||
| """The name of the parameter as a :py:class:`~.Wikicode` object.""" | |||
| @@ -73,4 +81,7 @@ class Parameter(StringMixIn): | |||
| @showkey.setter | |||
| 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 | |||
| @@ -77,17 +77,17 @@ class HTMLEntity(Node): | |||
| # Test whether we're on the wide or narrow Python build. Check | |||
| # the length of a non-BMP code point | |||
| # (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 | |||
| def value(self): | |||
| @@ -155,6 +155,7 @@ class Template(Node): | |||
| else: | |||
| self.params.pop(i) | |||
| return | |||
| raise ValueError(needle) | |||
| @property | |||
| def name(self): | |||
| @@ -254,21 +255,19 @@ class Template(Node): | |||
| return existing | |||
| if showkey is None: | |||
| try: | |||
| if Parameter.can_hide_key(name): | |||
| int_name = int(str(name)) | |||
| except ValueError: | |||
| showkey = True | |||
| else: | |||
| int_keys = set() | |||
| for param in self.params: | |||
| 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) | |||
| if expected == int_name: | |||
| showkey = False | |||
| else: | |||
| showkey = True | |||
| else: | |||
| showkey = True | |||
| if not showkey: | |||
| self._surface_escape(value, "=") | |||
| @@ -27,6 +27,7 @@ try: | |||
| except ImportError: | |||
| import unittest | |||
| from mwparserfromhell.compat import py3k | |||
| from mwparserfromhell.nodes import (Argument, Comment, ExternalLink, Heading, | |||
| HTMLEntity, Tag, Template, Text, Wikilink) | |||
| from mwparserfromhell.nodes.extras import Attribute, Parameter | |||
| @@ -422,9 +423,9 @@ class TestBuilder(TreeEqualityTestCase): | |||
| def test_parser_error(self): | |||
| """test whether ParserError gets thrown for bad input""" | |||
| func = self.assertRaisesRegex if py3k else self.assertRaisesRegexp | |||
| 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__": | |||
| unittest.main(verbosity=2) | |||
| @@ -108,6 +108,7 @@ class TestHTMLEntity(TreeEqualityTestCase): | |||
| self.assertRaises(ValueError, setattr, node3, "value", -1) | |||
| self.assertRaises(ValueError, setattr, node1, "value", 110000) | |||
| self.assertRaises(ValueError, setattr, node1, "value", "1114112") | |||
| self.assertRaises(ValueError, setattr, node1, "value", "12FFFF") | |||
| def test_named(self): | |||
| """test getter/setter for the named attribute""" | |||
| @@ -163,10 +164,14 @@ class TestHTMLEntity(TreeEqualityTestCase): | |||
| node2 = HTMLEntity("107") | |||
| node3 = HTMLEntity("e9") | |||
| node4 = HTMLEntity("1f648") | |||
| node5 = HTMLEntity("-2") | |||
| node6 = HTMLEntity("110000", named=False, hexadecimal=True) | |||
| self.assertEqual("\xa0", node1.normalize()) | |||
| self.assertEqual("k", node2.normalize()) | |||
| self.assertEqual("é", node3.normalize()) | |||
| self.assertEqual("\U0001F648", node4.normalize()) | |||
| self.assertRaises(ValueError, node5.normalize) | |||
| self.assertRaises(ValueError, node6.normalize) | |||
| if __name__ == "__main__": | |||
| unittest.main(verbosity=2) | |||
| @@ -71,9 +71,10 @@ class TestParameter(TreeEqualityTestCase): | |||
| self.assertFalse(node1.showkey) | |||
| self.assertTrue(node2.showkey) | |||
| node1.showkey = True | |||
| node2.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__": | |||
| unittest.main(verbosity=2) | |||
| @@ -33,6 +33,7 @@ from mwparserfromhell.nodes.extras import Attribute | |||
| from ._test_tree_equality import TreeEqualityTestCase, wrap, wraptext | |||
| 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) | |||
| 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) | |||
| @@ -74,10 +75,10 @@ class TestTag(TreeEqualityTestCase): | |||
| node1 = Tag(wraptext("ref"), wraptext("foobar")) | |||
| # '''bold text''' | |||
| node2 = Tag(wraptext("b"), wraptext("bold text"), wiki_markup="'''") | |||
| # <img id="foo" class="bar" /> | |||
| # <img id="foo" class="bar" selected /> | |||
| 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=" ") | |||
| gen1 = node1.__children__() | |||
| @@ -89,6 +90,7 @@ class TestTag(TreeEqualityTestCase): | |||
| self.assertEqual(node3.attributes[0].value, next(gen3)) | |||
| self.assertEqual(node3.attributes[1].name, 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(node2.contents, next(gen2)) | |||
| self.assertEqual(node1.closing_tag, next(gen1)) | |||
| @@ -113,7 +115,8 @@ class TestTag(TreeEqualityTestCase): | |||
| getter, marker = object(), object() | |||
| get = lambda code: output.append((getter, code)) | |||
| 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=" ") | |||
| node3 = Tag(wraptext("br"), self_closing=True, invalid=True, | |||
| implicit=True, padding=" ") | |||
| @@ -122,9 +125,10 @@ class TestTag(TreeEqualityTestCase): | |||
| node3.__showtree__(output.append, get, mark) | |||
| valid = [ | |||
| "<", (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) | |||
| def test_tag(self): | |||
| @@ -130,6 +130,8 @@ class TestTemplate(TreeEqualityTestCase): | |||
| self.assertTrue(node4.has("b", False)) | |||
| self.assertTrue(node3.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): | |||
| """test Template.get()""" | |||
| @@ -176,52 +178,41 @@ class TestTemplate(TreeEqualityTestCase): | |||
| pgens("b ", " c\n"), pgens("\nd ", " e"), pgens("\nf ", "g ")]) | |||
| node16 = Template(wraptext("a"), [ | |||
| 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")]) | |||
| 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")]) | |||
| 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")]) | |||
| 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")]) | |||
| 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")]) | |||
| node34 = Template(wraptext("a\n"), [ | |||
| node30 = Template(wraptext("a\n"), [ | |||
| pgens("b ", "c\n"), pgens("d ", " e"), pgens("f ", "g\n"), | |||
| pgens("h ", " i\n")]) | |||
| node35 = Template(wraptext("a"), [ | |||
| node31 = Template(wraptext("a"), [ | |||
| 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 ")]) | |||
| 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("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")]) | |||
| 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")]) | |||
| node40 = Template(wraptext("a"), [pgens("b", "c"), pgens("d", "e"), | |||
| node36 = Template(wraptext("a"), [pgens("b", "c"), pgens("d", "e"), | |||
| 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) | |||
| node2.add(2, "g", showkey=False) | |||
| @@ -241,31 +232,29 @@ class TestTemplate(TreeEqualityTestCase): | |||
| node14.add("j", "k", showkey=True) | |||
| node15.add("h", "i", showkey=True) | |||
| 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|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|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| 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=bar}}", node28) | |||
| self.assertIsInstance(node28.params[1].value.get(1), HTMLEntity) | |||
| self.assertEqual("{{a|b=d}}", node29) | |||
| self.assertEqual("{{a|foo=bar}}", node30) | |||
| self.assertIsInstance(node30.params[0].value.get(1), HTMLEntity) | |||
| self.assertEqual("{{a|1=foo=bar}}", node31) | |||
| self.assertEqual("{{a|foo=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=bar}}", node24) | |||
| self.assertIsInstance(node24.params[1].value.get(1), HTMLEntity) | |||
| self.assertEqual("{{a|b=d}}", node25) | |||
| self.assertEqual("{{a|foo=bar}}", node26) | |||
| self.assertIsInstance(node26.params[0].value.get(1), HTMLEntity) | |||
| self.assertEqual("{{a|1=foo=bar}}", node27) | |||
| self.assertEqual("{{a|foo=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): | |||
| """test Template.remove()""" | |||
| @@ -373,6 +359,8 @@ class TestTemplate(TreeEqualityTestCase): | |||
| node26 = Template(wraptext("foo"), [ | |||
| pgens("a", "b"), pgens("c", "d"), pgens("e", "f"), 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("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=b|c=d|e=f|a=b}}", node25) | |||
| self.assertEqual("{{foo|a=b|c=d|e=f|a=|a=b}}", node26) | |||
| self.assertRaises(ValueError, node27.remove, node28.get(1)) | |||
| if __name__ == "__main__": | |||
| unittest.main(verbosity=2) | |||