Add match_regex functionality to warns
This commit is contained in:
parent
d8ecca5ebd
commit
aa6a67044f
|
@ -8,6 +8,8 @@ import py
|
|||
import sys
|
||||
import warnings
|
||||
|
||||
import re
|
||||
|
||||
from _pytest.fixtures import yield_fixture
|
||||
from _pytest.outcomes import fail
|
||||
|
||||
|
@ -99,9 +101,11 @@ def warns(expected_warning, *args, **kwargs):
|
|||
>>> with warns(RuntimeWarning):
|
||||
... warnings.warn("my warning", RuntimeWarning)
|
||||
"""
|
||||
wcheck = WarningsChecker(expected_warning)
|
||||
match_expr = None
|
||||
if not args:
|
||||
return wcheck
|
||||
if "match" in kwargs:
|
||||
match_expr = kwargs.pop("match")
|
||||
return WarningsChecker(expected_warning, match_expr=match_expr)
|
||||
elif isinstance(args[0], str):
|
||||
code, = args
|
||||
assert isinstance(code, str)
|
||||
|
@ -109,12 +113,12 @@ def warns(expected_warning, *args, **kwargs):
|
|||
loc = frame.f_locals.copy()
|
||||
loc.update(kwargs)
|
||||
|
||||
with wcheck:
|
||||
with WarningsChecker(expected_warning, match_expr=match_expr):
|
||||
code = _pytest._code.Source(code).compile()
|
||||
py.builtin.exec_(code, frame.f_globals, loc)
|
||||
else:
|
||||
func = args[0]
|
||||
with wcheck:
|
||||
with WarningsChecker(expected_warning, match_expr=match_expr):
|
||||
return func(*args[1:], **kwargs)
|
||||
|
||||
|
||||
|
@ -174,7 +178,7 @@ class WarningsRecorder(warnings.catch_warnings):
|
|||
|
||||
|
||||
class WarningsChecker(WarningsRecorder):
|
||||
def __init__(self, expected_warning=None):
|
||||
def __init__(self, expected_warning=None, match_expr=None):
|
||||
super(WarningsChecker, self).__init__()
|
||||
|
||||
msg = ("exceptions must be old-style classes or "
|
||||
|
@ -189,6 +193,7 @@ class WarningsChecker(WarningsRecorder):
|
|||
raise TypeError(msg % type(expected_warning))
|
||||
|
||||
self.expected_warning = expected_warning
|
||||
self.match_expr = match_expr
|
||||
|
||||
def __exit__(self, *exc_info):
|
||||
super(WarningsChecker, self).__exit__(*exc_info)
|
||||
|
@ -203,3 +208,15 @@ class WarningsChecker(WarningsRecorder):
|
|||
"The list of emitted warnings is: {1}.".format(
|
||||
self.expected_warning,
|
||||
[each.message for each in self]))
|
||||
elif self.match_expr is not None:
|
||||
for r in self:
|
||||
if issubclass(r.category, self.expected_warning):
|
||||
if re.compile(self.match_expr).search(str(r.message)):
|
||||
break
|
||||
else:
|
||||
fail("DID NOT WARN. No warnings of type {0} matching"
|
||||
" ('{1}') was emitted. The list of emitted warnings"
|
||||
" is: {2}.".format(
|
||||
self.expected_warning,
|
||||
self.match_expr,
|
||||
[each.message for each in self]))
|
||||
|
|
|
@ -289,20 +289,22 @@ class TestWarns(object):
|
|||
with pytest.warns(UserWarning, match=r'must be \d+$'):
|
||||
warnings.warn("value must be 42", UserWarning)
|
||||
|
||||
with pytest.raises(AssertionError, match='pattern not found'):
|
||||
with pytest.raises(pytest.fail.Exception):
|
||||
with pytest.warns(UserWarning, match=r'must be \d+$'):
|
||||
warnings.warn("this is not here", UserWarning)
|
||||
|
||||
def test_one_from_multiple_warns():
|
||||
with warns(UserWarning, match=r'aaa'):
|
||||
with pytest.raises(pytest.fail.Exception):
|
||||
with pytest.warns(FutureWarning, match=r'must be \d+$'):
|
||||
warnings.warn("value must be 42", UserWarning)
|
||||
|
||||
def test_one_from_multiple_warns(self):
|
||||
with pytest.warns(UserWarning, match=r'aaa'):
|
||||
warnings.warn("cccccccccc", UserWarning)
|
||||
warnings.warn("bbbbbbbbbb", UserWarning)
|
||||
warnings.warn("aaaaaaaaaa", UserWarning)
|
||||
|
||||
def test_none_of_multiple_warns():
|
||||
a, b, c = ('aaa', 'bbbbbbbbbb', 'cccccccccc')
|
||||
expected_msg = "'{}' pattern not found in \['{}', '{}'\]".format(a, b, c)
|
||||
with raises(AssertionError, match=expected_msg):
|
||||
with warns(UserWarning, match=r'aaa'):
|
||||
def test_none_of_multiple_warns(self):
|
||||
with pytest.raises(pytest.fail.Exception):
|
||||
with pytest.warns(UserWarning, match=r'aaa'):
|
||||
warnings.warn("bbbbbbbbbb", UserWarning)
|
||||
warnings.warn("cccccccccc", UserWarning)
|
||||
|
|
Loading…
Reference in New Issue