7061: Add User.progress context manager
reapply from trunk svn: r23094
This commit is contained in:
@@ -32,9 +32,9 @@ import sys
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
if sys.version_info < (3,3):
|
if sys.version_info < (3,3):
|
||||||
from mock import Mock, NonCallableMock
|
from mock import Mock, patch
|
||||||
else:
|
else:
|
||||||
from unittest.mock import Mock, NonCallableMock
|
from unittest.mock import Mock, patch
|
||||||
|
|
||||||
MOCKING = True
|
MOCKING = True
|
||||||
|
|
||||||
@@ -151,5 +151,40 @@ class TestUser_quiet(unittest.TestCase):
|
|||||||
assert len(self.user._fileout.method_calls
|
assert len(self.user._fileout.method_calls
|
||||||
) == 0, list(self.user._fileout.method_calls)
|
) == 0, list(self.user._fileout.method_calls)
|
||||||
|
|
||||||
|
@unittest.skipUnless(MOCKING, "Requires unittest.mock to run")
|
||||||
|
class TestUser_progress(unittest.TestCase):
|
||||||
|
_progress_begin_step_end = \
|
||||||
|
TestUser_quiet.test_progress_can_begin_step_end.__func__
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.user = user.User()
|
||||||
|
self.user._fileout = Mock(spec=sys.stderr)
|
||||||
|
|
||||||
|
def test_can_step_using_with(self):
|
||||||
|
# Collect baseline output from the old-style interface (begin/step/end)
|
||||||
|
self._progress_begin_step_end()
|
||||||
|
self.expected_output = list(self.user._fileout.method_calls)
|
||||||
|
self.user._fileout.reset_mock()
|
||||||
|
self.assertTrue(
|
||||||
|
len(self.user._fileout.method_calls) == 0,
|
||||||
|
list(self.user._fileout.method_calls))
|
||||||
|
|
||||||
|
with self.user.progress("Foo", "Bar", 0) as step:
|
||||||
|
for i in range(10):
|
||||||
|
step()
|
||||||
|
|
||||||
|
# Output using `with' differs from one with `progress_...'
|
||||||
|
self.assertEqual(self.expected_output,
|
||||||
|
list(self.user._fileout.method_calls))
|
||||||
|
|
||||||
|
def test_ends_progress_upon_exception_in_with(self):
|
||||||
|
with patch('gramps.cli.user.User.end_progress') as MockEP:
|
||||||
|
try:
|
||||||
|
with self.user.progress("Foo", "Bar", 0) as step:
|
||||||
|
raise Exception()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
self.assertTrue(MockEP.called)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
@@ -21,6 +21,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
from contextlib import contextmanager
|
||||||
|
|
||||||
"""
|
"""
|
||||||
The User class provides basic interaction with the user.
|
The User class provides basic interaction with the user.
|
||||||
@@ -41,6 +42,8 @@ class User():
|
|||||||
"""
|
"""
|
||||||
Start showing a progress indicator to the user.
|
Start showing a progress indicator to the user.
|
||||||
|
|
||||||
|
Don't use this method directly, use progress instead.
|
||||||
|
|
||||||
@param title: the title of the progress meter
|
@param title: the title of the progress meter
|
||||||
@type title: str
|
@type title: str
|
||||||
@param message: the message associated with the progress meter
|
@param message: the message associated with the progress meter
|
||||||
@@ -56,6 +59,8 @@ class User():
|
|||||||
def step_progress(self):
|
def step_progress(self):
|
||||||
"""
|
"""
|
||||||
Advance the progress meter.
|
Advance the progress meter.
|
||||||
|
|
||||||
|
Don't use this method directly, use progress instead.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -80,9 +85,34 @@ class User():
|
|||||||
def end_progress(self):
|
def end_progress(self):
|
||||||
"""
|
"""
|
||||||
Stop showing the progress indicator to the user.
|
Stop showing the progress indicator to the user.
|
||||||
|
|
||||||
|
Don't use this method directly, use progress instead.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# Context-manager wrapper of the begin/step/end_progress above
|
||||||
|
@contextmanager
|
||||||
|
def progress(self, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Preferred form of context reporting.
|
||||||
|
|
||||||
|
Parameters: same as for begin_progress.
|
||||||
|
|
||||||
|
Usage example (see gramps/cli/test/user_test.py):
|
||||||
|
with self.user.progress("Foo", "Bar", 0) as step:
|
||||||
|
for i in range(10):
|
||||||
|
step()
|
||||||
|
|
||||||
|
Ensures end_progress will be called even if an exception was thrown.
|
||||||
|
"""
|
||||||
|
self.begin_progress(*args, **kwargs)
|
||||||
|
try:
|
||||||
|
yield self.step_progress
|
||||||
|
except:
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
self.end_progress()
|
||||||
|
|
||||||
def prompt(self, title, message, accept_label, reject_label):
|
def prompt(self, title, message, accept_label, reject_label):
|
||||||
"""
|
"""
|
||||||
Prompt the user with a message to select an alternative.
|
Prompt the user with a message to select an alternative.
|
||||||
|
Reference in New Issue
Block a user