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.
|
# 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()
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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())
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user