From d785871a32632fb0c2602aa839fd0c688a4b54c5 Mon Sep 17 00:00:00 2001 From: ptmcg Date: Wed, 18 May 2016 13:26:56 +0000 Subject: runTests changes: made parseAll=True the default; added support for failure tests; always return success,results tuple revamp unitTests to use new failureTests arg git-svn-id: svn://svn.code.sf.net/p/pyparsing/code/trunk@355 9bf210a0-9d2d-494c-87cf-cfb32e7dff7b --- src/CHANGES | 8 ++++++++ src/pyparsing.py | 32 +++++++++++++++++--------------- src/unitTests.py | 45 ++++++++++++++++++++++++++++++--------------- 3 files changed, 55 insertions(+), 30 deletions(-) diff --git a/src/CHANGES b/src/CHANGES index b1aa686..efa9958 100644 --- a/src/CHANGES +++ b/src/CHANGES @@ -11,6 +11,14 @@ Verison 2.1.5 - . ISO8601 date and date time strings . UUID (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) +- runTests now returns a two-tuple: success if all tests succeed, + and an output list of each test and its output lines. + +- Added failureTests argument (default=False) to runTests, so that + tests can be run that are expected failures, and if all tests fail + as expected, the runTests' success value will return True. Also, + parseAll now default to True. + Version 2.1.4 - May, 2016 ------------------------------ diff --git a/src/pyparsing.py b/src/pyparsing.py index 177d833..be90545 100644 --- a/src/pyparsing.py +++ b/src/pyparsing.py @@ -58,7 +58,7 @@ The pyparsing module handles some of the problems that are typically vexing when """ __version__ = "2.1.5" -__versionTime__ = "18 May 2016 06:01 UTC" +__versionTime__ = "18 May 2016 13:24 UTC" __author__ = "Paul McGuire " import string @@ -1641,20 +1641,22 @@ class ParserElement(object): except ParseBaseException: return False - def runTests(self, tests, parseAll=False, comment='#', printResults=True): + def runTests(self, tests, parseAll=True, comment='#', printResults=True, failureTests=False): """Execute the parse expression on a series of test strings, showing each test, the parsed results or where the parse failed. Quick and easy way to run a parse expression against a list of sample strings. Parameters: - tests - a list of separate test strings, or a multiline string of test strings - - parseAll - (default=False) - flag to pass to C{L{parseString}} when running tests + - parseAll - (default=True) - flag to pass to C{L{parseString}} when running tests - comment - (default='#') - expression for indicating embedded comments in the test string; pass None to disable comment filtering - - printResults - (default=True) prints test output to stdout; if False, returns a - (success, results) tuple, where success indicates that all tests succeeded, and the - results contain a list of lines of each test's output as it would have been - printed to stdout + - printResults - (default=True) prints test output to stdout + - failureTests - (default=False) indicates if these tests are expected to fail parsing + + Returns: a (success, results) tuple, where success indicates that all tests succeeded + (or failed if C{failureTest} is True), + and the results contain a list of lines of each test's output """ if isinstance(tests, basestring): tests = list(map(str.strip, tests.splitlines())) @@ -1673,6 +1675,7 @@ class ParserElement(object): comments = [] try: out.append(self.parseString(t, parseAll=parseAll).dump()) + success = success and not failureTests except ParseBaseException as pe: fatal = "(FATAL)" if isinstance(pe, ParseFatalException) else "" if '\n' in t: @@ -1681,7 +1684,7 @@ class ParserElement(object): else: out.append(' '*pe.loc + '^' + fatal) out.append("FAIL: " + str(pe)) - success = False + success = success and failureTests if printResults: out.append('') @@ -1689,8 +1692,7 @@ class ParserElement(object): else: allResults.append(out) - if not printResults: - return success, allResults + return success, allResults class Token(ParserElement): @@ -3937,12 +3939,12 @@ class pyparsing_common: ipv4_address = Regex(r'(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})(\.(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})){3}').setName("IPv4 address") "IPv4 address (C{0.0.0.0 - 255.255.255.255})" - _ipv6_part = Regex(r'[0-9a-fA-F]{1,4}') - _full_ipv6_address = _ipv6_part + (':' + _ipv6_part)*7 - _short_ipv6_address = Optional(_ipv6_part + (':' + _ipv6_part)*(0,7)) + "::" + Optional(_ipv6_part + (':' + _ipv6_part)*(0,7)) + _ipv6_part = Regex(r'[0-9a-fA-F]{1,4}').setName("hex_integer") + _full_ipv6_address = (_ipv6_part + (':' + _ipv6_part)*7).setName("full IPv6 address") + _short_ipv6_address = (Optional(_ipv6_part + (':' + _ipv6_part)*(0,6)) + "::" + Optional(_ipv6_part + (':' + _ipv6_part)*(0,6))).setName("short IPv6 address") _short_ipv6_address.addCondition(lambda t: sum(1 for tt in t if pyparsing_common._ipv6_part.matches(tt)) < 8) - _mixed_ipv6_address = "::ffff:" + ipv4_address - ipv6_address = Combine(_full_ipv6_address | _mixed_ipv6_address | _short_ipv6_address).setName("IPv6 address") + _mixed_ipv6_address = ("::ffff:" + ipv4_address).setName("mixed IPv6 address") + ipv6_address = Combine((_full_ipv6_address | _mixed_ipv6_address | _short_ipv6_address).setName("IPv6 address")).setName("IPv6 address") "IPv6 address (long, short, or mixed form)" mac_address = Regex(r'[0-9a-fA-F]{2}([:.-])[0-9a-fA-F]{2}(?:\1[0-9a-fA-F]{2}){4}').setName("MAC address") diff --git a/src/unitTests.py b/src/unitTests.py index ddbdf98..e2706be 100644 --- a/src/unitTests.py +++ b/src/unitTests.py @@ -2634,13 +2634,14 @@ class CommonExpressionsTest(ParseTestCase): AA:BB:CC:DD:EE:FF AA.BB.CC.DD.EE.FF AA-BB-CC-DD-EE-FF - """, printResults=False)[0] + """)[0] assert success, "error in parsing valid MAC address" success = pyparsing_common.mac_address.runTests(""" + # mixed delimiters AA.BB:CC:DD:EE:FF - """, printResults=False)[0] - assert not success, "error in detecting invalid mac address" + """, failureTests=True)[0] + assert success, "error in detecting invalid mac address" success = pyparsing_common.ipv4_address.runTests(""" 0.0.0.0 @@ -2648,13 +2649,14 @@ class CommonExpressionsTest(ParseTestCase): 127.0.0.1 1.10.100.199 255.255.255.255 - """, printResults=False)[0] + """)[0] assert success, "error in parsing valid IPv4 address" success = pyparsing_common.ipv4_address.runTests(""" + # out of range value 256.255.255.255 - """, printResults=False)[0] - assert not success, "error in detecting invalid IPv4 address" + """, failureTests=True)[0] + assert success, "error in detecting invalid IPv4 address" success = pyparsing_common.ipv6_address.runTests(""" 2001:0db8:85a3:0000:0000:8a2e:0370:7334 @@ -2662,16 +2664,26 @@ class CommonExpressionsTest(ParseTestCase): 0:0:0:0:0:0:A00:1 1080::8:800:200C:417A ::A00:1 + + # loopback address ::1 + + # the null address :: + + # ipv4 compatibility form ::ffff:192.168.0.1 - """, parseAll=True, printResults=False)[0] + """)[0] assert success, "error in parsing valid IPv6 address" success = pyparsing_common.ipv6_address.runTests(""" + # too few values 1080:0:0:0:8:800:200C - """, parseAll=True, printResults=False)[0] - assert not success, "error in detecting invalid IPv6 address" + + # too many ::'s, only 1 allowed + 2134::1234:4567::2444:2106 + """, failureTests=True)[0] + assert success, "error in detecting invalid IPv6 address" success = pyparsing_common.numeric.runTests(""" 100 @@ -2680,35 +2692,38 @@ class CommonExpressionsTest(ParseTestCase): 3.14159 6.02e23 1e-12 - """, parseAll=True, printResults=False)[0] + """)[0] assert success, "error in parsing valid numerics" # any int or real number, returned as float - success, results = pyparsing_common.number.runTests(""" + success = pyparsing_common.number.runTests(""" 100 -100 +100 3.14159 6.02e23 1e-12 - """, parseAll=True, printResults=False) + """)[0] assert success, "error in parsing valid numerics" success = pyparsing_common.iso8601_date.runTests(""" 1997 1997-07 1997-07-16 - """, parseAll=True, printResults=False)[0] + """)[0] assert success, "error in parsing valid iso8601_date" success = pyparsing_common.iso8601_datetime.runTests(""" 1997-07-16T19:20+01:00 1997-07-16T19:20:30+01:00 1997-07-16T19:20:30.45+01:00 - """, parseAll=True, printResults=False)[0] + """)[0] assert success, "error in parsing valid iso8601_datetime" - assert pyparsing_common.uuid.matches("123e4567-e89b-12d3-a456-426655440000"), "failed to parse valid uuid" + success = pyparsing_common.uuid.runTests(""" + 123e4567-e89b-12d3-a456-426655440000 + """)[0] + assert success, "failed to parse valid uuid" class MiscellaneousParserTests(ParseTestCase): def runTest(self): -- cgit v1.2.1