commit a8b48a4c14186f1192132fc0947761215d30da9d Author: Damian Johnson atagar@torproject.org Date: Sun May 4 14:32:48 2014 -0700
Unit tests for help module --- stem/interpretor/help.py | 12 ++++-- test/settings.cfg | 1 + test/unit/interpretor/__init__.py | 1 + test/unit/interpretor/help.py | 80 +++++++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 4 deletions(-)
diff --git a/stem/interpretor/help.py b/stem/interpretor/help.py index 7f8b878..20439d6 100644 --- a/stem/interpretor/help.py +++ b/stem/interpretor/help.py @@ -31,6 +31,10 @@ def response(controller, arg):
# Normalizing inputs first so we can better cache responses.
+ return _response(controller, _normalize(arg)) + + +def _normalize(arg): arg = arg.upper()
# If there's multiple arguments then just take the first. This is @@ -44,7 +48,7 @@ def response(controller, arg): if arg.startswith('/'): arg = arg[1:]
- return _response(controller, arg) + return arg
@lru_cache() @@ -86,10 +90,10 @@ def _response(controller, arg, config): for i in range(0, len(options), 2): line = ''
- for entry in options[i:i + 1]: + for entry in options[i:i + 2]: line += '%-42s' % entry
- output += format(line + '\n', *STANDARD_OUTPUT) + output += format(line.rstrip() + '\n', *STANDARD_OUTPUT) elif arg == 'SIGNAL': signal_options = config.get('help.signal.options', {})
@@ -110,7 +114,7 @@ def _response(controller, arg, config): for entry in entries[i:i + 4]: line += '%-20s' % entry
- output += format(line + '\n', *STANDARD_OUTPUT) + output += format(line.rstrip() + '\n', *STANDARD_OUTPUT) elif arg == 'USEFEATURE': results = controller.get_info('features/names', None)
diff --git a/test/settings.cfg b/test/settings.cfg index cf05541..9ecbcfc 100644 --- a/test/settings.cfg +++ b/test/settings.cfg @@ -185,6 +185,7 @@ test.unit_tests |test.unit.control.controller.TestControl |test.unit.interpretor.arguments.TestArgumentParsing |test.unit.interpretor.autocomplete.TestAutocompletion +|test.unit.interpretor.help.TestHelpResponses |test.unit.doctest.TestDocumentation
test.integ_tests diff --git a/test/unit/interpretor/__init__.py b/test/unit/interpretor/__init__.py index 62db05a..c49e07f 100644 --- a/test/unit/interpretor/__init__.py +++ b/test/unit/interpretor/__init__.py @@ -5,4 +5,5 @@ Unit tests for the stem's interpretor prompt. __all__ = [ "arguments", "autocomplete", + "help", ] diff --git a/test/unit/interpretor/help.py b/test/unit/interpretor/help.py new file mode 100644 index 0000000..51123e0 --- /dev/null +++ b/test/unit/interpretor/help.py @@ -0,0 +1,80 @@ +import unittest + +from stem.interpretor.help import response, _normalize + +try: + # added in python 3.3 + from unittest.mock import Mock +except ImportError: + from mock import Mock + +GETINFO_NAMES = """ +info/names -- List of GETINFO options, types, and documentation. +ip-to-country/* -- Perform a GEOIP lookup +md/id/* -- Microdescriptors by ID +""".strip() + +GETCONF_NAMES = """ +ExitNodes RouterList +ExitPolicy LineList +ExitPolicyRejectPrivate Boolean +""".strip() + + +CONTROLLER = Mock() + +CONTROLLER.get_info.side_effect = lambda arg, _: { + 'info/names': GETINFO_NAMES, + 'config/names': GETCONF_NAMES, + 'events/names': 'BW DEBUG INFO NOTICE', + 'features/names': 'VERBOSE_NAMES EXTENDED_EVENTS', +}[arg] + + +class TestHelpResponses(unittest.TestCase): + def test_normalization(self): + self.assertEqual('', _normalize('')) + self.assertEqual('', _normalize(' ')) + + self.assertEqual('GETINFO', _normalize('GETINFO')) + self.assertEqual('GETINFO', _normalize('GetInfo')) + self.assertEqual('GETINFO', _normalize('getinfo')) + self.assertEqual('GETINFO', _normalize('GETINFO version')) + self.assertEqual('GETINFO', _normalize('GETINFO ')) + + self.assertEqual('INFO', _normalize('/info')) + self.assertEqual('INFO', _normalize('/info caerSidi')) + + def test_unrecognized_option(self): + result = response(CONTROLLER, 'FOOBAR') + self.assertEqual("\x1b[1;31mNo help information available for 'FOOBAR'...\x1b[0m", result) + + def test_general_help(self): + result = response(CONTROLLER, '') + self.assertTrue('Interpretor commands include:' in result) + self.assertTrue('\x1b[34;1m GETINFO\x1b[0m\x1b[34m - queries information from tor\x1b[0m\n' in result) + + def test_getinfo_help(self): + result = response(CONTROLLER, 'GETINFO') + self.assertTrue('Queries the tor process for information. Options are...' in result) + self.assertTrue('\x1b[34;1minfo/names \x1b[0m\x1b[34m - List of GETINFO options, types, and documentation.\n' in result) + + def test_getconf_help(self): + result = response(CONTROLLER, 'GETCONF') + self.assertTrue('Provides the current value for a given configuration value. Options include...' in result) + self.assertTrue('\x1b[34mExitNodes ExitPolicy\n' in result) + + def test_signal_help(self): + result = response(CONTROLLER, 'SIGNAL') + self.assertTrue('Issues a signal that tells the tor process to' in result) + self.assertTrue('\x1b[34;1mRELOAD / HUP \x1b[0m\x1b[34m - reload our torrc\n' in result) + + def test_setevents_help(self): + result = response(CONTROLLER, 'SETEVENTS') + self.assertTrue('Sets the events that we will receive.' in result) + self.assertTrue('\x1b[34mBW DEBUG INFO NOTICE\n\x1b[0m' in result) + + def test_usefeature_help(self): + result = response(CONTROLLER, 'USEFEATURE') + self.assertTrue('Customizes the behavior of the control port.' in result) + self.assertTrue('\x1b[34mVERBOSE_NAMES EXTENDED_EVENTS\n\x1b[0m' in result)
tor-commits@lists.torproject.org