Add help to shell (#2)
This commit is contained in:
committed by
Ian Cordasco
parent
2046c486e7
commit
c123f0e35d
@@ -11,10 +11,55 @@
|
||||
# under the License.
|
||||
"""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():
|
||||
"""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
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -12,4 +12,5 @@
|
||||
|
||||
"""Command-line interface to the OpenStack Craton API V1."""
|
||||
|
||||
|
||||
# TODO(cmspence): from cratonclient.v1 import client
|
||||
|
||||
@@ -16,8 +16,31 @@
|
||||
# under the License.
|
||||
"""Base TestCase for all cratonclient tests."""
|
||||
|
||||
import mock
|
||||
import six
|
||||
import sys
|
||||
|
||||
from oslotest import base
|
||||
|
||||
from cratonclient.shell import main
|
||||
|
||||
|
||||
class TestCase(base.BaseTestCase):
|
||||
"""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())
|
||||
|
||||
@@ -12,13 +12,55 @@
|
||||
|
||||
"""Tests for `cratonclient.shell.main` module."""
|
||||
|
||||
|
||||
import mock
|
||||
import re
|
||||
|
||||
from testtools import matchers
|
||||
|
||||
from cratonclient.shell import main
|
||||
from cratonclient.tests import base
|
||||
|
||||
|
||||
class TestMainShell(base.TestCase):
|
||||
class TestMainShell(base.ShellTestCase):
|
||||
"""Test our craton main shell."""
|
||||
|
||||
def test_main_returns_successfully(self):
|
||||
"""Verify that cratonclient shell main returns as expected."""
|
||||
re_options = re.DOTALL | re.MULTILINE
|
||||
|
||||
@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)
|
||||
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user