mirror of
https://github.com/cool-RR/PySnooper.git
synced 2026-01-23 02:14:04 +00:00
Add testing for exceptions
This commit is contained in:
parent
a602866ce1
commit
473bb37a76
6 changed files with 67 additions and 10 deletions
|
|
@ -16,7 +16,8 @@ from pysnooper import pycompat
|
|||
from pysnooper.variables import needs_parentheses
|
||||
from .utils import (assert_output, assert_sample_output, VariableEntry,
|
||||
CallEntry, LineEntry, ReturnEntry, OpcodeEntry,
|
||||
ReturnValueEntry, ExceptionEntry, SourcePathEntry,
|
||||
ReturnValueEntry, ExceptionEntry, ExceptionValueEntry,
|
||||
SourcePathEntry, CallEndedByExceptionEntry,
|
||||
ElapsedTimeEntry)
|
||||
from . import mini_toolbox
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ import pysnooper
|
|||
from pysnooper.variables import needs_parentheses
|
||||
from ..utils import (assert_output, assert_sample_output, VariableEntry,
|
||||
CallEntry, LineEntry, ReturnEntry, OpcodeEntry,
|
||||
ReturnValueEntry, ExceptionEntry, SourcePathEntry,
|
||||
ReturnValueEntry, ExceptionEntry, ExceptionValueEntry,
|
||||
SourcePathEntry, CallEndedByExceptionEntry,
|
||||
ElapsedTimeEntry)
|
||||
from .. import mini_toolbox
|
||||
from .multiple_files import foo
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@ from pysnooper.variables import needs_parentheses
|
|||
from pysnooper import pycompat
|
||||
from .utils import (assert_output, assert_sample_output, VariableEntry,
|
||||
CallEntry, LineEntry, ReturnEntry, OpcodeEntry,
|
||||
ReturnValueEntry, ExceptionEntry, SourcePathEntry)
|
||||
ReturnValueEntry, ExceptionEntry, ExceptionValueEntry,
|
||||
SourcePathEntry, CallEndedByExceptionEntry,
|
||||
ElapsedTimeEntry)
|
||||
from . import mini_toolbox
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@ import pysnooper
|
|||
from pysnooper.variables import needs_parentheses
|
||||
from .utils import (assert_output, assert_sample_output, VariableEntry,
|
||||
CallEntry, LineEntry, ReturnEntry, OpcodeEntry,
|
||||
ReturnValueEntry, ExceptionEntry, SourcePathEntry,
|
||||
ReturnValueEntry, ExceptionEntry, ExceptionValueEntry,
|
||||
SourcePathEntry, CallEndedByExceptionEntry,
|
||||
ElapsedTimeEntry)
|
||||
from . import mini_toolbox
|
||||
|
||||
|
|
@ -1864,3 +1865,34 @@ def test_normalize_thread_info():
|
|||
|
||||
with pytest.raises(NotImplementedError):
|
||||
add()
|
||||
|
||||
|
||||
def test_exception():
|
||||
string_io = io.StringIO()
|
||||
@pysnooper.snoop(string_io)
|
||||
def f():
|
||||
x = 8
|
||||
raise MemoryError
|
||||
|
||||
with pytest.raises(MemoryError):
|
||||
f()
|
||||
|
||||
output = string_io.getvalue()
|
||||
assert_output(
|
||||
output,
|
||||
(
|
||||
SourcePathEntry(),
|
||||
CallEntry(),
|
||||
LineEntry(),
|
||||
VariableEntry(),
|
||||
LineEntry(),
|
||||
ExceptionEntry(),
|
||||
ExceptionValueEntry('MemoryError'),
|
||||
CallEndedByExceptionEntry(),
|
||||
ElapsedTimeEntry(),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -101,6 +101,19 @@ class ElapsedTimeEntry(_BaseEntry):
|
|||
|
||||
|
||||
|
||||
class CallEndedByExceptionEntry(_BaseEntry):
|
||||
# Todo: Looking at this class, we could rework the hierarchy.
|
||||
def __init__(self, prefix=''):
|
||||
_BaseEntry.__init__(self, prefix=prefix)
|
||||
|
||||
def check(self, s):
|
||||
return re.match(
|
||||
r'''(?P<indent>(?: {4})*)Call ended by exception''',
|
||||
s
|
||||
)
|
||||
|
||||
|
||||
|
||||
class VariableEntry(_BaseValueEntry):
|
||||
def __init__(self, name=None, value=None, stage=None, prefix='',
|
||||
name_regex=None, value_regex=None):
|
||||
|
|
@ -165,7 +178,7 @@ class VariableEntry(_BaseValueEntry):
|
|||
return stage == self.stage
|
||||
|
||||
|
||||
class ReturnValueEntry(_BaseValueEntry):
|
||||
class _BaseSimpleValueEntry(_BaseValueEntry):
|
||||
def __init__(self, value=None, value_regex=None, prefix=''):
|
||||
_BaseValueEntry.__init__(self, prefix=prefix)
|
||||
if value is not None:
|
||||
|
|
@ -175,10 +188,6 @@ class ReturnValueEntry(_BaseValueEntry):
|
|||
self.value_regex = (None if value_regex is None else
|
||||
re.compile(value_regex))
|
||||
|
||||
_preamble_pattern = re.compile(
|
||||
r"""^Return value$"""
|
||||
)
|
||||
|
||||
def _check_preamble(self, preamble):
|
||||
return bool(self._preamble_pattern.match(preamble))
|
||||
|
||||
|
|
@ -193,6 +202,16 @@ class ReturnValueEntry(_BaseValueEntry):
|
|||
else:
|
||||
return True
|
||||
|
||||
class ReturnValueEntry(_BaseSimpleValueEntry):
|
||||
_preamble_pattern = re.compile(
|
||||
r"""^Return value$"""
|
||||
)
|
||||
|
||||
class ExceptionValueEntry(_BaseSimpleValueEntry):
|
||||
_preamble_pattern = re.compile(
|
||||
r"""^Exception$"""
|
||||
)
|
||||
|
||||
class SourcePathEntry(_BaseValueEntry):
|
||||
def __init__(self, source_path=None, source_path_regex=None, prefix=''):
|
||||
_BaseValueEntry.__init__(self, prefix=prefix)
|
||||
|
|
@ -315,6 +334,8 @@ def verify_normalize(lines, prefix):
|
|||
|
||||
def assert_output(output, expected_entries, prefix=None, normalize=False):
|
||||
lines = tuple(filter(None, output.split('\n')))
|
||||
if expected_entries and not lines:
|
||||
raise OutputFailure("Output is empty")
|
||||
|
||||
if prefix is not None:
|
||||
for line in lines:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue