Fix help() rpc to display new lines properly in snippet shell. (#546)
diff --git a/mobly/controllers/android_device_lib/snippet_client.py b/mobly/controllers/android_device_lib/snippet_client.py
index a8bffe8..c33f373 100644
--- a/mobly/controllers/android_device_lib/snippet_client.py
+++ b/mobly/controllers/android_device_lib/snippet_client.py
@@ -13,6 +13,8 @@
# limitations under the License.
"""JSON RPC interface to Mobly Snippet Lib."""
+from __future__ import print_function
+
import re
import time
@@ -178,8 +180,7 @@
# Yaaay! We're done!
self.log.debug('Snippet %s started after %.1fs on host port %s',
- self.package,
- time.time() - start_time, self.host_port)
+ self.package, time.time() - start_time, self.host_port)
def restore_app_connection(self, port=None):
"""Restores the app after device got reconnected.
@@ -336,3 +337,23 @@
'at the same time performs USB disconnection may fail',
_SETSID_COMMAND, _NOHUP_COMMAND)
return ''
+
+ def help(self, print_output=True):
+ """Calls the help RPC, which returns the list of RPC calls available.
+
+ This RPC should normally be used in an interactive console environment
+ where the output should be printed instead of returned. Otherwise,
+ newlines will be escaped, which will make the output difficult to read.
+
+ Args:
+ print_output: A bool for whether the output should be printed.
+
+ Returns:
+ A str containing the help output otherwise None if print_output
+ wasn't set.
+ """
+ help_text = self._rpc('help')
+ if print_output:
+ print(help_text)
+ else:
+ return help_text
diff --git a/tests/mobly/controllers/android_device_lib/snippet_client_test.py b/tests/mobly/controllers/android_device_lib/snippet_client_test.py
index b0f28c7..5968411 100755
--- a/tests/mobly/controllers/android_device_lib/snippet_client_test.py
+++ b/tests/mobly/controllers/android_device_lib/snippet_client_test.py
@@ -16,6 +16,7 @@
from builtins import bytes
import mock
+import sys
from future.tests.base import unittest
from mobly.controllers.android_device_lib import adb
@@ -28,6 +29,18 @@
JSONRPC_BASE_CLASS = 'mobly.controllers.android_device_lib.jsonrpc_client_base.JsonRpcClientBase'
+def get_print_function_name():
+ """Gets the name of the print function for mocking.
+
+ Returns:
+ A str representing the print function to mock.
+ """
+ if sys.version_info >= (3, 0):
+ return 'builtins.print'
+ else:
+ return '__builtin__.print'
+
+
class MockAdbProxy(object):
def __init__(self, **kwargs):
self.apk_not_installed = kwargs.get('apk_not_installed', False)
@@ -449,6 +462,28 @@
'Unexpected EOF waiting for app to start'):
client.start_app_and_connect()
+ @mock.patch(get_print_function_name())
+ def test_help_rpc_when_printing_by_default(self, mock_print):
+ client = self._make_client()
+ mock_rpc = mock.MagicMock()
+ client._rpc = mock_rpc
+
+ result = client.help()
+ mock_rpc.assert_called_once_with('help')
+ self.assertEqual(None, result)
+ mock_print.assert_called_once_with(mock_rpc.return_value)
+
+ @mock.patch(get_print_function_name())
+ def test_help_rpc_when_not_printing(self, mock_print):
+ client = self._make_client()
+ mock_rpc = mock.MagicMock()
+ client._rpc = mock_rpc
+
+ result = client.help(print_output=False)
+ mock_rpc.assert_called_once_with('help')
+ self.assertEqual(mock_rpc.return_value, result)
+ mock_print.assert_not_called()
+
def _make_client(self, adb_proxy=None):
adb_proxy = adb_proxy or MockAdbProxy()
ad = mock.Mock()