summaryrefslogtreecommitdiff
path: root/simple_unit_tests.py
diff options
context:
space:
mode:
authorPaul McGuire <ptmcg@austin.rr.com>2018-09-21 00:25:36 -0500
committerPaul McGuire <ptmcg@austin.rr.com>2018-09-21 00:25:36 -0500
commit0b11e366e077e58268c4e38b1d333cb498898348 (patch)
tree84835edd0d6c7d6af569480d87dee905473010b5 /simple_unit_tests.py
parent8db18bde0c78b9162f64ec66eed5de84f5fdcf03 (diff)
downloadpyparsing-git-0b11e366e077e58268c4e38b1d333cb498898348.tar.gz
add more simple unit tests, plus support for tests with searchString and transformString
Diffstat (limited to 'simple_unit_tests.py')
-rw-r--r--simple_unit_tests.py109
1 files changed, 92 insertions, 17 deletions
diff --git a/simple_unit_tests.py b/simple_unit_tests.py
index 2345bc2..5266c92 100644
--- a/simple_unit_tests.py
+++ b/simple_unit_tests.py
@@ -14,8 +14,9 @@ from collections import namedtuple
from datetime import datetime
# Test spec data class for specifying simple pyparsing test cases
-PpTestSpec = namedtuple("PpTestSpec", "desc expr text expected_list expected_dict expected_fail_locn")
-PpTestSpec.__new__.__defaults__ = ('', pp.Empty(), '', None, None, None)
+PpTestSpec = namedtuple("PpTestSpec", "desc expr text parse_fn "
+ "expected_list expected_dict expected_fail_locn")
+PpTestSpec.__new__.__defaults__ = ('', pp.Empty(), '', 'parseString', None, None, None)
class PyparsingExpressionTestCase(unittest.TestCase):
@@ -42,20 +43,32 @@ class PyparsingExpressionTestCase(unittest.TestCase):
type(test_spec.expr).__name__,
test_spec.expr))
+ parsefn = getattr(test_spec.expr, test_spec.parse_fn)
if test_spec.expected_fail_locn is None:
# expect success
- result = test_spec.expr.parseString(test_spec.text)
- print(result.dump())
- # compare results against given list and/or dict
- if test_spec.expected_list is not None:
- self.assertEqual(result.asList(), test_spec.expected_list)
- if test_spec.expected_dict is not None:
- self.assertEqual(result.asDict(), test_spec.expected_dict)
+ result = parsefn(test_spec.text)
+ if test_spec.parse_fn == 'parseString':
+ print(result.dump())
+ # compare results against given list and/or dict
+ if test_spec.expected_list is not None:
+ self.assertEqual(result.asList(), test_spec.expected_list)
+ if test_spec.expected_dict is not None:
+ self.assertEqual(result.asDict(), test_spec.expected_dict)
+ elif test_spec.parse_fn == 'transformString':
+ print(result)
+ # compare results against given list and/or dict
+ if test_spec.expected_list is not None:
+ self.assertEqual([result], test_spec.expected_list)
+ elif test_spec.parse_fn == 'searchString':
+ print(result)
+ # compare results against given list and/or dict
+ if test_spec.expected_list is not None:
+ self.assertEqual([result], test_spec.expected_list)
else:
# expect fail
with self.assertRaises(pp.ParseException) as ar:
- test_spec.expr.parseString(test_spec.text)
+ parsefn(test_spec.text)
print(' ', test_spec.text or "''")
print(' ', ' '*ar.exception.loc+'^')
print(' ', ar.exception.msg)
@@ -103,6 +116,15 @@ class TestLiteral(PyparsingExpressionTestCase):
),
]
+class TestCaselessLiteral(PyparsingExpressionTestCase):
+ tests = [
+ PpTestSpec(
+ desc = "Match colors, converting to consistent case",
+ expr = pp.OneOrMore(pp.CaselessLiteral("RED") | pp.CaselessLiteral("GREEN") | pp.CaselessLiteral("BLUE")),
+ text = "red Green BluE blue GREEN green rEd",
+ expected_list = ['RED', 'GREEN', 'BLUE', 'BLUE', 'GREEN', 'GREEN', 'RED'],
+ ),
+ ]
class TestWord(PyparsingExpressionTestCase):
tests = [
@@ -183,20 +205,21 @@ class TestResultsName(PyparsingExpressionTestCase):
]
class TestGroups(PyparsingExpressionTestCase):
+ EQ = pp.Suppress('=')
tests = [
PpTestSpec(
desc = "Define multiple results names in groups",
- expr = pp.OneOrMore(pp.Group(pp.Word(pp.alphas, pp.alphanums)("key")
- + pp.Suppress('=')
+ expr = pp.OneOrMore(pp.Group(pp.Word(pp.alphas)("key")
+ + EQ
+ pp.pyparsing_common.number("value"))),
text = "range=5280 long=-138.52 lat=46.91",
expected_list = [['range', 5280], ['long', -138.52], ['lat', 46.91]],
),
PpTestSpec(
desc = "Define multiple results names in groups - use Dict to define results names using parsed keys",
- expr = pp.Dict(pp.OneOrMore(pp.Group(pp.Word(pp.alphas, pp.alphanums)("key")
- + pp.Suppress('=')
- + pp.pyparsing_common.number("value")))),
+ expr = pp.Dict(pp.OneOrMore(pp.Group(pp.Word(pp.alphas)
+ + EQ
+ + pp.pyparsing_common.number))),
text = "range=5280 long=-138.52 lat=46.91",
expected_list = [['range', 5280], ['long', -138.52], ['lat', 46.91]],
expected_dict = {'lat': 46.91, 'long': -138.52, 'range': 5280}
@@ -214,16 +237,48 @@ class TestParseAction(PyparsingExpressionTestCase):
PpTestSpec(
desc = "Use two parse actions to convert numeric string, then convert to datetime",
expr = pp.Word(pp.nums).addParseAction(lambda t: int(t[0]),
- lambda t: datetime.utcfromtimestamp(t[0])),
+ lambda t: datetime.utcfromtimestamp(t[0])),
text = "1537415628",
expected_list = [datetime(2018, 9, 20, 3, 53, 48)],
),
PpTestSpec(
desc = "Use tokenMap for parse actions that operate on a single-length token",
- expr = pp.Word(pp.nums).addParseAction(pp.tokenMap(int), pp.tokenMap(datetime.utcfromtimestamp)),
+ expr = pp.Word(pp.nums).addParseAction(pp.tokenMap(int),
+ pp.tokenMap(datetime.utcfromtimestamp)),
text = "1537415628",
expected_list = [datetime(2018, 9, 20, 3, 53, 48)],
),
+ PpTestSpec(
+ desc = "Using a built-in function that takes a sequence of strs as a parse action",
+ expr = pp.OneOrMore(pp.Word(pp.hexnums, exact=2)).addParseAction(':'.join),
+ text = "0A4B7321FE76",
+ expected_list = ['0A:4B:73:21:FE:76'],
+ ),
+ PpTestSpec(
+ desc = "Using a built-in function that takes a sequence of strs as a parse action",
+ expr = pp.OneOrMore(pp.Word(pp.hexnums, exact=2)).addParseAction(sorted),
+ text = "0A4B7321FE76",
+ expected_list = ['0A', '21', '4B', '73', '76', 'FE'],
+ ),
+ ]
+
+class TestResultsModifyingParseAction(PyparsingExpressionTestCase):
+ def compute_stats_parse_action(t):
+ # by the time this parse action is called, parsed numeric words have been converted to ints
+ # by a previous parse action, so they can be treated as ints
+ t['sum'] = sum(t)
+ t['ave'] = sum(t) / len(t)
+ t['min'] = min(t)
+ t['max'] = max(t)
+
+ tests = [
+ PpTestSpec(
+ desc = "A parse action that adds new key-values",
+ expr = pp.OneOrMore(pp.pyparsing_common.integer).addParseAction(compute_stats_parse_action),
+ text = "27 1 14 22 89",
+ expected_list = [27, 1, 14, 22, 89],
+ expected_dict = {'ave': 30.6, 'max': 89, 'min': 1, 'sum': 153}
+ ),
]
class TestParseCondition(PyparsingExpressionTestCase):
@@ -243,6 +298,26 @@ class TestParseCondition(PyparsingExpressionTestCase):
),
]
+class TestTransformStringUsingParseActions(PyparsingExpressionTestCase):
+ markup_convert_map = {
+ '*' : 'B',
+ '_' : 'U',
+ '/' : 'I',
+ }
+ def markup_convert(t):
+ htmltag = TestTransformStringUsingParseActions.markup_convert_map[t.markup_symbol]
+ return "<{}>{}</{}>".format(htmltag, t.body, htmltag)
+
+ tests = [
+ PpTestSpec(
+ desc = "Use transformString to convert simple markup to HTML",
+ expr = (pp.oneOf(markup_convert_map)('markup_symbol')
+ + "(" + pp.CharsNotIn(")")('body') + ")").addParseAction(markup_convert),
+ text = "Show in *(bold), _(underscore), or /(italic) type",
+ expected_list = ['Show in <B>bold</B>, <U>underscore</U>, or <I>italic</I> type'],
+ parse_fn = 'transformString',
+ ),
+ ]
if __name__ == '__main__':
# we use unittest features that are in Py3 only, bail out if run on Py2