mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Add tests for the help command & --help options
Move the parser setup from bootstrap_with_global_options to bootstrap, so all API objects have access to it. Add some CLI tests for the help system. Part of the effort for https://fedorahosted.org/freeipa/ticket/3060
This commit is contained in:
parent
abe26d55c8
commit
614082e6a6
@ -456,7 +456,7 @@ class API(DictProxy):
|
||||
def isdone(self, name):
|
||||
return name in self.__done
|
||||
|
||||
def bootstrap(self, **overrides):
|
||||
def bootstrap(self, parser=None, **overrides):
|
||||
"""
|
||||
Initialize environment variables and logging.
|
||||
"""
|
||||
@ -516,6 +516,10 @@ class API(DictProxy):
|
||||
log.error('Cannot open log file %r: %s', self.env.log, e)
|
||||
return
|
||||
|
||||
if not parser:
|
||||
parser = self.build_global_parser()
|
||||
object.__setattr__(self, 'parser', parser)
|
||||
|
||||
def build_global_parser(self, parser=None, context=None):
|
||||
"""
|
||||
Add global options to an optparse.OptionParser instance.
|
||||
@ -592,8 +596,7 @@ class API(DictProxy):
|
||||
overrides['webui_prod'] = options.prod
|
||||
if context is not None:
|
||||
overrides['context'] = context
|
||||
self.bootstrap(**overrides)
|
||||
object.__setattr__(self, 'parser', parser)
|
||||
self.bootstrap(parser, **overrides)
|
||||
return (options, args)
|
||||
|
||||
def load_plugins(self):
|
||||
|
130
tests/test_cmdline/test_help.py
Normal file
130
tests/test_cmdline/test_help.py
Normal file
@ -0,0 +1,130 @@
|
||||
# Authors: Petr Viktorin <pviktori@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2012 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
import sys
|
||||
import contextlib
|
||||
import StringIO
|
||||
|
||||
from nose.tools import assert_raises # pylint: disable=E0611
|
||||
|
||||
from ipalib import api, errors
|
||||
from ipalib.plugins.user import user_add
|
||||
|
||||
|
||||
class CLITestContext(object):
|
||||
"""Context manager that replaces stdout & stderr, and catches SystemExit
|
||||
|
||||
Whatever was printed to the streams is available in ``stdout`` and
|
||||
``stderr`` attrributes once the with statement finishes.
|
||||
|
||||
When exception is given, asserts that exception is raised. The exception
|
||||
will be available in the ``exception`` attribute.
|
||||
"""
|
||||
def __init__(self, exception=None):
|
||||
self.exception = exception
|
||||
|
||||
def __enter__(self):
|
||||
self.old_streams = sys.stdout, sys.stderr
|
||||
self.stdout_fileobj = sys.stdout = StringIO.StringIO()
|
||||
self.stderr_fileobj = sys.stderr = StringIO.StringIO()
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
sys.stdout, sys.stderr = self.old_streams
|
||||
self.stdout = self.stdout_fileobj.getvalue()
|
||||
self.stderr = self.stderr_fileobj.getvalue()
|
||||
self.stdout_fileobj.close()
|
||||
self.stderr_fileobj.close()
|
||||
if self.exception:
|
||||
assert isinstance(exc_value, self.exception), exc_value
|
||||
self.exception = exc_value
|
||||
return True
|
||||
|
||||
|
||||
def test_ipa_help():
|
||||
"""Test that `ipa help` only writes to stdout"""
|
||||
with CLITestContext() as ctx:
|
||||
return_value = api.Backend.cli.run(['help'])
|
||||
assert return_value == 0
|
||||
assert ctx.stderr == ''
|
||||
|
||||
|
||||
def test_ipa_without_arguments():
|
||||
"""Test that `ipa` errors out, and prints the help to stderr"""
|
||||
with CLITestContext(exception=SystemExit) as ctx:
|
||||
api.Backend.cli.run([])
|
||||
assert ctx.exception.code == 2
|
||||
assert ctx.stdout == ''
|
||||
assert 'Error: Command not specified' in ctx.stderr
|
||||
|
||||
with CLITestContext() as help_ctx:
|
||||
api.Backend.cli.run(['help'])
|
||||
assert help_ctx.stdout in ctx.stderr
|
||||
|
||||
|
||||
def test_bare_topic():
|
||||
"""Test that `ipa user` errors out, and prints the help to stderr
|
||||
|
||||
This is because `user` is a topic, not a command, so `ipa user` doesn't
|
||||
match our usage string. The help should be accessed using `ipa help user`.
|
||||
"""
|
||||
with CLITestContext(exception=errors.CommandError) as ctx:
|
||||
api.Backend.cli.run(['user'])
|
||||
assert ctx.exception.name == 'user'
|
||||
assert ctx.stdout == ''
|
||||
|
||||
with CLITestContext() as help_ctx:
|
||||
return_value = api.Backend.cli.run(['help', 'user'])
|
||||
assert return_value == 0
|
||||
assert help_ctx.stdout in ctx.stderr
|
||||
|
||||
|
||||
def test_command_help():
|
||||
"""Test that `help user-add` & `user-add -h` are equivalent and contain doc
|
||||
"""
|
||||
with CLITestContext() as help_ctx:
|
||||
return_value = api.Backend.cli.run(['help', 'user-add'])
|
||||
assert return_value == 0
|
||||
assert help_ctx.stderr == ''
|
||||
|
||||
with CLITestContext(exception=SystemExit) as h_ctx:
|
||||
api.Backend.cli.run(['user-add', '-h'])
|
||||
assert h_ctx.exception.code == 0
|
||||
assert h_ctx.stderr == ''
|
||||
|
||||
assert h_ctx.stdout == help_ctx.stdout
|
||||
assert unicode(user_add.__doc__) in help_ctx.stdout
|
||||
|
||||
|
||||
def test_ambiguous_command_or_topic():
|
||||
"""Test that `help ping` & `ping -h` are NOT equivalent
|
||||
|
||||
One is a topic, the other is a command
|
||||
"""
|
||||
with CLITestContext() as help_ctx:
|
||||
return_value = api.Backend.cli.run(['help', 'ping'])
|
||||
assert return_value == 0
|
||||
assert help_ctx.stderr == ''
|
||||
|
||||
with CLITestContext(exception=SystemExit) as h_ctx:
|
||||
api.Backend.cli.run(['ping', '-h'])
|
||||
assert h_ctx.exception.code == 0
|
||||
assert h_ctx.stderr == ''
|
||||
|
||||
assert h_ctx.stdout != help_ctx.stdout
|
Loading…
Reference in New Issue
Block a user