Skip to content

Commit

Permalink
Add test lib methods to check regexes
Browse files Browse the repository at this point in the history
We currently test regular expressions in two ways: does the expression
match and not match lists of strings, and does the expression parse a
string into the expected groups. Share those two methods in a common
module.
  • Loading branch information
dashea committed Feb 20, 2015
1 parent af3c396 commit 9ba6020
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 89 deletions.
71 changes: 71 additions & 0 deletions tests/lib/regexcheck.py
@@ -0,0 +1,71 @@
#
# regexcheck.py: check a regular expression against lists of matching and non-matching strings
#
# Copyright (C) 2015 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Author: David Shea <dshea@redhat.com>

def regex_match(expression, goodlist, badlist):
""" Check that a regular expression matches and does not match lists of strings.
This method will print a message for any failure and return a a bool
to indicate whether the testcase passed.
:param expression: a compiled regular expression object
:param goodlist: a list of strings expected to be matched by expression
:param badlist: a list of strings expected not to be matched by expression
:returns: True if all strings in the lists matched or did not match as expected
:rtype: bool
"""

success = True

for good in goodlist:
if expression.match(good) is None:
success = False
print("Good string %s did not match expression" % good)

for bad in badlist:
if expression.match(bad) is not None:
success = False
print("Bad string %s matched expression" % bad)

return success

def regex_group(expression, test_cases):
""" Check that a regex parses strings into expected groups.
Test cases is a list of tuples of the form (test_string, expected_result)
where expected_result is the groups tuples that should be returned by
regex.match.
:param expression: a compiled expression object
:param test_cases: a list of test strings and expected results
:returns: True if all test cases return the expected groups
:rtype: bool
"""

success = True
for test_str, result in test_cases:
match = expression.match(test_str)
if match is not None:
match = match.groups()

if match != result:
print("Test case `%s' did not parse as `%s': %s" % (test_str, result, match))
success = False

return success
11 changes: 2 additions & 9 deletions tests/regex_tests/groupparse_test.py
Expand Up @@ -20,6 +20,7 @@
#
import unittest

from regexcheck import regex_group
from pyanaconda.regexes import GROUPLIST_FANCY_PARSE

class GroupParseTestCase(unittest.TestCase):
Expand Down Expand Up @@ -49,13 +50,5 @@ def group_list_test(self):
("", ("", None)),
]

got_error = False
for group, result in tests:
try:
self.assertEqual(GROUPLIST_FANCY_PARSE.match(group).groups(), result)
except AssertionError:
got_error = True
print("Group parse error: `%s' did not not parse as `%s'" % (group, result))

if got_error:
if not regex_group(GROUPLIST_FANCY_PARSE, tests):
self.fail()
29 changes: 7 additions & 22 deletions tests/regex_tests/hostname_test.py
Expand Up @@ -22,28 +22,10 @@
import unittest
import re

from regexcheck import regex_match
from pyanaconda.regexes import HOSTNAME_PATTERN_WITHOUT_ANCHORS, IPV4_PATTERN_WITHOUT_ANCHORS,\
IPV6_PATTERN_WITHOUT_ANCHORS

def _run_tests(testcase, expression, goodlist, badlist):
got_error = False
for good in goodlist:
try:
testcase.assertIsNotNone(expression.match(good))
except AssertionError:
got_error = True
print("Good string %s did not match expression" % good)

for bad in badlist:
try:
testcase.assertIsNone(expression.match(bad))
except AssertionError:
got_error = True
print("Bad string %s matched expression" % bad)

if got_error:
testcase.fail()

class HostnameRegexTestCase(unittest.TestCase):
def hostname_test(self):
good_tests = [
Expand Down Expand Up @@ -76,7 +58,8 @@ def hostname_test(self):
]

hostname_re = re.compile('^' + HOSTNAME_PATTERN_WITHOUT_ANCHORS + '$')
_run_tests(self, hostname_re, good_tests, bad_tests)
if not regex_match(hostname_re, good_tests, bad_tests):
self.fail()

class IPv4RegexTestCase(unittest.TestCase):
def ipv4_test(self):
Expand All @@ -99,7 +82,8 @@ def ipv4_test(self):
]

ipv4_re = re.compile('^(' + IPV4_PATTERN_WITHOUT_ANCHORS + ')$')
_run_tests(self, ipv4_re, good_tests, bad_tests)
if not regex_match(ipv4_re, good_tests, bad_tests):
self.fail()

