Browse Source

Clean up pytest-ported tests

tags/v0.6.1
Ben Kurtovic 3 years ago
parent
commit
074e368684
29 changed files with 3384 additions and 3377 deletions
  1. +1
    -0
      CHANGELOG
  2. +3
    -2
      README.rst
  3. +2
    -0
      docs/changelog.rst
  4. +3
    -2
      docs/index.rst
  5. +1
    -1
      mwparserfromhell/parser/tokenizer.py
  6. +2
    -2
      scripts/release.sh
  7. +0
    -131
      tests/_test_tree_equality.py
  8. +138
    -0
      tests/conftest.py
  9. +66
    -66
      tests/test_argument.py
  10. +75
    -75
      tests/test_attribute.py
  11. +399
    -399
      tests/test_builder.py
  12. +34
    -35
      tests/test_comment.py
  13. +88
    -87
      tests/test_docs.py
  14. +88
    -88
      tests/test_external_link.py
  15. +55
    -55
      tests/test_heading.py
  16. +158
    -159
      tests/test_html_entity.py
  17. +42
    -42
      tests/test_parameter.py
  18. +46
    -46
      tests/test_parser.py
  19. +383
    -383
      tests/test_smart_list.py
  20. +378
    -378
      tests/test_string_mixin.py
  21. +299
    -298
      tests/test_tag.py
  22. +414
    -413
      tests/test_template.py
  23. +39
    -38
      tests/test_text.py
  24. +3
    -11
      tests/test_tokenizer.py
  25. +60
    -59
      tests/test_tokens.py
  26. +30
    -30
      tests/test_utils.py
  27. +511
    -510
      tests/test_wikicode.py
  28. +66
    -66
      tests/test_wikilink.py
  29. +0
    -1
      tests/tokenizer/integration.mwtest

+ 1
- 0
CHANGELOG View File

@@ -1,5 +1,6 @@
v0.7 (unreleased):

- Port tests to pytest. (#237)
- Improve parsing of external links. (#232)

v0.6 (released December 21, 2020):


+ 3
- 2
README.rst View File

@@ -29,8 +29,8 @@ Alternatively, get the latest development version::
cd mwparserfromhell
python setup.py install

You can run the comprehensive unit testing suite with
``python -m unittest discover``.
The comprehensive unit testing suite requires `pytest`_ (``pip install pytest``)
and can be run with ``python -m pytest``.

Usage
-----
@@ -210,6 +210,7 @@ Python 3 code (using the API_ and the requests_ library):
.. _GitHub: https://github.com/earwig/mwparserfromhell
.. _Python Package Index: https://pypi.org/
.. _get pip: https://pypi.org/project/pip/
.. _pytest: https://docs.pytest.org/
.. _Word-ending links: https://www.mediawiki.org/wiki/Help:Links#linktrail
.. _EarwigBot: https://github.com/earwig/earwigbot
.. _Pywikibot: https://www.mediawiki.org/wiki/Manual:Pywikibot


+ 2
- 0
docs/changelog.rst View File

@@ -7,6 +7,8 @@ v0.7
Unreleased
(`changes <https://github.com/earwig/mwparserfromhell/compare/v0.6...develop>`__):

- Port tests to pytest.
(`#237 <https://github.com/earwig/mwparserfromhell/issues/237>`_)
- Improve parsing of external links.
(`#232 <https://github.com/earwig/mwparserfromhell/issues/232>`_)



+ 3
- 2
docs/index.rst View File

@@ -27,11 +27,12 @@ Alternatively, get the latest development version::
cd mwparserfromhell
python setup.py install

You can run the comprehensive unit testing suite with
``python -m unittest discover``.
The comprehensive unit testing suite requires `pytest`_ (``pip install pytest``)
and can be run with ``python -m pytest``.

.. _Python Package Index: https://pypi.org/
.. _get pip: https://pypi.org/project/pip/
.. _pytest: https://docs.pytest.org/

Contents
--------


+ 1
- 1
mwparserfromhell/parser/tokenizer.py View File

@@ -491,7 +491,7 @@ class Tokenizer:
return self._parse(push=False), None, 0
elif any(ch in this for ch in (" ", "\n", "[", "]", "<", ">",
"\"")):
before, after = re.split("[ \n\[\]<>\"]", this, maxsplit=1)
before, after = re.split(r"[ \n[\]<>\"]", this, maxsplit=1)
delimiter = this[len(before)]
if brackets:
self._emit_text(before)


+ 2
- 2
scripts/release.sh View File

@@ -102,7 +102,7 @@ test_release() {
echo " done."
echo -n "Installing mwparserfromhell with pip..."
pip -q install --upgrade pip
pip -q install mwparserfromhell
pip -q install mwparserfromhell pytest
echo " done."
echo -n "Checking version..."
reported_version=$(python -c 'print(__import__("mwparserfromhell").__version__)')
@@ -135,7 +135,7 @@ test_release() {
cd mwparserfromhell-$VERSION
echo "Running unit tests..."
python setup.py -q install
python -m unittest discover
python -m pytest
if [[ "$?" != "0" ]]; then
echo "*** ERROR: Unit tests failed!"
deactivate


+ 0
- 131
tests/_test_tree_equality.py View File

@@ -1,131 +0,0 @@
# Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

from mwparserfromhell.nodes import (Argument, Comment, Heading, HTMLEntity,
Tag, Template, Text, Wikilink)
from mwparserfromhell.smart_list import SmartList
from mwparserfromhell.wikicode import Wikicode

wrap = lambda L: Wikicode(SmartList(L))
wraptext = lambda *args: wrap([Text(t) for t in args])

class TreeEqualityTestCase:
"""A base test case with support for comparing the equality of node trees.

This adds a number of type equality functions, for Wikicode, Text,
Templates, and Wikilinks.
"""

def assertNodeEqual(self, expected, actual):
"""Assert that two Nodes have the same type and have the same data."""
registry = {
Argument: self.assertArgumentNodeEqual,
Comment: self.assertCommentNodeEqual,
Heading: self.assertHeadingNodeEqual,
HTMLEntity: self.assertHTMLEntityNodeEqual,
Tag: self.assertTagNodeEqual,
Template: self.assertTemplateNodeEqual,
Text: self.assertTextNodeEqual,
Wikilink: self.assertWikilinkNodeEqual
}
for nodetype in registry:
if isinstance(expected, nodetype):
assert isinstance(actual, nodetype)
registry[nodetype](expected, actual)

def assertArgumentNodeEqual(self, expected, actual):
"""Assert that two Argument nodes have the same data."""
self.assertWikicodeEqual(expected.name, actual.name)
if expected.default is not None:
self.assertWikicodeEqual(expected.default, actual.default)
else:
assert actual.default is None

def assertCommentNodeEqual(self, expected, actual):
"""Assert that two Comment nodes have the same data."""
assert expected.contents == actual.contents

def assertHeadingNodeEqual(self, expected, actual):
"""Assert that two Heading nodes have the same data."""
self.assertWikicodeEqual(expected.title, actual.title)
assert expected.level == actual.level

def assertHTMLEntityNodeEqual(self, expected, actual):
"""Assert that two HTMLEntity nodes have the same data."""
assert expected.value == actual.value
assert expected.named is actual.named
assert expected.hexadecimal is actual.hexadecimal
assert expected.hex_char == actual.hex_char

def assertTagNodeEqual(self, expected, actual):
"""Assert that two Tag nodes have the same data."""
self.assertWikicodeEqual(expected.tag, actual.tag)
if expected.contents is not None:
self.assertWikicodeEqual(expected.contents, actual.contents)
length = len(expected.attributes)
assert length == len(actual.attributes)
for i in range(length):
exp_attr = expected.attributes[i]
act_attr = actual.attributes[i]
self.assertWikicodeEqual(exp_attr.name, act_attr.name)
if exp_attr.value is not None:
self.assertWikicodeEqual(exp_attr.value, act_attr.value)
assert exp_attr.quotes == act_attr.quotes
assert exp_attr.pad_first == act_attr.pad_first
assert exp_attr.pad_before_eq == act_attr.pad_before_eq
assert exp_attr.pad_after_eq == act_attr.pad_after_eq
assert expected.wiki_markup == actual.wiki_markup
assert expected.self_closing is actual.self_closing
assert expected.invalid is actual.invalid
assert expected.implicit is actual.implicit
assert expected.padding == actual.padding
self.assertWikicodeEqual(expected.closing_tag, actual.closing_tag)

def assertTemplateNodeEqual(self, expected, actual):
"""Assert that two Template nodes have the same data."""
self.assertWikicodeEqual(expected.name, actual.name)
length = len(expected.params)
assert length == len(actual.params)
for i in range(length):
exp_param = expected.params[i]
act_param = actual.params[i]
self.assertWikicodeEqual(exp_param.name, act_param.name)
self.assertWikicodeEqual(exp_param.value, act_param.value)
assert exp_param.showkey is act_param.showkey

def assertTextNodeEqual(self, expected, actual):
"""Assert that two Text nodes have the same data."""
assert expected.value == actual.value

def assertWikilinkNodeEqual(self, expected, actual):
"""Assert that two Wikilink nodes have the same data."""
self.assertWikicodeEqual(expected.title, actual.title)
if expected.text is not None:
self.assertWikicodeEqual(expected.text, actual.text)
else:
assert None is actual.text

def assertWikicodeEqual(self, expected, actual):
"""Assert that two Wikicode objects have the same data."""
assert isinstance(actual, Wikicode)
length = len(expected.nodes)
assert length == len(actual.nodes)
for i in range(length):
self.assertNodeEqual(expected.get(i), actual.get(i))

+ 138
- 0
tests/conftest.py View File

@@ -0,0 +1,138 @@
# Copyright (C) 2012-2020 Ben Kurtovic <ben.kurtovic@gmail.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

from mwparserfromhell.nodes import (Argument, Comment, ExternalLink, Heading,
HTMLEntity, Tag, Template, Text, Wikilink)
from mwparserfromhell.smart_list import SmartList
from mwparserfromhell.wikicode import Wikicode

wrap = lambda L: Wikicode(SmartList(L))
wraptext = lambda *args: wrap([Text(t) for t in args])

def _assert_node_equal(expected, actual):
"""Assert that two Nodes have the same type and have the same data."""
registry = {
Argument: _assert_argument_node_equal,
Comment: _assert_comment_node_equal,
ExternalLink: _assert_external_link_node_equal,
Heading: _assert_heading_node_equal,
HTMLEntity: _assert_html_entity_node_equal,
Tag: _assert_tag_node_equal,
Template: _assert_template_node_equal,
Text: _assert_text_node_equal,
Wikilink: _assert_wikilink_node_equal,
}
# pylint: disable=unidiomatic-typecheck
assert type(expected) == type(actual)
registry[type(expected)](expected, actual)

def _assert_argument_node_equal(expected, actual):
"""Assert that two Argument nodes have the same data."""
assert_wikicode_equal(expected.name, actual.name)
if expected.default is not None:
assert_wikicode_equal(expected.default, actual.default)
else:
assert actual.default is None

def _assert_comment_node_equal(expected, actual):
"""Assert that two Comment nodes have the same data."""
assert expected.contents == actual.contents

def _assert_external_link_node_equal(expected, actual):
"""Assert that two ExternalLink nodes have the same data."""
assert_wikicode_equal(expected.url, actual.url)
if expected.title is not None:
assert_wikicode_equal(expected.title, actual.title)
else:
assert actual.title is None
assert expected.brackets is actual.brackets
assert expected.suppress_space is actual.suppress_space

def _assert_heading_node_equal(expected, actual):
"""Assert that two Heading nodes have the same data."""
assert_wikicode_equal(expected.title, actual.title)
assert expected.level == actual.level

def _assert_html_entity_node_equal(expected, actual):
"""Assert that two HTMLEntity nodes have the same data."""
assert expected.value == actual.value
assert expected.named is actual.named
assert expected.hexadecimal is actual.hexadecimal
assert expected.hex_char == actual.hex_char

def _assert_tag_node_equal(expected, actual):
"""Assert that two Tag nodes have the same data."""
assert_wikicode_equal(expected.tag, actual.tag)
if expected.contents is not None:
assert_wikicode_equal(expected.contents, actual.contents)
else:
assert actual.contents is None
length = len(expected.attributes)
assert length == len(actual.attributes)
for i in range(length):
exp_attr = expected.attributes[i]
act_attr = actual.attributes[i]
assert_wikicode_equal(exp_attr.name, act_attr.name)
if exp_attr.value is not None:
assert_wikicode_equal(exp_attr.value, act_attr.value)
assert exp_attr.quotes == act_attr.quotes
else:
assert act_attr.value is None
assert exp_attr.pad_first == act_attr.pad_first
assert exp_attr.pad_before_eq == act_attr.pad_before_eq
assert exp_attr.pad_after_eq == act_attr.pad_after_eq
assert expected.wiki_markup == actual.wiki_markup
assert expected.self_closing is actual.self_closing
assert expected.invalid is actual.invalid
assert expected.implicit is actual.implicit
assert expected.padding == actual.padding
assert_wikicode_equal(expected.closing_tag, actual.closing_tag)

def _assert_template_node_equal(expected, actual):
"""Assert that two Template nodes have the same data."""
assert_wikicode_equal(expected.name, actual.name)
length = len(expected.params)
assert length == len(actual.params)
for i in range(length):
exp_param = expected.params[i]
act_param = actual.params[i]
assert_wikicode_equal(exp_param.name, act_param.name)
assert_wikicode_equal(exp_param.value, act_param.value)
assert exp_param.showkey is act_param.showkey

def _assert_text_node_equal(expected, actual):
"""Assert that two Text nodes have the same data."""
assert expected.value == actual.value

def _assert_wikilink_node_equal(expected, actual):
"""Assert that two Wikilink nodes have the same data."""
assert_wikicode_equal(expected.title, actual.title)
if expected.text is not None:
assert_wikicode_equal(expected.text, actual.text)
else:
assert actual.text is None

def assert_wikicode_equal(expected, actual):
"""Assert that two Wikicode objects have the same data."""
assert isinstance(actual, Wikicode)
length = len(expected.nodes)
assert length == len(actual.nodes)
for i in range(length):
_assert_node_equal(expected.get(i), actual.get(i))

+ 66
- 66
tests/test_argument.py View File

@@ -18,78 +18,78 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""
Test cases for the Argument node.
"""

import pytest

from mwparserfromhell.nodes import Argument, Text
from .conftest import assert_wikicode_equal, wrap, wraptext

from ._test_tree_equality import TreeEqualityTestCase, wrap, wraptext

class TestArgument(TreeEqualityTestCase):
"""Test cases for the Argument node."""

def test_str(self):
"""test Argument.__str__()"""
node = Argument(wraptext("foobar"))
assert "{{{foobar}}}" == str(node)
node2 = Argument(wraptext("foo"), wraptext("bar"))
assert "{{{foo|bar}}}" == str(node2)
def test_str():
"""test Argument.__str__()"""
node = Argument(wraptext("foobar"))
assert "{{{foobar}}}" == str(node)
node2 = Argument(wraptext("foo"), wraptext("bar"))
assert "{{{foo|bar}}}" == str(node2)

def test_children(self):
"""test Argument.__children__()"""
node1 = Argument(wraptext("foobar"))
node2 = Argument(wraptext("foo"), wrap([Text("bar"), Text("baz")]))
gen1 = node1.__children__()
gen2 = node2.__children__()
assert node1.name is next(gen1)
assert node2.name is next(gen2)
assert node2.default is next(gen2)
with pytest.raises(StopIteration):
next(gen1)
with pytest.raises(StopIteration):
next(gen2)
def test_children():
"""test Argument.__children__()"""
node1 = Argument(wraptext("foobar"))
node2 = Argument(wraptext("foo"), wrap([Text("bar"), Text("baz")]))
gen1 = node1.__children__()
gen2 = node2.__children__()
assert node1.name is next(gen1)
assert node2.name is next(gen2)
assert node2.default is next(gen2)
with pytest.raises(StopIteration):
next(gen1)
with pytest.raises(StopIteration):
next(gen2)

def test_strip(self):
"""test Argument.__strip__()"""
node1 = Argument(wraptext("foobar"))
node2 = Argument(wraptext("foo"), wraptext("bar"))
assert node1.__strip__() is None
assert "bar" == node2.__strip__()
def test_strip():
"""test Argument.__strip__()"""
node1 = Argument(wraptext("foobar"))
node2 = Argument(wraptext("foo"), wraptext("bar"))
assert node1.__strip__() is None
assert "bar" == node2.__strip__()

def test_showtree(self):
"""test Argument.__showtree__()"""
output = []
getter, marker = object(), object()
get = lambda code: output.append((getter, code))
mark = lambda: output.append(marker)
node1 = Argument(wraptext("foobar"))
node2 = Argument(wraptext("foo"), wraptext("bar"))
node1.__showtree__(output.append, get, mark)
node2.__showtree__(output.append, get, mark)
valid = [
"{{{", (getter, node1.name), "}}}", "{{{", (getter, node2.name),
" | ", marker, (getter, node2.default), "}}}"]
assert valid == output
def test_showtree():
"""test Argument.__showtree__()"""
output = []
getter, marker = object(), object()
get = lambda code: output.append((getter, code))
mark = lambda: output.append(marker)
node1 = Argument(wraptext("foobar"))
node2 = Argument(wraptext("foo"), wraptext("bar"))
node1.__showtree__(output.append, get, mark)
node2.__showtree__(output.append, get, mark)
valid = [
"{{{", (getter, node1.name), "}}}", "{{{", (getter, node2.name),
" | ", marker, (getter, node2.default), "}}}"]
assert valid == output

def test_name(self):
"""test getter/setter for the name attribute"""
name = wraptext("foobar")
node1 = Argument(name)
node2 = Argument(name, wraptext("baz"))
assert name is node1.name
assert name is node2.name
node1.name = "héhehé"
node2.name = "héhehé"
self.assertWikicodeEqual(wraptext("héhehé"), node1.name)
self.assertWikicodeEqual(wraptext("héhehé"), node2.name)
def test_name():
"""test getter/setter for the name attribute"""
name = wraptext("foobar")
node1 = Argument(name)
node2 = Argument(name, wraptext("baz"))
assert name is node1.name
assert name is node2.name
node1.name = "héhehé"
node2.name = "héhehé"
assert_wikicode_equal(wraptext("héhehé"), node1.name)
assert_wikicode_equal(wraptext("héhehé"), node2.name)

def test_default(self):
"""test getter/setter for the default attribute"""
default = wraptext("baz")
node1 = Argument(wraptext("foobar"))
node2 = Argument(wraptext("foobar"), default)
assert None is node1.default
assert default is node2.default
node1.default = "buzz"
node2.default = None
self.assertWikicodeEqual(wraptext("buzz"), node1.default)
assert None is node2.default
def test_default():
"""test getter/setter for the default attribute"""
default = wraptext("baz")
node1 = Argument(wraptext("foobar"))
node2 = Argument(wraptext("foobar"), default)
assert None is node1.default
assert default is node2.default
node1.default = "buzz"
node2.default = None
assert_wikicode_equal(wraptext("buzz"), node1.default)
assert None is node2.default

+ 75
- 75
tests/test_attribute.py View File

@@ -18,88 +18,88 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""
Test cases for the Attribute node extra.
"""

import pytest

from mwparserfromhell.nodes import Template
from mwparserfromhell.nodes.extras import Attribute
from .conftest import assert_wikicode_equal, wrap, wraptext

from ._test_tree_equality import TreeEqualityTestCase, wrap, wraptext

class TestAttribute(TreeEqualityTestCase):
"""Test cases for the Attribute node extra."""
def test_str():
"""test Attribute.__str__()"""
node = Attribute(wraptext("foo"))
assert " foo" == str(node)
node2 = Attribute(wraptext("foo"), wraptext("bar"))
assert ' foo="bar"' == str(node2)
node3 = Attribute(wraptext("a"), wraptext("b"), '"', "", " ", " ")
assert 'a = "b"' == str(node3)
node4 = Attribute(wraptext("a"), wraptext("b"), "'", "", " ", " ")
assert "a = 'b'" == str(node4)
node5 = Attribute(wraptext("a"), wraptext("b"), None, "", " ", " ")
assert "a = b" == str(node5)
node6 = Attribute(wraptext("a"), wrap([]), None, " ", "", " ")
assert " a= " == str(node6)

def test_str(self):
"""test Attribute.__str__()"""
node = Attribute(wraptext("foo"))
assert " foo" == str(node)
node2 = Attribute(wraptext("foo"), wraptext("bar"))
assert ' foo="bar"' == str(node2)
node3 = Attribute(wraptext("a"), wraptext("b"), '"', "", " ", " ")
assert 'a = "b"' == str(node3)
node4 = Attribute(wraptext("a"), wraptext("b"), "'", "", " ", " ")
assert "a = 'b'" == str(node4)
node5 = Attribute(wraptext("a"), wraptext("b"), None, "", " ", " ")
assert "a = b" == str(node5)
node6 = Attribute(wraptext("a"), wrap([]), None, " ", "", " ")
assert " a= " == str(node6)
def test_name():
"""test getter/setter for the name attribute"""
name = wraptext("id")
node = Attribute(name, wraptext("bar"))
assert name is node.name
node.name = "{{id}}"
assert_wikicode_equal(wrap([Template(wraptext("id"))]), node.name)

def test_name(self):
"""test getter/setter for the name attribute"""
name = wraptext("id")
node = Attribute(name, wraptext("bar"))
assert name is node.name
node.name = "{{id}}"
self.assertWikicodeEqual(wrap([Template(wraptext("id"))]), node.name)
def test_value():
"""test getter/setter for the value attribute"""
value = wraptext("foo")
node = Attribute(wraptext("id"), value)
assert value is node.value
node.value = "{{bar}}"
assert_wikicode_equal(wrap([Template(wraptext("bar"))]), node.value)
node.value = None
assert None is node.value
node2 = Attribute(wraptext("id"), wraptext("foo"), None)
node2.value = "foo bar baz"
assert_wikicode_equal(wraptext("foo bar baz"), node2.value)
assert '"' == node2.quotes
node2.value = 'foo "bar" baz'
assert_wikicode_equal(wraptext('foo "bar" baz'), node2.value)
assert "'" == node2.quotes
node2.value = "foo 'bar' baz"
assert_wikicode_equal(wraptext("foo 'bar' baz"), node2.value)
assert '"' == node2.quotes
node2.value = "fo\"o 'bar' b\"az"
assert_wikicode_equal(wraptext("fo\"o 'bar' b\"az"), node2.value)
assert '"' == node2.quotes

def test_value(self):
"""test getter/setter for the value attribute"""
value = wraptext("foo")
node = Attribute(wraptext("id"), value)
assert value is node.value
node.value = "{{bar}}"
self.assertWikicodeEqual(wrap([Template(wraptext("bar"))]), node.value)
node.value = None
assert None is node.value
node2 = Attribute(wraptext("id"), wraptext("foo"), None)
node2.value = "foo bar baz"
self.assertWikicodeEqual(wraptext("foo bar baz"), node2.value)
assert '"' == node2.quotes
node2.value = 'foo "bar" baz'
self.assertWikicodeEqual(wraptext('foo "bar" baz'), node2.value)
assert "'" == node2.quotes
node2.value = "foo 'bar' baz"
self.assertWikicodeEqual(wraptext("foo 'bar' baz"), node2.value)
assert '"' == node2.quotes
node2.value = "fo\"o 'bar' b\"az"
self.assertWikicodeEqual(wraptext("fo\"o 'bar' b\"az"), node2.value)
assert '"' == node2.quotes
def test_quotes():
"""test getter/setter for the quotes attribute"""
node1 = Attribute(wraptext("id"), wraptext("foo"), None)
node2 = Attribute(wraptext("id"), wraptext("bar"))
node3 = Attribute(wraptext("id"), wraptext("foo bar baz"))
assert None is node1.quotes
assert '"' == node2.quotes
node1.quotes = "'"
node2.quotes = None
assert "'" == node1.quotes
assert None is node2.quotes
with pytest.raises(ValueError):
node1.__setattr__("quotes", "foobar")
with pytest.raises(ValueError):
node3.__setattr__("quotes", None)
with pytest.raises(ValueError):
Attribute(wraptext("id"), wraptext("foo bar baz"), None)

def test_quotes(self):
"""test getter/setter for the quotes attribute"""
node1 = Attribute(wraptext("id"), wraptext("foo"), None)
node2 = Attribute(wraptext("id"), wraptext("bar"))
node3 = Attribute(wraptext("id"), wraptext("foo bar baz"))
assert None is node1.quotes
assert '"' == node2.quotes
node1.quotes = "'"
node2.quotes = None
assert "'" == node1.quotes
assert None is node2.quotes
with pytest.raises(ValueError):
node1.__setattr__("quotes", "foobar")
def test_padding():
"""test getter/setter for the padding attributes"""
for pad in ["pad_first", "pad_before_eq", "pad_after_eq"]:
node = Attribute(wraptext("id"), wraptext("foo"), **{pad: "\n"})
assert "\n" == getattr(node, pad)
setattr(node, pad, " ")
assert " " == getattr(node, pad)
setattr(node, pad, None)
assert "" == getattr(node, pad)
with pytest.raises(ValueError):
node3.__setattr__("quotes", None)
with pytest.raises(ValueError):
Attribute(wraptext("id"), wraptext("foo bar baz"), None)

def test_padding(self):
"""test getter/setter for the padding attributes"""
for pad in ["pad_first", "pad_before_eq", "pad_after_eq"]:
node = Attribute(wraptext("id"), wraptext("foo"), **{pad: "\n"})
assert "\n" == getattr(node, pad)
setattr(node, pad, " ")
assert " " == getattr(node, pad)
setattr(node, pad, None)
assert "" == getattr(node, pad)
with pytest.raises(ValueError):
node.__setattr__(pad, True)
node.__setattr__(pad, True)

+ 399
- 399
tests/test_builder.py View File

@@ -18,6 +18,10 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""
Tests for the builder, which turns tokens into Wikicode objects.
"""

import pytest

from mwparserfromhell.nodes import (Argument, Comment, ExternalLink, Heading,
@@ -25,402 +29,398 @@ from mwparserfromhell.nodes import (Argument, Comment, ExternalLink, Heading,
from mwparserfromhell.nodes.extras import Attribute, Parameter
from mwparserfromhell.parser import tokens, ParserError
from mwparserfromhell.parser.builder import Builder

from ._test_tree_equality import TreeEqualityTestCase, wrap, wraptext

class TestBuilder(TreeEqualityTestCase):
"""Tests for the builder, which turns tokens into Wikicode objects."""

@pytest.fixture()
def builder(self):
return Builder()

@pytest.mark.parametrize("test,valid", [
([tokens.Text(text="foobar")], wraptext("foobar")),
([tokens.Text(text="fóóbar")], wraptext("fóóbar")),
([tokens.Text(text="spam"), tokens.Text(text="eggs")],
wraptext("spam", "eggs")),
])
def test_text(self, builder, test, valid):
"""tests for building Text nodes"""
self.assertWikicodeEqual(valid, builder.build(test))

@pytest.mark.parametrize("test,valid", [
([tokens.TemplateOpen(), tokens.Text(text="foobar"),
tokens.TemplateClose()],
wrap([Template(wraptext("foobar"))])),

([tokens.TemplateOpen(), tokens.Text(text="spam"),
tokens.Text(text="eggs"), tokens.TemplateClose()],
wrap([Template(wraptext("spam", "eggs"))])),

([tokens.TemplateOpen(), tokens.Text(text="foo"),
tokens.TemplateParamSeparator(), tokens.Text(text="bar"),
tokens.TemplateClose()],
wrap([Template(wraptext("foo"), params=[
Parameter(wraptext("1"), wraptext("bar"), showkey=False)])])),

([tokens.TemplateOpen(), tokens.Text(text="foo"),
tokens.TemplateParamSeparator(), tokens.Text(text="bar"),
tokens.TemplateParamEquals(), tokens.Text(text="baz"),
tokens.TemplateClose()],
wrap([Template(wraptext("foo"), params=[
Parameter(wraptext("bar"), wraptext("baz"))])])),

([tokens.TemplateOpen(), tokens.TemplateParamSeparator(),
tokens.TemplateParamSeparator(), tokens.TemplateParamEquals(),
tokens.TemplateParamSeparator(), tokens.TemplateClose()],
wrap([Template(wrap([]), params=[
Parameter(wraptext("1"), wrap([]), showkey=False),
Parameter(wrap([]), wrap([]), showkey=True),
Parameter(wraptext("2"), wrap([]), showkey=False)])])),

([tokens.TemplateOpen(), tokens.Text(text="foo"),
tokens.TemplateParamSeparator(), tokens.Text(text="bar"),
tokens.TemplateParamEquals(), tokens.Text(text="baz"),
tokens.TemplateParamSeparator(), tokens.Text(text="biz"),
tokens.TemplateParamSeparator(), tokens.Text(text="buzz"),
tokens.TemplateParamSeparator(), tokens.Text(text="3"),
tokens.TemplateParamEquals(), tokens.Text(text="buff"),
tokens.TemplateParamSeparator(), tokens.Text(text="baff"),
tokens.TemplateClose()],
wrap([Template(wraptext("foo"), params=[
Parameter(wraptext("bar"), wraptext("baz")),
Parameter(wraptext("1"), wraptext("biz"), showkey=False),
Parameter(wraptext("2"), wraptext("buzz"), showkey=False),
Parameter(wraptext("3"), wraptext("buff")),
Parameter(wraptext("3"), wraptext("baff"),
showkey=False)])])),
])
def test_template(self, builder, test, valid):
"""tests for building Template nodes"""
self.assertWikicodeEqual(valid, builder.build(test))

@pytest.mark.parametrize("test,valid", [
([tokens.ArgumentOpen(), tokens.Text(text="foobar"),
tokens.ArgumentClose()],
wrap([Argument(wraptext("foobar"))])),

([tokens.ArgumentOpen(), tokens.Text(text="spam"),
tokens.Text(text="eggs"), tokens.ArgumentClose()],
wrap([Argument(wraptext("spam", "eggs"))])),

([tokens.ArgumentOpen(), tokens.Text(text="foo"),
tokens.ArgumentSeparator(), tokens.Text(text="bar"),
tokens.ArgumentClose()],
wrap([Argument(wraptext("foo"), wraptext("bar"))])),

([tokens.ArgumentOpen(), tokens.Text(text="foo"),
tokens.Text(text="bar"), tokens.ArgumentSeparator(),
tokens.Text(text="baz"), tokens.Text(text="biz"),
tokens.ArgumentClose()],
wrap([Argument(wraptext("foo", "bar"), wraptext("baz", "biz"))])),
])
def test_argument(self, builder, test, valid):
"""tests for building Argument nodes"""
self.assertWikicodeEqual(valid, builder.build(test))

@pytest.mark.parametrize("test,valid", [
([tokens.WikilinkOpen(), tokens.Text(text="foobar"),
tokens.WikilinkClose()],
wrap([Wikilink(wraptext("foobar"))])),

([tokens.WikilinkOpen(), tokens.Text(text="spam"),
tokens.Text(text="eggs"), tokens.WikilinkClose()],
wrap([Wikilink(wraptext("spam", "eggs"))])),

([tokens.WikilinkOpen(), tokens.Text(text="foo"),
tokens.WikilinkSeparator(), tokens.Text(text="bar"),
tokens.WikilinkClose()],
wrap([Wikilink(wraptext("foo"), wraptext("bar"))])),

([tokens.WikilinkOpen(), tokens.Text(text="foo"),
tokens.Text(text="bar"), tokens.WikilinkSeparator(),
tokens.Text(text="baz"), tokens.Text(text="biz"),
tokens.WikilinkClose()],
wrap([Wikilink(wraptext("foo", "bar"), wraptext("baz", "biz"))])),
])
def test_wikilink(self, builder, test, valid):
"""tests for building Wikilink nodes"""
self.assertWikicodeEqual(valid, builder.build(test))

@pytest.mark.parametrize("test,valid", [
([tokens.ExternalLinkOpen(brackets=False),
tokens.Text(text="http://example.com/"),
tokens.ExternalLinkClose()],
wrap([ExternalLink(wraptext("http://example.com/"),
brackets=False)])),

([tokens.ExternalLinkOpen(brackets=True),
tokens.Text(text="http://example.com/"),
tokens.ExternalLinkClose()],
wrap([ExternalLink(wraptext("http://example.com/"))])),

([tokens.ExternalLinkOpen(brackets=True),
tokens.Text(text="http://example.com/"),
tokens.ExternalLinkSeparator(), tokens.ExternalLinkClose()],
wrap([ExternalLink(wraptext("http://example.com/"), wrap([]))])),

([tokens.ExternalLinkOpen(brackets=True),
tokens.Text(text="http://example.com/"),
tokens.ExternalLinkSeparator(), tokens.Text(text="Example"),
tokens.ExternalLinkClose()],
wrap([ExternalLink(wraptext("http://example.com/"),
wraptext("Example"))])),

([tokens.ExternalLinkOpen(brackets=False),
tokens.Text(text="http://example"), tokens.Text(text=".com/foo"),
tokens.ExternalLinkClose()],
wrap([ExternalLink(wraptext("http://example", ".com/foo"),
brackets=False)])),

([tokens.ExternalLinkOpen(brackets=True),
tokens.Text(text="http://example"), tokens.Text(text=".com/foo"),
tokens.ExternalLinkSeparator(), tokens.Text(text="Example"),
tokens.Text(text=" Web Page"), tokens.ExternalLinkClose()],
wrap([ExternalLink(wraptext("http://example", ".com/foo"),
wraptext("Example", " Web Page"))])),
])
def test_external_link(self, builder, test, valid):
"""tests for building ExternalLink nodes"""
self.assertWikicodeEqual(valid, builder.build(test))

@pytest.mark.parametrize("test,valid", [
([tokens.HTMLEntityStart(), tokens.Text(text="nbsp"),
tokens.HTMLEntityEnd()],
wrap([HTMLEntity("nbsp", named=True, hexadecimal=False)])),

([tokens.HTMLEntityStart(), tokens.HTMLEntityNumeric(),
tokens.Text(text="107"), tokens.HTMLEntityEnd()],
wrap([HTMLEntity("107", named=False, hexadecimal=False)])),

([tokens.HTMLEntityStart(), tokens.HTMLEntityNumeric(),
tokens.HTMLEntityHex(char="X"), tokens.Text(text="6B"),
tokens.HTMLEntityEnd()],
wrap([HTMLEntity("6B", named=False, hexadecimal=True,
hex_char="X")])),
])
def test_html_entity(self, builder, test, valid):
"""tests for building HTMLEntity nodes"""
self.assertWikicodeEqual(valid, builder.build(test))

@pytest.mark.parametrize("test,valid", [
([tokens.HeadingStart(level=2), tokens.Text(text="foobar"),
tokens.HeadingEnd()],
wrap([Heading(wraptext("foobar"), 2)])),

([tokens.HeadingStart(level=4), tokens.Text(text="spam"),
tokens.Text(text="eggs"), tokens.HeadingEnd()],
wrap([Heading(wraptext("spam", "eggs"), 4)])),
])
def test_heading(self, builder, test, valid):
"""tests for building Heading nodes"""
self.assertWikicodeEqual(valid, builder.build(test))

@pytest.mark.parametrize("test,valid", [
([tokens.CommentStart(), tokens.Text(text="foobar"),
tokens.CommentEnd()],
wrap([Comment("foobar")])),

([tokens.CommentStart(), tokens.Text(text="spam"),
tokens.Text(text="eggs"), tokens.CommentEnd()],
wrap([Comment("spameggs")])),
])
def test_comment(self, builder, test, valid):
"""tests for building Comment nodes"""
self.assertWikicodeEqual(valid, builder.build(test))

@pytest.mark.parametrize("test,valid", [
# <ref></ref>
([tokens.TagOpenOpen(), tokens.Text(text="ref"),
tokens.TagCloseOpen(padding=""), tokens.TagOpenClose(),
tokens.Text(text="ref"), tokens.TagCloseClose()],
wrap([Tag(wraptext("ref"), wrap([]),
closing_tag=wraptext("ref"))])),

# <ref name></ref>
([tokens.TagOpenOpen(), tokens.Text(text="ref"),
tokens.TagAttrStart(pad_first=" ", pad_before_eq="",
pad_after_eq=""),
tokens.Text(text="name"), tokens.TagCloseOpen(padding=""),
tokens.TagOpenClose(), tokens.Text(text="ref"),
tokens.TagCloseClose()],
wrap([Tag(wraptext("ref"), wrap([]),
attrs=[Attribute(wraptext("name"))])])),

# <ref name="abc" />
([tokens.TagOpenOpen(), tokens.Text(text="ref"),
tokens.TagAttrStart(pad_first=" ", pad_before_eq="",
pad_after_eq=""),
tokens.Text(text="name"), tokens.TagAttrEquals(),
tokens.TagAttrQuote(char='"'), tokens.Text(text="abc"),
tokens.TagCloseSelfclose(padding=" ")],
wrap([Tag(wraptext("ref"),
attrs=[Attribute(wraptext("name"), wraptext("abc"))],
self_closing=True, padding=" ")])),

# <br/>
([tokens.TagOpenOpen(), tokens.Text(text="br"),
tokens.TagCloseSelfclose(padding="")],
wrap([Tag(wraptext("br"), self_closing=True)])),

# <li>
([tokens.TagOpenOpen(), tokens.Text(text="li"),
tokens.TagCloseSelfclose(padding="", implicit=True)],
wrap([Tag(wraptext("li"), self_closing=True, implicit=True)])),

# </br>
([tokens.TagOpenOpen(invalid=True), tokens.Text(text="br"),
tokens.TagCloseSelfclose(padding="", implicit=True)],
wrap([Tag(wraptext("br"), self_closing=True, invalid=True,
implicit=True)])),

# </br/>
([tokens.TagOpenOpen(invalid=True), tokens.Text(text="br"),
tokens.TagCloseSelfclose(padding="")],
wrap([Tag(wraptext("br"), self_closing=True, invalid=True)])),

# <ref name={{abc}} foo="bar {{baz}}" abc={{de}}f ghi=j{{k}}{{l}}
# mno = '{{p}} [[q]] {{r}}'>[[Source]]</ref>
([tokens.TagOpenOpen(), tokens.Text(text="ref"),
tokens.TagAttrStart(pad_first=" ", pad_before_eq="",
pad_after_eq=""),
tokens.Text(text="name"), tokens.TagAttrEquals(),
tokens.TemplateOpen(), tokens.Text(text="abc"),
tokens.TemplateClose(),
tokens.TagAttrStart(pad_first=" ", pad_before_eq="",
pad_after_eq=""),
tokens.Text(text="foo"), tokens.TagAttrEquals(),
tokens.TagAttrQuote(char='"'), tokens.Text(text="bar "),
tokens.TemplateOpen(), tokens.Text(text="baz"),
tokens.TemplateClose(),
tokens.TagAttrStart(pad_first=" ", pad_before_eq="",
pad_after_eq=""),
tokens.Text(text="abc"), tokens.TagAttrEquals(),
tokens.TemplateOpen(), tokens.Text(text="de"),
tokens.TemplateClose(), tokens.Text(text="f"),
tokens.TagAttrStart(pad_first=" ", pad_before_eq="",
pad_after_eq=""),
tokens.Text(text="ghi"), tokens.TagAttrEquals(),
tokens.Text(text="j"), tokens.TemplateOpen(),
tokens.Text(text="k"), tokens.TemplateClose(),
tokens.TemplateOpen(), tokens.Text(text="l"),
tokens.TemplateClose(),
tokens.TagAttrStart(pad_first=" \n ", pad_before_eq=" ",
pad_after_eq=" "),
tokens.Text(text="mno"), tokens.TagAttrEquals(),
tokens.TagAttrQuote(char="'"), tokens.TemplateOpen(),
tokens.Text(text="p"), tokens.TemplateClose(),
tokens.Text(text=" "), tokens.WikilinkOpen(),
tokens.Text(text="q"), tokens.WikilinkClose(),
tokens.Text(text=" "), tokens.TemplateOpen(),
tokens.Text(text="r"), tokens.TemplateClose(),
tokens.TagCloseOpen(padding=""), tokens.WikilinkOpen(),
tokens.Text(text="Source"), tokens.WikilinkClose(),
tokens.TagOpenClose(), tokens.Text(text="ref"),
tokens.TagCloseClose()],
wrap([Tag(wraptext("ref"), wrap([Wikilink(wraptext("Source"))]), [
Attribute(wraptext("name"),
wrap([Template(wraptext("abc"))]), None),
Attribute(wraptext("foo"), wrap([Text("bar "),
Template(wraptext("baz"))]), pad_first=" "),
Attribute(wraptext("abc"), wrap([Template(wraptext("de")),
Text("f")]), None),
Attribute(wraptext("ghi"), wrap([Text("j"),
Template(wraptext("k")),
Template(wraptext("l"))]), None),
Attribute(wraptext("mno"), wrap([Template(wraptext("p")),
Text(" "), Wikilink(wraptext("q")), Text(" "),
Template(wraptext("r"))]), "'", " \n ", " ",
" ")])])),

# "''italic text''"
([tokens.TagOpenOpen(wiki_markup="''"), tokens.Text(text="i"),
tokens.TagCloseOpen(), tokens.Text(text="italic text"),
tokens.TagOpenClose(), tokens.Text(text="i"),
tokens.TagCloseClose()],
wrap([Tag(wraptext("i"), wraptext("italic text"),
wiki_markup="''")])),

# * bullet
([tokens.TagOpenOpen(wiki_markup="*"), tokens.Text(text="li"),
tokens.TagCloseSelfclose(), tokens.Text(text=" bullet")],
wrap([Tag(wraptext("li"), wiki_markup="*", self_closing=True),
Text(" bullet")])),
])
def test_tag(self, builder, test, valid):
"""tests for building Tag nodes"""
self.assertWikicodeEqual(valid, builder.build(test))

def test_integration(self, builder):
"""a test for building a combination of templates together"""
# {{{{{{{{foo}}bar|baz=biz}}buzz}}usr|{{bin}}}}
test = [tokens.TemplateOpen(), tokens.TemplateOpen(),
tokens.TemplateOpen(), tokens.TemplateOpen(),
tokens.Text(text="foo"), tokens.TemplateClose(),
tokens.Text(text="bar"), tokens.TemplateParamSeparator(),
tokens.Text(text="baz"), tokens.TemplateParamEquals(),
tokens.Text(text="biz"), tokens.TemplateClose(),
tokens.Text(text="buzz"), tokens.TemplateClose(),
tokens.Text(text="usr"), tokens.TemplateParamSeparator(),
tokens.TemplateOpen(), tokens.Text(text="bin"),
tokens.TemplateClose(), tokens.TemplateClose()]
valid = wrap(
[Template(wrap([Template(wrap([Template(wrap([Template(wraptext(
"foo")), Text("bar")]), params=[Parameter(wraptext("baz"),
wraptext("biz"))]), Text("buzz")])), Text("usr")]), params=[
Parameter(wraptext("1"), wrap([Template(wraptext("bin"))]),
showkey=False)])])
self.assertWikicodeEqual(valid, builder.build(test))

def test_integration2(self, builder):
"""an even more audacious test for building a horrible wikicode mess"""
# {{a|b|{{c|[[d]]{{{e}}}}}}}[[f|{{{g}}}<!--h-->]]{{i|j=&nbsp;}}
test = [tokens.TemplateOpen(), tokens.Text(text="a"),
tokens.TemplateParamSeparator(), tokens.Text(text="b"),
tokens.TemplateParamSeparator(), tokens.TemplateOpen(),
tokens.Text(text="c"), tokens.TemplateParamSeparator(),
tokens.WikilinkOpen(), tokens.Text(text="d"),
tokens.WikilinkClose(), tokens.ArgumentOpen(),
tokens.Text(text="e"), tokens.ArgumentClose(),
tokens.TemplateClose(), tokens.TemplateClose(),
tokens.WikilinkOpen(), tokens.Text(text="f"),
tokens.WikilinkSeparator(), tokens.ArgumentOpen(),
tokens.Text(text="g"), tokens.ArgumentClose(),
tokens.CommentStart(), tokens.Text(text="h"),
tokens.CommentEnd(), tokens.WikilinkClose(),
tokens.TemplateOpen(), tokens.Text(text="i"),
tokens.TemplateParamSeparator(), tokens.Text(text="j"),
tokens.TemplateParamEquals(), tokens.HTMLEntityStart(),
tokens.Text(text="nbsp"), tokens.HTMLEntityEnd(),
tokens.TemplateClose()]
valid = wrap(
[Template(wraptext("a"), params=[Parameter(wraptext("1"), wraptext(
"b"), showkey=False), Parameter(wraptext("2"), wrap([Template(
wraptext("c"), params=[Parameter(wraptext("1"), wrap([Wikilink(
wraptext("d")), Argument(wraptext("e"))]), showkey=False)])]),
showkey=False)]), Wikilink(wraptext("f"), wrap([Argument(wraptext(
"g")), Comment("h")])), Template(wraptext("i"), params=[
Parameter(wraptext("j"), wrap([HTMLEntity("nbsp",
named=True)]))])])
self.assertWikicodeEqual(valid, builder.build(test))

@pytest.mark.parametrize("tokens", [
[tokens.TemplateOpen(), tokens.TemplateParamSeparator()],
[tokens.TemplateOpen()], [tokens.ArgumentOpen()],
[tokens.WikilinkOpen()], [tokens.ExternalLinkOpen()],
[tokens.HeadingStart()], [tokens.CommentStart()],
[tokens.TagOpenOpen(), tokens.TagAttrStart()],
[tokens.TagOpenOpen()]
])
def test_parser_errors(self, builder, tokens):
"""test whether ParserError gets thrown for bad input"""
with pytest.raises(ParserError):
builder.build(tokens)

def test_parser_errors_templateclose(self, builder):
with pytest.raises(
ParserError,
match=r"_handle_token\(\) got unexpected TemplateClose"
):
builder.build([tokens.TemplateClose()])
from .conftest import assert_wikicode_equal, wrap, wraptext

@pytest.fixture()
def builder():
return Builder()

@pytest.mark.parametrize("test,valid", [
([tokens.Text(text="foobar")], wraptext("foobar")),
([tokens.Text(text="fóóbar")], wraptext("fóóbar")),
([tokens.Text(text="spam"), tokens.Text(text="eggs")],
wraptext("spam", "eggs")),
])
def test_text(builder, test, valid):
"""tests for building Text nodes"""
assert_wikicode_equal(valid, builder.build(test))

@pytest.mark.parametrize("test,valid", [
([tokens.TemplateOpen(), tokens.Text(text="foobar"),
tokens.TemplateClose()],
wrap([Template(wraptext("foobar"))])),

([tokens.TemplateOpen(), tokens.Text(text="spam"),
tokens.Text(text="eggs"), tokens.TemplateClose()],
wrap([Template(wraptext("spam", "eggs"))])),

([tokens.TemplateOpen(), tokens.Text(text="foo"),
tokens.TemplateParamSeparator(), tokens.Text(text="bar"),
tokens.TemplateClose()],
wrap([Template(wraptext("foo"), params=[
Parameter(wraptext("1"), wraptext("bar"), showkey=False)])])),

([tokens.TemplateOpen(), tokens.Text(text="foo"),
tokens.TemplateParamSeparator(), tokens.Text(text="bar"),
tokens.TemplateParamEquals(), tokens.Text(text="baz"),
tokens.TemplateClose()],
wrap([Template(wraptext("foo"), params=[
Parameter(wraptext("bar"), wraptext("baz"))])])),

([tokens.TemplateOpen(), tokens.TemplateParamSeparator(),
tokens.TemplateParamSeparator(), tokens.TemplateParamEquals(),
tokens.TemplateParamSeparator(), tokens.TemplateClose()],
wrap([Template(wrap([]), params=[
Parameter(wraptext("1"), wrap([]), showkey=False),
Parameter(wrap([]), wrap([]), showkey=True),
Parameter(wraptext("2"), wrap([]), showkey=False)])])),

([tokens.TemplateOpen(), tokens.Text(text="foo"),
tokens.TemplateParamSeparator(), tokens.Text(text="bar"),
tokens.TemplateParamEquals(), tokens.Text(text="baz"),
tokens.TemplateParamSeparator(), tokens.Text(text="biz"),
tokens.TemplateParamSeparator(), tokens.Text(text="buzz"),
tokens.TemplateParamSeparator(), tokens.Text(text="3"),
tokens.TemplateParamEquals(), tokens.Text(text="buff"),
tokens.TemplateParamSeparator(), tokens.Text(text="baff"),
tokens.TemplateClose()],
wrap([Template(wraptext("foo"), params=[
Parameter(wraptext("bar"), wraptext("baz")),
Parameter(wraptext("1"), wraptext("biz"), showkey=False),
Parameter(wraptext("2"), wraptext("buzz"), showkey=False),
Parameter(wraptext("3"), wraptext("buff")),
Parameter(wraptext("3"), wraptext("baff"),
showkey=False)])])),
])
def test_template(builder, test, valid):
"""tests for building Template nodes"""
assert_wikicode_equal(valid, builder.build(test))

@pytest.mark.parametrize("test,valid", [
([tokens.ArgumentOpen(), tokens.Text(text="foobar"),
tokens.ArgumentClose()],
wrap([Argument(wraptext("foobar"))])),

([tokens.ArgumentOpen(), tokens.Text(text="spam"),
tokens.Text(text="eggs"), tokens.ArgumentClose()],
wrap([Argument(wraptext("spam", "eggs"))])),

([tokens.ArgumentOpen(), tokens.Text(text="foo"),
tokens.ArgumentSeparator(), tokens.Text(text="bar"),
tokens.ArgumentClose()],
wrap([Argument(wraptext("foo"), wraptext("bar"))])),

([tokens.ArgumentOpen(), tokens.Text(text="foo"),
tokens.Text(text="bar"), tokens.ArgumentSeparator(),
tokens.Text(text="baz"), tokens.Text(text="biz"),
tokens.ArgumentClose()],
wrap([Argument(wraptext("foo", "bar"), wraptext("baz", "biz"))])),
])
def test_argument(builder, test, valid):
"""tests for building Argument nodes"""
assert_wikicode_equal(valid, builder.build(test))

@pytest.mark.parametrize("test,valid", [
([tokens.WikilinkOpen(), tokens.Text(text="foobar"),
tokens.WikilinkClose()],
wrap([Wikilink(wraptext("foobar"))])),

([tokens.WikilinkOpen(), tokens.Text(text="spam"),
tokens.Text(text="eggs"), tokens.WikilinkClose()],
wrap([Wikilink(wraptext("spam", "eggs"))])),

([tokens.WikilinkOpen(), tokens.Text(text="foo"),
tokens.WikilinkSeparator(), tokens.Text(text="bar"),
tokens.WikilinkClose()],
wrap([Wikilink(wraptext("foo"), wraptext("bar"))])),

([tokens.WikilinkOpen(), tokens.Text(text="foo"),
tokens.Text(text="bar"), tokens.WikilinkSeparator(),
tokens.Text(text="baz"), tokens.Text(text="biz"),
tokens.WikilinkClose()],
wrap([Wikilink(wraptext("foo", "bar"), wraptext("baz", "biz"))])),
])
def test_wikilink(builder, test, valid):
"""tests for building Wikilink nodes"""
assert_wikicode_equal(valid, builder.build(test))

@pytest.mark.parametrize("test,valid", [
([tokens.ExternalLinkOpen(brackets=False),
tokens.Text(text="http://example.com/"),
tokens.ExternalLinkClose()],
wrap([ExternalLink(wraptext("http://example.com/"),
brackets=False)])),

([tokens.ExternalLinkOpen(brackets=True),
tokens.Text(text="http://example.com/"),
tokens.ExternalLinkClose()],
wrap([ExternalLink(wraptext("http://example.com/"))])),

([tokens.ExternalLinkOpen(brackets=True),
tokens.Text(text="http://example.com/"),
tokens.ExternalLinkSeparator(), tokens.ExternalLinkClose()],
wrap([ExternalLink(wraptext("http://example.com/"), wrap([]))])),

([tokens.ExternalLinkOpen(brackets=True),
tokens.Text(text="http://example.com/"),
tokens.ExternalLinkSeparator(), tokens.Text(text="Example"),
tokens.ExternalLinkClose()],
wrap([ExternalLink(wraptext("http://example.com/"),
wraptext("Example"))])),

([tokens.ExternalLinkOpen(brackets=False),
tokens.Text(text="http://example"), tokens.Text(text=".com/foo"),
tokens.ExternalLinkClose()],
wrap([ExternalLink(wraptext("http://example", ".com/foo"),
brackets=False)])),

([tokens.ExternalLinkOpen(brackets=True),
tokens.Text(text="http://example"), tokens.Text(text=".com/foo"),
tokens.ExternalLinkSeparator(), tokens.Text(text="Example"),
tokens.Text(text=" Web Page"), tokens.ExternalLinkClose()],
wrap([ExternalLink(wraptext("http://example", ".com/foo"),
wraptext("Example", " Web Page"))])),
])
def test_external_link(builder, test, valid):
"""tests for building ExternalLink nodes"""
assert_wikicode_equal(valid, builder.build(test))

@pytest.mark.parametrize("test,valid", [
([tokens.HTMLEntityStart(), tokens.Text(text="nbsp"),
tokens.HTMLEntityEnd()],
wrap([HTMLEntity("nbsp", named=True, hexadecimal=False)])),

([tokens.HTMLEntityStart(), tokens.HTMLEntityNumeric(),
tokens.Text(text="107"), tokens.HTMLEntityEnd()],
wrap([HTMLEntity("107", named=False, hexadecimal=False)])),

([tokens.HTMLEntityStart(), tokens.HTMLEntityNumeric(),
tokens.HTMLEntityHex(char="X"), tokens.Text(text="6B"),
tokens.HTMLEntityEnd()],
wrap([HTMLEntity("6B", named=False, hexadecimal=True,
hex_char="X")])),
])
def test_html_entity(builder, test, valid):
"""tests for building HTMLEntity nodes"""
assert_wikicode_equal(valid, builder.build(test))

@pytest.mark.parametrize("test,valid", [
([tokens.HeadingStart(level=2), tokens.Text(text="foobar"),
tokens.HeadingEnd()],
wrap([Heading(wraptext("foobar"), 2)])),

([tokens.HeadingStart(level=4), tokens.Text(text="spam"),
tokens.Text(text="eggs"), tokens.HeadingEnd()],
wrap([Heading(wraptext("spam", "eggs"), 4)])),
])
def test_heading(builder, test, valid):
"""tests for building Heading nodes"""
assert_wikicode_equal(valid, builder.build(test))

@pytest.mark.parametrize("test,valid", [
([tokens.CommentStart(), tokens.Text(text="foobar"),
tokens.CommentEnd()],
wrap([Comment("foobar")])),

([tokens.CommentStart(), tokens.Text(text="spam"),
tokens.Text(text="eggs"), tokens.CommentEnd()],
wrap([Comment("spameggs")])),
])
def test_comment(builder, test, valid):
"""tests for building Comment nodes"""
assert_wikicode_equal(valid, builder.build(test))

@pytest.mark.parametrize("test,valid", [
# <ref></ref>
([tokens.TagOpenOpen(), tokens.Text(text="ref"),
tokens.TagCloseOpen(padding=""), tokens.TagOpenClose(),
tokens.Text(text="ref"), tokens.TagCloseClose()],
wrap([Tag(wraptext("ref"), wrap([]),
closing_tag=wraptext("ref"))])),

# <ref name></ref>
([tokens.TagOpenOpen(), tokens.Text(text="ref"),
tokens.TagAttrStart(pad_first=" ", pad_before_eq="",
pad_after_eq=""),
tokens.Text(text="name"), tokens.TagCloseOpen(padding=""),
tokens.TagOpenClose(), tokens.Text(text="ref"),
tokens.TagCloseClose()],
wrap([Tag(wraptext("ref"), wrap([]),
attrs=[Attribute(wraptext("name"))])])),

# <ref name="abc" />
([tokens.TagOpenOpen(), tokens.Text(text="ref"),
tokens.TagAttrStart(pad_first=" ", pad_before_eq="",
pad_after_eq=""),
tokens.Text(text="name"), tokens.TagAttrEquals(),
tokens.TagAttrQuote(char='"'), tokens.Text(text="abc"),
tokens.TagCloseSelfclose(padding=" ")],
wrap([Tag(wraptext("ref"),
attrs=[Attribute(wraptext("name"), wraptext("abc"))],
self_closing=True, padding=" ")])),

# <br/>
([tokens.TagOpenOpen(), tokens.Text(text="br"),
tokens.TagCloseSelfclose(padding="")],
wrap([Tag(wraptext("br"), self_closing=True)])),

# <li>
([tokens.TagOpenOpen(), tokens.Text(text="li"),
tokens.TagCloseSelfclose(padding="", implicit=True)],
wrap([Tag(wraptext("li"), self_closing=True, implicit=True)])),

# </br>
([tokens.TagOpenOpen(invalid=True), tokens.Text(text="br"),
tokens.TagCloseSelfclose(padding="", implicit=True)],
wrap([Tag(wraptext("br"), self_closing=True, invalid=True,
implicit=True)])),

# </br/>
([tokens.TagOpenOpen(invalid=True), tokens.Text(text="br"),
tokens.TagCloseSelfclose(padding="")],
wrap([Tag(wraptext("br"), self_closing=True, invalid=True)])),

# <ref name={{abc}} foo="bar {{baz}}" abc={{de}}f ghi=j{{k}}{{l}}
# mno = '{{p}} [[q]] {{r}}'>[[Source]]</ref>
([tokens.TagOpenOpen(), tokens.Text(text="ref"),
tokens.TagAttrStart(pad_first=" ", pad_before_eq="",
pad_after_eq=""),
tokens.Text(text="name"), tokens.TagAttrEquals(),
tokens.TemplateOpen(), tokens.Text(text="abc"),
tokens.TemplateClose(),
tokens.TagAttrStart(pad_first=" ", pad_before_eq="",
pad_after_eq=""),
tokens.Text(text="foo"), tokens.TagAttrEquals(),
tokens.TagAttrQuote(char='"'), tokens.Text(text="bar "),
tokens.TemplateOpen(), tokens.Text(text="baz"),
tokens.TemplateClose(),
tokens.TagAttrStart(pad_first=" ", pad_before_eq="",
pad_after_eq=""),
tokens.Text(text="abc"), tokens.TagAttrEquals(),
tokens.TemplateOpen(), tokens.Text(text="de"),
tokens.TemplateClose(), tokens.Text(text="f"),
tokens.TagAttrStart(pad_first=" ", pad_before_eq="",
pad_after_eq=""),
tokens.Text(text="ghi"), tokens.TagAttrEquals(),
tokens.Text(text="j"), tokens.TemplateOpen(),
tokens.Text(text="k"), tokens.TemplateClose(),
tokens.TemplateOpen(), tokens.Text(text="l"),
tokens.TemplateClose(),
tokens.TagAttrStart(pad_first=" \n ", pad_before_eq=" ",
pad_after_eq=" "),
tokens.Text(text="mno"), tokens.TagAttrEquals(),
tokens.TagAttrQuote(char="'"), tokens.TemplateOpen(),
tokens.Text(text="p"), tokens.TemplateClose(),
tokens.Text(text=" "), tokens.WikilinkOpen(),
tokens.Text(text="q"), tokens.WikilinkClose(),
tokens.Text(text=" "), tokens.TemplateOpen(),
tokens.Text(text="r"), tokens.TemplateClose(),
tokens.TagCloseOpen(padding=""), tokens.WikilinkOpen(),
tokens.Text(text="Source"), tokens.WikilinkClose(),
tokens.TagOpenClose(), tokens.Text(text="ref"),
tokens.TagCloseClose()],
wrap([Tag(wraptext("ref"), wrap([Wikilink(wraptext("Source"))]), [
Attribute(wraptext("name"),
wrap([Template(wraptext("abc"))]), None),
Attribute(wraptext("foo"), wrap([Text("bar "),
Template(wraptext("baz"))]), pad_first=" "),
Attribute(wraptext("abc"), wrap([Template(wraptext("de")),
Text("f")]), None),
Attribute(wraptext("ghi"), wrap([Text("j"),
Template(wraptext("k")),
Template(wraptext("l"))]), None),
Attribute(wraptext("mno"), wrap([Template(wraptext("p")),
Text(" "), Wikilink(wraptext("q")), Text(" "),
Template(wraptext("r"))]), "'", " \n ", " ",
" ")])])),

# "''italic text''"
([tokens.TagOpenOpen(wiki_markup="''"), tokens.Text(text="i"),
tokens.TagCloseOpen(), tokens.Text(text="italic text"),
tokens.TagOpenClose(), tokens.Text(text="i"),
tokens.TagCloseClose()],
wrap([Tag(wraptext("i"), wraptext("italic text"),
wiki_markup="''")])),

# * bullet
([tokens.TagOpenOpen(wiki_markup="*"), tokens.Text(text="li"),
tokens.TagCloseSelfclose(), tokens.Text(text=" bullet")],
wrap([Tag(wraptext("li"), wiki_markup="*", self_closing=True),
Text(" bullet")])),
])
def test_tag(builder, test, valid):
"""tests for building Tag nodes"""
assert_wikicode_equal(valid, builder.build(test))

def test_integration(builder):
"""a test for building a combination of templates together"""
# {{{{{{{{foo}}bar|baz=biz}}buzz}}usr|{{bin}}}}
test = [tokens.TemplateOpen(), tokens.TemplateOpen(),
tokens.TemplateOpen(), tokens.TemplateOpen(),
tokens.Text(text="foo"), tokens.TemplateClose(),
tokens.Text(text="bar"), tokens.TemplateParamSeparator(),
tokens.Text(text="baz"), tokens.TemplateParamEquals(),
tokens.Text(text="biz"), tokens.TemplateClose(),
tokens.Text(text="buzz"), tokens.TemplateClose(),
tokens.Text(text="usr"), tokens.TemplateParamSeparator(),
tokens.TemplateOpen(), tokens.Text(text="bin"),
tokens.TemplateClose(), tokens.TemplateClose()]
valid = wrap(
[Template(wrap([Template(wrap([Template(wrap([Template(wraptext(
"foo")), Text("bar")]), params=[Parameter(wraptext("baz"),
wraptext("biz"))]), Text("buzz")])), Text("usr")]), params=[
Parameter(wraptext("1"), wrap([Template(wraptext("bin"))]),
showkey=False)])])
assert_wikicode_equal(valid, builder.build(test))

def test_integration2(builder):
"""an even more audacious test for building a horrible wikicode mess"""
# {{a|b|{{c|[[d]]{{{e}}}}}}}[[f|{{{g}}}<!--h-->]]{{i|j=&nbsp;}}
test = [tokens.TemplateOpen(), tokens.Text(text="a"),
tokens.TemplateParamSeparator(), tokens.Text(text="b"),
tokens.TemplateParamSeparator(), tokens.TemplateOpen(),
tokens.Text(text="c"), tokens.TemplateParamSeparator(),
tokens.WikilinkOpen(), tokens.Text(text="d"),
tokens.WikilinkClose(), tokens.ArgumentOpen(),
tokens.Text(text="e"), tokens.ArgumentClose(),
tokens.TemplateClose(), tokens.TemplateClose(),
tokens.WikilinkOpen(), tokens.Text(text="f"),
tokens.WikilinkSeparator(), tokens.ArgumentOpen(),
tokens.Text(text="g"), tokens.ArgumentClose(),
tokens.CommentStart(), tokens.Text(text="h"),
tokens.CommentEnd(), tokens.WikilinkClose(),
tokens.TemplateOpen(), tokens.Text(text="i"),
tokens.TemplateParamSeparator(), tokens.Text(text="j"),
tokens.TemplateParamEquals(), tokens.HTMLEntityStart(),
tokens.Text(text="nbsp"), tokens.HTMLEntityEnd(),
tokens.TemplateClose()]
valid = wrap(
[Template(wraptext("a"), params=[Parameter(wraptext("1"), wraptext(
"b"), showkey=False), Parameter(wraptext("2"), wrap([Template(
wraptext("c"), params=[Parameter(wraptext("1"), wrap([Wikilink(
wraptext("d")), Argument(wraptext("e"))]), showkey=False)])]),
showkey=False)]), Wikilink(wraptext("f"), wrap([Argument(wraptext(
"g")), Comment("h")])), Template(wraptext("i"), params=[
Parameter(wraptext("j"), wrap([HTMLEntity("nbsp",
named=True)]))])])
assert_wikicode_equal(valid, builder.build(test))

@pytest.mark.parametrize("tokens", [
[tokens.TemplateOpen(), tokens.TemplateParamSeparator()],
[tokens.TemplateOpen()], [tokens.ArgumentOpen()],
[tokens.WikilinkOpen()], [tokens.ExternalLinkOpen()],
[tokens.HeadingStart()], [tokens.CommentStart()],
[tokens.TagOpenOpen(), tokens.TagAttrStart()],
[tokens.TagOpenOpen()]
])
def test_parser_errors(builder, tokens):
"""test whether ParserError gets thrown for bad input"""
with pytest.raises(ParserError):
builder.build(tokens)

def test_parser_errors_templateclose(builder):
with pytest.raises(
ParserError,
match=r"_handle_token\(\) got unexpected TemplateClose"
):
builder.build([tokens.TemplateClose()])

+ 34
- 35
tests/test_comment.py View File

@@ -18,42 +18,41 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""
Test cases for the Comment node.
"""

import pytest

from mwparserfromhell.nodes import Comment

from ._test_tree_equality import TreeEqualityTestCase

class TestComment(TreeEqualityTestCase):
"""Test cases for the Comment node."""

def test_str(self):
"""test Comment.__str__()"""
node = Comment("foobar")
assert "<!--foobar-->" == str(node)

def test_children(self):
"""test Comment.__children__()"""
node = Comment("foobar")
gen = node.__children__()
with pytest.raises(StopIteration):
next(gen)

def test_strip(self):
"""test Comment.__strip__()"""
node = Comment("foobar")
assert node.__strip__() is None

def test_showtree(self):
"""test Comment.__showtree__()"""
output = []
node = Comment("foobar")
node.__showtree__(output.append, None, None)
assert ["<!--foobar-->"] == output

def test_contents(self):
"""test getter/setter for the contents attribute"""
node = Comment("foobar")
assert "foobar" == node.contents
node.contents = "barfoo"
assert "barfoo" == node.contents
def test_str():
"""test Comment.__str__()"""
node = Comment("foobar")
assert "<!--foobar-->" == str(node)

def test_children():
"""test Comment.__children__()"""
node = Comment("foobar")
gen = node.__children__()
with pytest.raises(StopIteration):
next(gen)

def test_strip():
"""test Comment.__strip__()"""
node = Comment("foobar")
assert node.__strip__() is None

def test_showtree():
"""test Comment.__showtree__()"""
output = []
node = Comment("foobar")
node.__showtree__(output.append, None, None)
assert ["<!--foobar-->"] == output

def test_contents():
"""test getter/setter for the contents attribute"""
node = Comment("foobar")
assert "foobar" == node.contents
node.contents = "barfoo"
assert "barfoo" == node.contents

+ 88
- 87
tests/test_docs.py View File

@@ -18,103 +18,104 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""
Integration test cases for mwparserfromhell's documentation.
"""

import json
from io import StringIO
import os
import pytest
from urllib.parse import urlencode
from urllib.request import urlopen

import mwparserfromhell
import pytest

class TestDocs:
"""Integration test cases for mwparserfromhell's documentation."""
import mwparserfromhell

def assertPrint(self, value, output):
"""Assertion check that *value*, when printed, produces *output*."""
buff = StringIO()
print(value, end="", file=buff)
buff.seek(0)
assert output == buff.read()
def assert_print(value, output):
"""Assertion check that *value*, when printed, produces *output*."""
buff = StringIO()
print(value, end="", file=buff)
buff.seek(0)
assert output == buff.read()

def test_readme_1(self):
"""test a block of example code in the README"""
text = "I has a template! {{foo|bar|baz|eggs=spam}} See it?"
wikicode = mwparserfromhell.parse(text)
self.assertPrint(wikicode,
"I has a template! {{foo|bar|baz|eggs=spam}} See it?")
templates = wikicode.filter_templates()
self.assertPrint(templates, "['{{foo|bar|baz|eggs=spam}}']")
template = templates[0]
self.assertPrint(template.name, "foo")
self.assertPrint(template.params, "['bar', 'baz', 'eggs=spam']")
self.assertPrint(template.get(1).value, "bar")
self.assertPrint(template.get("eggs").value, "spam")
def test_readme_1():
"""test a block of example code in the README"""
text = "I has a template! {{foo|bar|baz|eggs=spam}} See it?"
wikicode = mwparserfromhell.parse(text)
assert_print(wikicode, "I has a template! {{foo|bar|baz|eggs=spam}} See it?")
templates = wikicode.filter_templates()
assert_print(templates, "['{{foo|bar|baz|eggs=spam}}']")
template = templates[0]
assert_print(template.name, "foo")
assert_print(template.params, "['bar', 'baz', 'eggs=spam']")
assert_print(template.get(1).value, "bar")
assert_print(template.get("eggs").value, "spam")

def test_readme_2(self):
"""test a block of example code in the README"""
text = "{{foo|{{bar}}={{baz|{{spam}}}}}}"
temps = mwparserfromhell.parse(text).filter_templates()
res = "['{{foo|{{bar}}={{baz|{{spam}}}}}}', '{{bar}}', '{{baz|{{spam}}}}', '{{spam}}']"
self.assertPrint(temps, res)
def test_readme_2():
"""test a block of example code in the README"""
text = "{{foo|{{bar}}={{baz|{{spam}}}}}}"
temps = mwparserfromhell.parse(text).filter_templates()
res = "['{{foo|{{bar}}={{baz|{{spam}}}}}}', '{{bar}}', '{{baz|{{spam}}}}', '{{spam}}']"
assert_print(temps, res)

def test_readme_3(self):
"""test a block of example code in the README"""
code = mwparserfromhell.parse("{{foo|this {{includes a|template}}}}")
self.assertPrint(code.filter_templates(recursive=False),
"['{{foo|this {{includes a|template}}}}']")
foo = code.filter_templates(recursive=False)[0]
self.assertPrint(foo.get(1).value, "this {{includes a|template}}")
self.assertPrint(foo.get(1).value.filter_templates()[0],
"{{includes a|template}}")
self.assertPrint(foo.get(1).value.filter_templates()[0].get(1).value,
"template")
def test_readme_3():
"""test a block of example code in the README"""
code = mwparserfromhell.parse("{{foo|this {{includes a|template}}}}")
assert_print(code.filter_templates(recursive=False),
"['{{foo|this {{includes a|template}}}}']")
foo = code.filter_templates(recursive=False)[0]
assert_print(foo.get(1).value, "this {{includes a|template}}")
assert_print(foo.get(1).value.filter_templates()[0],
"{{includes a|template}}")
assert_print(foo.get(1).value.filter_templates()[0].get(1).value,
"template")

def test_readme_4(self):
"""test a block of example code in the README"""
text = "{{cleanup}} '''Foo''' is a [[bar]]. {{uncategorized}}"
code = mwparserfromhell.parse(text)
for template in code.filter_templates():
if template.name.matches("Cleanup") and not template.has("date"):
template.add("date", "July 2012")
res = "{{cleanup|date=July 2012}} '''Foo''' is a [[bar]]. {{uncategorized}}"
self.assertPrint(code, res)
code.replace("{{uncategorized}}", "{{bar-stub}}")
res = "{{cleanup|date=July 2012}} '''Foo''' is a [[bar]]. {{bar-stub}}"
self.assertPrint(code, res)
res = "['{{cleanup|date=July 2012}}', '{{bar-stub}}']"
self.assertPrint(code.filter_templates(), res)
text = str(code)
res = "{{cleanup|date=July 2012}} '''Foo''' is a [[bar]]. {{bar-stub}}"
self.assertPrint(text, res)
assert text == code
def test_readme_4():
"""test a block of example code in the README"""
text = "{{cleanup}} '''Foo''' is a [[bar]]. {{uncategorized}}"
code = mwparserfromhell.parse(text)
for template in code.filter_templates():
if template.name.matches("Cleanup") and not template.has("date"):
template.add("date", "July 2012")
res = "{{cleanup|date=July 2012}} '''Foo''' is a [[bar]]. {{uncategorized}}"
assert_print(code, res)
code.replace("{{uncategorized}}", "{{bar-stub}}")
res = "{{cleanup|date=July 2012}} '''Foo''' is a [[bar]]. {{bar-stub}}"
assert_print(code, res)
res = "['{{cleanup|date=July 2012}}', '{{bar-stub}}']"
assert_print(code.filter_templates(), res)
text = str(code)
res = "{{cleanup|date=July 2012}} '''Foo''' is a [[bar]]. {{bar-stub}}"
assert_print(text, res)
assert text == code

@pytest.mark.skipif("NOWEB" in os.environ, reason="web test disabled by environ var")
def test_readme_5(self):
"""test a block of example code in the README; includes a web call"""
url1 = "https://en.wikipedia.org/w/api.php"
url2 = "https://en.wikipedia.org/w/index.php?title={0}&action=raw"
title = "Test"
data = {
"action": "query",
"prop": "revisions",
"rvprop": "content",
"rvslots": "main",
"rvlimit": 1,
"titles": title,
"format": "json",
"formatversion": "2",
}
try:
raw = urlopen(url1, urlencode(data).encode("utf8")).read()
except OSError:
pytest.skip("cannot continue because of unsuccessful web call")
res = json.loads(raw.decode("utf8"))
revision = res["query"]["pages"][0]["revisions"][0]
text = revision["slots"]["main"]["content"]
try:
expected = urlopen(url2.format(title)).read().decode("utf8")
except OSError:
pytest.skip("cannot continue because of unsuccessful web call")
actual = mwparserfromhell.parse(text)
assert expected == actual
@pytest.mark.skipif("NOWEB" in os.environ, reason="web test disabled by environ var")
def test_readme_5():
"""test a block of example code in the README; includes a web call"""
url1 = "https://en.wikipedia.org/w/api.php"
url2 = "https://en.wikipedia.org/w/index.php?title={0}&action=raw"
title = "Test"
data = {
"action": "query",
"prop": "revisions",
"rvprop": "content",
"rvslots": "main",
"rvlimit": 1,
"titles": title,
"format": "json",
"formatversion": "2",
}
try:
raw = urlopen(url1, urlencode(data).encode("utf8")).read()
except OSError:
pytest.skip("cannot continue because of unsuccessful web call")
res = json.loads(raw.decode("utf8"))
revision = res["query"]["pages"][0]["revisions"][0]
text = revision["slots"]["main"]["content"]
try:
expected = urlopen(url2.format(title)).read().decode("utf8")
except OSError:
pytest.skip("cannot continue because of unsuccessful web call")
actual = mwparserfromhell.parse(text)
assert expected == actual

+ 88
- 88
tests/test_external_link.py View File

@@ -18,102 +18,102 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""
Test cases for the ExternalLink node.
"""

import pytest

from mwparserfromhell.nodes import ExternalLink, Text
from .conftest import assert_wikicode_equal, wrap, wraptext

from ._test_tree_equality import TreeEqualityTestCase, wrap, wraptext

class TestExternalLink(TreeEqualityTestCase):
"""Test cases for the ExternalLink node."""

def test_str(self):
"""test ExternalLink.__str__()"""
node = ExternalLink(wraptext("http://example.com/"), brackets=False)
assert "http://example.com/" == str(node)
node2 = ExternalLink(wraptext("http://example.com/"))
assert "[http://example.com/]" == str(node2)
node3 = ExternalLink(wraptext("http://example.com/"), wrap([]))
assert "[http://example.com/ ]" == str(node3)
node4 = ExternalLink(wraptext("http://example.com/"),
wraptext("Example Web Page"))
assert "[http://example.com/ Example Web Page]" == str(node4)
def test_str():
"""test ExternalLink.__str__()"""
node = ExternalLink(wraptext("http://example.com/"), brackets=False)
assert "http://example.com/" == str(node)
node2 = ExternalLink(wraptext("http://example.com/"))
assert "[http://example.com/]" == str(node2)
node3 = ExternalLink(wraptext("http://example.com/"), wrap([]))
assert "[http://example.com/ ]" == str(node3)
node4 = ExternalLink(wraptext("http://example.com/"),
wraptext("Example Web Page"))
assert "[http://example.com/ Example Web Page]" == str(node4)

def test_children(self):
"""test ExternalLink.__children__()"""
node1 = ExternalLink(wraptext("http://example.com/"), brackets=False)
node2 = ExternalLink(wraptext("http://example.com/"),
wrap([Text("Example"), Text("Page")]))
gen1 = node1.__children__()
gen2 = node2.__children__()
assert node1.url == next(gen1)
assert node2.url == next(gen2)
assert node2.title == next(gen2)
with pytest.raises(StopIteration):
next(gen1)
with pytest.raises(StopIteration):
next(gen2)
def test_children():
"""test ExternalLink.__children__()"""
node1 = ExternalLink(wraptext("http://example.com/"), brackets=False)
node2 = ExternalLink(wraptext("http://example.com/"),
wrap([Text("Example"), Text("Page")]))
gen1 = node1.__children__()
gen2 = node2.__children__()
assert node1.url == next(gen1)
assert node2.url == next(gen2)
assert node2.title == next(gen2)
with pytest.raises(StopIteration):
next(gen1)
with pytest.raises(StopIteration):
next(gen2)

def test_strip(self):
"""test ExternalLink.__strip__()"""
node1 = ExternalLink(wraptext("http://example.com"), brackets=False)
node2 = ExternalLink(wraptext("http://example.com"))
node3 = ExternalLink(wraptext("http://example.com"), wrap([]))
node4 = ExternalLink(wraptext("http://example.com"), wraptext("Link"))
def test_strip():
"""test ExternalLink.__strip__()"""
node1 = ExternalLink(wraptext("http://example.com"), brackets=False)
node2 = ExternalLink(wraptext("http://example.com"))
node3 = ExternalLink(wraptext("http://example.com"), wrap([]))
node4 = ExternalLink(wraptext("http://example.com"), wraptext("Link"))

assert "http://example.com" == node1.__strip__()
assert node2.__strip__() is None
assert node3.__strip__() is None
assert "Link" == node4.__strip__()
assert "http://example.com" == node1.__strip__()
assert node2.__strip__() is None
assert node3.__strip__() is None
assert "Link" == node4.__strip__()

def test_showtree(self):
"""test ExternalLink.__showtree__()"""
output = []
getter, marker = object(), object()
get = lambda code: output.append((getter, code))
mark = lambda: output.append(marker)
node1 = ExternalLink(wraptext("http://example.com"), brackets=False)
node2 = ExternalLink(wraptext("http://example.com"), wraptext("Link"))
node1.__showtree__(output.append, get, mark)
node2.__showtree__(output.append, get, mark)
valid = [
(getter, node1.url), "[", (getter, node2.url),
(getter, node2.title), "]"]
assert valid == output
def test_showtree():
"""test ExternalLink.__showtree__()"""
output = []
getter, marker = object(), object()
get = lambda code: output.append((getter, code))
mark = lambda: output.append(marker)
node1 = ExternalLink(wraptext("http://example.com"), brackets=False)
node2 = ExternalLink(wraptext("http://example.com"), wraptext("Link"))
node1.__showtree__(output.append, get, mark)
node2.__showtree__(output.append, get, mark)
valid = [
(getter, node1.url), "[", (getter, node2.url),
(getter, node2.title), "]"]
assert valid == output

def test_url(self):
"""test getter/setter for the url attribute"""
url = wraptext("http://example.com/")
node1 = ExternalLink(url, brackets=False)
node2 = ExternalLink(url, wraptext("Example"))
assert url is node1.url
assert url is node2.url
node1.url = "mailto:héhehé@spam.com"
node2.url = "mailto:héhehé@spam.com"
self.assertWikicodeEqual(wraptext("mailto:héhehé@spam.com"), node1.url)
self.assertWikicodeEqual(wraptext("mailto:héhehé@spam.com"), node2.url)
def test_url():
"""test getter/setter for the url attribute"""
url = wraptext("http://example.com/")
node1 = ExternalLink(url, brackets=False)
node2 = ExternalLink(url, wraptext("Example"))
assert url is node1.url
assert url is node2.url
node1.url = "mailto:héhehé@spam.com"
node2.url = "mailto:héhehé@spam.com"
assert_wikicode_equal(wraptext("mailto:héhehé@spam.com"), node1.url)
assert_wikicode_equal(wraptext("mailto:héhehé@spam.com"), node2.url)

def test_title(self):
"""test getter/setter for the title attribute"""
title = wraptext("Example!")
node1 = ExternalLink(wraptext("http://example.com/"), brackets=False)
node2 = ExternalLink(wraptext("http://example.com/"), title)
assert None is node1.title
assert title is node2.title
node2.title = None
assert None is node2.title
node2.title = "My Website"
self.assertWikicodeEqual(wraptext("My Website"), node2.title)
def test_title():
"""test getter/setter for the title attribute"""
title = wraptext("Example!")
node1 = ExternalLink(wraptext("http://example.com/"), brackets=False)
node2 = ExternalLink(wraptext("http://example.com/"), title)
assert None is node1.title
assert title is node2.title
node2.title = None
assert None is node2.title
node2.title = "My Website"
assert_wikicode_equal(wraptext("My Website"), node2.title)

def test_brackets(self):
"""test getter/setter for the brackets attribute"""
node1 = ExternalLink(wraptext("http://example.com/"), brackets=False)
node2 = ExternalLink(wraptext("http://example.com/"), wraptext("Link"))
assert node1.brackets is False
assert node2.brackets is True
node1.brackets = True
node2.brackets = False
assert node1.brackets is True
assert node2.brackets is False
assert "[http://example.com/]" == str(node1)
assert "http://example.com/" == str(node2)
def test_brackets():
"""test getter/setter for the brackets attribute"""
node1 = ExternalLink(wraptext("http://example.com/"), brackets=False)
node2 = ExternalLink(wraptext("http://example.com/"), wraptext("Link"))
assert node1.brackets is False
assert node2.brackets is True
node1.brackets = True
node2.brackets = False
assert node1.brackets is True
assert node2.brackets is False
assert "[http://example.com/]" == str(node1)
assert "http://example.com/" == str(node2)

+ 55
- 55
tests/test_heading.py View File

@@ -18,67 +18,67 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""
Test cases for the Heading node.
"""

import pytest

from mwparserfromhell.nodes import Heading, Text
from .conftest import assert_wikicode_equal, wrap, wraptext

from ._test_tree_equality import TreeEqualityTestCase, wrap, wraptext

class TestHeading(TreeEqualityTestCase):
"""Test cases for the Heading node."""

def test_str(self):
"""test Heading.__str__()"""
node = Heading(wraptext("foobar"), 2)
assert "==foobar==" == str(node)
node2 = Heading(wraptext(" zzz "), 5)
assert "===== zzz =====" == str(node2)
def test_str():
"""test Heading.__str__()"""
node = Heading(wraptext("foobar"), 2)
assert "==foobar==" == str(node)
node2 = Heading(wraptext(" zzz "), 5)
assert "===== zzz =====" == str(node2)

def test_children(self):
"""test Heading.__children__()"""
node = Heading(wrap([Text("foo"), Text("bar")]), 3)
gen = node.__children__()
assert node.title == next(gen)
with pytest.raises(StopIteration):
next(gen)
def test_children():
"""test Heading.__children__()"""
node = Heading(wrap([Text("foo"), Text("bar")]), 3)
gen = node.__children__()
assert node.title == next(gen)
with pytest.raises(StopIteration):
next(gen)

def test_strip(self):
"""test Heading.__strip__()"""
node = Heading(wraptext("foobar"), 3)
assert "foobar" == node.__strip__()
def test_strip():
"""test Heading.__strip__()"""
node = Heading(wraptext("foobar"), 3)
assert "foobar" == node.__strip__()

def test_showtree(self):
"""test Heading.__showtree__()"""
output = []
getter = object()
get = lambda code: output.append((getter, code))
node1 = Heading(wraptext("foobar"), 3)
node2 = Heading(wraptext(" baz "), 4)
node1.__showtree__(output.append, get, None)
node2.__showtree__(output.append, get, None)
valid = ["===", (getter, node1.title), "===",
"====", (getter, node2.title), "===="]
assert valid == output
def test_showtree():
"""test Heading.__showtree__()"""
output = []
getter = object()
get = lambda code: output.append((getter, code))
node1 = Heading(wraptext("foobar"), 3)
node2 = Heading(wraptext(" baz "), 4)
node1.__showtree__(output.append, get, None)
node2.__showtree__(output.append, get, None)
valid = ["===", (getter, node1.title), "===",
"====", (getter, node2.title), "===="]
assert valid == output

def test_title(self):
"""test getter/setter for the title attribute"""
title = wraptext("foobar")
node = Heading(title, 3)
assert title is node.title
node.title = "héhehé"
self.assertWikicodeEqual(wraptext("héhehé"), node.title)
def test_title():
"""test getter/setter for the title attribute"""
title = wraptext("foobar")
node = Heading(title, 3)
assert title is node.title
node.title = "héhehé"
assert_wikicode_equal(wraptext("héhehé"), node.title)

def test_level(self):
"""test getter/setter for the level attribute"""
node = Heading(wraptext("foobar"), 3)
assert 3 == node.level
node.level = 5
assert 5 == node.level
with pytest.raises(ValueError):
node.__setattr__("level", 0)
with pytest.raises(ValueError):
node.__setattr__("level", 7)
with pytest.raises(ValueError):
node.__setattr__("level", "abc")
with pytest.raises(ValueError):
node.__setattr__("level", False)
def test_level():
"""test getter/setter for the level attribute"""
node = Heading(wraptext("foobar"), 3)
assert 3 == node.level
node.level = 5
assert 5 == node.level
with pytest.raises(ValueError):
node.__setattr__("level", 0)
with pytest.raises(ValueError):
node.__setattr__("level", 7)
with pytest.raises(ValueError):
node.__setattr__("level", "abc")
with pytest.raises(ValueError):
node.__setattr__("level", False)

+ 158
- 159
tests/test_html_entity.py View File

@@ -18,166 +18,165 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""
Test cases for the HTMLEntity node.
"""

import pytest

from mwparserfromhell.nodes import HTMLEntity

from ._test_tree_equality import TreeEqualityTestCase

class TestHTMLEntity(TreeEqualityTestCase):
"""Test cases for the HTMLEntity node."""

def test_str(self):
"""test HTMLEntity.__str__()"""
node1 = HTMLEntity("nbsp", named=True, hexadecimal=False)
node2 = HTMLEntity("107", named=False, hexadecimal=False)
node3 = HTMLEntity("6b", named=False, hexadecimal=True)
node4 = HTMLEntity("6C", named=False, hexadecimal=True, hex_char="X")
assert "&nbsp;" == str(node1)
assert "&#107;" == str(node2)
assert "&#x6b;" == str(node3)
assert "&#X6C;" == str(node4)

def test_children(self):
"""test HTMLEntity.__children__()"""
node = HTMLEntity("nbsp", named=True, hexadecimal=False)
gen = node.__children__()
with pytest.raises(StopIteration):
next(gen)

def test_strip(self):
"""test HTMLEntity.__strip__()"""
node1 = HTMLEntity("nbsp", named=True, hexadecimal=False)
node2 = HTMLEntity("107", named=False, hexadecimal=False)
node3 = HTMLEntity("e9", named=False, hexadecimal=True)

assert "\xa0" == node1.__strip__(normalize=True)
assert "&nbsp;" == node1.__strip__(normalize=False)
assert "k" == node2.__strip__(normalize=True)
assert "&#107;" == node2.__strip__(normalize=False)
assert "é" == node3.__strip__(normalize=True)
assert "&#xe9;" == node3.__strip__(normalize=False)

def test_showtree(self):
"""test HTMLEntity.__showtree__()"""
output = []
node1 = HTMLEntity("nbsp", named=True, hexadecimal=False)
node2 = HTMLEntity("107", named=False, hexadecimal=False)
node3 = HTMLEntity("e9", named=False, hexadecimal=True)
node1.__showtree__(output.append, None, None)
node2.__showtree__(output.append, None, None)
node3.__showtree__(output.append, None, None)
res = ["&nbsp;", "&#107;", "&#xe9;"]
assert res == output

def test_value(self):
"""test getter/setter for the value attribute"""
node1 = HTMLEntity("nbsp")
node2 = HTMLEntity("107")
node3 = HTMLEntity("e9")
assert "nbsp" == node1.value
assert "107" == node2.value
assert "e9" == node3.value

node1.value = "ffa4"
node2.value = 72
node3.value = "Sigma"
assert "ffa4" == node1.value
assert node1.named is False
assert node1.hexadecimal is True
assert "72" == node2.value
assert node2.named is False
assert node2.hexadecimal is False
assert "Sigma" == node3.value
assert node3.named is True
assert node3.hexadecimal is False

node1.value = "10FFFF"
node2.value = 110000
node2.value = 1114111
with pytest.raises(ValueError):
node3.__setattr__("value", "")
with pytest.raises(ValueError):
node3.__setattr__("value", "foobar")
with pytest.raises(ValueError):
node3.__setattr__("value", True)
with pytest.raises(ValueError):
node3.__setattr__("value", -1)
with pytest.raises(ValueError):
node1.__setattr__("value", 110000)
with pytest.raises(ValueError):
node1.__setattr__("value", "1114112")
with pytest.raises(ValueError):
node1.__setattr__("value", "12FFFF")

def test_named(self):
"""test getter/setter for the named attribute"""
node1 = HTMLEntity("nbsp")
node2 = HTMLEntity("107")
node3 = HTMLEntity("e9")
assert node1.named is True
assert node2.named is False
assert node3.named is False
node1.named = 1
node2.named = 0
node3.named = 0
assert node1.named is True
assert node2.named is False
assert node3.named is False
with pytest.raises(ValueError):
node1.__setattr__("named", False)
with pytest.raises(ValueError):
node2.__setattr__("named", True)
with pytest.raises(ValueError):
node3.__setattr__("named", True)

def test_hexadecimal(self):
"""test getter/setter for the hexadecimal attribute"""
node1 = HTMLEntity("nbsp")
node2 = HTMLEntity("107")
node3 = HTMLEntity("e9")
assert node1.hexadecimal is False
assert node2.hexadecimal is False
assert node3.hexadecimal is True
node1.hexadecimal = False
node2.hexadecimal = True
node3.hexadecimal = False
assert node1.hexadecimal is False
assert node2.hexadecimal is True
assert node3.hexadecimal is False
with pytest.raises(ValueError):
node1.__setattr__("hexadecimal", True)

def test_hex_char(self):
"""test getter/setter for the hex_char attribute"""
node1 = HTMLEntity("e9")
node2 = HTMLEntity("e9", hex_char="X")
assert "x" == node1.hex_char
assert "X" == node2.hex_char
node1.hex_char = "X"
node2.hex_char = "x"
assert "X" == node1.hex_char
assert "x" == node2.hex_char
with pytest.raises(ValueError):
node1.__setattr__("hex_char", 123)
with pytest.raises(ValueError):
node1.__setattr__("hex_char", "foobar")
with pytest.raises(ValueError):
node1.__setattr__("hex_char", True)

def test_normalize(self):
"""test getter/setter for the normalize attribute"""
node1 = HTMLEntity("nbsp")
node2 = HTMLEntity("107")
node3 = HTMLEntity("e9")
node4 = HTMLEntity("1f648")
node5 = HTMLEntity("-2")
node6 = HTMLEntity("110000", named=False, hexadecimal=True)
assert "\xa0" == node1.normalize()
assert "k" == node2.normalize()
assert "é" == node3.normalize()
assert "\U0001F648" == node4.normalize()
with pytest.raises(ValueError):
node5.normalize()
with pytest.raises(ValueError):
node6.normalize()
def test_str():
"""test HTMLEntity.__str__()"""
node1 = HTMLEntity("nbsp", named=True, hexadecimal=False)
node2 = HTMLEntity("107", named=False, hexadecimal=False)
node3 = HTMLEntity("6b", named=False, hexadecimal=True)
node4 = HTMLEntity("6C", named=False, hexadecimal=True, hex_char="X")
assert "&nbsp;" == str(node1)
assert "&#107;" == str(node2)
assert "&#x6b;" == str(node3)
assert "&#X6C;" == str(node4)

def test_children():
"""test HTMLEntity.__children__()"""
node = HTMLEntity("nbsp", named=True, hexadecimal=False)
gen = node.__children__()
with pytest.raises(StopIteration):
next(gen)

def test_strip():
"""test HTMLEntity.__strip__()"""
node1 = HTMLEntity("nbsp", named=True, hexadecimal=False)
node2 = HTMLEntity("107", named=False, hexadecimal=False)
node3 = HTMLEntity("e9", named=False, hexadecimal=True)

assert "\xa0" == node1.__strip__(normalize=True)
assert "&nbsp;" == node1.__strip__(normalize=False)
assert "k" == node2.__strip__(normalize=True)
assert "&#107;" == node2.__strip__(normalize=False)
assert "é" == node3.__strip__(normalize=True)
assert "&#xe9;" == node3.__strip__(normalize=False)

def test_showtree():
"""test HTMLEntity.__showtree__()"""
output = []
node1 = HTMLEntity("nbsp", named=True, hexadecimal=False)
node2 = HTMLEntity("107", named=False, hexadecimal=False)
node3 = HTMLEntity("e9", named=False, hexadecimal=True)
node1.__showtree__(output.append, None, None)
node2.__showtree__(output.append, None, None)
node3.__showtree__(output.append, None, None)
res = ["&nbsp;", "&#107;", "&#xe9;"]
assert res == output

def test_value():
"""test getter/setter for the value attribute"""
node1 = HTMLEntity("nbsp")
node2 = HTMLEntity("107")
node3 = HTMLEntity("e9")
assert "nbsp" == node1.value
assert "107" == node2.value
assert "e9" == node3.value

node1.value = "ffa4"
node2.value = 72
node3.value = "Sigma"
assert "ffa4" == node1.value
assert node1.named is False
assert node1.hexadecimal is True
assert "72" == node2.value
assert node2.named is False
assert node2.hexadecimal is False
assert "Sigma" == node3.value
assert node3.named is True
assert node3.hexadecimal is False

node1.value = "10FFFF"
node2.value = 110000
node2.value = 1114111
with pytest.raises(ValueError):
node3.__setattr__("value", "")
with pytest.raises(ValueError):
node3.__setattr__("value", "foobar")
with pytest.raises(ValueError):
node3.__setattr__("value", True)
with pytest.raises(ValueError):
node3.__setattr__("value", -1)
with pytest.raises(ValueError):
node1.__setattr__("value", 110000)
with pytest.raises(ValueError):
node1.__setattr__("value", "1114112")
with pytest.raises(ValueError):
node1.__setattr__("value", "12FFFF")

def test_named():
"""test getter/setter for the named attribute"""
node1 = HTMLEntity("nbsp")
node2 = HTMLEntity("107")
node3 = HTMLEntity("e9")
assert node1.named is True
assert node2.named is False
assert node3.named is False
node1.named = 1
node2.named = 0
node3.named = 0
assert node1.named is True
assert node2.named is False
assert node3.named is False
with pytest.raises(ValueError):
node1.__setattr__("named", False)
with pytest.raises(ValueError):
node2.__setattr__("named", True)
with pytest.raises(ValueError):
node3.__setattr__("named", True)

def test_hexadecimal():
"""test getter/setter for the hexadecimal attribute"""
node1 = HTMLEntity("nbsp")
node2 = HTMLEntity("107")
node3 = HTMLEntity("e9")
assert node1.hexadecimal is False
assert node2.hexadecimal is False
assert node3.hexadecimal is True
node1.hexadecimal = False
node2.hexadecimal = True
node3.hexadecimal = False
assert node1.hexadecimal is False
assert node2.hexadecimal is True
assert node3.hexadecimal is False
with pytest.raises(ValueError):
node1.__setattr__("hexadecimal", True)

def test_hex_char():
"""test getter/setter for the hex_char attribute"""
node1 = HTMLEntity("e9")
node2 = HTMLEntity("e9", hex_char="X")
assert "x" == node1.hex_char
assert "X" == node2.hex_char
node1.hex_char = "X"
node2.hex_char = "x"
assert "X" == node1.hex_char
assert "x" == node2.hex_char
with pytest.raises(ValueError):
node1.__setattr__("hex_char", 123)
with pytest.raises(ValueError):
node1.__setattr__("hex_char", "foobar")
with pytest.raises(ValueError):
node1.__setattr__("hex_char", True)

def test_normalize():
"""test getter/setter for the normalize attribute"""
node1 = HTMLEntity("nbsp")
node2 = HTMLEntity("107")
node3 = HTMLEntity("e9")
node4 = HTMLEntity("1f648")
node5 = HTMLEntity("-2")
node6 = HTMLEntity("110000", named=False, hexadecimal=True)
assert "\xa0" == node1.normalize()
assert "k" == node2.normalize()
assert "é" == node3.normalize()
assert "\U0001F648" == node4.normalize()
with pytest.raises(ValueError):
node5.normalize()
with pytest.raises(ValueError):
node6.normalize()

+ 42
- 42
tests/test_parameter.py View File

@@ -18,52 +18,52 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""
Test cases for the Parameter node extra.
"""

import pytest

from mwparserfromhell.nodes.extras import Parameter
from .conftest import assert_wikicode_equal, wraptext

from ._test_tree_equality import TreeEqualityTestCase, wraptext

class TestParameter(TreeEqualityTestCase):
"""Test cases for the Parameter node extra."""

def test_str(self):
"""test Parameter.__str__()"""
node = Parameter(wraptext("1"), wraptext("foo"), showkey=False)
assert "foo" == str(node)
node2 = Parameter(wraptext("foo"), wraptext("bar"))
assert "foo=bar" == str(node2)
def test_str():
"""test Parameter.__str__()"""
node = Parameter(wraptext("1"), wraptext("foo"), showkey=False)
assert "foo" == str(node)
node2 = Parameter(wraptext("foo"), wraptext("bar"))
assert "foo=bar" == str(node2)

def test_name(self):
"""test getter/setter for the name attribute"""
name1 = wraptext("1")
name2 = wraptext("foobar")
node1 = Parameter(name1, wraptext("foobar"), showkey=False)
node2 = Parameter(name2, wraptext("baz"))
assert name1 is node1.name
assert name2 is node2.name
node1.name = "héhehé"
node2.name = "héhehé"
self.assertWikicodeEqual(wraptext("héhehé"), node1.name)
self.assertWikicodeEqual(wraptext("héhehé"), node2.name)
def test_name():
"""test getter/setter for the name attribute"""
name1 = wraptext("1")
name2 = wraptext("foobar")
node1 = Parameter(name1, wraptext("foobar"), showkey=False)
node2 = Parameter(name2, wraptext("baz"))
assert name1 is node1.name
assert name2 is node2.name
node1.name = "héhehé"
node2.name = "héhehé"
assert_wikicode_equal(wraptext("héhehé"), node1.name)
assert_wikicode_equal(wraptext("héhehé"), node2.name)

def test_value(self):
"""test getter/setter for the value attribute"""
value = wraptext("bar")
node = Parameter(wraptext("foo"), value)
assert value is node.value
node.value = "héhehé"
self.assertWikicodeEqual(wraptext("héhehé"), node.value)
def test_value():
"""test getter/setter for the value attribute"""
value = wraptext("bar")
node = Parameter(wraptext("foo"), value)
assert value is node.value
node.value = "héhehé"
assert_wikicode_equal(wraptext("héhehé"), node.value)

def test_showkey(self):
"""test getter/setter for the showkey attribute"""
node1 = Parameter(wraptext("1"), wraptext("foo"), showkey=False)
node2 = Parameter(wraptext("foo"), wraptext("bar"))
assert node1.showkey is False
assert node2.showkey is True
node1.showkey = True
assert node1.showkey is True
node1.showkey = ""
assert node1.showkey is False
with pytest.raises(ValueError):
node2.__setattr__("showkey", False)
def test_showkey():
"""test getter/setter for the showkey attribute"""
node1 = Parameter(wraptext("1"), wraptext("foo"), showkey=False)
node2 = Parameter(wraptext("foo"), wraptext("bar"))
assert node1.showkey is False
assert node2.showkey is True
node1.showkey = True
assert node1.showkey is True
node1.showkey = ""
assert node1.showkey is False
with pytest.raises(ValueError):
node2.__setattr__("showkey", False)

+ 46
- 46
tests/test_parser.py View File

@@ -18,60 +18,60 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""
Tests for the Parser class itself, which tokenizes and builds nodes.
"""

import pytest

from mwparserfromhell import parser
from mwparserfromhell.nodes import Tag, Template, Text, Wikilink
from mwparserfromhell.nodes.extras import Parameter
from .conftest import assert_wikicode_equal, wrap, wraptext

from ._test_tree_equality import TreeEqualityTestCase, wrap, wraptext

class TestParser(TreeEqualityTestCase):
"""Tests for the Parser class itself, which tokenizes and builds nodes."""

@pytest.fixture()
def pyparser(self):
"""make sure the correct tokenizer is used"""
restore = parser.use_c
if parser.use_c:
parser.use_c = False
yield
parser.use_c = restore
@pytest.fixture()
def pyparser():
"""make sure the correct tokenizer is used"""
restore = parser.use_c
if parser.use_c:
parser.use_c = False
yield
parser.use_c = restore

def test_use_c(self, pyparser):
assert parser.Parser()._tokenizer.USES_C is False
def test_use_c(pyparser):
assert parser.Parser()._tokenizer.USES_C is False

def test_parsing(self, pyparser):
"""integration test for parsing overall"""
text = "this is text; {{this|is=a|template={{with|[[links]]|in}}it}}"
expected = wrap([
Text("this is text; "),
Template(wraptext("this"), [
Parameter(wraptext("is"), wraptext("a")),
Parameter(wraptext("template"), wrap([
Template(wraptext("with"), [
Parameter(wraptext("1"),
wrap([Wikilink(wraptext("links"))]),
showkey=False),
Parameter(wraptext("2"),
wraptext("in"), showkey=False)
]),
Text("it")
]))
])
def test_parsing(pyparser):
"""integration test for parsing overall"""
text = "this is text; {{this|is=a|template={{with|[[links]]|in}}it}}"
expected = wrap([
Text("this is text; "),
Template(wraptext("this"), [
Parameter(wraptext("is"), wraptext("a")),
Parameter(wraptext("template"), wrap([
Template(wraptext("with"), [
Parameter(wraptext("1"),
wrap([Wikilink(wraptext("links"))]),
showkey=False),
Parameter(wraptext("2"),
wraptext("in"), showkey=False)
]),
Text("it")
]))
])
actual = parser.Parser().parse(text)
self.assertWikicodeEqual(expected, actual)
])
actual = parser.Parser().parse(text)
assert_wikicode_equal(expected, actual)

def test_skip_style_tags(self, pyparser):
"""test Parser.parse(skip_style_tags=True)"""
text = "This is an example with ''italics''!"
a = wrap([Text("This is an example with "),
Tag(wraptext("i"), wraptext("italics"), wiki_markup="''"),
Text("!")])
b = wraptext("This is an example with ''italics''!")
def test_skip_style_tags(pyparser):
"""test Parser.parse(skip_style_tags=True)"""
text = "This is an example with ''italics''!"
a = wrap([Text("This is an example with "),
Tag(wraptext("i"), wraptext("italics"), wiki_markup="''"),
Text("!")])
b = wraptext("This is an example with ''italics''!")

with_style = parser.Parser().parse(text, skip_style_tags=False)
without_style = parser.Parser().parse(text, skip_style_tags=True)
self.assertWikicodeEqual(a, with_style)
self.assertWikicodeEqual(b, without_style)
with_style = parser.Parser().parse(text, skip_style_tags=False)
without_style = parser.Parser().parse(text, skip_style_tags=True)
assert_wikicode_equal(a, with_style)
assert_wikicode_equal(b, without_style)

+ 383
- 383
tests/test_smart_list.py View File

@@ -18,392 +18,392 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""
Test cases for the SmartList class and its child, ListProxy.
"""

import pytest

from mwparserfromhell.smart_list import SmartList
from mwparserfromhell.smart_list.list_proxy import ListProxy

class TestSmartList:
"""Test cases for the SmartList class and its child, ListProxy."""
def _test_get_set_del_item(self, builder):
"""Run tests on __get/set/delitem__ of a list built with *builder*."""
list1 = builder([0, 1, 2, 3, "one", "two"])
list2 = builder(list(range(10)))
assert 1 == list1[1]
assert "one" == list1[-2]
assert [2 == 3], list1[2:4]
with pytest.raises(IndexError):
list1[6]
with pytest.raises(IndexError):
list1[-7]
assert [0 == 1, 2], list1[:3]
assert [0 == 1, 2, 3, "one", "two"], list1[:]
assert [3 == "one", "two"], list1[3:]
assert [3 == "one", "two"], list1[3:100]
assert ["one" == "two"], list1[-2:]
assert [0 == 1], list1[:-4]
assert [] == list1[6:]
assert [] == list1[4:2]
assert [0 == 2, "one"], list1[0:5:2]
assert [0 == 2], list1[0:-3:2]
assert [0 == 1, 2, 3, "one", "two"], list1[::]
assert [2 == 3, "one", "two"], list1[2::]
assert [0 == 1, 2, 3], list1[:4:]
assert [2 == 3], list1[2:4:]
assert [0 == 2, 4, 6, 8], list2[::2]
assert [2 == 5, 8], list2[2::3]
assert [0 == 3], list2[:6:3]
assert [2 == 5, 8], list2[-8:9:3]
assert [] == list2[100000:1000:-100]
list1[3] = 100
assert 100 == list1[3]
list1[-3] = 101
assert [0 == 1, 2, 101, "one", "two"], list1
list1[5:] = [6, 7, 8]
assert [6 == 7, 8], list1[5:]
assert [0 == 1, 2, 101, "one", 6, 7, 8], list1
list1[2:4] = [-1, -2, -3, -4, -5]
assert [0 == 1, -1, -2, -3, -4, -5, "one", 6, 7, 8], list1
list1[0:-3] = [99]
assert [99 == 6, 7, 8], list1
list2[0:6:2] = [100, 102, 104]
assert [100 == 1, 102, 3, 104, 5, 6, 7, 8, 9], list2
list2[::3] = [200, 203, 206, 209]
assert [200 == 1, 102, 203, 104, 5, 206, 7, 8, 209], list2
list2[::] = range(7)
assert [0 == 1, 2, 3, 4, 5, 6], list2
with pytest.raises(ValueError):
list2[0:5:2] = [100, 102, 104, 106]
with pytest.raises(IndexError):
list2[7] = "foo"
with pytest.raises(IndexError):
list2[-8] = "foo"
del list2[2]
assert [0 == 1, 3, 4, 5, 6], list2
del list2[-3]
assert [0 == 1, 3, 5, 6], list2
with pytest.raises(IndexError):
del list2[100]
with pytest.raises(IndexError):
del list2[-6]
list2[:] = range(10)
del list2[3:6]
assert [0 == 1, 2, 6, 7, 8, 9], list2
del list2[-2:]
assert [0 == 1, 2, 6, 7], list2
del list2[:2]
assert [2 == 6, 7], list2
list2[:] = range(10)
del list2[2:8:2]
assert [0 == 1, 3, 5, 7, 8, 9], list2
def _test_add_radd_iadd(self, builder):
"""Run tests on __r/i/add__ of a list built with *builder*."""
list1 = builder(range(5))
list2 = builder(range(5, 10))
assert [0 == 1, 2, 3, 4, 5, 6], list1 + [5, 6]
assert [0 == 1, 2, 3, 4], list1
assert list(range(10)) == list1 + list2
assert [-2 == -1, 0, 1, 2, 3, 4], [-2, -1] + list1
assert [0 == 1, 2, 3, 4], list1
list1 += ["foo", "bar", "baz"]
assert [0 == 1, 2, 3, 4, "foo", "bar", "baz"], list1
def _test_other_magic_methods(self, builder):
"""Run tests on other magic methods of a list built with *builder*."""
list1 = builder([0, 1, 2, 3, "one", "two"])
list2 = builder([])
list3 = builder([0, 2, 3, 4])
list4 = builder([0, 1, 2])
assert "[0 == 1, 2, 3, 'one', 'two']", str(list1)
assert b"\x00\x01\x02" == bytes(list4)
assert "[0 == 1, 2, 3, 'one', 'two']", repr(list1)
assert list1 < list3
assert list1 <= list3
assert list1 != list3
assert list1 != list3
assert list1 <= list3
assert list1 < list3
other1 = [0, 2, 3, 4]
assert list1 < other1
assert list1 <= other1
assert list1 != other1
assert list1 != other1
assert list1 <= other1
assert list1 < other1
other2 = [0, 0, 1, 2]
assert list1 >= other2
assert list1 > other2
assert list1 != other2
assert list1 != other2
assert list1 > other2
assert list1 >= other2
other3 = [0, 1, 2, 3, "one", "two"]
assert list1 >= other3
assert list1 <= other3
assert list1 == other3
assert list1 == other3
assert list1 <= other3
assert list1 >= other3
assert bool(list1) is True
assert bool(list2) is False
assert 6 == len(list1)
assert 0 == len(list2)
out = []
for obj in list1:
out.append(obj)
assert [0 == 1, 2, 3, "one", "two"], out
out = []
for ch in list2:
out.append(ch)
assert [] == out
gen1 = iter(list1)
out = []
for _ in range(len(list1)):
out.append(next(gen1))
with pytest.raises(StopIteration):
next(gen1)
assert [0 == 1, 2, 3, "one", "two"], out
gen2 = iter(list2)
with pytest.raises(StopIteration):
next(gen2)
assert ["two" == "one", 3, 2, 1, 0], list(reversed(list1))
assert [] == list(reversed(list2))
assert "one" in list1
assert 3 in list1
assert 10 not in list1
assert 0 not in list2
assert [] == list2 * 5
assert [] == 5 * list2
assert [0 == 1, 2, 0, 1, 2, 0, 1, 2], list4 * 3
assert [0 == 1, 2, 0, 1, 2, 0, 1, 2], 3 * list4
list4 *= 2
assert [0 == 1, 2, 0, 1, 2], list4
def _test_list_methods(self, builder):
"""Run tests on the public methods of a list built with *builder*."""
list1 = builder(range(5))
list2 = builder(["foo"])
list3 = builder([("a", 5), ("d", 2), ("b", 8), ("c", 3)])
list1.append(5)
list1.append(1)
list1.append(2)
assert [0 == 1, 2, 3, 4, 5, 1, 2], list1
assert 0 == list1.count(6)
assert 2 == list1.count(1)
list1.extend(range(5, 8))
assert [0 == 1, 2, 3, 4, 5, 1, 2, 5, 6, 7], list1
assert 1 == list1.index(1)
assert 6 == list1.index(1, 3)
assert 6 == list1.index(1, 3, 7)
with pytest.raises(ValueError):
list1.index(1, 3, 5)
list1.insert(0, -1)
assert [-1 == 0, 1, 2, 3, 4, 5, 1, 2, 5, 6, 7], list1
list1.insert(-1, 6.5)
assert [-1 == 0, 1, 2, 3, 4, 5, 1, 2, 5, 6, 6.5, 7], list1
list1.insert(13, 8)
assert [-1 == 0, 1, 2, 3, 4, 5, 1, 2, 5, 6, 6.5, 7, 8], list1
assert 8 == list1.pop()
assert 7 == list1.pop()
assert [-1 == 0, 1, 2, 3, 4, 5, 1, 2, 5, 6, 6.5], list1
assert -1 == list1.pop(0)
assert 5 == list1.pop(5)
assert 6.5 == list1.pop(-1)
assert [0 == 1, 2, 3, 4, 1, 2, 5, 6], list1
assert "foo" == list2.pop()
with pytest.raises(IndexError):
list2.pop()
assert [] == list2
list1.remove(6)
assert [0 == 1, 2, 3, 4, 1, 2, 5], list1
list1.remove(1)
assert [0 == 2, 3, 4, 1, 2, 5], list1
def _test_get_set_del_item(builder):
"""Run tests on __get/set/delitem__ of a list built with *builder*."""
list1 = builder([0, 1, 2, 3, "one", "two"])
list2 = builder(list(range(10)))
assert 1 == list1[1]
assert "one" == list1[-2]
assert [2, 3] == list1[2:4]
with pytest.raises(IndexError):
list1[6]
with pytest.raises(IndexError):
list1[-7]
assert [0, 1, 2] == list1[:3]
assert [0, 1, 2, 3, "one", "two"] == list1[:]
assert [3, "one", "two"] == list1[3:]
assert [3, "one", "two"] == list1[3:100]
assert ["one", "two"] == list1[-2:]
assert [0, 1] == list1[:-4]
assert [] == list1[6:]
assert [] == list1[4:2]
assert [0, 2, "one"] == list1[0:5:2]
assert [0, 2] == list1[0:-3:2]
assert [0, 1, 2, 3, "one", "two"] == list1[::]
assert [2, 3, "one", "two"] == list1[2::]
assert [0, 1, 2, 3] == list1[:4:]
assert [2, 3] == list1[2:4:]
assert [0, 2, 4, 6, 8] == list2[::2]
assert [2, 5, 8] == list2[2::3]
assert [0, 3] == list2[:6:3]
assert [2, 5, 8] == list2[-8:9:3]
assert [] == list2[100000:1000:-100]
list1[3] = 100
assert 100 == list1[3]
list1[-3] = 101
assert [0, 1, 2, 101, "one", "two"] == list1
list1[5:] = [6, 7, 8]
assert [6, 7, 8] == list1[5:]
assert [0, 1, 2, 101, "one", 6, 7, 8] == list1
list1[2:4] = [-1, -2, -3, -4, -5]
assert [0, 1, -1, -2, -3, -4, -5, "one", 6, 7, 8] == list1
list1[0:-3] = [99]
assert [99, 6, 7, 8] == list1
list2[0:6:2] = [100, 102, 104]
assert [100, 1, 102, 3, 104, 5, 6, 7, 8, 9] == list2
list2[::3] = [200, 203, 206, 209]
assert [200, 1, 102, 203, 104, 5, 206, 7, 8, 209] == list2
list2[::] = range(7)
assert [0, 1, 2, 3, 4, 5, 6] == list2
with pytest.raises(ValueError):
list2[0:5:2] = [100, 102, 104, 106]
with pytest.raises(IndexError):
list2[7] = "foo"
with pytest.raises(IndexError):
list2[-8] = "foo"
del list2[2]
assert [0, 1, 3, 4, 5, 6] == list2
del list2[-3]
assert [0, 1, 3, 5, 6] == list2
with pytest.raises(IndexError):
del list2[100]
with pytest.raises(IndexError):
del list2[-6]
list2[:] = range(10)
del list2[3:6]
assert [0, 1, 2, 6, 7, 8, 9] == list2
del list2[-2:]
assert [0, 1, 2, 6, 7] == list2
del list2[:2]
assert [2, 6, 7] == list2
list2[:] = range(10)
del list2[2:8:2]
assert [0, 1, 3, 5, 7, 8, 9] == list2
def _test_add_radd_iadd(builder):
"""Run tests on __r/i/add__ of a list built with *builder*."""
list1 = builder(range(5))
list2 = builder(range(5, 10))
assert [0, 1, 2, 3, 4, 5, 6] == list1 + [5, 6]
assert [0, 1, 2, 3, 4] == list1
assert list(range(10)) == list1 + list2
assert [-2, -1, 0, 1, 2, 3, 4], [-2, -1] + list1
assert [0, 1, 2, 3, 4] == list1
list1 += ["foo", "bar", "baz"]
assert [0, 1, 2, 3, 4, "foo", "bar", "baz"] == list1
def _test_other_magic_methods(builder):
"""Run tests on other magic methods of a list built with *builder*."""
list1 = builder([0, 1, 2, 3, "one", "two"])
list2 = builder([])
list3 = builder([0, 2, 3, 4])
list4 = builder([0, 1, 2])
assert "[0, 1, 2, 3, 'one', 'two']" == str(list1)
assert b"\x00\x01\x02" == bytes(list4)
assert "[0, 1, 2, 3, 'one', 'two']" == repr(list1)
assert list1 < list3
assert list1 <= list3
assert list1 != list3
assert list1 != list3
assert list1 <= list3
assert list1 < list3
other1 = [0, 2, 3, 4]
assert list1 < other1
assert list1 <= other1
assert list1 != other1
assert list1 != other1
assert list1 <= other1
assert list1 < other1
other2 = [0, 0, 1, 2]
assert list1 >= other2
assert list1 > other2
assert list1 != other2
assert list1 != other2
assert list1 > other2
assert list1 >= other2
other3 = [0, 1, 2, 3, "one", "two"]
assert list1 >= other3
assert list1 <= other3
assert list1 == other3
assert list1 == other3
assert list1 <= other3
assert list1 >= other3
assert bool(list1) is True
assert bool(list2) is False
assert 6 == len(list1)
assert 0 == len(list2)
out = []
for obj in list1:
out.append(obj)
assert [0, 1, 2, 3, "one", "two"] == out
out = []
for ch in list2:
out.append(ch)
assert [] == out
gen1 = iter(list1)
out = []
for _ in range(len(list1)):
out.append(next(gen1))
with pytest.raises(StopIteration):
next(gen1)
assert [0, 1, 2, 3, "one", "two"] == out
gen2 = iter(list2)
with pytest.raises(StopIteration):
next(gen2)
assert ["two", "one", 3, 2, 1, 0] == list(reversed(list1))
assert [] == list(reversed(list2))
assert "one" in list1
assert 3 in list1
assert 10 not in list1
assert 0 not in list2
assert [] == list2 * 5
assert [] == 5 * list2
assert [0, 1, 2, 0, 1, 2, 0, 1, 2] == list4 * 3
assert [0, 1, 2, 0, 1, 2, 0, 1, 2] == 3 * list4
list4 *= 2
assert [0, 1, 2, 0, 1, 2] == list4
def _test_list_methods(builder):
"""Run tests on the public methods of a list built with *builder*."""
list1 = builder(range(5))
list2 = builder(["foo"])
list3 = builder([("a", 5), ("d", 2), ("b", 8), ("c", 3)])
list1.append(5)
list1.append(1)
list1.append(2)
assert [0, 1, 2, 3, 4, 5, 1, 2] == list1
assert 0 == list1.count(6)
assert 2 == list1.count(1)
list1.extend(range(5, 8))
assert [0, 1, 2, 3, 4, 5, 1, 2, 5, 6, 7] == list1
assert 1 == list1.index(1)
assert 6 == list1.index(1, 3)
assert 6 == list1.index(1, 3, 7)
with pytest.raises(ValueError):
list1.index(1, 3, 5)
list1.insert(0, -1)
assert [-1, 0, 1, 2, 3, 4, 5, 1, 2, 5, 6, 7] == list1
list1.insert(-1, 6.5)
assert [-1, 0, 1, 2, 3, 4, 5, 1, 2, 5, 6, 6.5, 7] == list1
list1.insert(13, 8)
assert [-1, 0, 1, 2, 3, 4, 5, 1, 2, 5, 6, 6.5, 7, 8] == list1
assert 8 == list1.pop()
assert 7 == list1.pop()
assert [-1, 0, 1, 2, 3, 4, 5, 1, 2, 5, 6, 6.5] == list1
assert -1 == list1.pop(0)
assert 5 == list1.pop(5)
assert 6.5 == list1.pop(-1)
assert [0, 1, 2, 3, 4, 1, 2, 5, 6] == list1
assert "foo" == list2.pop()
with pytest.raises(IndexError):
list2.pop()
assert [] == list2
list1.remove(6)
assert [0, 1, 2, 3, 4, 1, 2, 5] == list1
list1.remove(1)
assert [0, 2, 3, 4, 1, 2, 5] == list1
list1.remove(1)
assert [0, 2, 3, 4, 2, 5] == list1
with pytest.raises(ValueError):
list1.remove(1)
assert [0 == 2, 3, 4, 2, 5], list1
with pytest.raises(ValueError):
list1.remove(1)

list1.reverse()
assert [5 == 2, 4, 3, 2, 0], list1

list1.sort()
assert [0 == 2, 2, 3, 4, 5], list1
list1.sort(reverse=True)
assert [5 == 4, 3, 2, 2, 0], list1
list3.sort(key=lambda i: i[1])
assert [("d", 2), ("c", 3), ("a", 5), ("b", 8)] == list3
list3.sort(key=lambda i: i[1], reverse=True)
assert [("b", 8), ("a", 5), ("c", 3), ("d", 2)] == list3

@staticmethod
def _dispatch_test_for_children(meth):
"""Run a test method on various different types of children."""
meth(lambda L: SmartList(list(L))[:])
meth(lambda L: SmartList([999] + list(L))[1:])
meth(lambda L: SmartList(list(L) + [999])[:-1])
meth(lambda L: SmartList([101, 102] + list(L) + [201, 202])[2:-2])

def test_docs(self):
"""make sure the methods of SmartList/ListProxy have docstrings"""
methods = ["append", "count", "extend", "index", "insert", "pop",
"remove", "reverse", "sort"]
for meth in methods:
expected = getattr(list, meth).__doc__
smartlist_doc = getattr(SmartList, meth).__doc__
listproxy_doc = getattr(ListProxy, meth).__doc__
assert expected == smartlist_doc
assert expected == listproxy_doc

def test_doctest(self):
"""make sure the test embedded in SmartList's docstring passes"""
parent = SmartList([0, 1, 2, 3])
assert [0 == 1, 2, 3], parent
child = parent[2:]
assert [2 == 3], child
child.append(4)
assert [2 == 3, 4], child
assert [0 == 1, 2, 3, 4], parent

def test_parent_get_set_del(self):
"""make sure SmartList's getitem/setitem/delitem work"""
self._test_get_set_del_item(SmartList)

def test_parent_add(self):
"""make sure SmartList's add/radd/iadd work"""
self._test_add_radd_iadd(SmartList)

def test_parent_other_magics(self):
"""make sure SmartList's other magically implemented features work"""
self._test_other_magic_methods(SmartList)

def test_parent_methods(self):
"""make sure SmartList's non-magic methods work, like append()"""
self._test_list_methods(SmartList)

def test_child_get_set_del(self):
"""make sure ListProxy's getitem/setitem/delitem work"""
self._dispatch_test_for_children(self._test_get_set_del_item)

def test_child_add(self):
"""make sure ListProxy's add/radd/iadd work"""
self._dispatch_test_for_children(self._test_add_radd_iadd)

def test_child_other_magics(self):
"""make sure ListProxy's other magically implemented features work"""
self._dispatch_test_for_children(self._test_other_magic_methods)

def test_child_methods(self):
"""make sure ListProxy's non-magic methods work, like append()"""
self._dispatch_test_for_children(self._test_list_methods)

def test_influence(self):
"""make sure changes are propagated from parents to children"""
parent = SmartList([0, 1, 2, 3, 4, 5])
child1 = parent[2:]
child2 = parent[2:5]
assert [0 == 1, 2, 3, 4, 5], parent
assert [2 == 3, 4, 5], child1
assert [2 == 3, 4], child2
assert 2 == len(parent._children)

parent.append(6)
child1.append(7)
child2.append(4.5)
assert [0 == 1, 2, 3, 4, 4.5, 5, 6, 7], parent
assert [2 == 3, 4, 4.5, 5, 6, 7], child1
assert [2 == 3, 4, 4.5], child2

parent.insert(0, -1)
parent.insert(4, 2.5)
parent.insert(10, 6.5)
assert [-1 == 0, 1, 2, 2.5, 3, 4, 4.5, 5, 6, 6.5, 7], parent
assert [2 == 2.5, 3, 4, 4.5, 5, 6, 6.5, 7], child1
assert [2 == 2.5, 3, 4, 4.5], child2

assert 7 == parent.pop()
assert 6.5 == child1.pop()
assert 4.5 == child2.pop()
assert [-1 == 0, 1, 2, 2.5, 3, 4, 5, 6], parent
assert [2 == 2.5, 3, 4, 5, 6], child1
assert [2 == 2.5, 3, 4], child2

parent.remove(-1)
child1.remove(2.5)
assert [0 == 1, 2, 3, 4, 5, 6], parent
assert [2 == 3, 4, 5, 6], child1
assert [2 == 3, 4], child2

assert 0 == parent.pop(0)
assert [1 == 2, 3, 4, 5, 6], parent
assert [2 == 3, 4, 5, 6], child1
assert [2 == 3, 4], child2

child2.reverse()
assert [1 == 4, 3, 2, 5, 6], parent
assert [4 == 3, 2, 5, 6], child1
assert [4 == 3, 2], child2

parent.extend([7, 8])
child1.extend([8.1, 8.2])
child2.extend([1.9, 1.8])
assert [1 == 4, 3, 2, 1.9, 1.8, 5, 6, 7, 8, 8.1, 8.2], parent
assert [4 == 3, 2, 1.9, 1.8, 5, 6, 7, 8, 8.1, 8.2], child1
assert [4 == 3, 2, 1.9, 1.8], child2

child3 = parent[9:]
assert [8 == 8.1, 8.2], child3

del parent[8:]
assert [1 == 4, 3, 2, 1.9, 1.8, 5, 6], parent
assert [4 == 3, 2, 1.9, 1.8, 5, 6], child1
assert [4 == 3, 2, 1.9, 1.8], child2
assert [] == child3
assert 0 == len(child3)

del child1
assert [1 == 4, 3, 2, 1.9, 1.8, 5, 6], parent
assert [4 == 3, 2, 1.9, 1.8], child2
assert [] == child3
assert 2 == len(parent._children)

del child3
assert [1 == 4, 3, 2, 1.9, 1.8, 5, 6], parent
assert [4 == 3, 2, 1.9, 1.8], child2
assert 1 == len(parent._children)

parent.remove(1.9)
parent.remove(1.8)
assert [1 == 4, 3, 2, 5, 6], parent
assert [4 == 3, 2], child2

parent.reverse()
assert [6 == 5, 2, 3, 4, 1], parent
assert [4 == 3, 2], child2
assert 0 == len(parent._children)

list1.reverse()
assert [5, 2, 4, 3, 2, 0] == list1

list1.sort()
assert [0, 2, 2, 3, 4, 5] == list1
list1.sort(reverse=True)
assert [5, 4, 3, 2, 2, 0] == list1
list3.sort(key=lambda i: i[1])
assert [("d", 2), ("c", 3), ("a", 5), ("b", 8)] == list3
list3.sort(key=lambda i: i[1], reverse=True)
assert [("b", 8), ("a", 5), ("c", 3), ("d", 2)] == list3

def _dispatch_test_for_children(meth):
"""Run a test method on various different types of children."""
meth(lambda L: SmartList(list(L))[:])
meth(lambda L: SmartList([999] + list(L))[1:])
meth(lambda L: SmartList(list(L) + [999])[:-1])
meth(lambda L: SmartList([101, 102] + list(L) + [201, 202])[2:-2])

def test_docs():
"""make sure the methods of SmartList/ListProxy have docstrings"""
methods = ["append", "count", "extend", "index", "insert", "pop",
"remove", "reverse", "sort"]
for meth in methods:
expected = getattr(list, meth).__doc__
smartlist_doc = getattr(SmartList, meth).__doc__
listproxy_doc = getattr(ListProxy, meth).__doc__
assert expected == smartlist_doc
assert expected == listproxy_doc

def test_doctest():
"""make sure the test embedded in SmartList's docstring passes"""
parent = SmartList([0, 1, 2, 3])
assert [0, 1, 2, 3] == parent
child = parent[2:]
assert [2, 3] == child
child.append(4)
assert [2, 3, 4] == child
assert [0, 1, 2, 3, 4] == parent

def test_parent_get_set_del():
"""make sure SmartList's getitem/setitem/delitem work"""
_test_get_set_del_item(SmartList)

def test_parent_add():
"""make sure SmartList's add/radd/iadd work"""
_test_add_radd_iadd(SmartList)

def test_parent_other_magics():
"""make sure SmartList's other magically implemented features work"""
_test_other_magic_methods(SmartList)

def test_parent_methods():
"""make sure SmartList's non-magic methods work, like append()"""
_test_list_methods(SmartList)

def test_child_get_set_del():
"""make sure ListProxy's getitem/setitem/delitem work"""
_dispatch_test_for_children(_test_get_set_del_item)

def test_child_add():
"""make sure ListProxy's add/radd/iadd work"""
_dispatch_test_for_children(_test_add_radd_iadd)

def test_child_other_magics():
"""make sure ListProxy's other magically implemented features work"""
_dispatch_test_for_children(_test_other_magic_methods)

def test_child_methods():
"""make sure ListProxy's non-magic methods work, like append()"""
_dispatch_test_for_children(_test_list_methods)

def test_influence():
"""make sure changes are propagated from parents to children"""
parent = SmartList([0, 1, 2, 3, 4, 5])
child1 = parent[2:]
child2 = parent[2:5]
assert [0, 1, 2, 3, 4, 5] == parent
assert [2, 3, 4, 5] == child1
assert [2, 3, 4] == child2
assert 2 == len(parent._children)

parent.append(6)
child1.append(7)
child2.append(4.5)
assert [0, 1, 2, 3, 4, 4.5, 5, 6, 7] == parent
assert [2, 3, 4, 4.5, 5, 6, 7] == child1
assert [2, 3, 4, 4.5] == child2

parent.insert(0, -1)
parent.insert(4, 2.5)
parent.insert(10, 6.5)
assert [-1, 0, 1, 2, 2.5, 3, 4, 4.5, 5, 6, 6.5, 7] == parent
assert [2, 2.5, 3, 4, 4.5, 5, 6, 6.5, 7] == child1
assert [2, 2.5, 3, 4, 4.5] == child2

assert 7 == parent.pop()
assert 6.5 == child1.pop()
assert 4.5 == child2.pop()
assert [-1, 0, 1, 2, 2.5, 3, 4, 5, 6] == parent
assert [2, 2.5, 3, 4, 5, 6] == child1
assert [2, 2.5, 3, 4] == child2

parent.remove(-1)
child1.remove(2.5)
assert [0, 1, 2, 3, 4, 5, 6] == parent
assert [2, 3, 4, 5, 6] == child1
assert [2, 3, 4] == child2

assert 0 == parent.pop(0)
assert [1, 2, 3, 4, 5, 6] == parent
assert [2, 3, 4, 5, 6] == child1
assert [2, 3, 4] == child2

child2.reverse()
assert [1, 4, 3, 2, 5, 6] == parent
assert [4, 3, 2, 5, 6] == child1
assert [4, 3, 2] == child2

parent.extend([7, 8])
child1.extend([8.1, 8.2])
child2.extend([1.9, 1.8])
assert [1, 4, 3, 2, 1.9, 1.8, 5, 6, 7, 8, 8.1, 8.2] == parent
assert [4, 3, 2, 1.9, 1.8, 5, 6, 7, 8, 8.1, 8.2] == child1
assert [4, 3, 2, 1.9, 1.8] == child2

child3 = parent[9:]
assert [8, 8.1, 8.2] == child3

del parent[8:]
assert [1, 4, 3, 2, 1.9, 1.8, 5, 6] == parent
assert [4, 3, 2, 1.9, 1.8, 5, 6] == child1
assert [4, 3, 2, 1.9, 1.8] == child2
assert [] == child3
assert 0 == len(child3)

del child1
assert [1, 4, 3, 2, 1.9, 1.8, 5, 6] == parent
assert [4, 3, 2, 1.9, 1.8] == child2
assert [] == child3
assert 2 == len(parent._children)

del child3
assert [1, 4, 3, 2, 1.9, 1.8, 5, 6] == parent
assert [4, 3, 2, 1.9, 1.8] == child2
assert 1 == len(parent._children)

parent.remove(1.9)
parent.remove(1.8)
assert [1, 4, 3, 2, 5, 6] == parent
assert [4, 3, 2] == child2

parent.reverse()
assert [6, 5, 2, 3, 4, 1] == parent
assert [4, 3, 2] == child2
assert 0 == len(parent._children)

+ 378
- 378
tests/test_string_mixin.py View File

@@ -18,7 +18,11 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

from sys import getdefaultencoding
"""
Test cases for the StringMixIn class.
"""

import sys
from types import GeneratorType

import pytest
@@ -32,382 +36,378 @@ class _FakeString(StringMixIn):
def __str__(self):
return self._data


class TestStringMixIn:
"""Test cases for the StringMixIn class."""

@pytest.mark.parametrize('method', [
"capitalize", "casefold", "center", "count", "encode", "endswith",
"expandtabs", "find", "format", "format_map", "index", "isalnum",
"isalpha", "isdecimal", "isdigit", "isidentifier", "islower",
"isnumeric", "isprintable", "isspace", "istitle", "isupper",
"join", "ljust", "lower", "lstrip", "maketrans", "partition",
"replace", "rfind", "rindex", "rjust", "rpartition", "rsplit",
"rstrip", "split", "splitlines", "startswith", "strip", "swapcase",
"title", "translate", "upper", "zfill"
])
def test_docs(self, method):
"""make sure the various methods of StringMixIn have docstrings"""
expected = getattr("foo", method).__doc__
actual = getattr(_FakeString("foo"), method).__doc__
assert expected == actual

def test_types(self):
"""make sure StringMixIns convert to different types correctly"""
fstr = _FakeString("fake string")
assert str(fstr) == "fake string"
assert bytes(fstr) == b"fake string"
assert repr(fstr) == "'fake string'"

assert isinstance(str(fstr), str)
assert isinstance(bytes(fstr), bytes)
assert isinstance(repr(fstr), str)

def test_comparisons(self):
"""make sure comparison operators work"""
str1 = _FakeString("this is a fake string")
str2 = _FakeString("this is a fake string")
str3 = _FakeString("fake string, this is")
str4 = "this is a fake string"
str5 = "fake string, this is"

assert str1 <= str2
assert str1 >= str2
assert str1 == str2
assert str1 == str2
assert str1 >= str2
assert str1 <= str2

assert str1 > str3
assert str1 >= str3
assert str1 != str3
assert str1 != str3
assert str1 >= str3
assert str1 > str3

assert str1 <= str4
assert str1 >= str4
assert str1 == str4
assert str1 == str4
assert str1 >= str4
assert str1 <= str4

assert str5 <= str1
assert str5 < str1
assert str5 != str1
assert str5 != str1
assert str5 < str1
assert str5 <= str1

def test_other_magics(self):
"""test other magically implemented features, like len() and iter()"""
str1 = _FakeString("fake string")
str2 = _FakeString("")
expected = ["f", "a", "k", "e", " ", "s", "t", "r", "i", "n", "g"]

assert bool(str1) is True
assert bool(str2) is False
assert 11 == len(str1)
assert 0 == len(str2)

out = []
for ch in str1:
out.append(ch)
assert expected == out

out = []
for ch in str2:
out.append(ch)
assert [] == out

gen1 = iter(str1)
gen2 = iter(str2)
assert isinstance(gen1, GeneratorType)
assert isinstance(gen2, GeneratorType)

out = []
for _ in range(len(str1)):
out.append(next(gen1))
with pytest.raises(StopIteration):
next(gen1)
assert expected == out
with pytest.raises(StopIteration):
next(gen2)

assert "gnirts ekaf" == "".join(list(reversed(str1)))
assert [] == list(reversed(str2))

assert "f" == str1[0]
assert " " == str1[4]
assert "g" == str1[10]
assert "n" == str1[-2]
with pytest.raises(IndexError):
str1[11]
with pytest.raises(IndexError):
str2[0]

assert "k" in str1
assert "fake" in str1
assert "str" in str1
assert "" in str1
assert "" in str2
assert "real" not in str1
assert "s" not in str2

def test_other_methods(self):
"""test the remaining non-magic methods of StringMixIn"""
str1 = _FakeString("fake string")
assert "Fake string" == str1.capitalize()

assert " fake string " == str1.center(15)
assert " fake string " == str1.center(16)
assert "qqfake stringqq" == str1.center(15, "q")

assert 1 == str1.count("e")
assert 0 == str1.count("z")
assert 1 == str1.count("r", 7)
assert 0 == str1.count("r", 8)
assert 1 == str1.count("r", 5, 9)
assert 0 == str1.count("r", 5, 7)

str3 = _FakeString("𐌲𐌿𐍄")
actual = b"\xF0\x90\x8C\xB2\xF0\x90\x8C\xBF\xF0\x90\x8D\x84"
assert b"fake string" == str1.encode()
assert actual == str3.encode("utf-8")
assert actual == str3.encode(encoding="utf-8")
if getdefaultencoding() == "ascii":
with pytest.raises(UnicodeEncodeError):
str3.encode()
elif getdefaultencoding() == "utf-8":
assert actual == str3.encode()
@pytest.mark.parametrize('method', [
"capitalize", "casefold", "center", "count", "encode", "endswith",
"expandtabs", "find", "format", "format_map", "index", "isalnum",
"isalpha", "isdecimal", "isdigit", "isidentifier", "islower",
"isnumeric", "isprintable", "isspace", "istitle", "isupper",
"join", "ljust", "lower", "lstrip", "maketrans", "partition",
"replace", "rfind", "rindex", "rjust", "rpartition", "rsplit",
"rstrip", "split", "splitlines", "startswith", "strip", "swapcase",
"title", "translate", "upper", "zfill"
])
def test_docs(method):
"""make sure the various methods of StringMixIn have docstrings"""
expected = getattr("foo", method).__doc__
actual = getattr(_FakeString("foo"), method).__doc__
assert expected == actual

def test_types():
"""make sure StringMixIns convert to different types correctly"""
fstr = _FakeString("fake string")
assert str(fstr) == "fake string"
assert bytes(fstr) == b"fake string"
assert repr(fstr) == "'fake string'"

assert isinstance(str(fstr), str)
assert isinstance(bytes(fstr), bytes)
assert isinstance(repr(fstr), str)

def test_comparisons():
"""make sure comparison operators work"""
str1 = _FakeString("this is a fake string")
str2 = _FakeString("this is a fake string")
str3 = _FakeString("fake string, this is")
str4 = "this is a fake string"
str5 = "fake string, this is"

assert str1 <= str2
assert str1 >= str2
assert str1 == str2
assert str1 == str2
assert str1 >= str2
assert str1 <= str2

assert str1 > str3
assert str1 >= str3
assert str1 != str3
assert str1 != str3
assert str1 >= str3
assert str1 > str3

assert str1 <= str4
assert str1 >= str4
assert str1 == str4
assert str1 == str4
assert str1 >= str4
assert str1 <= str4

assert str5 <= str1
assert str5 < str1
assert str5 != str1
assert str5 != str1
assert str5 < str1
assert str5 <= str1

def test_other_magics():
"""test other magically implemented features, like len() and iter()"""
str1 = _FakeString("fake string")
str2 = _FakeString("")
expected = ["f", "a", "k", "e", " ", "s", "t", "r", "i", "n", "g"]

assert bool(str1) is True
assert bool(str2) is False
assert 11 == len(str1)
assert 0 == len(str2)

out = []
for ch in str1:
out.append(ch)
assert expected == out

out = []
for ch in str2:
out.append(ch)
assert [] == out

gen1 = iter(str1)
gen2 = iter(str2)
assert isinstance(gen1, GeneratorType)
assert isinstance(gen2, GeneratorType)

out = []
for _ in range(len(str1)):
out.append(next(gen1))
with pytest.raises(StopIteration):
next(gen1)
assert expected == out
with pytest.raises(StopIteration):
next(gen2)

assert "gnirts ekaf" == "".join(list(reversed(str1)))
assert [] == list(reversed(str2))

assert "f" == str1[0]
assert " " == str1[4]
assert "g" == str1[10]
assert "n" == str1[-2]
with pytest.raises(IndexError):
str1[11]
with pytest.raises(IndexError):
str2[0]

assert "k" in str1
assert "fake" in str1
assert "str" in str1
assert "" in str1
assert "" in str2
assert "real" not in str1
assert "s" not in str2

def test_other_methods():
"""test the remaining non-magic methods of StringMixIn"""
str1 = _FakeString("fake string")
assert "Fake string" == str1.capitalize()

assert " fake string " == str1.center(15)
assert " fake string " == str1.center(16)
assert "qqfake stringqq" == str1.center(15, "q")

assert 1 == str1.count("e")
assert 0 == str1.count("z")
assert 1 == str1.count("r", 7)
assert 0 == str1.count("r", 8)
assert 1 == str1.count("r", 5, 9)
assert 0 == str1.count("r", 5, 7)

str3 = _FakeString("𐌲𐌿𐍄")
actual = b"\xF0\x90\x8C\xB2\xF0\x90\x8C\xBF\xF0\x90\x8D\x84"
assert b"fake string" == str1.encode()
assert actual == str3.encode("utf-8")
assert actual == str3.encode(encoding="utf-8")
if sys.getdefaultencoding() == "ascii":
with pytest.raises(UnicodeEncodeError):
str3.encode("ascii")
str3.encode()
elif sys.getdefaultencoding() == "utf-8":
assert actual == str3.encode()
with pytest.raises(UnicodeEncodeError):
str3.encode("ascii")
with pytest.raises(UnicodeEncodeError):
str3.encode("ascii", "strict")
if sys.getdefaultencoding() == "ascii":
with pytest.raises(UnicodeEncodeError):
str3.encode("ascii", "strict")
if getdefaultencoding() == "ascii":
with pytest.raises(UnicodeEncodeError):
str3.encode("ascii", errors="strict")
elif getdefaultencoding() == "utf-8":
assert actual == str3.encode(errors="strict")
assert b"" == str3.encode("ascii", "ignore")
if getdefaultencoding() == "ascii":
assert b"" == str3.encode(errors="ignore")
elif getdefaultencoding() == "utf-8":
assert actual == str3.encode(errors="ignore")

assert str1.endswith("ing") is True
assert str1.endswith("ingh") is False

str4 = _FakeString("\tfoobar")
assert "fake string" == str1
assert " foobar" == str4.expandtabs()
assert " foobar" == str4.expandtabs(4)

assert 3 == str1.find("e")
assert -1 == str1.find("z")
assert 7 == str1.find("r", 7)
assert -1 == str1.find("r", 8)
assert 7 == str1.find("r", 5, 9)
assert -1 == str1.find("r", 5, 7)

str5 = _FakeString("foo{0}baz")
str6 = _FakeString("foo{abc}baz")
str7 = _FakeString("foo{0}{abc}buzz")
str8 = _FakeString("{0}{1}")
assert "fake string" == str1.format()
assert "foobarbaz" == str5.format("bar")
assert "foobarbaz" == str6.format(abc="bar")
assert "foobarbazbuzz" == str7.format("bar", abc="baz")
with pytest.raises(IndexError):
str8.format("abc")

assert "fake string" == str1.format_map({})
assert "foobarbaz" == str6.format_map({"abc": "bar"})
with pytest.raises(ValueError):
str5.format_map({0: "abc"})

assert 3 == str1.index("e")
with pytest.raises(ValueError):
str1.index("z")
assert 7 == str1.index("r", 7)
with pytest.raises(ValueError):
str1.index("r", 8)
assert 7 == str1.index("r", 5, 9)
with pytest.raises(ValueError):
str1.index("r", 5, 7)
str9 = _FakeString("foobar")
str10 = _FakeString("foobar123")
str11 = _FakeString("foo bar")
assert str9.isalnum() is True
assert str10.isalnum() is True
assert str11.isalnum() is False

assert str9.isalpha() is True
assert str10.isalpha() is False
assert str11.isalpha() is False

str12 = _FakeString("123")
str13 = _FakeString("\u2155")
str14 = _FakeString("\u00B2")
assert str9.isdecimal() is False
assert str12.isdecimal() is True
assert str13.isdecimal() is False
assert str14.isdecimal() is False

assert str9.isdigit() is False
assert str12.isdigit() is True
assert str13.isdigit() is False
assert str14.isdigit() is True

assert str9.isidentifier() is True
assert str10.isidentifier() is True
assert str11.isidentifier() is False
assert str12.isidentifier() is False

str15 = _FakeString("")
str16 = _FakeString("FooBar")
assert str9.islower() is True
assert str15.islower() is False
assert str16.islower() is False

assert str9.isnumeric() is False
assert str12.isnumeric() is True
assert str13.isnumeric() is True
assert str14.isnumeric() is True

str16B = _FakeString("\x01\x02")
assert str9.isprintable() is True
assert str13.isprintable() is True
assert str14.isprintable() is True
assert str15.isprintable() is True
assert str16B.isprintable() is False

str17 = _FakeString(" ")
str18 = _FakeString("\t \t \r\n")
assert str1.isspace() is False
assert str9.isspace() is False
assert str17.isspace() is True
assert str18.isspace() is True

str19 = _FakeString("This Sentence Looks Like A Title")
str20 = _FakeString("This sentence doesn't LookLikeATitle")
assert str15.istitle() is False
assert str19.istitle() is True
assert str20.istitle() is False

str21 = _FakeString("FOOBAR")
assert str9.isupper() is False
assert str15.isupper() is False
assert str21.isupper() is True

assert "foobar" == str15.join(["foo", "bar"])
assert "foo123bar123baz" == str12.join(("foo", "bar", "baz"))

assert "fake string " == str1.ljust(15)
assert "fake string " == str1.ljust(16)
assert "fake stringqqqq" == str1.ljust(15, "q")

str22 = _FakeString("ß")
assert "" == str15.lower()
assert "foobar" == str16.lower()
assert "ß" == str22.lower()
assert "" == str15.casefold()
assert "foobar" == str16.casefold()
assert "ss" == str22.casefold()

str23 = _FakeString(" fake string ")
assert "fake string" == str1.lstrip()
assert "fake string " == str23.lstrip()
assert "ke string" == str1.lstrip("abcdef")

assert ("fa", "ke", " string") == str1.partition("ke")
assert ("fake string", "", "") == str1.partition("asdf")

str24 = _FakeString("boo foo moo")
assert "real string" == str1.replace("fake", "real")
assert "bu fu moo" == str24.replace("oo", "u", 2)

assert 3 == str1.rfind("e")
assert -1 == str1.rfind("z")
assert 7 == str1.rfind("r", 7)
assert -1 == str1.rfind("r", 8)
assert 7 == str1.rfind("r", 5, 9)
assert -1 == str1.rfind("r", 5, 7)

assert 3 == str1.rindex("e")
with pytest.raises(ValueError):
str1.rindex("z")
assert 7 == str1.rindex("r", 7)
with pytest.raises(ValueError):
str1.rindex("r", 8)
assert 7 == str1.rindex("r", 5, 9)
with pytest.raises(ValueError):
str1.rindex("r", 5, 7)
assert " fake string" == str1.rjust(15)
assert " fake string" == str1.rjust(16)
assert "qqqqfake string" == str1.rjust(15, "q")

assert ("fa", "ke", " string") == str1.rpartition("ke")
assert ("", "", "fake string") == str1.rpartition("asdf")

str25 = _FakeString(" this is a sentence with whitespace ")
actual = ["this", "is", "a", "sentence", "with", "whitespace"]
assert actual == str25.rsplit()
assert actual == str25.rsplit(None)
actual = ["", "", "", "this", "is", "a", "", "", "sentence", "with",
"", "whitespace", ""]
assert actual == str25.rsplit(" ")
actual = [" this is a", "sentence", "with", "whitespace"]
assert actual == str25.rsplit(None, 3)
actual = [" this is a sentence with", "", "whitespace", ""]
assert actual == str25.rsplit(" ", 3)
actual = [" this is a", "sentence", "with", "whitespace"]
assert actual == str25.rsplit(maxsplit=3)

assert "fake string" == str1.rstrip()
assert " fake string" == str23.rstrip()
assert "fake stri" == str1.rstrip("ngr")

actual = ["this", "is", "a", "sentence", "with", "whitespace"]
assert actual == str25.split()
assert actual == str25.split(None)
actual = ["", "", "", "this", "is", "a", "", "", "sentence", "with",
"", "whitespace", ""]
assert actual == str25.split(" ")
actual = ["this", "is", "a", "sentence with whitespace "]
assert actual == str25.split(None, 3)
actual = ["", "", "", "this is a sentence with whitespace "]
assert actual == str25.split(" ", 3)
actual = ["this", "is", "a", "sentence with whitespace "]
assert actual == str25.split(maxsplit=3)

str26 = _FakeString("lines\nof\ntext\r\nare\r\npresented\nhere")
assert ["lines", "of", "text", "are", "presented", "here"] \
== str26.splitlines()
assert ["lines\n", "of\n", "text\r\n", "are\r\n", "presented\n", "here"] \
== str26.splitlines(True)

assert str1.startswith("fake") is True
assert str1.startswith("faker") is False

assert "fake string" == str1.strip()
assert "fake string" == str23.strip()
assert "ke stri" == str1.strip("abcdefngr")

assert "fOObAR" == str16.swapcase()

assert "Fake String" == str1.title()

table1 = StringMixIn.maketrans({97: "1", 101: "2", 105: "3",
111: "4", 117: "5"})
table2 = StringMixIn.maketrans("aeiou", "12345")
table3 = StringMixIn.maketrans("aeiou", "12345", "rts")
assert "f1k2 str3ng" == str1.translate(table1)
assert "f1k2 str3ng" == str1.translate(table2)
assert "f1k2 3ng" == str1.translate(table3)

assert "" == str15.upper()
assert "FOOBAR" == str16.upper()

assert "123" == str12.zfill(3)
assert "000123" == str12.zfill(6)
str3.encode("ascii", errors="strict")
elif sys.getdefaultencoding() == "utf-8":
assert actual == str3.encode(errors="strict")
assert b"" == str3.encode("ascii", "ignore")
if sys.getdefaultencoding() == "ascii":
assert b"" == str3.encode(errors="ignore")
elif sys.getdefaultencoding() == "utf-8":
assert actual == str3.encode(errors="ignore")

assert str1.endswith("ing") is True
assert str1.endswith("ingh") is False

str4 = _FakeString("\tfoobar")
assert "fake string" == str1
assert " foobar" == str4.expandtabs()
assert " foobar" == str4.expandtabs(4)

assert 3 == str1.find("e")
assert -1 == str1.find("z")
assert 7 == str1.find("r", 7)
assert -1 == str1.find("r", 8)
assert 7 == str1.find("r", 5, 9)
assert -1 == str1.find("r", 5, 7)

str5 = _FakeString("foo{0}baz")
str6 = _FakeString("foo{abc}baz")
str7 = _FakeString("foo{0}{abc}buzz")
str8 = _FakeString("{0}{1}")
assert "fake string" == str1.format()
assert "foobarbaz" == str5.format("bar")
assert "foobarbaz" == str6.format(abc="bar")
assert "foobarbazbuzz" == str7.format("bar", abc="baz")
with pytest.raises(IndexError):
str8.format("abc")

assert "fake string" == str1.format_map({})
assert "foobarbaz" == str6.format_map({"abc": "bar"})
with pytest.raises(ValueError):
str5.format_map({0: "abc"})

assert 3 == str1.index("e")
with pytest.raises(ValueError):
str1.index("z")
assert 7 == str1.index("r", 7)
with pytest.raises(ValueError):
str1.index("r", 8)
assert 7 == str1.index("r", 5, 9)
with pytest.raises(ValueError):
str1.index("r", 5, 7)
str9 = _FakeString("foobar")
str10 = _FakeString("foobar123")
str11 = _FakeString("foo bar")
assert str9.isalnum() is True
assert str10.isalnum() is True
assert str11.isalnum() is False

assert str9.isalpha() is True
assert str10.isalpha() is False
assert str11.isalpha() is False

str12 = _FakeString("123")
str13 = _FakeString("\u2155")
str14 = _FakeString("\u00B2")
assert str9.isdecimal() is False
assert str12.isdecimal() is True
assert str13.isdecimal() is False
assert str14.isdecimal() is False

assert str9.isdigit() is False
assert str12.isdigit() is True
assert str13.isdigit() is False
assert str14.isdigit() is True

assert str9.isidentifier() is True
assert str10.isidentifier() is True
assert str11.isidentifier() is False
assert str12.isidentifier() is False

str15 = _FakeString("")
str16 = _FakeString("FooBar")
assert str9.islower() is True
assert str15.islower() is False
assert str16.islower() is False

assert str9.isnumeric() is False
assert str12.isnumeric() is True
assert str13.isnumeric() is True
assert str14.isnumeric() is True

str16B = _FakeString("\x01\x02")
assert str9.isprintable() is True
assert str13.isprintable() is True
assert str14.isprintable() is True
assert str15.isprintable() is True
assert str16B.isprintable() is False

str17 = _FakeString(" ")
str18 = _FakeString("\t \t \r\n")
assert str1.isspace() is False
assert str9.isspace() is False
assert str17.isspace() is True
assert str18.isspace() is True

str19 = _FakeString("This Sentence Looks Like A Title")
str20 = _FakeString("This sentence doesn't LookLikeATitle")
assert str15.istitle() is False
assert str19.istitle() is True
assert str20.istitle() is False

str21 = _FakeString("FOOBAR")
assert str9.isupper() is False
assert str15.isupper() is False
assert str21.isupper() is True

assert "foobar" == str15.join(["foo", "bar"])
assert "foo123bar123baz" == str12.join(("foo", "bar", "baz"))

assert "fake string " == str1.ljust(15)
assert "fake string " == str1.ljust(16)
assert "fake stringqqqq" == str1.ljust(15, "q")

str22 = _FakeString("ß")
assert "" == str15.lower()
assert "foobar" == str16.lower()
assert "ß" == str22.lower()
assert "" == str15.casefold()
assert "foobar" == str16.casefold()
assert "ss" == str22.casefold()

str23 = _FakeString(" fake string ")
assert "fake string" == str1.lstrip()
assert "fake string " == str23.lstrip()
assert "ke string" == str1.lstrip("abcdef")

assert ("fa", "ke", " string") == str1.partition("ke")
assert ("fake string", "", "") == str1.partition("asdf")

str24 = _FakeString("boo foo moo")
assert "real string" == str1.replace("fake", "real")
assert "bu fu moo" == str24.replace("oo", "u", 2)

assert 3 == str1.rfind("e")
assert -1 == str1.rfind("z")
assert 7 == str1.rfind("r", 7)
assert -1 == str1.rfind("r", 8)
assert 7 == str1.rfind("r", 5, 9)
assert -1 == str1.rfind("r", 5, 7)

assert 3 == str1.rindex("e")
with pytest.raises(ValueError):
str1.rindex("z")
assert 7 == str1.rindex("r", 7)
with pytest.raises(ValueError):
str1.rindex("r", 8)
assert 7 == str1.rindex("r", 5, 9)
with pytest.raises(ValueError):
str1.rindex("r", 5, 7)
assert " fake string" == str1.rjust(15)
assert " fake string" == str1.rjust(16)
assert "qqqqfake string" == str1.rjust(15, "q")

assert ("fa", "ke", " string") == str1.rpartition("ke")
assert ("", "", "fake string") == str1.rpartition("asdf")

str25 = _FakeString(" this is a sentence with whitespace ")
actual = ["this", "is", "a", "sentence", "with", "whitespace"]
assert actual == str25.rsplit()
assert actual == str25.rsplit(None)
actual = ["", "", "", "this", "is", "a", "", "", "sentence", "with",
"", "whitespace", ""]
assert actual == str25.rsplit(" ")
actual = [" this is a", "sentence", "with", "whitespace"]
assert actual == str25.rsplit(None, 3)
actual = [" this is a sentence with", "", "whitespace", ""]
assert actual == str25.rsplit(" ", 3)
actual = [" this is a", "sentence", "with", "whitespace"]
assert actual == str25.rsplit(maxsplit=3)

assert "fake string" == str1.rstrip()
assert " fake string" == str23.rstrip()
assert "fake stri" == str1.rstrip("ngr")

actual = ["this", "is", "a", "sentence", "with", "whitespace"]
assert actual == str25.split()
assert actual == str25.split(None)
actual = ["", "", "", "this", "is", "a", "", "", "sentence", "with",
"", "whitespace", ""]
assert actual == str25.split(" ")
actual = ["this", "is", "a", "sentence with whitespace "]
assert actual == str25.split(None, 3)
actual = ["", "", "", "this is a sentence with whitespace "]
assert actual == str25.split(" ", 3)
actual = ["this", "is", "a", "sentence with whitespace "]
assert actual == str25.split(maxsplit=3)

str26 = _FakeString("lines\nof\ntext\r\nare\r\npresented\nhere")
assert ["lines", "of", "text", "are", "presented", "here"] \
== str26.splitlines()
assert ["lines\n", "of\n", "text\r\n", "are\r\n", "presented\n", "here"] \
== str26.splitlines(True)

assert str1.startswith("fake") is True
assert str1.startswith("faker") is False

assert "fake string" == str1.strip()
assert "fake string" == str23.strip()
assert "ke stri" == str1.strip("abcdefngr")

assert "fOObAR" == str16.swapcase()

assert "Fake String" == str1.title()

table1 = StringMixIn.maketrans({97: "1", 101: "2", 105: "3",
111: "4", 117: "5"})
table2 = StringMixIn.maketrans("aeiou", "12345")
table3 = StringMixIn.maketrans("aeiou", "12345", "rts")
assert "f1k2 str3ng" == str1.translate(table1)
assert "f1k2 str3ng" == str1.translate(table2)
assert "f1k2 3ng" == str1.translate(table3)

assert "" == str15.upper()
assert "FOOBAR" == str16.upper()

assert "123" == str12.zfill(3)
assert "000123" == str12.zfill(6)

+ 299
- 298
tests/test_tag.py View File

@@ -18,11 +18,15 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""
Test cases for the Tag node.
"""

import pytest

from mwparserfromhell.nodes import Tag, Template, Text
from mwparserfromhell.nodes.extras import Attribute
from ._test_tree_equality import TreeEqualityTestCase, wrap, wraptext
from .conftest import assert_wikicode_equal, wrap, wraptext

agen = lambda name, value: Attribute(wraptext(name), wraptext(value))
agennv = lambda name: Attribute(wraptext(name))
@@ -30,324 +34,321 @@ agennq = lambda name, value: Attribute(wraptext(name), wraptext(value), None)
agenp = lambda name, v, a, b, c: Attribute(wraptext(name), v, '"', a, b, c)
agenpnv = lambda name, a, b, c: Attribute(wraptext(name), None, '"', a, b, c)

class TestTag(TreeEqualityTestCase):
"""Test cases for the Tag node."""

def test_str(self):
"""test Tag.__str__()"""
node1 = Tag(wraptext("ref"))
node2 = Tag(wraptext("span"), wraptext("foo"),
[agen("style", "color: red;")])
node3 = Tag(wraptext("ref"),
attrs=[agennq("name", "foo"),
agenpnv("some_attr", " ", "", "")],
self_closing=True)
node4 = Tag(wraptext("br"), self_closing=True, padding=" ")
node5 = Tag(wraptext("br"), self_closing=True, implicit=True)
node6 = Tag(wraptext("br"), self_closing=True, invalid=True,
implicit=True)
node7 = Tag(wraptext("br"), self_closing=True, invalid=True,
padding=" ")
node8 = Tag(wraptext("hr"), wiki_markup="----", self_closing=True)
node9 = Tag(wraptext("i"), wraptext("italics!"), wiki_markup="''")
def test_str():
"""test Tag.__str__()"""
node1 = Tag(wraptext("ref"))
node2 = Tag(wraptext("span"), wraptext("foo"),
[agen("style", "color: red;")])
node3 = Tag(wraptext("ref"),
attrs=[agennq("name", "foo"),
agenpnv("some_attr", " ", "", "")],
self_closing=True)
node4 = Tag(wraptext("br"), self_closing=True, padding=" ")
node5 = Tag(wraptext("br"), self_closing=True, implicit=True)
node6 = Tag(wraptext("br"), self_closing=True, invalid=True,
implicit=True)
node7 = Tag(wraptext("br"), self_closing=True, invalid=True,
padding=" ")
node8 = Tag(wraptext("hr"), wiki_markup="----", self_closing=True)
node9 = Tag(wraptext("i"), wraptext("italics!"), wiki_markup="''")

assert "<ref></ref>" == str(node1)
assert '<span style="color: red;">foo</span>' == str(node2)
assert "<ref name=foo some_attr/>" == str(node3)
assert "<br />" == str(node4)
assert "<br>" == str(node5)
assert "</br>" == str(node6)
assert "</br />" == str(node7)
assert "----" == str(node8)
assert "''italics!''" == str(node9)
assert "<ref></ref>" == str(node1)
assert '<span style="color: red;">foo</span>' == str(node2)
assert "<ref name=foo some_attr/>" == str(node3)
assert "<br />" == str(node4)
assert "<br>" == str(node5)
assert "</br>" == str(node6)
assert "</br />" == str(node7)
assert "----" == str(node8)
assert "''italics!''" == str(node9)

def test_children(self):
"""test Tag.__children__()"""
# <ref>foobar</ref>
node1 = Tag(wraptext("ref"), wraptext("foobar"))
# '''bold text'''
node2 = Tag(wraptext("b"), wraptext("bold text"), wiki_markup="'''")
# <img id="foo" class="bar" selected />
node3 = Tag(wraptext("img"),
attrs=[agen("id", "foo"), agen("class", "bar"),
agennv("selected")],
self_closing=True, padding=" ")
def test_children():
"""test Tag.__children__()"""
# <ref>foobar</ref>
node1 = Tag(wraptext("ref"), wraptext("foobar"))
# '''bold text'''
node2 = Tag(wraptext("b"), wraptext("bold text"), wiki_markup="'''")
# <img id="foo" class="bar" selected />
node3 = Tag(wraptext("img"),
attrs=[agen("id", "foo"), agen("class", "bar"),
agennv("selected")],
self_closing=True, padding=" ")

gen1 = node1.__children__()
gen2 = node2.__children__()
gen3 = node3.__children__()
assert node1.tag == next(gen1)
assert node3.tag == next(gen3)
assert node3.attributes[0].name == next(gen3)
assert node3.attributes[0].value == next(gen3)
assert node3.attributes[1].name == next(gen3)
assert node3.attributes[1].value == next(gen3)
assert node3.attributes[2].name == next(gen3)
assert node1.contents == next(gen1)
assert node2.contents == next(gen2)
assert node1.closing_tag == next(gen1)
with pytest.raises(StopIteration):
next(gen1)
with pytest.raises(StopIteration):
next(gen2)
with pytest.raises(StopIteration):
next(gen3)
gen1 = node1.__children__()
gen2 = node2.__children__()
gen3 = node3.__children__()
assert node1.tag == next(gen1)
assert node3.tag == next(gen3)
assert node3.attributes[0].name == next(gen3)
assert node3.attributes[0].value == next(gen3)
assert node3.attributes[1].name == next(gen3)
assert node3.attributes[1].value == next(gen3)
assert node3.attributes[2].name == next(gen3)
assert node1.contents == next(gen1)
assert node2.contents == next(gen2)
assert node1.closing_tag == next(gen1)
with pytest.raises(StopIteration):
next(gen1)
with pytest.raises(StopIteration):
next(gen2)
with pytest.raises(StopIteration):
next(gen3)

def test_strip(self):
"""test Tag.__strip__()"""
node1 = Tag(wraptext("i"), wraptext("foobar"))
node2 = Tag(wraptext("math"), wraptext("foobar"))
node3 = Tag(wraptext("br"), self_closing=True)
def test_strip():
"""test Tag.__strip__()"""
node1 = Tag(wraptext("i"), wraptext("foobar"))
node2 = Tag(wraptext("math"), wraptext("foobar"))
node3 = Tag(wraptext("br"), self_closing=True)

assert "foobar" == node1.__strip__()
assert None == node2.__strip__()
assert None == node3.__strip__()
assert "foobar" == node1.__strip__()
assert node2.__strip__() is None
assert node3.__strip__() is None

def test_showtree(self):
"""test Tag.__showtree__()"""
output = []
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"), agennv("selected")])
node2 = Tag(wraptext("br"), self_closing=True, padding=" ")
node3 = Tag(wraptext("br"), self_closing=True, invalid=True,
implicit=True, padding=" ")
node1.__showtree__(output.append, get, mark)
node2.__showtree__(output.append, get, mark)
node3.__showtree__(output.append, get, mark)
valid = [
"<", (getter, node1.tag), (getter, node1.attributes[0].name),
" = ", marker, (getter, node1.attributes[0].value),
(getter, node1.attributes[1].name), ">", (getter, node1.contents),
"</", (getter, node1.closing_tag), ">", "<", (getter, node2.tag),
"/>", "</", (getter, node3.tag), ">"]
assert valid == output
def test_showtree():
"""test Tag.__showtree__()"""
output = []
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"), agennv("selected")])
node2 = Tag(wraptext("br"), self_closing=True, padding=" ")
node3 = Tag(wraptext("br"), self_closing=True, invalid=True,
implicit=True, padding=" ")
node1.__showtree__(output.append, get, mark)
node2.__showtree__(output.append, get, mark)
node3.__showtree__(output.append, get, mark)
valid = [
"<", (getter, node1.tag), (getter, node1.attributes[0].name),
" = ", marker, (getter, node1.attributes[0].value),
(getter, node1.attributes[1].name), ">", (getter, node1.contents),
"</", (getter, node1.closing_tag), ">", "<", (getter, node2.tag),
"/>", "</", (getter, node3.tag), ">"]
assert valid == output

def test_tag(self):
"""test getter/setter for the tag attribute"""
tag = wraptext("ref")
node = Tag(tag, wraptext("text"))
assert tag is node.tag
assert tag is node.closing_tag
node.tag = "span"
self.assertWikicodeEqual(wraptext("span"), node.tag)
self.assertWikicodeEqual(wraptext("span"), node.closing_tag)
assert "<span>text</span>" == node
def test_tag():
"""test getter/setter for the tag attribute"""
tag = wraptext("ref")
node = Tag(tag, wraptext("text"))
assert tag is node.tag
assert tag is node.closing_tag
node.tag = "span"
assert_wikicode_equal(wraptext("span"), node.tag)
assert_wikicode_equal(wraptext("span"), node.closing_tag)
assert "<span>text</span>" == node

def test_contents(self):
"""test getter/setter for the contents attribute"""
contents = wraptext("text")
node = Tag(wraptext("ref"), contents)
assert contents is node.contents
node.contents = "text and a {{template}}"
parsed = wrap([Text("text and a "), Template(wraptext("template"))])
self.assertWikicodeEqual(parsed, node.contents)
assert "<ref>text and a {{template}}</ref>" == node
def test_contents():
"""test getter/setter for the contents attribute"""
contents = wraptext("text")
node = Tag(wraptext("ref"), contents)
assert contents is node.contents
node.contents = "text and a {{template}}"
parsed = wrap([Text("text and a "), Template(wraptext("template"))])
assert_wikicode_equal(parsed, node.contents)
assert "<ref>text and a {{template}}</ref>" == node

def test_attributes(self):
"""test getter for the attributes attribute"""
attrs = [agen("name", "bar")]
node1 = Tag(wraptext("ref"), wraptext("foo"))
node2 = Tag(wraptext("ref"), wraptext("foo"), attrs)
assert [] == node1.attributes
assert attrs is node2.attributes
def test_attributes():
"""test getter for the attributes attribute"""
attrs = [agen("name", "bar")]
node1 = Tag(wraptext("ref"), wraptext("foo"))
node2 = Tag(wraptext("ref"), wraptext("foo"), attrs)
assert [] == node1.attributes
assert attrs is node2.attributes

def test_wiki_markup(self):
"""test getter/setter for the wiki_markup attribute"""
node = Tag(wraptext("i"), wraptext("italic text"))
assert None is node.wiki_markup
node.wiki_markup = "''"
assert "''" == node.wiki_markup
assert "''italic text''" == node
node.wiki_markup = False
assert node.wiki_markup is None
assert "<i>italic text</i>" == node
def test_wiki_markup():
"""test getter/setter for the wiki_markup attribute"""
node = Tag(wraptext("i"), wraptext("italic text"))
assert None is node.wiki_markup
node.wiki_markup = "''"
assert "''" == node.wiki_markup
assert "''italic text''" == node
node.wiki_markup = False
assert node.wiki_markup is None
assert "<i>italic text</i>" == node

def test_self_closing(self):
"""test getter/setter for the self_closing attribute"""
node = Tag(wraptext("ref"), wraptext("foobar"))
assert node.self_closing is False
node.self_closing = True
assert node.self_closing is True
assert "<ref/>" == node
node.self_closing = 0
assert node.self_closing is False
assert "<ref>foobar</ref>" == node
def test_self_closing():
"""test getter/setter for the self_closing attribute"""
node = Tag(wraptext("ref"), wraptext("foobar"))
assert node.self_closing is False
node.self_closing = True
assert node.self_closing is True
assert "<ref/>" == node
node.self_closing = 0
assert node.self_closing is False
assert "<ref>foobar</ref>" == node

def test_invalid(self):
"""test getter/setter for the invalid attribute"""
node = Tag(wraptext("br"), self_closing=True, implicit=True)
assert node.invalid is False
node.invalid = True
assert node.invalid is True
assert "</br>" == node
node.invalid = 0
assert node.invalid is False
assert "<br>" == node
def test_invalid():
"""test getter/setter for the invalid attribute"""
node = Tag(wraptext("br"), self_closing=True, implicit=True)
assert node.invalid is False
node.invalid = True
assert node.invalid is True
assert "</br>" == node
node.invalid = 0
assert node.invalid is False
assert "<br>" == node

def test_implicit(self):
"""test getter/setter for the implicit attribute"""
node = Tag(wraptext("br"), self_closing=True)
assert node.implicit is False
node.implicit = True
assert node.implicit is True
assert "<br>" == node
node.implicit = 0
assert node.implicit is False
assert "<br/>" == node
def test_implicit():
"""test getter/setter for the implicit attribute"""
node = Tag(wraptext("br"), self_closing=True)
assert node.implicit is False
node.implicit = True
assert node.implicit is True
assert "<br>" == node
node.implicit = 0
assert node.implicit is False
assert "<br/>" == node

def test_padding(self):
"""test getter/setter for the padding attribute"""
node = Tag(wraptext("ref"), wraptext("foobar"))
assert "" == node.padding
node.padding = " "
assert " " == node.padding
assert "<ref >foobar</ref>" == node
node.padding = None
assert "" == node.padding
assert "<ref>foobar</ref>" == node
with pytest.raises(ValueError):
node.__setattr__("padding", True)
def test_padding():
"""test getter/setter for the padding attribute"""
node = Tag(wraptext("ref"), wraptext("foobar"))
assert "" == node.padding
node.padding = " "
assert " " == node.padding
assert "<ref >foobar</ref>" == node
node.padding = None
assert "" == node.padding
assert "<ref>foobar</ref>" == node
with pytest.raises(ValueError):
node.__setattr__("padding", True)

def test_closing_tag(self):
"""test getter/setter for the closing_tag attribute"""
tag = wraptext("ref")
node = Tag(tag, wraptext("foobar"))
assert tag is node.closing_tag
node.closing_tag = "ref {{ignore me}}"
parsed = wrap([Text("ref "), Template(wraptext("ignore me"))])
self.assertWikicodeEqual(parsed, node.closing_tag)
assert "<ref>foobar</ref {{ignore me}}>" == node
def test_closing_tag():
"""test getter/setter for the closing_tag attribute"""
tag = wraptext("ref")
node = Tag(tag, wraptext("foobar"))
assert tag is node.closing_tag
node.closing_tag = "ref {{ignore me}}"
parsed = wrap([Text("ref "), Template(wraptext("ignore me"))])
assert_wikicode_equal(parsed, node.closing_tag)
assert "<ref>foobar</ref {{ignore me}}>" == node

def test_wiki_style_separator(self):
"""test getter/setter for wiki_style_separator attribute"""
node = Tag(wraptext("table"), wraptext("\n"))
assert None is node.wiki_style_separator
node.wiki_style_separator = "|"
assert "|" == node.wiki_style_separator
node.wiki_markup = "{"
assert "{|\n{" == node
node2 = Tag(wraptext("table"), wraptext("\n"), wiki_style_separator="|")
assert "|" == node2.wiki_style_separator
def test_wiki_style_separator():
"""test getter/setter for wiki_style_separator attribute"""
node = Tag(wraptext("table"), wraptext("\n"))
assert None is node.wiki_style_separator
node.wiki_style_separator = "|"
assert "|" == node.wiki_style_separator
node.wiki_markup = "{"
assert "{|\n{" == node
node2 = Tag(wraptext("table"), wraptext("\n"), wiki_style_separator="|")
assert "|" == node2.wiki_style_separator

def test_closing_wiki_markup(self):
"""test getter/setter for closing_wiki_markup attribute"""
node = Tag(wraptext("table"), wraptext("\n"))
assert None is node.closing_wiki_markup
node.wiki_markup = "{|"
assert "{|" == node.closing_wiki_markup
node.closing_wiki_markup = "|}"
assert "|}" == node.closing_wiki_markup
assert "{|\n|}" == node
node.wiki_markup = "!!"
assert "|}" == node.closing_wiki_markup
assert "!!\n|}" == node
node.wiki_markup = False
assert node.closing_wiki_markup is None
assert "<table>\n</table>" == node
node2 = Tag(wraptext("table"), wraptext("\n"),
attrs=[agen("id", "foo")], wiki_markup="{|",
closing_wiki_markup="|}")
assert "|}" == node2.closing_wiki_markup
assert '{| id="foo"\n|}' == node2
def test_closing_wiki_markup():
"""test getter/setter for closing_wiki_markup attribute"""
node = Tag(wraptext("table"), wraptext("\n"))
assert None is node.closing_wiki_markup
node.wiki_markup = "{|"
assert "{|" == node.closing_wiki_markup
node.closing_wiki_markup = "|}"
assert "|}" == node.closing_wiki_markup
assert "{|\n|}" == node
node.wiki_markup = "!!"
assert "|}" == node.closing_wiki_markup
assert "!!\n|}" == node
node.wiki_markup = False
assert node.closing_wiki_markup is None
assert "<table>\n</table>" == node
node2 = Tag(wraptext("table"), wraptext("\n"),
attrs=[agen("id", "foo")], wiki_markup="{|",
closing_wiki_markup="|}")
assert "|}" == node2.closing_wiki_markup
assert '{| id="foo"\n|}' == node2

def test_has(self):
"""test Tag.has()"""
node = Tag(wraptext("ref"), wraptext("cite"), [agen("name", "foo")])
assert node.has("name") is True
assert node.has(" name ") is True
assert node.has(wraptext("name")) is True
assert node.has("Name") is False
assert node.has("foo") is False
def test_has():
"""test Tag.has()"""
node = Tag(wraptext("ref"), wraptext("cite"), [agen("name", "foo")])
assert node.has("name") is True
assert node.has(" name ") is True
assert node.has(wraptext("name")) is True
assert node.has("Name") is False
assert node.has("foo") is False

attrs = [agen("id", "foo"), agenp("class", "bar", " ", "\n", "\n"),
agen("foo", "bar"), agenpnv("foo", " ", " \n ", " \t")]
node2 = Tag(wraptext("div"), attrs=attrs, self_closing=True)
assert node2.has("id") is True
assert node2.has("class") is True
assert node2.has(attrs[1].pad_first + str(attrs[1].name) +
attrs[1].pad_before_eq) is True
assert node2.has(attrs[3]) is True
assert node2.has(str(attrs[3])) is True
assert node2.has("idclass") is False
assert node2.has("id class") is False
assert node2.has("id=foo") is False
attrs = [agen("id", "foo"), agenp("class", "bar", " ", "\n", "\n"),
agen("foo", "bar"), agenpnv("foo", " ", " \n ", " \t")]
node2 = Tag(wraptext("div"), attrs=attrs, self_closing=True)
assert node2.has("id") is True
assert node2.has("class") is True
assert node2.has(attrs[1].pad_first + str(attrs[1].name) +
attrs[1].pad_before_eq) is True
assert node2.has(attrs[3]) is True
assert node2.has(str(attrs[3])) is True
assert node2.has("idclass") is False
assert node2.has("id class") is False
assert node2.has("id=foo") is False

def test_get(self):
"""test Tag.get()"""
attrs = [agen("name", "foo")]
node = Tag(wraptext("ref"), wraptext("cite"), attrs)
assert attrs[0] is node.get("name")
assert attrs[0] is node.get(" name ")
assert attrs[0] is node.get(wraptext("name"))
with pytest.raises(ValueError):
node.get("Name")
with pytest.raises(ValueError):
node.get("foo")
def test_get():
"""test Tag.get()"""
attrs = [agen("name", "foo")]
node = Tag(wraptext("ref"), wraptext("cite"), attrs)
assert attrs[0] is node.get("name")
assert attrs[0] is node.get(" name ")
assert attrs[0] is node.get(wraptext("name"))
with pytest.raises(ValueError):
node.get("Name")
with pytest.raises(ValueError):
node.get("foo")

attrs = [agen("id", "foo"), agenp("class", "bar", " ", "\n", "\n"),
agen("foo", "bar"), agenpnv("foo", " ", " \n ", " \t")]
node2 = Tag(wraptext("div"), attrs=attrs, self_closing=True)
assert attrs[0] is node2.get("id")
assert attrs[1] is node2.get("class")
assert attrs[1] is node2.get(
attrs[1].pad_first + str(attrs[1].name) + attrs[1].pad_before_eq)
assert attrs[3] is node2.get(attrs[3])
assert attrs[3] is node2.get(str(attrs[3]))
assert attrs[3] is node2.get(" foo")
with pytest.raises(ValueError):
node2.get("idclass")
with pytest.raises(ValueError):
node2.get("id class")
with pytest.raises(ValueError):
node2.get("id=foo")
attrs = [agen("id", "foo"), agenp("class", "bar", " ", "\n", "\n"),
agen("foo", "bar"), agenpnv("foo", " ", " \n ", " \t")]
node2 = Tag(wraptext("div"), attrs=attrs, self_closing=True)
assert attrs[0] is node2.get("id")
assert attrs[1] is node2.get("class")
assert attrs[1] is node2.get(
attrs[1].pad_first + str(attrs[1].name) + attrs[1].pad_before_eq)
assert attrs[3] is node2.get(attrs[3])
assert attrs[3] is node2.get(str(attrs[3]))
assert attrs[3] is node2.get(" foo")
with pytest.raises(ValueError):
node2.get("idclass")
with pytest.raises(ValueError):
node2.get("id class")
with pytest.raises(ValueError):
node2.get("id=foo")

def test_add(self):
"""test Tag.add()"""
node = Tag(wraptext("ref"), wraptext("cite"))
node.add("name", "value")
node.add("name", "value", quotes=None)
node.add("name", "value", quotes="'")
node.add("name")
node.add(1, False)
node.add("style", "{{foobar}}")
node.add("name", "value", '"', "\n", " ", " ")
attr1 = ' name="value"'
attr2 = " name=value"
attr3 = " name='value'"
attr4 = " name"
attr5 = ' 1="False"'
attr6 = ' style="{{foobar}}"'
attr7 = '\nname = "value"'
assert attr1 == node.attributes[0]
assert attr2 == node.attributes[1]
assert attr3 == node.attributes[2]
assert attr4 == node.attributes[3]
assert attr5 == node.attributes[4]
assert attr6 == node.attributes[5]
assert attr7 == node.attributes[6]
assert attr7 == node.get("name")
self.assertWikicodeEqual(wrap([Template(wraptext("foobar"))]),
node.attributes[5].value)
assert "".join(("<ref", attr1, attr2, attr3, attr4, attr5,
attr6, attr7, ">cite</ref>")) == node
with pytest.raises(ValueError):
node.add("name", "foo", quotes="bar")
with pytest.raises(ValueError):
node.add("name", "a bc d", quotes=None)
def test_add():
"""test Tag.add()"""
node = Tag(wraptext("ref"), wraptext("cite"))
node.add("name", "value")
node.add("name", "value", quotes=None)
node.add("name", "value", quotes="'")
node.add("name")
node.add(1, False)
node.add("style", "{{foobar}}")
node.add("name", "value", '"', "\n", " ", " ")
attr1 = ' name="value"'
attr2 = " name=value"
attr3 = " name='value'"
attr4 = " name"
attr5 = ' 1="False"'
attr6 = ' style="{{foobar}}"'
attr7 = '\nname = "value"'
assert attr1 == node.attributes[0]
assert attr2 == node.attributes[1]
assert attr3 == node.attributes[2]
assert attr4 == node.attributes[3]
assert attr5 == node.attributes[4]
assert attr6 == node.attributes[5]
assert attr7 == node.attributes[6]
assert attr7 == node.get("name")
assert_wikicode_equal(wrap([Template(wraptext("foobar"))]),
node.attributes[5].value)
assert "".join(("<ref", attr1, attr2, attr3, attr4, attr5,
attr6, attr7, ">cite</ref>")) == node
with pytest.raises(ValueError):
node.add("name", "foo", quotes="bar")
with pytest.raises(ValueError):
node.add("name", "a bc d", quotes=None)

def test_remove(self):
"""test Tag.remove()"""
attrs = [agen("id", "foo"), agenp("class", "bar", " ", "\n", "\n"),
agen("foo", "bar"), agenpnv("foo", " ", " \n ", " \t")]
node = Tag(wraptext("div"), attrs=attrs, self_closing=True)
node.remove("class")
assert '<div id="foo" foo="bar" foo \n />' == node
def test_remove():
"""test Tag.remove()"""
attrs = [agen("id", "foo"), agenp("class", "bar", " ", "\n", "\n"),
agen("foo", "bar"), agenpnv("foo", " ", " \n ", " \t")]
node = Tag(wraptext("div"), attrs=attrs, self_closing=True)
node.remove("class")
assert '<div id="foo" foo="bar" foo \n />' == node
node.remove("foo")
assert '<div id="foo"/>' == node
with pytest.raises(ValueError):
node.remove("foo")
assert '<div id="foo"/>' == node
with pytest.raises(ValueError):
node.remove("foo")
node.remove("id")
assert '<div/>' == node
node.remove("id")
assert '<div/>' == node

+ 414
- 413
tests/test_template.py View File

@@ -18,435 +18,436 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""
Test cases for the Template node.
"""

from difflib import unified_diff

import pytest

from mwparserfromhell.nodes import HTMLEntity, Template, Text
from mwparserfromhell.nodes.extras import Parameter
from mwparserfromhell import parse

from ._test_tree_equality import TreeEqualityTestCase, wrap, wraptext
from .conftest import assert_wikicode_equal, wrap, wraptext

pgens = lambda k, v: Parameter(wraptext(k), wraptext(v), showkey=True)
pgenh = lambda k, v: Parameter(wraptext(k), wraptext(v), showkey=False)

class TestTemplate(TreeEqualityTestCase):
"""Test cases for the Template node."""
def test_str():
"""test Template.__str__()"""
node = Template(wraptext("foobar"))
assert "{{foobar}}" == str(node)
node2 = Template(wraptext("foo"),
[pgenh("1", "bar"), pgens("abc", "def")])
assert "{{foo|bar|abc=def}}" == str(node2)

def test_str(self):
"""test Template.__str__()"""
node = Template(wraptext("foobar"))
assert "{{foobar}}" == str(node)
node2 = Template(wraptext("foo"),
[pgenh("1", "bar"), pgens("abc", "def")])
assert "{{foo|bar|abc=def}}" == str(node2)
def test_children():
"""test Template.__children__()"""
node2p1 = Parameter(wraptext("1"), wraptext("bar"), showkey=False)
node2p2 = Parameter(wraptext("abc"), wrap([Text("def"), Text("ghi")]),
showkey=True)
node1 = Template(wraptext("foobar"))
node2 = Template(wraptext("foo"), [node2p1, node2p2])

def test_children(self):
"""test Template.__children__()"""
node2p1 = Parameter(wraptext("1"), wraptext("bar"), showkey=False)
node2p2 = Parameter(wraptext("abc"), wrap([Text("def"), Text("ghi")]),
showkey=True)
node1 = Template(wraptext("foobar"))
node2 = Template(wraptext("foo"), [node2p1, node2p2])
gen1 = node1.__children__()
gen2 = node2.__children__()
assert node1.name == next(gen1)
assert node2.name == next(gen2)
assert node2.params[0].value == next(gen2)
assert node2.params[1].name == next(gen2)
assert node2.params[1].value == next(gen2)
with pytest.raises(StopIteration):
next(gen1)
with pytest.raises(StopIteration):
next(gen2)

gen1 = node1.__children__()
gen2 = node2.__children__()
assert node1.name == next(gen1)
assert node2.name == next(gen2)
assert node2.params[0].value == next(gen2)
assert node2.params[1].name == next(gen2)
assert node2.params[1].value == next(gen2)
with pytest.raises(StopIteration):
next(gen1)
with pytest.raises(StopIteration):
next(gen2)
def test_strip():
"""test Template.__strip__()"""
node1 = Template(wraptext("foobar"))
node2 = Template(wraptext("foo"), [
pgenh("1", "bar"), pgens("foo", ""), pgens("abc", "def")])
node3 = Template(wraptext("foo"), [
pgenh("1", "foo"),
Parameter(wraptext("2"), wrap([Template(wraptext("hello"))]),
showkey=False),
pgenh("3", "bar")])

def test_strip(self):
"""test Template.__strip__()"""
node1 = Template(wraptext("foobar"))
node2 = Template(wraptext("foo"), [
pgenh("1", "bar"), pgens("foo", ""), pgens("abc", "def")])
node3 = Template(wraptext("foo"), [
pgenh("1", "foo"),
Parameter(wraptext("2"), wrap([Template(wraptext("hello"))]),
showkey=False),
pgenh("3", "bar")])
assert node1.__strip__(keep_template_params=False) is None
assert node2.__strip__(keep_template_params=False) is None
assert "" == node1.__strip__(keep_template_params=True)
assert "bar def" == node2.__strip__(keep_template_params=True)
assert "foo bar" == node3.__strip__(keep_template_params=True)

assert node1.__strip__(keep_template_params=False) is None
assert node2.__strip__(keep_template_params=False) is None
assert "" == node1.__strip__(keep_template_params=True)
assert "bar def" == node2.__strip__(keep_template_params=True)
assert "foo bar" == node3.__strip__(keep_template_params=True)
def test_showtree():
"""test Template.__showtree__()"""
output = []
getter, marker = object(), object()
get = lambda code: output.append((getter, code))
mark = lambda: output.append(marker)
node1 = Template(wraptext("foobar"))
node2 = Template(wraptext("foo"),
[pgenh("1", "bar"), pgens("abc", "def")])
node1.__showtree__(output.append, get, mark)
node2.__showtree__(output.append, get, mark)
valid = [
"{{", (getter, node1.name), "}}", "{{", (getter, node2.name),
" | ", marker, (getter, node2.params[0].name), " = ", marker,
(getter, node2.params[0].value), " | ", marker,
(getter, node2.params[1].name), " = ", marker,
(getter, node2.params[1].value), "}}"]
assert valid == output

def test_showtree(self):
"""test Template.__showtree__()"""
output = []
getter, marker = object(), object()
get = lambda code: output.append((getter, code))
mark = lambda: output.append(marker)
node1 = Template(wraptext("foobar"))
node2 = Template(wraptext("foo"),
[pgenh("1", "bar"), pgens("abc", "def")])
node1.__showtree__(output.append, get, mark)
node2.__showtree__(output.append, get, mark)
valid = [
"{{", (getter, node1.name), "}}", "{{", (getter, node2.name),
" | ", marker, (getter, node2.params[0].name), " = ", marker,
(getter, node2.params[0].value), " | ", marker,
(getter, node2.params[1].name), " = ", marker,
(getter, node2.params[1].value), "}}"]
assert valid == output
def test_name():
"""test getter/setter for the name attribute"""
name = wraptext("foobar")
node1 = Template(name)
node2 = Template(name, [pgenh("1", "bar")])
assert name is node1.name
assert name is node2.name
node1.name = "asdf"
node2.name = "téstïng"
assert_wikicode_equal(wraptext("asdf"), node1.name)
assert_wikicode_equal(wraptext("téstïng"), node2.name)

def test_name(self):
"""test getter/setter for the name attribute"""
name = wraptext("foobar")
node1 = Template(name)
node2 = Template(name, [pgenh("1", "bar")])
assert name is node1.name
assert name is node2.name
node1.name = "asdf"
node2.name = "téstïng"
self.assertWikicodeEqual(wraptext("asdf"), node1.name)
self.assertWikicodeEqual(wraptext("téstïng"), node2.name)
def test_params():
"""test getter for the params attribute"""
node1 = Template(wraptext("foobar"))
plist = [pgenh("1", "bar"), pgens("abc", "def")]
node2 = Template(wraptext("foo"), plist)
assert [] == node1.params
assert plist is node2.params

def test_params(self):
"""test getter for the params attribute"""
node1 = Template(wraptext("foobar"))
plist = [pgenh("1", "bar"), pgens("abc", "def")]
node2 = Template(wraptext("foo"), plist)
assert [] == node1.params
assert plist is node2.params
def test_has():
"""test Template.has()"""
node1 = Template(wraptext("foobar"))
node2 = Template(wraptext("foo"),
[pgenh("1", "bar"), pgens("\nabc ", "def")])
node3 = Template(wraptext("foo"),
[pgenh("1", "a"), pgens("b", "c"), pgens("1", "d")])
node4 = Template(wraptext("foo"), [pgenh("1", "a"), pgens("b", " ")])
assert node1.has("foobar", False) is False
assert node2.has(1, False) is True
assert node2.has("abc", False) is True
assert node2.has("def", False) is False
assert node3.has("1", False) is True
assert node3.has(" b ", False) is True
assert node4.has("b", False) is True
assert node3.has("b", True) is True
assert node4.has("b", True) is False
assert node1.has_param("foobar", False) is False
assert node2.has_param(1, False) is True

def test_has(self):
"""test Template.has()"""
node1 = Template(wraptext("foobar"))
node2 = Template(wraptext("foo"),
[pgenh("1", "bar"), pgens("\nabc ", "def")])
node3 = Template(wraptext("foo"),
[pgenh("1", "a"), pgens("b", "c"), pgens("1", "d")])
node4 = Template(wraptext("foo"), [pgenh("1", "a"), pgens("b", " ")])
assert node1.has("foobar", False) is False
assert node2.has(1, False) is True
assert node2.has("abc", False) is True
assert node2.has("def", False) is False
assert node3.has("1", False) is True
assert node3.has(" b ", False) is True
assert node4.has("b", False) is True
assert node3.has("b", True) is True
assert node4.has("b", True) is False
assert node1.has_param("foobar", False) is False
assert node2.has_param(1, False) is True
def test_get():
"""test Template.get()"""
node1 = Template(wraptext("foobar"))
node2p1 = pgenh("1", "bar")
node2p2 = pgens("abc", "def")
node2 = Template(wraptext("foo"), [node2p1, node2p2])
node3p1 = pgens("b", "c")
node3p2 = pgens("1", "d")
node3 = Template(wraptext("foo"), [pgenh("1", "a"), node3p1, node3p2])
node4p1 = pgens(" b", " ")
node4 = Template(wraptext("foo"), [pgenh("1", "a"), node4p1])
with pytest.raises(ValueError):
node1.get("foobar")
assert node2p1 is node2.get(1)
assert node2p2 is node2.get("abc")
with pytest.raises(ValueError):
node2.get("def")
assert node3p1 is node3.get("b")
assert node3p2 is node3.get("1")
assert node4p1 is node4.get("b ")

def test_get(self):
"""test Template.get()"""
node1 = Template(wraptext("foobar"))
node2p1 = pgenh("1", "bar")
node2p2 = pgens("abc", "def")
node2 = Template(wraptext("foo"), [node2p1, node2p2])
node3p1 = pgens("b", "c")
node3p2 = pgens("1", "d")
node3 = Template(wraptext("foo"), [pgenh("1", "a"), node3p1, node3p2])
node4p1 = pgens(" b", " ")
node4 = Template(wraptext("foo"), [pgenh("1", "a"), node4p1])
with pytest.raises(ValueError):
node1.get("foobar")
assert node2p1 is node2.get(1)
assert node2p2 is node2.get("abc")
with pytest.raises(ValueError):
node2.get("def")
assert node3p1 is node3.get("b")
assert node3p2 is node3.get("1")
assert node4p1 is node4.get("b ")
def test_add():
"""test Template.add()"""
node1 = Template(wraptext("a"), [pgens("b", "c"), pgenh("1", "d")])
node2 = Template(wraptext("a"), [pgens("b", "c"), pgenh("1", "d")])
node3 = Template(wraptext("a"), [pgens("b", "c"), pgenh("1", "d")])
node4 = Template(wraptext("a"), [pgens("b", "c"), pgenh("1", "d")])
node5 = Template(wraptext("a"), [pgens("b", "c"),
pgens(" d ", "e")])
node6 = Template(wraptext("a"), [pgens("b", "c"), pgens("b", "d"),
pgens("b", "e")])
node7 = Template(wraptext("a"), [pgens("b", "c"), pgenh("1", "d")])
node8p = pgenh("1", "d")
node8 = Template(wraptext("a"), [pgens("b", "c"), node8p])
node9 = Template(wraptext("a"), [pgens("b", "c"), pgenh("1", "d")])
node10 = Template(wraptext("a"), [pgens("b", "c"), pgenh("1", "e")])
node11 = Template(wraptext("a"), [pgens("b", "c")])
node12 = Template(wraptext("a"), [pgens("b", "c")])
node13 = Template(wraptext("a"), [
pgens("\nb ", " c"), pgens("\nd ", " e"), pgens("\nf ", " g")])
node14 = Template(wraptext("a\n"), [
pgens("b ", "c\n"), pgens("d ", " e"), pgens("f ", "g\n"),
pgens("h ", " i\n")])
node15 = Template(wraptext("a"), [
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"), [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")])
node21 = Template(wraptext("a"), [pgenh("1", "b"), pgenh("2", "c"),
pgens("4", "d"), pgens("5", "e")])
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"), [pgens("1", "b")])
node29 = Template(wraptext("a"), [
pgens("\nb ", " c"), pgens("\nd ", " e"), pgens("\nf ", " g")])
node30 = Template(wraptext("a\n"), [
pgens("b ", "c\n"), pgens("d ", " e"), pgens("f ", "g\n"),
pgens("h ", " i\n")])
node31 = Template(wraptext("a"), [
pgens("b ", " c\n"), pgens("\nd ", " e"), pgens("\nf ", "g ")])
node32 = Template(wraptext("a"), [
pgens("\nb ", " c "), pgens("\nd ", " e "), pgens("\nf ", " g ")])
node33 = Template(wraptext("a"), [pgens("b", "c"), pgens("d", "e"),
pgens("b", "f"), pgens("b", "h"),
pgens("i", "j")])
node34 = Template(wraptext("a"), [pgens("1", "b"), pgens("x", "y"),
pgens("1", "c"), pgens("2", "d")])
node35 = Template(wraptext("a"), [pgens("1", "b"), pgens("x", "y"),
pgenh("1", "c"), pgenh("2", "d")])
node36 = Template(wraptext("a"), [pgens("b", "c"), pgens("d", "e"),
pgens("f", "g")])
node37 = Template(wraptext("a"), [pgenh("1", "")])
node38 = Template(wraptext("abc"))
node39 = Template(wraptext("a"), [pgenh("1", " b ")])
node40 = Template(wraptext("a"), [pgenh("1", " b"), pgenh("2", " c")])
node41 = Template(wraptext("a"), [pgens("1", " b"), pgens("2", " c")])
node42 = Template(wraptext("a"), [pgens("b", " \n")])

def test_add(self):
"""test Template.add()"""
node1 = Template(wraptext("a"), [pgens("b", "c"), pgenh("1", "d")])
node2 = Template(wraptext("a"), [pgens("b", "c"), pgenh("1", "d")])
node3 = Template(wraptext("a"), [pgens("b", "c"), pgenh("1", "d")])
node4 = Template(wraptext("a"), [pgens("b", "c"), pgenh("1", "d")])
node5 = Template(wraptext("a"), [pgens("b", "c"),
pgens(" d ", "e")])
node6 = Template(wraptext("a"), [pgens("b", "c"), pgens("b", "d"),
pgens("b", "e")])
node7 = Template(wraptext("a"), [pgens("b", "c"), pgenh("1", "d")])
node8p = pgenh("1", "d")
node8 = Template(wraptext("a"), [pgens("b", "c"), node8p])
node9 = Template(wraptext("a"), [pgens("b", "c"), pgenh("1", "d")])
node10 = Template(wraptext("a"), [pgens("b", "c"), pgenh("1", "e")])
node11 = Template(wraptext("a"), [pgens("b", "c")])
node12 = Template(wraptext("a"), [pgens("b", "c")])
node13 = Template(wraptext("a"), [
pgens("\nb ", " c"), pgens("\nd ", " e"), pgens("\nf ", " g")])
node14 = Template(wraptext("a\n"), [
pgens("b ", "c\n"), pgens("d ", " e"), pgens("f ", "g\n"),
pgens("h ", " i\n")])
node15 = Template(wraptext("a"), [
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"), [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")])
node21 = Template(wraptext("a"), [pgenh("1", "b"), pgenh("2", "c"),
pgens("4", "d"), pgens("5", "e")])
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"), [pgens("1", "b")])
node29 = Template(wraptext("a"), [
pgens("\nb ", " c"), pgens("\nd ", " e"), pgens("\nf ", " g")])
node30 = Template(wraptext("a\n"), [
pgens("b ", "c\n"), pgens("d ", " e"), pgens("f ", "g\n"),
pgens("h ", " i\n")])
node31 = Template(wraptext("a"), [
pgens("b ", " c\n"), pgens("\nd ", " e"), pgens("\nf ", "g ")])
node32 = Template(wraptext("a"), [
pgens("\nb ", " c "), pgens("\nd ", " e "), pgens("\nf ", " g ")])
node33 = Template(wraptext("a"), [pgens("b", "c"), pgens("d", "e"),
pgens("b", "f"), pgens("b", "h"),
pgens("i", "j")])
node34 = Template(wraptext("a"), [pgens("1", "b"), pgens("x", "y"),
pgens("1", "c"), pgens("2", "d")])
node35 = Template(wraptext("a"), [pgens("1", "b"), pgens("x", "y"),
pgenh("1", "c"), pgenh("2", "d")])
node36 = Template(wraptext("a"), [pgens("b", "c"), pgens("d", "e"),
pgens("f", "g")])
node37 = Template(wraptext("a"), [pgenh("1", "")])
node38 = Template(wraptext("abc"))
node39 = Template(wraptext("a"), [pgenh("1", " b ")])
node40 = Template(wraptext("a"), [pgenh("1", " b"), pgenh("2", " c")])
node41 = Template(wraptext("a"), [pgens("1", " b"), pgens("2", " c")])
node42 = Template(wraptext("a"), [pgens("b", " \n")])
node1.add("e", "f", showkey=True)
node2.add(2, "g", showkey=False)
node3.add("e", "foo|bar", showkey=True)
node4.add("e", "f", showkey=True, before="b")
node5.add("f", "g", showkey=True, before=" d ")
node6.add("f", "g", showkey=True, before="b")
with pytest.raises(ValueError):
node7.add("e", "f", showkey=True, before="q")
node8.add("e", "f", showkey=True, before=node8p)
node9.add("e", "f", showkey=True, before=pgenh("1", "d"))
with pytest.raises(ValueError):
node10.add("e", "f", showkey=True, before=pgenh("1", "d"))
node11.add("d", "foo=bar", showkey=True)
node12.add("1", "foo=bar", showkey=False)
node13.add("h", "i", showkey=True)
node14.add("j", "k", showkey=True)
node15.add("h", "i", showkey=True)
node16.add("h", "i", showkey=True, preserve_spacing=False)
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")
with pytest.raises(ValueError):
node38.add("z", "bar", showkey=False)
node39.add("1", "c")
node40.add("3", "d")
node41.add("3", "d")
node42.add("b", "hello")

node1.add("e", "f", showkey=True)
node2.add(2, "g", showkey=False)
node3.add("e", "foo|bar", showkey=True)
node4.add("e", "f", showkey=True, before="b")
node5.add("f", "g", showkey=True, before=" d ")
node6.add("f", "g", showkey=True, before="b")
with pytest.raises(ValueError):
node7.add("e", "f", showkey=True, before="q")
node8.add("e", "f", showkey=True, before=node8p)
node9.add("e", "f", showkey=True, before=pgenh("1", "d"))
with pytest.raises(ValueError):
node10.add("e", "f", showkey=True, before=pgenh("1", "d"))
node11.add("d", "foo=bar", showkey=True)
node12.add("1", "foo=bar", showkey=False)
node13.add("h", "i", showkey=True)
node14.add("j", "k", showkey=True)
node15.add("h", "i", showkey=True)
node16.add("h", "i", showkey=True, preserve_spacing=False)
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")
with pytest.raises(ValueError):
node38.add("z", "bar", showkey=False)
node39.add("1", "c")
node40.add("3", "d")
node41.add("3", "d")
node42.add("b", "hello")
assert "{{a|b=c|d|e=f}}" == node1
assert "{{a|b=c|d|g}}" == node2
assert "{{a|b=c|d|e=foo&#124;bar}}" == node3
assert isinstance(node3.params[2].value.get(1), HTMLEntity)
assert "{{a|e=f|b=c|d}}" == node4
assert "{{a|b=c|f=g| d =e}}" == node5
assert "{{a|b=c|b=d|f=g|b=e}}" == node6
assert "{{a|b=c|d}}" == node7
assert "{{a|b=c|e=f|d}}" == node8
assert "{{a|b=c|e=f|d}}" == node9
assert "{{a|b=c|e}}" == node10
assert "{{a|b=c|d=foo=bar}}" == node11
assert "{{a|b=c|foo&#61;bar}}" == node12
assert isinstance(node12.params[1].value.get(1), HTMLEntity)
assert "{{a|\nb = c|\nd = e|\nf = g|\nh = i}}" == node13
assert "{{a\n|b =c\n|d = e|f =g\n|h = i\n|j =k\n}}" == node14
assert "{{a|b = c\n|\nd = e|\nf =g |\nh = i}}" == node15
assert "{{a|\nb = c|\nd = e|\nf = g|h=i}}" == node16
assert "{{a|b|c}}" == node17
assert "{{a|b|3=c}}" == node18
assert "{{a|b|c=d}}" == node19
assert "{{a|b|c|d|e|f}}" == node20
assert "{{a|b|c|4=d|5=e|f}}" == node21
assert "{{a|b|c|4=d|5=e|6=f}}" == node22
assert "{{a|b|c=foo=bar}}" == node23
assert "{{a|b|foo&#61;bar}}" == node24
assert isinstance(node24.params[1].value.get(1), HTMLEntity)
assert "{{a|b=d}}" == node25
assert "{{a|foo&#61;bar}}" == node26
assert isinstance(node26.params[0].value.get(1), HTMLEntity)
assert "{{a|1=foo=bar}}" == node27
assert "{{a|foo&#61;bar}}" == node28
assert isinstance(node28.params[0].value.get(1), HTMLEntity)
assert "{{a|\nb = c|\nd = foo|\nf = g}}" == node29
assert "{{a\n|b =c\n|d = e|f =foo\n|h = i\n}}" == node30
assert "{{a|b = c\n|\nd = e|\nf =foo }}" == node31
assert "{{a|\nb = c |\nd =foo|\nf = g }}" == node32
assert "{{a|b=k|d=e|i=j}}" == node33
assert "{{a|1=e|x=y|2=d}}" == node34
assert "{{a|x=y|e|d}}" == node35
assert "{{a|b=c|d=h|f=g}}" == node36
assert "{{a|b}}" == node37
assert "{{abc|foo}}" == node38
assert "{{a|c}}" == node39
assert "{{a| b| c|d}}" == node40
assert "{{a|1= b|2= c|3= d}}" == node41
assert "{{a|b=hello \n}}" == node42

assert "{{a|b=c|d|e=f}}" == node1
assert "{{a|b=c|d|g}}" == node2
assert "{{a|b=c|d|e=foo&#124;bar}}" == node3
assert isinstance(node3.params[2].value.get(1), HTMLEntity)
assert "{{a|e=f|b=c|d}}" == node4
assert "{{a|b=c|f=g| d =e}}" == node5
assert "{{a|b=c|b=d|f=g|b=e}}" == node6
assert "{{a|b=c|d}}" == node7
assert "{{a|b=c|e=f|d}}" == node8
assert "{{a|b=c|e=f|d}}" == node9
assert "{{a|b=c|e}}" == node10
assert "{{a|b=c|d=foo=bar}}" == node11
assert "{{a|b=c|foo&#61;bar}}" == node12
assert isinstance(node12.params[1].value.get(1), HTMLEntity)
assert "{{a|\nb = c|\nd = e|\nf = g|\nh = i}}" == node13
assert "{{a\n|b =c\n|d = e|f =g\n|h = i\n|j =k\n}}" == node14
assert "{{a|b = c\n|\nd = e|\nf =g |\nh = i}}" == node15
assert "{{a|\nb = c|\nd = e|\nf = g|h=i}}" == node16
assert "{{a|b|c}}" == node17
assert "{{a|b|3=c}}" == node18
assert "{{a|b|c=d}}" == node19
assert "{{a|b|c|d|e|f}}" == node20
assert "{{a|b|c|4=d|5=e|f}}" == node21
assert "{{a|b|c|4=d|5=e|6=f}}" == node22
assert "{{a|b|c=foo=bar}}" == node23
assert "{{a|b|foo&#61;bar}}" == node24
assert isinstance(node24.params[1].value.get(1), HTMLEntity)
assert "{{a|b=d}}" == node25
assert "{{a|foo&#61;bar}}" == node26
assert isinstance(node26.params[0].value.get(1), HTMLEntity)
assert "{{a|1=foo=bar}}" == node27
assert "{{a|foo&#61;bar}}" == node28
assert isinstance(node28.params[0].value.get(1), HTMLEntity)
assert "{{a|\nb = c|\nd = foo|\nf = g}}" == node29
assert "{{a\n|b =c\n|d = e|f =foo\n|h = i\n}}" == node30
assert "{{a|b = c\n|\nd = e|\nf =foo }}" == node31
assert "{{a|\nb = c |\nd =foo|\nf = g }}" == node32
assert "{{a|b=k|d=e|i=j}}" == node33
assert "{{a|1=e|x=y|2=d}}" == node34
assert "{{a|x=y|e|d}}" == node35
assert "{{a|b=c|d=h|f=g}}" == node36
assert "{{a|b}}" == node37
assert "{{abc|foo}}" == node38
assert "{{a|c}}" == node39
assert "{{a| b| c|d}}" == node40
assert "{{a|1= b|2= c|3= d}}" == node41
assert "{{a|b=hello \n}}" == node42
def test_remove():
"""test Template.remove()"""
node1 = Template(wraptext("foobar"))
node2 = Template(wraptext("foo"),
[pgenh("1", "bar"), pgens("abc", "def")])
node3 = Template(wraptext("foo"),
[pgenh("1", "bar"), pgens("abc", "def")])
node4 = Template(wraptext("foo"),
[pgenh("1", "bar"), pgenh("2", "baz")])
node5 = Template(wraptext("foo"), [
pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")])
node6 = Template(wraptext("foo"), [
pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")])
node7 = Template(wraptext("foo"), [
pgens("1 ", "a"), pgens(" 1", "b"), pgens("2", "c")])
node8 = Template(wraptext("foo"), [
pgens("1 ", "a"), pgens(" 1", "b"), pgens("2", "c")])
node9 = Template(wraptext("foo"), [
pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")])
node10 = Template(wraptext("foo"), [
pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")])
node11 = Template(wraptext("foo"), [
pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")])
node12 = Template(wraptext("foo"), [
pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")])
node13 = Template(wraptext("foo"), [
pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")])
node14 = Template(wraptext("foo"), [
pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")])
node15 = Template(wraptext("foo"), [
pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")])
node16 = Template(wraptext("foo"), [
pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")])
node17 = Template(wraptext("foo"), [
pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")])
node18 = Template(wraptext("foo"), [
pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")])
node19 = Template(wraptext("foo"), [
pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")])
node20 = Template(wraptext("foo"), [
pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")])
node21 = Template(wraptext("foo"), [
pgens("a", "b"), pgens("c", "d"), pgens("e", "f"), pgens("a", "b"),
pgens("a", "b")])
node22 = Template(wraptext("foo"), [
pgens("a", "b"), pgens("c", "d"), pgens("e", "f"), pgens("a", "b"),
pgens("a", "b")])
node23 = Template(wraptext("foo"), [
pgens("a", "b"), pgens("c", "d"), pgens("e", "f"), pgens("a", "b"),
pgens("a", "b")])
node24 = Template(wraptext("foo"), [
pgens("a", "b"), pgens("c", "d"), pgens("e", "f"), pgens("a", "b"),
pgens("a", "b")])
node25 = Template(wraptext("foo"), [
pgens("a", "b"), pgens("c", "d"), pgens("e", "f"), pgens("a", "b"),
pgens("a", "b")])
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")])

def test_remove(self):
"""test Template.remove()"""
node1 = Template(wraptext("foobar"))
node2 = Template(wraptext("foo"),
[pgenh("1", "bar"), pgens("abc", "def")])
node3 = Template(wraptext("foo"),
[pgenh("1", "bar"), pgens("abc", "def")])
node4 = Template(wraptext("foo"),
[pgenh("1", "bar"), pgenh("2", "baz")])
node5 = Template(wraptext("foo"), [
pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")])
node6 = Template(wraptext("foo"), [
pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")])
node7 = Template(wraptext("foo"), [
pgens("1 ", "a"), pgens(" 1", "b"), pgens("2", "c")])
node8 = Template(wraptext("foo"), [
pgens("1 ", "a"), pgens(" 1", "b"), pgens("2", "c")])
node9 = Template(wraptext("foo"), [
pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")])
node10 = Template(wraptext("foo"), [
pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")])
node11 = Template(wraptext("foo"), [
pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")])
node12 = Template(wraptext("foo"), [
pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")])
node13 = Template(wraptext("foo"), [
pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")])
node14 = Template(wraptext("foo"), [
pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")])
node15 = Template(wraptext("foo"), [
pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")])
node16 = Template(wraptext("foo"), [
pgens(" a", "b"), pgens("b", "c"), pgens("a ", "d")])
node17 = Template(wraptext("foo"), [
pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")])
node18 = Template(wraptext("foo"), [
pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")])
node19 = Template(wraptext("foo"), [
pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")])
node20 = Template(wraptext("foo"), [
pgens("1 ", "a"), pgenh("1", "b"), pgenh("2", "c")])
node21 = Template(wraptext("foo"), [
pgens("a", "b"), pgens("c", "d"), pgens("e", "f"), pgens("a", "b"),
pgens("a", "b")])
node22 = Template(wraptext("foo"), [
pgens("a", "b"), pgens("c", "d"), pgens("e", "f"), pgens("a", "b"),
pgens("a", "b")])
node23 = Template(wraptext("foo"), [
pgens("a", "b"), pgens("c", "d"), pgens("e", "f"), pgens("a", "b"),
pgens("a", "b")])
node24 = Template(wraptext("foo"), [
pgens("a", "b"), pgens("c", "d"), pgens("e", "f"), pgens("a", "b"),
pgens("a", "b")])
node25 = Template(wraptext("foo"), [
pgens("a", "b"), pgens("c", "d"), pgens("e", "f"), pgens("a", "b"),
pgens("a", "b")])
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")
node3.remove(1, keep_field=True)
node3.remove("abc", keep_field=True)
node4.remove("1", keep_field=False)
node5.remove("a", keep_field=False)
node6.remove("a", keep_field=True)
node7.remove(1, keep_field=True)
node8.remove(1, keep_field=False)
node9.remove(1, keep_field=True)
node10.remove(1, keep_field=False)
node11.remove(node11.params[0], keep_field=False)
node12.remove(node12.params[0], keep_field=True)
node13.remove(node13.params[1], keep_field=False)
node14.remove(node14.params[1], keep_field=True)
node15.remove(node15.params[2], keep_field=False)
node16.remove(node16.params[2], keep_field=True)
node17.remove(node17.params[0], keep_field=False)
node18.remove(node18.params[0], keep_field=True)
node19.remove(node19.params[1], keep_field=False)
node20.remove(node20.params[1], keep_field=True)
node21.remove("a", keep_field=False)
node22.remove("a", keep_field=True)
node23.remove(node23.params[0], keep_field=False)
node24.remove(node24.params[0], keep_field=True)
node25.remove(node25.params[3], keep_field=False)
node26.remove(node26.params[3], keep_field=True)

with pytest.raises(ValueError):
node1.remove(1)
with pytest.raises(ValueError):
node1.remove("a")
with pytest.raises(ValueError):
node2.remove("1")
node2.remove("abc")
node3.remove(1, keep_field=True)
node3.remove("abc", keep_field=True)
node4.remove("1", keep_field=False)
node5.remove("a", keep_field=False)
node6.remove("a", keep_field=True)
node7.remove(1, keep_field=True)
node8.remove(1, keep_field=False)
node9.remove(1, keep_field=True)
node10.remove(1, keep_field=False)
node11.remove(node11.params[0], keep_field=False)
node12.remove(node12.params[0], keep_field=True)
node13.remove(node13.params[1], keep_field=False)
node14.remove(node14.params[1], keep_field=True)
node15.remove(node15.params[2], keep_field=False)
node16.remove(node16.params[2], keep_field=True)
node17.remove(node17.params[0], keep_field=False)
node18.remove(node18.params[0], keep_field=True)
node19.remove(node19.params[1], keep_field=False)
node20.remove(node20.params[1], keep_field=True)
node21.remove("a", keep_field=False)
node22.remove("a", keep_field=True)
node23.remove(node23.params[0], keep_field=False)
node24.remove(node24.params[0], keep_field=True)
node25.remove(node25.params[3], keep_field=False)
node26.remove(node26.params[3], keep_field=True)

with pytest.raises(ValueError):
node1.remove(1)
with pytest.raises(ValueError):
node1.remove("a")
with pytest.raises(ValueError):
node2.remove("1")
assert "{{foo}}" == node2
assert "{{foo||abc=}}" == node3
assert "{{foo|2=baz}}" == node4
assert "{{foo|b=c}}" == node5
assert "{{foo| a=|b=c}}" == node6
assert "{{foo|1 =|2=c}}" == node7
assert "{{foo|2=c}}" == node8
assert "{{foo||c}}" == node9
assert "{{foo|2=c}}" == node10
assert "{{foo|b=c|a =d}}" == node11
assert "{{foo| a=|b=c|a =d}}" == node12
assert "{{foo| a=b|a =d}}" == node13
assert "{{foo| a=b|b=|a =d}}" == node14
assert "{{foo| a=b|b=c}}" == node15
assert "{{foo| a=b|b=c|a =}}" == node16
assert "{{foo|b|c}}" == node17
assert "{{foo|1 =|b|c}}" == node18
assert "{{foo|1 =a|2=c}}" == node19
assert "{{foo|1 =a||c}}" == node20
assert "{{foo|c=d|e=f}}" == node21
assert "{{foo|a=|c=d|e=f}}" == node22
assert "{{foo|c=d|e=f|a=b|a=b}}" == node23
assert "{{foo|a=|c=d|e=f|a=b|a=b}}" == node24
assert "{{foo|a=b|c=d|e=f|a=b}}" == node25
assert "{{foo|a=b|c=d|e=f|a=|a=b}}" == node26
with pytest.raises(ValueError):
node27.remove(node28.get(1))
assert "{{foo}}" == node2
assert "{{foo||abc=}}" == node3
assert "{{foo|2=baz}}" == node4
assert "{{foo|b=c}}" == node5
assert "{{foo| a=|b=c}}" == node6
assert "{{foo|1 =|2=c}}" == node7
assert "{{foo|2=c}}" == node8
assert "{{foo||c}}" == node9
assert "{{foo|2=c}}" == node10
assert "{{foo|b=c|a =d}}" == node11
assert "{{foo| a=|b=c|a =d}}" == node12
assert "{{foo| a=b|a =d}}" == node13
assert "{{foo| a=b|b=|a =d}}" == node14
assert "{{foo| a=b|b=c}}" == node15
assert "{{foo| a=b|b=c|a =}}" == node16
assert "{{foo|b|c}}" == node17
assert "{{foo|1 =|b|c}}" == node18
assert "{{foo|1 =a|2=c}}" == node19
assert "{{foo|1 =a||c}}" == node20
assert "{{foo|c=d|e=f}}" == node21
assert "{{foo|a=|c=d|e=f}}" == node22
assert "{{foo|c=d|e=f|a=b|a=b}}" == node23
assert "{{foo|a=|c=d|e=f|a=b|a=b}}" == node24
assert "{{foo|a=b|c=d|e=f|a=b}}" == node25
assert "{{foo|a=b|c=d|e=f|a=|a=b}}" == node26
with pytest.raises(ValueError):
node27.remove(node28.get(1))

def test_formatting(self):
"""test realistic param manipulation with complex whitespace formatting
(assumes that parsing works correctly)"""
tests = [
def test_formatting():
"""test realistic param manipulation with complex whitespace formatting
(assumes that parsing works correctly)"""
tests = [
# https://en.wikipedia.org/w/index.php?title=Lamar_County,_Georgia&oldid=792356004
("""{{Infobox U.S. county
| county = Lamar County
@@ -597,15 +598,15 @@ class TestTemplate(TreeEqualityTestCase):
+ pop = 12345<ref>example ref</ref> |
density_sq_mi = 575""")]

for (original, expected) in tests:
code = parse(original)
template = code.filter_templates()[0]
template.add("pop", "12345<ref>example ref</ref>")
template.add('census estimate yr', "2016", before="pop")
template.remove("census yr")
for (original, expected) in tests:
code = parse(original)
template = code.filter_templates()[0]
template.add("pop", "12345<ref>example ref</ref>")
template.add('census estimate yr', "2016", before="pop")
template.remove("census yr")

oldlines = original.splitlines(True)
newlines = str(code).splitlines(True)
difflines = unified_diff(oldlines, newlines, n=1)
diff = "".join(list(difflines)[2:]).strip()
assert expected == diff
oldlines = original.splitlines(True)
newlines = str(code).splitlines(True)
difflines = unified_diff(oldlines, newlines, n=1)
diff = "".join(list(difflines)[2:]).strip()
assert expected == diff

+ 39
- 38
tests/test_text.py View File

@@ -18,49 +18,50 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""
Test cases for the Text node.
"""

import pytest

from mwparserfromhell.nodes import Text

class TestText:
"""Test cases for the Text node."""

def test_str(self):
"""test Text.__str__()"""
node = Text("foobar")
assert "foobar" == str(node)
node2 = Text("fóóbar")
assert "fóóbar" == str(node2)
def test_str():
"""test Text.__str__()"""
node = Text("foobar")
assert "foobar" == str(node)
node2 = Text("fóóbar")
assert "fóóbar" == str(node2)

def test_children(self):
"""test Text.__children__()"""
node = Text("foobar")
gen = node.__children__()
with pytest.raises(StopIteration):
next(gen)
def test_children():
"""test Text.__children__()"""
node = Text("foobar")
gen = node.__children__()
with pytest.raises(StopIteration):
next(gen)

def test_strip(self):
"""test Text.__strip__()"""
node = Text("foobar")
assert node is node.__strip__()
def test_strip():
"""test Text.__strip__()"""
node = Text("foobar")
assert node is node.__strip__()

def test_showtree(self):
"""test Text.__showtree__()"""
output = []
node1 = Text("foobar")
node2 = Text("fóóbar")
node3 = Text("𐌲𐌿𐍄")
node1.__showtree__(output.append, None, None)
node2.__showtree__(output.append, None, None)
node3.__showtree__(output.append, None, None)
res = ["foobar", r"f\xf3\xf3bar", "\\U00010332\\U0001033f\\U00010344"]
assert res == output
def test_showtree():
"""test Text.__showtree__()"""
output = []
node1 = Text("foobar")
node2 = Text("fóóbar")
node3 = Text("𐌲𐌿𐍄")
node1.__showtree__(output.append, None, None)
node2.__showtree__(output.append, None, None)
node3.__showtree__(output.append, None, None)
res = ["foobar", r"f\xf3\xf3bar", "\\U00010332\\U0001033f\\U00010344"]
assert res == output

def test_value(self):
"""test getter/setter for the value attribute"""
node = Text("foobar")
assert "foobar" == node.value
assert isinstance(node.value, str)
node.value = "héhéhé"
assert "héhéhé" == node.value
assert isinstance(node.value, str)
def test_value():
"""test getter/setter for the value attribute"""
node = Text("foobar")
assert "foobar" == node.value
assert isinstance(node.value, str)
node.value = "héhéhé"
assert "héhéhé" == node.value
assert isinstance(node.value, str)

+ 3
- 11
tests/test_tokenizer.py View File

@@ -20,9 +20,10 @@

import codecs
from os import listdir, path
import pytest
import warnings

import pytest

from mwparserfromhell.parser import contexts, tokens
from mwparserfromhell.parser.builder import Builder
from mwparserfromhell.parser.tokenizer import Tokenizer as PyTokenizer
@@ -32,11 +33,8 @@ try:
except ImportError:
CTokenizer = None


class _TestParseError(Exception):
"""Raised internally when a test could not be parsed."""
pass


def _parse_test(test, data):
"""Parse an individual *test*, storing its info in *data*."""
@@ -56,8 +54,7 @@ def _parse_test(test, data):
try:
data["output"] = eval(raw, vars(tokens))
except Exception as err:
raise _TestParseError(err)

raise _TestParseError(err) from err

def _load_tests(filename, name, text):
"""Load all tests in *text* from the file *filename*."""
@@ -89,7 +86,6 @@ def _load_tests(filename, name, text):

yield data


def build():
"""Load and install all tests from the 'tokenizer' directory."""
directory = path.join(path.dirname(__file__), "tokenizer")
@@ -103,7 +99,6 @@ def build():
name = path.split(fullname)[1][:-len(extension)]
yield from _load_tests(fullname, name, text)


@pytest.mark.parametrize("tokenizer", filter(None, (
CTokenizer, PyTokenizer
)), ids=lambda t: 'CTokenizer' if t.USES_C else 'PyTokenizer')
@@ -113,21 +108,18 @@ def test_tokenizer(tokenizer, data):
actual = tokenizer().tokenize(data["input"])
assert expected == actual


@pytest.mark.parametrize("data", build(), ids=lambda data: data['name'])
def test_roundtrip(data):
expected = data["input"]
actual = str(Builder().build(data["output"][:]))
assert expected == actual


@pytest.mark.skipif(CTokenizer is None, reason='CTokenizer not available')
def test_c_tokenizer_uses_c():
"""make sure the C tokenizer identifies as using a C extension"""
assert CTokenizer.USES_C is True
assert CTokenizer().USES_C is True


def test_describe_context():
assert "" == contexts.describe(0)
ctx = contexts.describe(contexts.TEMPLATE_PARAM_KEY|contexts.HAS_TEXT)


+ 60
- 59
tests/test_tokens.py View File

@@ -18,75 +18,76 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""
Test cases for the Token class and its subclasses.
"""

import pytest

from mwparserfromhell.parser import tokens

class TestTokens:
"""Test cases for the Token class and its subclasses."""

@pytest.mark.parametrize("name", tokens.__all__)
def test_issubclass(self, name):
"""check that all classes within the tokens module are really Tokens"""
klass = getattr(tokens, name)
assert issubclass(klass, tokens.Token) is True
assert isinstance(klass(), klass)
assert isinstance(klass(), tokens.Token)
@pytest.mark.parametrize("name", tokens.__all__)
def test_issubclass(name):
"""check that all classes within the tokens module are really Tokens"""
klass = getattr(tokens, name)
assert issubclass(klass, tokens.Token) is True
assert isinstance(klass(), klass)
assert isinstance(klass(), tokens.Token)

def test_attributes(self):
"""check that Token attributes can be managed properly"""
token1 = tokens.Token()
token2 = tokens.Token(foo="bar", baz=123)
def test_attributes():
"""check that Token attributes can be managed properly"""
token1 = tokens.Token()
token2 = tokens.Token(foo="bar", baz=123)

assert "bar" == token2.foo
assert 123 == token2.baz
assert token1.foo is None
assert token2.bar is None
assert "bar" == token2.foo
assert 123 == token2.baz
assert token1.foo is None
assert token2.bar is None

token1.spam = "eggs"
token2.foo = "ham"
del token2.baz
token1.spam = "eggs"
token2.foo = "ham"
del token2.baz

assert "eggs" == token1.spam
assert "ham" == token2.foo
assert token2.baz is None
with pytest.raises(KeyError):
token2.__delattr__("baz")
assert "eggs" == token1.spam
assert "ham" == token2.foo
assert token2.baz is None
with pytest.raises(KeyError):
token2.__delattr__("baz")

def test_repr(self):
"""check that repr() on a Token works as expected"""
token1 = tokens.Token()
token2 = tokens.Token(foo="bar", baz=123)
token3 = tokens.Text(text="earwig" * 100)
hundredchars = ("earwig" * 100)[:97] + "..."
def test_repr():
"""check that repr() on a Token works as expected"""
token1 = tokens.Token()
token2 = tokens.Token(foo="bar", baz=123)
token3 = tokens.Text(text="earwig" * 100)
hundredchars = ("earwig" * 100)[:97] + "..."

assert "Token()" == repr(token1)
assert repr(token2) in ("Token(foo='bar', baz=123)", "Token(baz=123, foo='bar')")
assert "Text(text='" + hundredchars + "')" == repr(token3)
assert "Token()" == repr(token1)
assert repr(token2) in ("Token(foo='bar', baz=123)", "Token(baz=123, foo='bar')")
assert "Text(text='" + hundredchars + "')" == repr(token3)

def test_equality(self):
"""check that equivalent tokens are considered equal"""
token1 = tokens.Token()
token2 = tokens.Token()
token3 = tokens.Token(foo="bar", baz=123)
token4 = tokens.Text(text="asdf")
token5 = tokens.Text(text="asdf")
token6 = tokens.TemplateOpen(text="asdf")
def test_equality():
"""check that equivalent tokens are considered equal"""
token1 = tokens.Token()
token2 = tokens.Token()
token3 = tokens.Token(foo="bar", baz=123)
token4 = tokens.Text(text="asdf")
token5 = tokens.Text(text="asdf")
token6 = tokens.TemplateOpen(text="asdf")

assert token1 == token2
assert token2 == token1
assert token4 == token5
assert token5 == token4
assert token1 != token3
assert token2 != token3
assert token4 != token6
assert token5 != token6
assert token1 == token2
assert token2 == token1
assert token4 == token5
assert token5 == token4
assert token1 != token3
assert token2 != token3
assert token4 != token6
assert token5 != token6

@pytest.mark.parametrize("token", [
tokens.Token(),
tokens.Token(foo="bar", baz=123),
tokens.Text(text="earwig")
])
def test_repr_equality(self, token):
"""check that eval(repr(token)) == token"""
assert token == eval(repr(token), vars(tokens))
@pytest.mark.parametrize("token", [
tokens.Token(),
tokens.Token(foo="bar", baz=123),
tokens.Text(text="earwig")
])
def test_repr_equality(token):
"""check that eval(repr(token)) == token"""
assert token == eval(repr(token), vars(tokens))

+ 30
- 30
tests/test_utils.py View File

@@ -18,39 +18,39 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""
Tests for the utils module, which provides parse_anything().
"""

import pytest

from mwparserfromhell.nodes import Template, Text
from mwparserfromhell.utils import parse_anything
from .conftest import assert_wikicode_equal, wrap, wraptext

from ._test_tree_equality import TreeEqualityTestCase, wrap, wraptext

class TestUtils(TreeEqualityTestCase):
"""Tests for the utils module, which provides parse_anything()."""

@pytest.mark.parametrize("test,valid", [
(wraptext("foobar"), wraptext("foobar")),
(Template(wraptext("spam")), wrap([Template(wraptext("spam"))])),
("fóóbar", wraptext("fóóbar")),
(b"foob\xc3\xa1r", wraptext("foobár")),
(123, wraptext("123")),
(True, wraptext("True")),
(None, wrap([])),
([Text("foo"), Text("bar"), Text("baz")],
wraptext("foo", "bar", "baz")),
([wraptext("foo"), Text("bar"), "baz", 123, 456],
wraptext("foo", "bar", "baz", "123", "456")),
([[[([[((("foo",),),)], "bar"],)]]], wraptext("foo", "bar"))
])
def test_parse_anything_valid(self, test, valid):
"""tests for valid input to utils.parse_anything()"""
self.assertWikicodeEqual(valid, parse_anything(test))
@pytest.mark.parametrize("test,valid", [
(wraptext("foobar"), wraptext("foobar")),
(Template(wraptext("spam")), wrap([Template(wraptext("spam"))])),
("fóóbar", wraptext("fóóbar")),
(b"foob\xc3\xa1r", wraptext("foobár")),
(123, wraptext("123")),
(True, wraptext("True")),
(None, wrap([])),
([Text("foo"), Text("bar"), Text("baz")],
wraptext("foo", "bar", "baz")),
([wraptext("foo"), Text("bar"), "baz", 123, 456],
wraptext("foo", "bar", "baz", "123", "456")),
([[[([[((("foo",),),)], "bar"],)]]], wraptext("foo", "bar"))
])
def test_parse_anything_valid(test, valid):
"""tests for valid input to utils.parse_anything()"""
assert_wikicode_equal(valid, parse_anything(test))

@pytest.mark.parametrize("invalid", [
Ellipsis, object, object(), type,
["foo", [object]]
])
def test_parse_anything_invalid(self, invalid):
"""tests for invalid input to utils.parse_anything()"""
with pytest.raises(ValueError):
parse_anything(invalid)
@pytest.mark.parametrize("invalid", [
Ellipsis, object, object(), type,
["foo", [object]]
])
def test_parse_anything_invalid(invalid):
"""tests for invalid input to utils.parse_anything()"""
with pytest.raises(ValueError):
parse_anything(invalid)

+ 511
- 510
tests/test_wikicode.py
File diff suppressed because it is too large
View File


+ 66
- 66
tests/test_wikilink.py View File

@@ -18,78 +18,78 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""
Test cases for the Wikilink node.
"""

import pytest

from mwparserfromhell.nodes import Text, Wikilink
from .conftest import assert_wikicode_equal, wrap, wraptext

from ._test_tree_equality import TreeEqualityTestCase, wrap, wraptext

class TestWikilink(TreeEqualityTestCase):
"""Test cases for the Wikilink node."""

def test_str(self):
"""test Wikilink.__str__()"""
node = Wikilink(wraptext("foobar"))
assert "[[foobar]]" == str(node)
node2 = Wikilink(wraptext("foo"), wraptext("bar"))
assert "[[foo|bar]]" == str(node2)
def test_str():
"""test Wikilink.__str__()"""
node = Wikilink(wraptext("foobar"))
assert "[[foobar]]" == str(node)
node2 = Wikilink(wraptext("foo"), wraptext("bar"))
assert "[[foo|bar]]" == str(node2)

def test_children(self):
"""test Wikilink.__children__()"""
node1 = Wikilink(wraptext("foobar"))
node2 = Wikilink(wraptext("foo"), wrap([Text("bar"), Text("baz")]))
gen1 = node1.__children__()
gen2 = node2.__children__()
assert node1.title == next(gen1)
assert node2.title == next(gen2)
assert node2.text == next(gen2)
with pytest.raises(StopIteration):
next(gen1)
with pytest.raises(StopIteration):
next(gen2)
def test_children():
"""test Wikilink.__children__()"""
node1 = Wikilink(wraptext("foobar"))
node2 = Wikilink(wraptext("foo"), wrap([Text("bar"), Text("baz")]))
gen1 = node1.__children__()
gen2 = node2.__children__()
assert node1.title == next(gen1)
assert node2.title == next(gen2)
assert node2.text == next(gen2)
with pytest.raises(StopIteration):
next(gen1)
with pytest.raises(StopIteration):
next(gen2)

def test_strip(self):
"""test Wikilink.__strip__()"""
node = Wikilink(wraptext("foobar"))
node2 = Wikilink(wraptext("foo"), wraptext("bar"))
assert "foobar" == node.__strip__()
assert "bar" == node2.__strip__()
def test_strip():
"""test Wikilink.__strip__()"""
node = Wikilink(wraptext("foobar"))
node2 = Wikilink(wraptext("foo"), wraptext("bar"))
assert "foobar" == node.__strip__()
assert "bar" == node2.__strip__()

def test_showtree(self):
"""test Wikilink.__showtree__()"""
output = []
getter, marker = object(), object()
get = lambda code: output.append((getter, code))
mark = lambda: output.append(marker)
node1 = Wikilink(wraptext("foobar"))
node2 = Wikilink(wraptext("foo"), wraptext("bar"))
node1.__showtree__(output.append, get, mark)
node2.__showtree__(output.append, get, mark)
valid = [
"[[", (getter, node1.title), "]]", "[[", (getter, node2.title),
" | ", marker, (getter, node2.text), "]]"]
assert valid == output
def test_showtree():
"""test Wikilink.__showtree__()"""
output = []
getter, marker = object(), object()
get = lambda code: output.append((getter, code))
mark = lambda: output.append(marker)
node1 = Wikilink(wraptext("foobar"))
node2 = Wikilink(wraptext("foo"), wraptext("bar"))
node1.__showtree__(output.append, get, mark)
node2.__showtree__(output.append, get, mark)
valid = [
"[[", (getter, node1.title), "]]", "[[", (getter, node2.title),
" | ", marker, (getter, node2.text), "]]"]
assert valid == output

def test_title(self):
"""test getter/setter for the title attribute"""
title = wraptext("foobar")
node1 = Wikilink(title)
node2 = Wikilink(title, wraptext("baz"))
assert title is node1.title
assert title is node2.title
node1.title = "héhehé"
node2.title = "héhehé"
self.assertWikicodeEqual(wraptext("héhehé"), node1.title)
self.assertWikicodeEqual(wraptext("héhehé"), node2.title)
def test_title():
"""test getter/setter for the title attribute"""
title = wraptext("foobar")
node1 = Wikilink(title)
node2 = Wikilink(title, wraptext("baz"))
assert title is node1.title
assert title is node2.title
node1.title = "héhehé"
node2.title = "héhehé"
assert_wikicode_equal(wraptext("héhehé"), node1.title)
assert_wikicode_equal(wraptext("héhehé"), node2.title)

def test_text(self):
"""test getter/setter for the text attribute"""
text = wraptext("baz")
node1 = Wikilink(wraptext("foobar"))
node2 = Wikilink(wraptext("foobar"), text)
assert None is node1.text
assert text is node2.text
node1.text = "buzz"
node2.text = None
self.assertWikicodeEqual(wraptext("buzz"), node1.text)
assert None is node2.text
def test_text():
"""test getter/setter for the text attribute"""
text = wraptext("baz")
node1 = Wikilink(wraptext("foobar"))
node2 = Wikilink(wraptext("foobar"), text)
assert None is node1.text
assert text is node2.text
node1.text = "buzz"
node2.text = None
assert_wikicode_equal(wraptext("buzz"), node1.text)
assert None is node2.text

+ 0
- 1
tests/tokenizer/integration.mwtest View File

@@ -143,7 +143,6 @@ label: a bracketed external link nested inside a template, before the end
input: "{{URL|[http://example.com}}]"
output: [Text(text="{{URL|"), ExternalLinkOpen(brackets=True), Text(text="http://example.com}}"), ExternalLinkClose()]


---

name: comment_inside_bracketed_link


Loading…
Cancel
Save