Add help to shell (#2)

This commit is contained in:
ChristopherMSpencer
2016-07-06 09:18:58 -07:00
committed by Ian Cordasco
parent 2046c486e7
commit c123f0e35d
4 changed files with 114 additions and 3 deletions

View File

@@ -11,10 +11,55 @@
# under the License. # under the License.
"""Main shell for parsing arguments directed toward Craton.""" """Main shell for parsing arguments directed toward Craton."""
from __future__ import print_function
import argparse
import six
import sys
from oslo_utils import encodeutils
class CratonShell(object):
"""Class used to handle shell definition and parsing."""
def get_base_parser(self):
"""Configure base craton arguments and parsing."""
parser = argparse.ArgumentParser(
prog='craton',
description=__doc__.strip(),
epilog='See "craton help COMMAND" '
'for help on a specific command.',
add_help=False,
formatter_class=argparse.HelpFormatter
)
parser.add_argument('-h', '--help',
action='store_true',
help=argparse.SUPPRESS)
return parser
def main(self, argv):
"""Main entry-point for cratonclient shell argument parsing."""
parser = self.get_base_parser()
(options, args) = parser.parse_known_args(argv)
if options.help or not argv:
parser.print_help()
return 0
def main(): def main():
"""Main entry-point for cratonclient's CLI.""" """Main entry-point for cratonclient's CLI."""
try:
CratonShell().main(map(encodeutils.safe_decode, sys.argv[1:]))
except Exception as e:
print("ERROR: %s" % encodeutils.safe_encode(six.text_type(e)),
file=sys.stderr)
sys.exit(1)
return 0 return 0
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@@ -12,4 +12,5 @@
"""Command-line interface to the OpenStack Craton API V1.""" """Command-line interface to the OpenStack Craton API V1."""
# TODO(cmspence): from cratonclient.v1 import client # TODO(cmspence): from cratonclient.v1 import client

View File

@@ -16,8 +16,31 @@
# under the License. # under the License.
"""Base TestCase for all cratonclient tests.""" """Base TestCase for all cratonclient tests."""
import mock
import six
import sys
from oslotest import base from oslotest import base
from cratonclient.shell import main
class TestCase(base.BaseTestCase): class TestCase(base.BaseTestCase):
"""Test case base class for all unit tests.""" """Test case base class for all unit tests."""
class ShellTestCase(base.BaseTestCase):
"""Test case base class for all shell unit tests."""
def shell(self, arg_str, exitcodes=(0,)):
"""Main function for exercising the craton shell."""
with mock.patch('sys.stdout', new=six.StringIO()) as mock_stdout, \
mock.patch('sys.stderr', new=six.StringIO()) as mock_stderr:
try:
main_shell = main.CratonShell()
main_shell.main(arg_str.split())
except SystemExit:
exc_type, exc_value, exc_traceback = sys.exc_info()
self.assertIn(exc_value.code, exitcodes)
return (mock_stdout.getvalue(), mock_stderr.getvalue())

View File

@@ -12,13 +12,55 @@
"""Tests for `cratonclient.shell.main` module.""" """Tests for `cratonclient.shell.main` module."""
import mock
import re
from testtools import matchers
from cratonclient.shell import main from cratonclient.shell import main
from cratonclient.tests import base from cratonclient.tests import base
class TestMainShell(base.TestCase): class TestMainShell(base.ShellTestCase):
"""Test our craton main shell.""" """Test our craton main shell."""
def test_main_returns_successfully(self): re_options = re.DOTALL | re.MULTILINE
"""Verify that cratonclient shell main returns as expected."""
@mock.patch('cratonclient.shell.main.CratonShell.main')
def test_main_returns_successfully(self, cratonShellMainMock):
"""Verify that main returns as expected."""
cratonShellMainMock.return_value = 0
self.assertEqual(main.main(), 0) self.assertEqual(main.main(), 0)
def test_print_help_no_args(self):
"""Verify that no arguments prints out help by default."""
required_help_responses = [
'.*?^usage: craton',
'.*?^See "craton help COMMAND" '
'for help on a specific command.',
]
stdout, stderr = self.shell('')
for r in required_help_responses:
self.assertThat((stdout + stderr),
matchers.MatchesRegex(r, self.re_options))
def test_print_help_with_args(self):
"""Verify that help command(s) prints out help text correctly."""
required_help_responses = [
'.*?^usage: craton',
'.*?^See "craton help COMMAND" '
'for help on a specific command.',
]
for help_args in ['-h', '--help']:
stdout, stderr = self.shell(help_args)
for r in required_help_responses:
self.assertThat((stdout + stderr),
matchers.MatchesRegex(r, self.re_options))
@mock.patch('cratonclient.shell.main.CratonShell.main')
def test_main_catches_exception(self, cratonShellMainMock):
"""Verify exceptions will be caught and shell will exit properly."""
cratonShellMainMock.side_effect = Exception(mock.Mock(status=404),
'some error')
self.assertRaises(SystemExit, main.main)