tests: Do custom fnmatch-like matching.

fnmatch treats [, ] and ? as shell metacharacters too, and has no way to escape
them. We need a literal [] and really only need * for filtering.
This commit is contained in:
Florian Bruhin 2015-11-13 07:49:33 +01:00
parent 205af3737f
commit 3290048458
4 changed files with 41 additions and 8 deletions

View File

@ -48,3 +48,24 @@ def test_partial_compare_equal(val1, val2):
])
def test_partial_compare_not_equal(val1, val2):
assert not utils.partial_compare(val1, val2)
@pytest.mark.parametrize('pattern, value, expected', [
('foo', 'foo', True),
('foo', 'bar', False),
('foo', 'Foo', False),
('foo', 'foobar', False),
('foo', 'barfoo', False),
('foo*', 'foobarbaz', True),
('*bar', 'foobar', True),
('foo*baz', 'foobarbaz', True),
('foo[b]ar', 'foobar', False),
('foo[b]ar', 'foo[b]ar', True),
('foo?ar', 'foobar', False),
('foo?ar', 'foo?ar', True),
])
def test_pattern_match(pattern, value, expected):
assert utils.pattern_match(pattern=pattern, value=value) == expected

View File

@ -20,7 +20,7 @@
"""Partial comparison of dicts/lists."""
import fnmatch
import re
import pprint
@ -86,9 +86,19 @@ def partial_compare(val1, val2, *, indent=0):
equal = abs(val1 - val2) < 0.00001
elif isinstance(val2, str):
print_i("|======= Doing string comparison", indent)
equal = fnmatch.fnmatchcase(val1, val2)
equal = pattern_match(pattern=val2, value=val1)
else:
print_i("|======= Comparing via ==", indent)
equal = val1 == val2
print_i("---> {}".format(equal), indent)
return equal
def pattern_match(*, pattern, value):
"""Do fnmatch.fnmatchcase like matching, but only with * active.
Return:
True on a match, False otherwise.
"""
re_pattern = '.*'.join(re.escape(part) for part in pattern.split('*'))
return re.fullmatch(re_pattern, value) is not None

View File

@ -103,12 +103,13 @@ class TestWaitFor:
with pytest.raises(testprocess.WaitForTimeout):
pyproc.wait_for(data="foobar", timeout=100)
def test_existing_message(self, pyproc):
@pytest.mark.parametrize('message', ['foobar', 'literal [x]'])
def test_existing_message(self, message, pyproc):
"""Test with a message which already passed when waiting."""
pyproc.code = "print('foobar')"
pyproc.code = "print('{}')".format(message)
pyproc.start()
time.sleep(0.5) # to make sure the message is printed
pyproc.wait_for(data="foobar")
pyproc.wait_for(data=message)
def test_existing_message_previous_test(self, pyproc):
"""Make sure the message of a previous test gets ignored."""

View File

@ -22,12 +22,13 @@
import re
import os
import time
import fnmatch
import pytestqt.plugin # pylint: disable=import-error
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QProcess, QObject, QElapsedTimer
from PyQt5.QtTest import QSignalSpy
from helpers import utils # pylint: disable=import-error
class InvalidLine(Exception):
@ -199,7 +200,7 @@ class Process(QObject):
- If expected is None, the filter always matches.
- If the value is a string or bytes object and the expected value is
too, the pattern is treated as a fnmatch glob pattern.
too, the pattern is treated as a glob pattern (with only * active).
- If the value is a string or bytes object and the expected value is a
compiled regex, it is used for matching.
- If the value is any other type, == is used.
@ -213,7 +214,7 @@ class Process(QObject):
elif isinstance(expected, regex_type):
return expected.match(value)
elif isinstance(value, (bytes, str)):
return fnmatch.fnmatchcase(value, expected)
return utils.pattern_match(pattern=expected, value=value)
else:
return value == expected