@@ -34,17 +34,44 @@ class BaseTestCase(unittest.TestCase):
34
34
"""Shared test case for Python Fire tests."""
35
35
36
36
@contextlib .contextmanager
37
- def assertStdoutMatches (self , regexp ):
38
- """Asserts that the context generates stdout matching regexp."""
39
- stdout = six .StringIO ()
40
- with mock .patch .object (sys , 'stdout' , stdout ):
41
- yield
42
- value = stdout .getvalue ()
43
- if not re .search (regexp , value , re .DOTALL | re .MULTILINE ):
44
- raise AssertionError ('Expected %r to match %r' % (value , regexp ))
37
+ def assertOutputMatches (self , stdout = '.*' , stderr = '.*' , capture = True ):
38
+ """Asserts that the context generates stdout and stderr matching regexps.
39
+
40
+ Note: If wrapped code raises an exception, stdout and stderr will not be
41
+ checked.
42
+
43
+ Args:
44
+ stdout: (str) regexp to match against stdout (None will check no stdout)
45
+ stderr: (str) regexp to match against stderr (None will check no stderr)
46
+ capture: (bool, default True) do not bubble up stdout or stderr
47
+ Yields:
48
+ Yields to the wrapped context.
49
+ """
50
+ stdout_fp = six .StringIO ()
51
+ stderr_fp = six .StringIO ()
52
+ try :
53
+ with mock .patch .object (sys , 'stdout' , stdout_fp ):
54
+ with mock .patch .object (sys , 'stderr' , stderr_fp ):
55
+ yield
56
+ finally :
57
+ if not capture :
58
+ sys .stdout .write (stdout_fp .getvalue ())
59
+ sys .stderr .write (stderr_fp .getvalue ())
60
+
61
+ for name , regexp , fp in [('stdout' , stdout , stdout_fp ),
62
+ ('stderr' , stderr , stderr_fp )]:
63
+ value = fp .getvalue ()
64
+ if regexp is None :
65
+ if value :
66
+ raise AssertionError ('%s: Expected no output. Got: %r' %
67
+ (name , value ))
68
+ else :
69
+ if not re .search (regexp , value , re .DOTALL | re .MULTILINE ):
70
+ raise AssertionError ('%s: Expected %r to match %r' %
71
+ (name , value , regexp ))
45
72
46
73
@contextlib .contextmanager
47
- def assertRaisesFireExit (self , code , regexp = None ):
74
+ def assertRaisesFireExit (self , code , regexp = '.*' ):
48
75
"""Asserts that a FireExit error is raised in the context.
49
76
50
77
Allows tests to check that Fire's wrapper around SystemExit is raised
@@ -56,23 +83,15 @@ def assertRaisesFireExit(self, code, regexp=None):
56
83
Yields:
57
84
Yields to the wrapped context.
58
85
"""
59
- if regexp is None :
60
- regexp = '.*'
61
- with self .assertRaises (core .FireExit ):
62
- stdout = six .StringIO ()
63
- with mock .patch .object (sys , 'stdout' , stdout ):
86
+ with self .assertOutputMatches (stderr = regexp ):
87
+ with self .assertRaises (core .FireExit ):
64
88
try :
65
89
yield
66
90
except core .FireExit as exc :
67
91
if exc .code != code :
68
92
raise AssertionError ('Incorrect exit code: %r != %r' % (exc .code ,
69
93
code ))
70
94
self .assertIsInstance (exc .trace , trace .FireTrace )
71
- stdout .flush ()
72
- stdout .seek (0 )
73
- value = stdout .getvalue ()
74
- if not re .search (regexp , value , re .DOTALL | re .MULTILINE ):
75
- raise AssertionError ('Expected %r to match %r' % (value , regexp ))
76
95
raise
77
96
78
97
0 commit comments