class IPv6RegexTestCase(unittest.TestCase):
def ipv6_test(self):
Expand Down Expand Up @@ -187,4 +171,5 @@ def ipv6_test(self):
]

ipv6_re = re.compile('^(' + IPV6_PATTERN_WITHOUT_ANCHORS + ')$')
_run_tests(self, ipv6_re, good_tests, bad_tests)
if not regex_match(ipv6_re, good_tests, bad_tests):
self.fail()
23 changes: 3 additions & 20 deletions tests/regex_tests/repo_name_test.py
Expand Up @@ -21,27 +21,9 @@
#
import unittest

from regexcheck import regex_match
from pyanaconda.regexes import REPO_NAME_VALID

def _run_tests(testcase, expression, goodlist, badlist):
got_error = False
for good in goodlist:
try:
testcase.assertIsNotNone(expression.match(good))
except AssertionError:
got_error = True
print("Good string %s did not match expression" % good)

for bad in badlist:
try:
testcase.assertIsNone(expression.match(bad))
except AssertionError:
got_error = True
print("Bad string %s matched expression" % bad)

if got_error:
testcase.fail()

class RepoNameTestCase(unittest.TestCase):
def reponame_test(self):
good_tests = [
Expand All @@ -63,4 +45,5 @@ def reponame_test(self):
'[reponame]'
]

_run_tests(self, REPO_NAME_VALID, good_tests, bad_tests)
if not regex_match(REPO_NAME_VALID, good_tests, bad_tests):
self.fail()
17 changes: 2 additions & 15 deletions tests/regex_tests/url_test.py
Expand Up @@ -21,6 +21,7 @@

import unittest

from regexcheck import regex_group
from pyanaconda.regexes import URL_PARSE

class URLRegexTestCase(unittest.TestCase):
Expand Down Expand Up @@ -165,19 +166,5 @@ def url_regex_test(self):
]


got_error = False
for proxy, result in tests:
match = URL_PARSE.match(proxy)
if match:
match= match.groups()
else:
match = None

try:
self.assertEqual(match, result)
except AssertionError:
got_error = True
print("Proxy parse error: `%s' did not parse as `%s': %s" % (proxy, result, match))

if got_error:
if not regex_group(URL_PARSE, tests):
self.fail()
32 changes: 9 additions & 23 deletions tests/regex_tests/username_test.py
Expand Up @@ -21,28 +21,10 @@
#
import unittest

from regexcheck import regex_match
from pyanaconda.regexes import GECOS_VALID, USERNAME_VALID, GROUPNAME_VALID, GROUPLIST_SIMPLE_VALID

class UsernameRegexTestCase(unittest.TestCase):
def _run_tests(self, expression, goodlist, badlist):
got_error = False
for good in goodlist:
try:
self.assertIsNotNone(expression.match(good))
except AssertionError:
got_error = True
print("Good string %s did not match expression" % good)

for bad in badlist:
try:
self.assertIsNone(expression.match(bad))
except AssertionError:
got_error = True
print("Bad string %s matched expression" % bad)

if got_error:
self.fail()

def gecos_test(self):
"""Test a list of possible Full Name values."""
# These are valid full names
Expand All @@ -59,7 +41,8 @@ def gecos_test(self):
# These are invalid full names
bad_tests = ['George:Burdell']

self._run_tests(GECOS_VALID, good_tests, bad_tests)
if not regex_match(GECOS_VALID, good_tests, bad_tests):
self.fail()

def username_test(self):
"""Test a list of possible username values."""
Expand Down Expand Up @@ -94,10 +77,12 @@ def username_test(self):
'-'
]

self._run_tests(USERNAME_VALID, good_tests, bad_tests)
if not regex_match(USERNAME_VALID, good_tests, bad_tests):
self.fail()

# The group name checks for the same thing as the user name
self._run_tests(GROUPNAME_VALID, good_tests, bad_tests)
if not regex_match(GROUPNAME_VALID, good_tests, bad_tests):
self.fail()

def grouplist_simple_test(self):
good_tests = [
Expand Down Expand Up @@ -129,4 +114,5 @@ def grouplist_simple_test(self):
'gburdell, wheel,'
]

self._run_tests(GROUPLIST_SIMPLE_VALID, good_tests, bad_tests)
if not regex_match(GROUPLIST_SIMPLE_VALID, good_tests, bad_tests):
self.fail()

0 comments on commit 9ba6020

Please sign in to comment.