From e3f89af62dcc323b6119174a07868057e814ede9 Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Sat, 30 Mar 2013 18:38:29 -0400 Subject: [PATCH] Adding a TreeEqualityTestCase base class. --- tests/_test_tokenizer.py | 3 +- tests/_test_tree_equality.py | 78 ++++++++++++++++++++++++++++++++++++++++++++ tests/test_ctokenizer.py | 2 +- tests/test_parser.py | 33 ++----------------- tests/test_pytokenizer.py | 2 +- 5 files changed, 84 insertions(+), 34 deletions(-) create mode 100644 tests/_test_tree_equality.py diff --git a/tests/_test_tokenizer.py b/tests/_test_tokenizer.py index 379b4fa..13882aa 100644 --- a/tests/_test_tokenizer.py +++ b/tests/_test_tokenizer.py @@ -21,6 +21,7 @@ # SOFTWARE. from __future__ import print_function, unicode_literals +from unittest import TestCase from os import listdir, path from mwparserfromhell.compat import py3k @@ -31,7 +32,7 @@ class _TestParseError(Exception): pass -class TokenizerTestCase(object): +class TokenizerTestCase(TestCase): """A base test case for tokenizers, whose tests are loaded dynamically. Subclassed along with unittest.TestCase to form TestPyTokenizer and diff --git a/tests/_test_tree_equality.py b/tests/_test_tree_equality.py new file mode 100644 index 0000000..26c373d --- /dev/null +++ b/tests/_test_tree_equality.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2013 Ben Kurtovic +# +# 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 __future__ import unicode_literals +from unittest import TestCase + +from mwparserfromhell.nodes import Template, Text, Wikilink +from mwparserfromhell.nodes.extras import Parameter +from mwparserfromhell.wikicode import Wikicode + +class TreeEqualityTestCase(TestCase): + """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): + registry = { + Text: self.assertTextNodeEqual, + Template: self.assertTemplateNodeEqual, + Wikilink: self.assertWikilinkNodeEqual + } + for nodetype in registry: + if isinstance(expected, nodetype): + self.assertIsInstance(actual, nodetype) + registry[nodetype](expected, actual) + + def assertTextNodeEqual(self, expected, actual): + """Assert that two Text nodes have the same data.""" + self.assertEqual(expected.value, actual.value) + + def assertTemplateNodeEqual(self, expected, actual): + """Assert that two Template nodes have the same data.""" + self.assertWikicodeEqual(expected.name, actual.name) + length = len(expected.params) + self.assertEqual(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) + self.assertIs(exp_param.showkey, act_param.showkey) + + 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: + self.assertIs(None, actual.text) + + def assertWikicodeEqual(self, expected, actual): + """Assert that two Wikicode objects have the same data.""" + self.assertIsInstance(actual, Wikicode) + length = len(expected.nodes) + self.assertEqual(length, len(actual.nodes)) + for i in range(length): + self.assertNodeEqual(expected.get(i), actual.get(i)) diff --git a/tests/test_ctokenizer.py b/tests/test_ctokenizer.py index 7a082e8..955b9a0 100644 --- a/tests/test_ctokenizer.py +++ b/tests/test_ctokenizer.py @@ -31,7 +31,7 @@ except ImportError: from ._test_tokenizer import TokenizerTestCase @unittest.skipUnless(CTokenizer, "C tokenizer not available") -class TestCTokenizer(TokenizerTestCase, unittest.TestCase): +class TestCTokenizer(TokenizerTestCase): """Test cases for the C tokenizer.""" @classmethod diff --git a/tests/test_parser.py b/tests/test_parser.py index 1c37a85..9d2c969 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -29,41 +29,12 @@ from mwparserfromhell.nodes.extras import Parameter from mwparserfromhell.smart_list import SmartList from mwparserfromhell.wikicode import Wikicode +from ._test_tree_equality import TreeEqualityTestCase from .compat import range -class TestParser(unittest.TestCase): +class TestParser(TreeEqualityTestCase): """Tests for the Parser class itself, which tokenizes and builds nodes.""" - def assertNodesEqual(self, expected, actual): - """Assert that two Nodes are the same type and have the same data.""" - self.assertIs(type(expected), type(actual)) - if isinstance(expected, Text): - self.assertEqual(expected.value, actual.value) - elif isinstance(expected, Template): - self.assertWikicodeEqual(expected.name, actual.name) - length = len(expected.params) - self.assertEqual(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) - self.assertIs(exp_param.showkey, act_param.showkey) - elif isinstance(expected, Wikilink): - self.assertWikicodeEqual(expected.title, actual.title) - if expected.text is not None: - self.assertWikicodeEqual(expected.text, actual.text) - else: - self.assertIs(None, actual.text) - - def assertWikicodeEqual(self, expected, actual): - """Assert that two Wikicode objects have the same data.""" - self.assertIsInstance(actual, Wikicode) - length = len(expected.nodes) - self.assertEqual(length, len(actual.nodes)) - for i in range(length): - self.assertNodesEqual(expected.get(i), actual.get(i)) - def test_use_c(self): """make sure the correct tokenizer is used""" if parser.use_c: diff --git a/tests/test_pytokenizer.py b/tests/test_pytokenizer.py index 697c7e5..7b37eb3 100644 --- a/tests/test_pytokenizer.py +++ b/tests/test_pytokenizer.py @@ -27,7 +27,7 @@ from mwparserfromhell.parser.tokenizer import Tokenizer from ._test_tokenizer import TokenizerTestCase -class TestPyTokenizer(TokenizerTestCase, unittest.TestCase): +class TestPyTokenizer(TokenizerTestCase): """Test cases for the Python tokenizer.""" @classmethod