covert test suite to use testrepository

Drop the use of nose in favor of testrepository. Set up the gitignore
rules for the output files.

Add coverage reporting to test jobs.

Update tox.ini so the default environments make sense so it is possible
to just run "tox" for local development.

Change-Id: Ieeffdde3bb8a1869af01f5be2bc682a1a834ba13
Signed-off-by: Doug Hellmann <doug@doughellmann.com>
This commit is contained in:
Doug Hellmann 2017-04-23 10:16:30 -04:00
parent d2f23f3aaf
commit c548b7b44c
22 changed files with 2016 additions and 1886 deletions

3
.gitignore vendored
View File

@ -38,3 +38,6 @@ ChangeLog
# Editors
*~
.*.swp
/.testrepository/
/cover/
.coverage.*

7
.testr.conf Normal file
View File

@ -0,0 +1,7 @@
[DEFAULT]
test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \
OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \
OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-60} \
${PYTHON:-python} -m subunit.run discover -t ./ ./cliff $LISTOPT $IDOPTION
test_id_option=--load-list $IDFILE
test_list_option=--list

29
cliff/tests/base.py Normal file
View File

@ -0,0 +1,29 @@
# -*- encoding: utf-8 -*-
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import testtools
import fixtures
class TestBase(testtools.TestCase):
def setUp(self):
super(TestBase, self).setUp()
self._stdout_fixture = fixtures.StringStream('stdout')
self.stdout = self.useFixture(self._stdout_fixture).stream
self.useFixture(fixtures.MonkeyPatch('sys.stdout', self.stdout))
self._stderr_fixture = fixtures.StringStream('stderr')
self.stderr = self.useFixture(self._stderr_fixture).stream
self.useFixture(fixtures.MonkeyPatch('sys.stderr', self.stderr))

View File

@ -13,20 +13,21 @@
# under the License.
import argparse
import codecs
import locale
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
import sys
import codecs
import locale
import mock
import six
import sys
from cliff import app as application
from cliff import command as c_cmd
from cliff import commandmanager
from cliff.tests import base
from cliff.tests import utils as test_utils
from cliff import utils
@ -59,46 +60,49 @@ def make_app(**kwargs):
return app, command
def test_no_args_triggers_interactive_mode():
class TestInteractiveMode(base.TestBase):
def test_no_args_triggers_interactive_mode(self):
app, command = make_app()
app.interact = mock.MagicMock(name='inspect')
app.run([])
app.interact.assert_called_once_with()
def test_interactive_mode_cmdloop():
def test_interactive_mode_cmdloop(self):
app, command = make_app()
app.interactive_app_factory = mock.MagicMock(
name='interactive_app_factory'
)
assert app.interpreter is None
self.assertIs(None, app.interpreter)
app.run([])
assert app.interpreter is not None
app.interactive_app_factory.return_value.cmdloop.assert_called_once_with()
self.assertIsNot(None, app.interpreter)
cmdloop = app.interactive_app_factory.return_value.cmdloop
cmdloop.assert_called_once_with()
def test_initialize_app():
class TestInitAndCleanup(base.TestBase):
def test_initialize_app(self):
app, command = make_app()
app.initialize_app = mock.MagicMock(name='initialize_app')
app.run(['mock'])
app.initialize_app.assert_called_once_with(['mock'])
def test_prepare_to_run_command():
def test_prepare_to_run_command(self):
app, command = make_app()
app.prepare_to_run_command = mock.MagicMock(name='prepare_to_run_command')
app.prepare_to_run_command = mock.MagicMock(
name='prepare_to_run_command',
)
app.run(['mock'])
app.prepare_to_run_command.assert_called_once_with(command())
def test_clean_up_success():
def test_clean_up_success(self):
app, command = make_app()
app.clean_up = mock.MagicMock(name='clean_up')
app.run(['mock'])
app.clean_up.assert_called_once_with(command.return_value, 0, None)
def test_clean_up_error():
def test_clean_up_error(self):
app, command = make_app()
app.clean_up = mock.MagicMock(name='clean_up')
@ -106,32 +110,30 @@ def test_clean_up_error():
app.clean_up.assert_called_once_with(mock.ANY, mock.ANY, mock.ANY)
call_args = app.clean_up.call_args_list[0]
assert call_args == mock.call(mock.ANY, 1, mock.ANY)
self.assertEqual(mock.call(mock.ANY, 1, mock.ANY), call_args)
args, kwargs = call_args
assert isinstance(args[2], RuntimeError)
assert args[2].args == ('test exception',)
self.assertIsInstance(args[2], RuntimeError)
self.assertEqual(('test exception',), args[2].args)
def test_clean_up_error_debug():
def test_clean_up_error_debug(self):
app, command = make_app()
app.clean_up = mock.MagicMock(name='clean_up')
try:
app.run(['--debug', 'error'])
except RuntimeError as err:
assert app.clean_up.call_args_list[0][0][2] is err
self.assertIs(err, app.clean_up.call_args_list[0][0][2])
else:
assert False, 'Should have had an exception'
self.fail('Should have had an exception')
assert app.clean_up.called
self.assertTrue(app.clean_up.called)
call_args = app.clean_up.call_args_list[0]
assert call_args == mock.call(mock.ANY, 1, mock.ANY)
self.assertEqual(mock.call(mock.ANY, 1, mock.ANY), call_args)
args, kwargs = call_args
assert isinstance(args[2], RuntimeError)
assert args[2].args == ('test exception',)
self.assertIsInstance(args[2], RuntimeError)
self.assertEqual(('test exception',), args[2].args)
def test_error_handling_clean_up_raises_exception():
def test_error_handling_clean_up_raises_exception(self):
app, command = make_app()
app.clean_up = mock.MagicMock(
@ -140,15 +142,14 @@ def test_error_handling_clean_up_raises_exception():
)
app.run(['error'])
assert app.clean_up.called
self.assertTrue(app.clean_up.called)
call_args = app.clean_up.call_args_list[0]
assert call_args == mock.call(mock.ANY, 1, mock.ANY)
self.assertEqual(mock.call(mock.ANY, 1, mock.ANY), call_args)
args, kwargs = call_args
assert isinstance(args[2], RuntimeError)
assert args[2].args == ('test exception',)
self.assertIsInstance(args[2], RuntimeError)
self.assertEqual(('test exception',), args[2].args)
def test_error_handling_clean_up_raises_exception_debug():
def test_error_handling_clean_up_raises_exception_debug(self):
app, command = make_app()
app.clean_up = mock.MagicMock(
@ -163,19 +164,18 @@ def test_error_handling_clean_up_raises_exception_debug():
# caused *by* clean_up. This test is only valid in python
# 2 because under v3 the original exception is re-raised
# with the new one as a __context__ attribute.
assert app.clean_up.call_args_list[0][0][2] is not err
self.assertIsNot(err, app.clean_up.call_args_list[0][0][2])
else:
assert False, 'Should have had an exception'
self.fail('Should have had an exception')
assert app.clean_up.called
self.assertTrue(app.clean_up.called)
call_args = app.clean_up.call_args_list[0]
assert call_args == mock.call(mock.ANY, 1, mock.ANY)
self.assertEqual(mock.call(mock.ANY, 1, mock.ANY), call_args)
args, kwargs = call_args
assert isinstance(args[2], RuntimeError)
assert args[2].args == ('test exception',)
self.assertIsInstance(args[2], RuntimeError)
self.assertEqual(('test exception',), args[2].args)
def test_normal_clean_up_raises_exception():
def test_normal_clean_up_raises_exception(self):
app, command = make_app()
app.clean_up = mock.MagicMock(
@ -184,12 +184,11 @@ def test_normal_clean_up_raises_exception():
)
app.run(['mock'])
assert app.clean_up.called
self.assertTrue(app.clean_up.called)
call_args = app.clean_up.call_args_list[0]
assert call_args == mock.call(mock.ANY, 0, None)
self.assertEqual(mock.call(mock.ANY, 0, None), call_args)
def test_normal_clean_up_raises_exception_debug():
def test_normal_clean_up_raises_exception_debug(self):
app, command = make_app()
app.clean_up = mock.MagicMock(
@ -198,12 +197,14 @@ def test_normal_clean_up_raises_exception_debug():
)
app.run(['--debug', 'mock'])
assert app.clean_up.called
self.assertTrue(app.clean_up.called)
call_args = app.clean_up.call_args_list[0]
assert call_args == mock.call(mock.ANY, 0, None)
self.assertEqual(mock.call(mock.ANY, 0, None), call_args)
def test_build_option_parser_conflicting_option_should_throw():
class TestOptionParser(base.TestBase):
def test_conflicting_option_should_throw(self):
class MyApp(application.App):
def __init__(self):
super(MyApp, self).__init__(
@ -221,16 +222,12 @@ def test_build_option_parser_conflicting_option_should_throw():
help="Show help message and exit.",
)
# TODO: tests should really use unittest2.
try:
MyApp()
except argparse.ArgumentError:
pass
else:
raise Exception('Exception was not thrown')
self.assertRaises(
argparse.ArgumentError,
MyApp,
)
def test_option_parser_conflicting_option_custom_arguments_should_not_throw():
def test_conflicting_option_custom_arguments_should_not_throw(self):
class MyApp(application.App):
def __init__(self):
super(MyApp, self).__init__(
@ -253,8 +250,7 @@ def test_option_parser_conflicting_option_custom_arguments_should_not_throw():
MyApp()
def test_option_parser_abbrev_issue():
def test_option_parser_abbrev_issue(self):
class MyCommand(c_cmd.Command):
def get_parser(self, prog_name):
parser = super(MyCommand, self).get_parser(prog_name)
@ -285,45 +281,42 @@ def test_option_parser_abbrev_issue():
return parser
app = MyApp()
# NOTE(jd) --debug is necessary so assert in take_action() raises correctly
# here
# NOTE(jd) --debug is necessary so assert in take_action()
# raises correctly here
app.run(['--debug', 'mycommand', '--end', '123'])
def _test_help(deferred_help):
class TestHelpHandling(base.TestBase):
def _test_help(self, deferred_help):
app, _ = make_app(deferred_help=deferred_help)
with mock.patch.object(app, 'initialize_app') as init:
with mock.patch('cliff.help.HelpAction.__call__',
side_effect=SystemExit(0)) as helper:
try:
app.run(['--help'])
except SystemExit:
pass
else:
raise Exception('Exception was not thrown')
assert helper.called
assert init.called == deferred_help
self.assertRaises(
SystemExit,
app.run,
['--help'],
)
self.assertTrue(helper.called)
self.assertEqual(deferred_help, init.called)
def test_help(self):
self._test_help(False)
def test_help():
_test_help(False)
def test_deferred_help(self):
self._test_help(True)
def test_deferred_help():
_test_help(True)
def test_subcommand_help():
def test_subcommand_help(self):
app, _ = make_app(deferred_help=False)
# Help is called immediately
with mock.patch('cliff.help.HelpAction.__call__') as helper:
app.run(['show', 'files', '--help'])
assert helper.called
self.assertTrue(helper.called)
def test_subcommand_deferred_help():
def test_subcommand_deferred_help(self):
app, _ = make_app(deferred_help=True)
# Show that provide_help_if_requested() did not show help and exit
@ -333,20 +326,20 @@ def test_subcommand_deferred_help():
helper.assert_called_once_with(['help', 'show', 'files'])
def test_unknown_cmd():
class TestCommandLookup(base.TestBase):
def test_unknown_cmd(self):
app, command = make_app()
assert app.run(['hell']) == 2
self.assertEqual(2, app.run(['hell']))
def test_unknown_cmd_debug():
def test_unknown_cmd_debug(self):
app, command = make_app()
try:
app.run(['--debug', 'hell']) == 2
self.assertEqual(2, app.run(['--debug', 'hell']))
except ValueError as err:
assert "['hell']" in ('%s' % err)
self.assertIn("['hell']", str(err))
def test_list_matching_commands():
def test_list_matching_commands(self):
stdout = StringIO()
app = application.App('testing', '1',
test_utils.TestCommandManager(
@ -354,24 +347,23 @@ def test_list_matching_commands():
stdout=stdout)
app.NAME = 'test'
try:
assert app.run(['t']) == 2
self.assertEqual(2, app.run(['t']))
except SystemExit:
pass
output = stdout.getvalue()
assert "test: 't' is not a test command. See 'test --help'." in output
assert 'Did you mean one of these?' in output
assert 'three word command\n two words\n' in output
self.assertIn("test: 't' is not a test command. See 'test --help'.",
output)
self.assertIn('Did you mean one of these?', output)
self.assertIn('three word command\n two words\n', output)
def test_fuzzy_no_commands():
def test_fuzzy_no_commands(self):
cmd_mgr = commandmanager.CommandManager('cliff.fuzzy')
app = application.App('test', '1.0', cmd_mgr)
cmd_mgr.commands = {}
matches = app.get_fuzzy_matches('foo')
assert matches == []
self.assertEqual([], matches)
def test_fuzzy_common_prefix():
def test_fuzzy_common_prefix(self):
# searched string is a prefix of all commands
cmd_mgr = commandmanager.CommandManager('cliff.fuzzy')
app = application.App('test', '1.0', cmd_mgr)
@ -379,30 +371,33 @@ def test_fuzzy_common_prefix():
cmd_mgr.add_command('user list', test_utils.TestCommand)
cmd_mgr.add_command('user show', test_utils.TestCommand)
matches = app.get_fuzzy_matches('user')
assert matches == ['user list', 'user show']
self.assertEqual(['user list', 'user show'], matches)
def test_fuzzy_same_distance():
def test_fuzzy_same_distance(self):
# searched string has the same distance to all commands
cmd_mgr = commandmanager.CommandManager('cliff.fuzzy')
app = application.App('test', '1.0', cmd_mgr)
cmd_mgr.add_command('user', test_utils.TestCommand)
for cmd in cmd_mgr.commands.keys():
assert utils.damerau_levenshtein('node', cmd, utils.COST) == 8
self.assertEqual(
8,
utils.damerau_levenshtein('node', cmd, utils.COST),
)
matches = app.get_fuzzy_matches('node')
assert matches == ['complete', 'help', 'user']
self.assertEqual(['complete', 'help', 'user'], matches)
def test_fuzzy_no_prefix():
def test_fuzzy_no_prefix(self):
# search by distance, no common prefix with any command
cmd_mgr = commandmanager.CommandManager('cliff.fuzzy')
app = application.App('test', '1.0', cmd_mgr)
cmd_mgr.add_command('user', test_utils.TestCommand)
matches = app.get_fuzzy_matches('uesr')
assert matches == ['user']
self.assertEqual(['user'], matches)
def test_verbose():
class TestVerboseMode(base.TestBase):
def test_verbose(self):
app, command = make_app()
app.clean_up = mock.MagicMock(name='clean_up')
app.run(['--verbose', 'mock'])
@ -410,15 +405,16 @@ def test_verbose():
app.clean_up.reset_mock()
app.run(['--quiet', 'mock'])
app.clean_up.assert_called_once_with(command.return_value, 0, None)
try:
app.run(['--verbose', '--quiet', 'mock'])
except SystemExit:
pass
else:
raise Exception('Exception was not thrown')
self.assertRaises(
SystemExit,
app.run,
['--verbose', '--quiet', 'mock'],
)
def test_io_streams():
class TestIO(base.TestBase):
def test_io_streams(self):
cmd_mgr = commandmanager.CommandManager('cliff.tests')
io = mock.Mock()
@ -429,70 +425,76 @@ def test_io_streams():
encoding = locale.getpreferredencoding() or 'utf-8'
app = application.App('no io streams', 1, cmd_mgr)
assert isinstance(app.stdin, codecs.StreamReader)
assert isinstance(app.stdout, codecs.StreamWriter)
assert isinstance(app.stderr, codecs.StreamWriter)
self.assertIsInstance(app.stdin, codecs.StreamReader)
self.assertIsInstance(app.stdout, codecs.StreamWriter)
self.assertIsInstance(app.stderr, codecs.StreamWriter)
app = application.App('with stdin io stream', 1, cmd_mgr, stdin=io)
assert app.stdin is io
assert isinstance(app.stdout, codecs.StreamWriter)
assert isinstance(app.stderr, codecs.StreamWriter)
self.assertIs(io, app.stdin)
self.assertIsInstance(app.stdout, codecs.StreamWriter)
self.assertIsInstance(app.stderr, codecs.StreamWriter)
app = application.App('with stdout io stream', 1, cmd_mgr, stdout=io)
assert isinstance(app.stdin, codecs.StreamReader)
assert app.stdout is io
assert isinstance(app.stderr, codecs.StreamWriter)
app = application.App('with stdout io stream', 1, cmd_mgr,
stdout=io)
self.assertIsInstance(app.stdin, codecs.StreamReader)
self.assertIs(io, app.stdout)
self.assertIsInstance(app.stderr, codecs.StreamWriter)
app = application.App('with stderr io stream', 1, cmd_mgr, stderr=io)
assert isinstance(app.stdin, codecs.StreamReader)
assert isinstance(app.stdout, codecs.StreamWriter)
assert app.stderr is io
app = application.App('with stderr io stream', 1, cmd_mgr,
stderr=io)
self.assertIsInstance(app.stdin, codecs.StreamReader)
self.assertIsInstance(app.stdout, codecs.StreamWriter)
self.assertIs(io, app.stderr)
try:
sys.stdin = codecs.getreader(encoding)(sys.stdin)
app = application.App(
'with wrapped sys.stdin io stream', 1, cmd_mgr)
assert app.stdin is sys.stdin
assert isinstance(app.stdout, codecs.StreamWriter)
assert isinstance(app.stderr, codecs.StreamWriter)
self.assertIs(sys.stdin, app.stdin)
self.assertIsInstance(app.stdout, codecs.StreamWriter)
self.assertIsInstance(app.stderr, codecs.StreamWriter)
finally:
sys.stdin = stdin_save
try:
sys.stdout = codecs.getwriter(encoding)(sys.stdout)
app = application.App('with wrapped stdout io stream', 1, cmd_mgr)
assert isinstance(app.stdin, codecs.StreamReader)
assert app.stdout is sys.stdout
assert isinstance(app.stderr, codecs.StreamWriter)
app = application.App('with wrapped stdout io stream', 1,
cmd_mgr)
self.assertIsInstance(app.stdin, codecs.StreamReader)
self.assertIs(sys.stdout, app.stdout)
self.assertIsInstance(app.stderr, codecs.StreamWriter)
finally:
sys.stdout = stdout_save
try:
sys.stderr = codecs.getwriter(encoding)(sys.stderr)
app = application.App('with wrapped stderr io stream', 1, cmd_mgr)
assert isinstance(app.stdin, codecs.StreamReader)
assert isinstance(app.stdout, codecs.StreamWriter)
assert app.stderr is sys.stderr
app = application.App('with wrapped stderr io stream', 1,
cmd_mgr)
self.assertIsInstance(app.stdin, codecs.StreamReader)
self.assertIsInstance(app.stdout, codecs.StreamWriter)
self.assertIs(sys.stderr, app.stderr)
finally:
sys.stderr = stderr_save
else:
app = application.App('no io streams', 1, cmd_mgr)
assert app.stdin is sys.stdin
assert app.stdout is sys.stdout
assert app.stderr is sys.stderr
self.assertIs(sys.stdin, app.stdin)
self.assertIs(sys.stdout, app.stdout)
self.assertIs(sys.stderr, app.stderr)
app = application.App('with stdin io stream', 1, cmd_mgr, stdin=io)
assert app.stdin is io
assert app.stdout is sys.stdout
assert app.stderr is sys.stderr
self.assertIs(io, app.stdin)
self.assertIs(sys.stdout, app.stdout)
self.assertIs(sys.stderr, app.stderr)
app = application.App('with stdout io stream', 1, cmd_mgr, stdout=io)
assert app.stdin is sys.stdin
assert app.stdout is io
assert app.stderr is sys.stderr
app = application.App('with stdout io stream', 1, cmd_mgr,
stdout=io)
self.assertIs(sys.stdin, app.stdin)
self.assertIs(io, app.stdout)
self.assertIs(sys.stderr, app.stderr)
app = application.App('with stderr io stream', 1, cmd_mgr, stderr=io)
assert app.stdin is sys.stdin
assert app.stdout is sys.stdout
assert app.stderr is io
app = application.App('with stderr io stream', 1, cmd_mgr,
stderr=io)
self.assertIs(sys.stdin, app.stdin)
self.assertIs(sys.stdout, app.stdout)
self.assertIs(io, app.stderr)

View File

@ -10,6 +10,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import unittest
from cliff import columns
@ -19,12 +21,15 @@ class FauxColumn(columns.FormattableColumn):
return u'I made this string myself: {}'.format(self._value)
def test_faux_column_machine():
c = FauxColumn(['list', 'of', 'values'])
assert c.machine_readable() == ['list', 'of', 'values']
class TestColumns(unittest.TestCase):
def test_faux_column_human():
def test_faux_column_machine(self):
c = FauxColumn(['list', 'of', 'values'])
assert c.human_readable() == \
u"I made this string myself: ['list', 'of', 'values']"
self.assertEqual(['list', 'of', 'values'], c.machine_readable())
def test_faux_column_human(self):
c = FauxColumn(['list', 'of', 'values'])
self.assertEqual(
u"I made this string myself: ['list', 'of', 'values']",
c.human_readable(),
)

View File

@ -11,6 +11,7 @@
# under the License.
from cliff import command
from cliff.tests import base
class TestCommand(command.Command):
@ -51,13 +52,14 @@ class TestCommandNoDocstring(command.Command):
return 42
def test_get_description_docstring():
class TestDescription(base.TestBase):
def test_get_description_docstring(self):
cmd = TestCommand(None, None)
desc = cmd.get_description()
assert desc == "Description of command.\n "
def test_get_description_attribute():
def test_get_description_attribute(self):
cmd = TestCommand(None, None)
# Artificially inject a value for _description to verify that it
# overrides the docstring.
@ -65,33 +67,29 @@ def test_get_description_attribute():
desc = cmd.get_description()
assert desc == 'this is not the default'
def test_get_description_default():
def test_get_description_default(self):
cmd = TestCommandNoDocstring(None, None)
desc = cmd.get_description()
assert desc == ''
def test_get_parser():
class TestBasicValues(base.TestBase):
def test_get_parser(self):
cmd = TestCommand(None, None)
parser = cmd.get_parser('NAME')
assert parser.prog == 'NAME'
def test_get_name():
def test_get_name(self):
cmd = TestCommand(None, None, cmd_name='object action')
assert cmd.cmd_name == 'object action'
def test_run_return():
def test_run_return(self):
cmd = TestCommand(None, None, cmd_name='object action')
assert cmd.run(None) == 42
def test_smart_help_formatter():
cmd = TestCommand(None, None)
parser = cmd.get_parser('NAME')
expected_help_message = """
expected_help_message = """
long_help_argument Create a NIC on the server.
Specify option multiple times to create multiple NICs.
Either net-id or port-id must be provided, but not
@ -108,4 +106,11 @@ def test_smart_help_formatter():
regular_help_argument
The quick brown fox jumps over the lazy dog.
"""
assert expected_help_message in parser.format_help()
class TestHelp(base.TestBase):
def test_smart_help_formatter(self):
cmd = TestCommand(None, None)
parser = cmd.get_parser('NAME')
self.assertIn(expected_help_message, parser.format_help())

View File

@ -11,77 +11,88 @@
# under the License.
import mock
import testscenarios
from cliff import commandmanager
from cliff.tests import base
from cliff.tests import utils
def test_lookup_and_find():
def check(mgr, argv):
cmd, name, remaining = mgr.find_command(argv)
assert cmd
assert name == ' '.join(argv)
assert not remaining
load_tests = testscenarios.load_tests_apply_scenarios
class TestLookupAndFind(base.TestBase):
scenarios = [
('one-word', {'argv': ['one']}),
('two-words', {'argv': ['two', 'words']}),
('three-words', {'argv': ['three', 'word', 'command']}),
]
def test(self):
mgr = utils.TestCommandManager(utils.TEST_NAMESPACE)
for expected in [['one'],
['two', 'words'],
['three', 'word', 'command'],
]:
yield check, mgr, expected
return
cmd, name, remaining = mgr.find_command(self.argv)
self.assertTrue(cmd)
self.assertEqual(' '.join(self.argv), name)
self.assertFalse(remaining)
def test_lookup_with_remainder():
def check(mgr, argv):
cmd, name, remaining = mgr.find_command(argv)
assert cmd
assert remaining == ['--opt']
class TestLookupWithRemainder(base.TestBase):
scenarios = [
('one', {'argv': ['one', '--opt']}),
('two', {'argv': ['two', 'words', '--opt']}),
('three', {'argv': ['three', 'word', 'command', '--opt']}),
]
def test(self):
mgr = utils.TestCommandManager(utils.TEST_NAMESPACE)
for expected in [['one', '--opt'],
['two', 'words', '--opt'],
['three', 'word', 'command', '--opt'],
]:
yield check, mgr, expected
return
cmd, name, remaining = mgr.find_command(self.argv)
self.assertTrue(cmd)
self.assertEqual(['--opt'], remaining)
def test_find_invalid_command():
class TestFindInvalidCommand(base.TestBase):
scenarios = [
('no-such-command', {'argv': ['a', '-b']}),
('no-command-given', {'argv': ['-b']}),
]
def test(self):
mgr = utils.TestCommandManager(utils.TEST_NAMESPACE)
def check_one(argv):
try:
mgr.find_command(argv)
mgr.find_command(self.argv)
except ValueError as err:
# make sure err include 'a' when ['a', '-b']
assert argv[0] in ('%s' % err)
assert '-b' in ('%s' % err)
self.assertIn(self.argv[0], str(err))
self.assertIn('-b', str(err))
else:
assert False, 'expected a failure'
for argv in [['a', '-b'],
['-b'],
]:
yield check_one, argv
self.fail('expected a failure')
def test_find_unknown_command():
class TestFindUnknownCommand(base.TestBase):
def test(self):
mgr = utils.TestCommandManager(utils.TEST_NAMESPACE)
try:
mgr.find_command(['a', 'b'])
except ValueError as err:
assert "['a', 'b']" in ('%s' % err)
self.assertIn("['a', 'b']", str(err))
else:
assert False, 'expected a failure'
self.fail('expected a failure')
def test_add_command():
class TestDynamicCommands(base.TestBase):
def test_add(self):
mgr = utils.TestCommandManager(utils.TEST_NAMESPACE)
mock_cmd = mock.Mock()
mgr.add_command('mock', mock_cmd)
found_cmd, name, args = mgr.find_command(['mock'])
assert found_cmd is mock_cmd
self.assertIs(mock_cmd, found_cmd)
def test_intersected_commands():
def test_intersected_commands(self):
def foo(arg):
pass
@ -92,11 +103,16 @@ def test_intersected_commands():
mgr.add_command('foo', foo)
mgr.add_command('foo bar', foo_bar)
assert mgr.find_command(['foo', 'bar'])[0] is foo_bar
assert mgr.find_command(['foo', 'arg0'])[0] is foo
self.assertIs(foo_bar, mgr.find_command(['foo', 'bar'])[0])
self.assertIs(
foo,
mgr.find_command(['foo', 'arg0'])[0],
)
def test_load_commands():
class TestLoad(base.TestBase):
def test_load_commands(self):
testcmd = mock.Mock(name='testcmd')
testcmd.name.replace.return_value = 'test'
mock_pkg_resources = mock.Mock(return_value=[testcmd])
@ -105,28 +121,32 @@ def test_load_commands():
mgr = commandmanager.CommandManager('test')
iter_entry_points.assert_called_once_with('test')
names = [n for n, v in mgr]
assert names == ['test']
self.assertEqual(['test'], names)
def test_load_commands_keep_underscores():
def test_load_commands_keep_underscores(self):
testcmd = mock.Mock()
testcmd.name = 'test_cmd'
mock_pkg_resources = mock.Mock(return_value=[testcmd])
with mock.patch('pkg_resources.iter_entry_points',
mock_pkg_resources) as iter_entry_points:
mgr = commandmanager.CommandManager('test', convert_underscores=False)
mgr = commandmanager.CommandManager(
'test',
convert_underscores=False,
)
iter_entry_points.assert_called_once_with('test')
names = [n for n, v in mgr]
assert names == ['test_cmd']
self.assertEqual(['test_cmd'], names)
def test_load_commands_replace_underscores():
def test_load_commands_replace_underscores(self):
testcmd = mock.Mock()
testcmd.name = 'test_cmd'
mock_pkg_resources = mock.Mock(return_value=[testcmd])
with mock.patch('pkg_resources.iter_entry_points',
mock_pkg_resources) as iter_entry_points:
mgr = commandmanager.CommandManager('test', convert_underscores=True)
mgr = commandmanager.CommandManager(
'test',
convert_underscores=True,
)
iter_entry_points.assert_called_once_with('test')
names = [n for n, v in mgr]
assert names == ['test cmd']
self.assertEqual(['test cmd'], names)

View File

@ -18,9 +18,12 @@ import mock
from cliff import app as application
from cliff import commandmanager
from cliff import complete
from cliff.tests import base
def test_complete_dictionary():
class TestCompletion(base.TestBase):
def test_dictionary(self):
sot = complete.CompleteDictionary()
sot.add_command("image delete".split(),
[mock.Mock(option_strings=["1"])])
@ -32,19 +35,18 @@ def test_complete_dictionary():
[mock.Mock(option_strings=["4"])])
sot.add_command("volume type delete".split(),
[mock.Mock(option_strings=["5"])])
assert "image volume" == sot.get_commands()
self.assertEqual("image volume", sot.get_commands())
result = sot.get_data()
assert "image" == result[0][0]
assert "create delete list" == result[0][1]
assert "image_create" == result[1][0]
assert "3" == result[1][1]
assert "image_delete" == result[2][0]
assert "1" == result[2][1]
assert "image_list" == result[3][0]
assert "2" == result[3][1]
self.assertEqual("image", result[0][0])
self.assertEqual("create delete list", result[0][1])
self.assertEqual("image_create", result[1][0])
self.assertEqual("3", result[1][1])
self.assertEqual("image_delete", result[2][0])
self.assertEqual("1", result[2][1])
self.assertEqual("image_list", result[3][0])
self.assertEqual("2", result[3][1])
def test_complete_dictionary_subcmd():
def test_complete_dictionary_subcmd(self):
sot = complete.CompleteDictionary()
sot.add_command("image delete".split(),
[mock.Mock(option_strings=["1"])])
@ -52,16 +54,16 @@ def test_complete_dictionary_subcmd():
[mock.Mock(option_strings=["2"])])
sot.add_command("image list better".split(),
[mock.Mock(option_strings=["3"])])
assert "image" == sot.get_commands()
self.assertEqual("image", sot.get_commands())
result = sot.get_data()
assert "image" == result[0][0]
assert "delete list list_better" == result[0][1]
assert "image_delete" == result[1][0]
assert "1" == result[1][1]
assert "image_list" == result[2][0]
assert "2 better" == result[2][1]
assert "image_list_better" == result[3][0]
assert "3" == result[3][1]
self.assertEqual("image", result[0][0])
self.assertEqual("delete list list_better", result[0][1])
self.assertEqual("image_delete", result[1][0])
self.assertEqual("1", result[1][1])
self.assertEqual("image_list", result[2][0])
self.assertEqual("2 better", result[2][1])
self.assertEqual("image_list_better", result[3][0])
self.assertEqual("3", result[3][1])
class FakeStdout:
@ -78,7 +80,9 @@ class FakeStdout:
return result
def given_cmdo_data():
class TestCompletionAlternatives(base.TestBase):
def given_cmdo_data(self):
cmdo = "image server"
data = [("image", "create"),
("image_create", "--eolus"),
@ -87,87 +91,81 @@ def given_cmdo_data():
("server_ssh", "--sunlight")]
return cmdo, data
def then_data(self, content):
self.assertIn(" cmds='image server'\n", content)
self.assertIn(" cmds_image='create'\n", content)
self.assertIn(" cmds_image_create='--eolus'\n", content)
self.assertIn(" cmds_server='meta ssh'\n", content)
self.assertIn(" cmds_server_meta_delete='--wilson'\n", content)
self.assertIn(" cmds_server_ssh='--sunlight'\n", content)
def then_data(content):
assert " cmds='image server'\n" in content
assert " cmds_image='create'\n" in content
assert " cmds_image_create='--eolus'\n" in content
assert " cmds_server='meta ssh'\n" in content
assert " cmds_server_meta_delete='--wilson'\n" in content
assert " cmds_server_ssh='--sunlight'\n" in content
def test_complete_no_code():
def test_complete_no_code(self):
output = FakeStdout()
sot = complete.CompleteNoCode("doesNotMatter", output)
sot.write(*given_cmdo_data())
then_data(output.content)
sot.write(*self.given_cmdo_data())
self.then_data(output.content)
def test_complete_bash():
def test_complete_bash(self):
output = FakeStdout()
sot = complete.CompleteBash("openstack", output)
sot.write(*given_cmdo_data())
then_data(output.content)
assert "_openstack()\n" in output.content[0]
assert "complete -F _openstack openstack\n" in output.content[-1]
sot.write(*self.given_cmdo_data())
self.then_data(output.content)
self.assertIn("_openstack()\n", output.content[0])
self.assertIn("complete -F _openstack openstack\n", output.content[-1])
def test_complete_command_parser():
def test_complete_command_parser(self):
sot = complete.CompleteCommand(mock.Mock(), mock.Mock())
parser = sot.get_parser('nothing')
assert "nothing" == parser.prog
assert "print bash completion command\n " == parser.description
self.assertEqual("nothing", parser.prog)
self.assertEqual("print bash completion command\n ",
parser.description)
def given_complete_command():
class TestCompletionAction(base.TestBase):
def given_complete_command(self):
cmd_mgr = commandmanager.CommandManager('cliff.tests')
app = application.App('testing', '1', cmd_mgr, stdout=FakeStdout())
sot = complete.CompleteCommand(app, mock.Mock())
cmd_mgr.add_command('complete', complete.CompleteCommand)
return sot, app, cmd_mgr
def then_actions_equal(actions):
def then_actions_equal(self, actions):
optstr = ' '.join(opt for action in actions
for opt in action.option_strings)
assert '-h --help --name --shell' == optstr
self.assertEqual('-h --help --name --shell', optstr)
def test_complete_command_get_actions():
sot, app, cmd_mgr = given_complete_command()
def test_complete_command_get_actions(self):
sot, app, cmd_mgr = self.given_complete_command()
app.interactive_mode = False
actions = sot.get_actions(["complete"])
then_actions_equal(actions)
self.then_actions_equal(actions)
def test_complete_command_get_actions_interactive():
sot, app, cmd_mgr = given_complete_command()
def test_complete_command_get_actions_interactive(self):
sot, app, cmd_mgr = self.given_complete_command()
app.interactive_mode = True
actions = sot.get_actions(["complete"])
then_actions_equal(actions)
self.then_actions_equal(actions)
def test_complete_command_take_action():
sot, app, cmd_mgr = given_complete_command()
def test_complete_command_take_action(self):
sot, app, cmd_mgr = self.given_complete_command()
parsed_args = mock.Mock()
parsed_args.name = "test_take"
parsed_args.shell = "bash"
content = app.stdout.content
assert 0 == sot.take_action(parsed_args)
assert "_test_take()\n" in content[0]
assert "complete -F _test_take test_take\n" in content[-1]
assert " cmds='complete help'\n" in content
assert " cmds_complete='-h --help --name --shell'\n" in content
assert " cmds_help='-h --help'\n" in content
self.assertEqual(0, sot.take_action(parsed_args))
self.assertIn("_test_take()\n", content[0])
self.assertIn("complete -F _test_take test_take\n", content[-1])
self.assertIn(" cmds='complete help'\n", content)
self.assertIn(" cmds_complete='-h --help --name --shell'\n", content)
self.assertIn(" cmds_help='-h --help'\n", content)
def test_complete_command_remove_dashes():
sot, app, cmd_mgr = given_complete_command()
def test_complete_command_remove_dashes(self):
sot, app, cmd_mgr = self.given_complete_command()
parsed_args = mock.Mock()
parsed_args.name = "test-take"
parsed_args.shell = "bash"
content = app.stdout.content
assert 0 == sot.take_action(parsed_args)
assert "_test_take()\n" in content[0]
assert "complete -F _test_take test-take\n" in content[-1]
self.assertEqual(0, sot.take_action(parsed_args))
self.assertIn("_test_take()\n", content[0])
self.assertIn("complete -F _test_take test-take\n", content[-1])

View File

@ -13,15 +13,19 @@
# License for the specific language governing permissions and limitations
# under the License.
import mock
import argparse
import unittest
import mock
import six
from cliff.formatters import commaseparated
from cliff.tests import test_columns
def test_commaseparated_list_formatter():
class TestCSVFormatter(unittest.TestCase):
def test_commaseparated_list_formatter(self):
sf = commaseparated.CSVLister()
c = ('a', 'b', 'c')
d1 = ('A', 'B', 'C')
@ -33,10 +37,9 @@ def test_commaseparated_list_formatter():
parsed_args.quote_mode = 'none'
sf.emit_list(c, data, output, parsed_args)
actual = output.getvalue()
assert expected == actual
self.assertEqual(expected, actual)
def test_commaseparated_list_formatter_quoted():
def test_commaseparated_list_formatter_quoted(self):
sf = commaseparated.CSVLister()
c = ('a', 'b', 'c')
d1 = ('A', 'B', 'C')
@ -50,10 +53,9 @@ def test_commaseparated_list_formatter_quoted():
parsed_args = parser.parse_args(['--quote', 'all'])
sf.emit_list(c, data, output, parsed_args)
actual = output.getvalue()
assert expected == actual
self.assertEqual(expected, actual)
def test_commaseparated_list_formatter_formattable_column():
def test_commaseparated_list_formatter_formattable_column(self):
sf = commaseparated.CSVLister()
c = ('a', 'b', 'c')
d1 = ('A', 'B', test_columns.FauxColumn(['the', 'value']))
@ -64,10 +66,9 @@ def test_commaseparated_list_formatter_formattable_column():
parsed_args.quote_mode = 'none'
sf.emit_list(c, data, output, parsed_args)
actual = output.getvalue()
assert expected == actual
self.assertEqual(expected, actual)
def test_commaseparated_list_formatter_unicode():
def test_commaseparated_list_formatter_unicode(self):
sf = commaseparated.CSVLister()
c = (u'a', u'b', u'c')
d1 = (u'A', u'B', u'C')
@ -82,4 +83,4 @@ def test_commaseparated_list_formatter_unicode():
actual = output.getvalue()
if six.PY2:
actual = actual.decode('utf-8')
assert expected == actual
self.assertEqual(expected, actual)

View File

@ -13,15 +13,18 @@
# under the License.
import json
import six
from cliff.formatters import json_format
from cliff.tests import base
from cliff.tests import test_columns
import mock
import six
def test_json_format_one():
class TestJSONFormatter(base.TestBase):
def test_one(self):
sf = json_format.JSONFormatter()
c = ('a', 'b', 'c', 'd')
d = ('A', 'B', 'C', '"escape me"')
@ -39,20 +42,19 @@ def test_json_format_one():
sf.emit_one(c, d, output, args)
value = output.getvalue()
print(len(value.splitlines()))
assert 1 == len(value.splitlines())
self.assertEqual(1, len(value.splitlines()))
actual = json.loads(value)
assert expected == actual
self.assertEqual(expected, actual)
args.noindent = False
output = six.StringIO()
sf.emit_one(c, d, output, args)
value = output.getvalue()
assert 6 == len(value.splitlines())
self.assertEqual(6, len(value.splitlines()))
actual = json.loads(value)
assert expected == actual
self.assertEqual(expected, actual)
def test_json_format_formattablecolumn_one():
def test_formattablecolumn_one(self):
sf = json_format.JSONFormatter()
c = ('a', 'b', 'c', 'd')
d = ('A', 'B', 'C', test_columns.FauxColumn(['the', 'value']))
@ -70,12 +72,11 @@ def test_json_format_formattablecolumn_one():
sf.emit_one(c, d, output, args)
value = output.getvalue()
print(len(value.splitlines()))
assert 1 == len(value.splitlines())
self.assertEqual(1, len(value.splitlines()))
actual = json.loads(value)
assert expected == actual
self.assertEqual(expected, actual)
def test_json_format_list():
def test_list(self):
sf = json_format.JSONFormatter()
c = ('a', 'b', 'c')
d = (
@ -95,20 +96,19 @@ def test_json_format_list():
output = six.StringIO()
sf.emit_list(c, d, output, args)
value = output.getvalue()
assert 1 == len(value.splitlines())
self.assertEqual(1, len(value.splitlines()))
actual = json.loads(value)
assert expected == actual
self.assertEqual(expected, actual)
args.noindent = False
output = six.StringIO()
sf.emit_list(c, d, output, args)
value = output.getvalue()
assert 17 == len(value.splitlines())
self.assertEqual(17, len(value.splitlines()))
actual = json.loads(value)
assert expected == actual
self.assertEqual(expected, actual)
def test_json_format_formattablecolumn_list():
def test_formattablecolumn_list(self):
sf = json_format.JSONFormatter()
c = ('a', 'b', 'c')
d = (
@ -124,6 +124,6 @@ def test_json_format_formattablecolumn_list():
output = six.StringIO()
sf.emit_list(c, d, output, args)
value = output.getvalue()
assert 1 == len(value.splitlines())
self.assertEqual(1, len(value.splitlines()))
actual = json.loads(value)
assert expected == actual
self.assertEqual(expected, actual)

View File

@ -16,12 +16,15 @@ import argparse
import six
from cliff.formatters import shell
from cliff.tests import base
from cliff.tests import test_columns
import mock
def test_shell_formatter():
class TestShellFormatter(base.TestBase):
def test(self):
sf = shell.ShellFormatter()
c = ('a', 'b', 'c', 'd')
d = ('A', 'B', 'C', '"escape me"')
@ -32,10 +35,9 @@ def test_shell_formatter():
args.prefix = ''
sf.emit_one(c, d, output, args)
actual = output.getvalue()
assert expected == actual
self.assertEqual(expected, actual)
def test_shell_formatter_args():
def test_args(self):
sf = shell.ShellFormatter()
c = ('a', 'b', 'c', 'd')
d = ('A', 'B', 'C', '"escape me"')
@ -47,10 +49,9 @@ def test_shell_formatter_args():
parsed_args = parser.parse_args(['--variable', 'd', '--prefix', 'X'])
sf.emit_one(c, d, output, parsed_args)
actual = output.getvalue()
assert expected == actual
self.assertEqual(expected, actual)
def test_shell_formatter_formattable_column():
def test_formattable_column(self):
sf = shell.ShellFormatter()
c = ('a', 'b', 'c')
d = ('A', 'B', test_columns.FauxColumn(['the', 'value']))
@ -65,24 +66,23 @@ def test_shell_formatter_formattable_column():
args.prefix = ''
sf.emit_one(c, d, output, args)
actual = output.getvalue()
assert expected == actual
self.assertEqual(expected, actual)
def test_shell_formatter_with_non_string_values():
def test_non_string_values(self):
sf = shell.ShellFormatter()
c = ('a', 'b', 'c', 'd', 'e')
d = (True, False, 100, '"esc"', six.text_type('"esc"'))
expected = 'a="True"\nb="False"\nc="100"\nd="\\"esc\\""\ne="\\"esc\\""\n'
expected = ('a="True"\nb="False"\nc="100"\n'
'd="\\"esc\\""\ne="\\"esc\\""\n')
output = six.StringIO()
args = mock.Mock()
args.variables = ['a', 'b', 'c', 'd', 'e']
args.prefix = ''
sf.emit_one(c, d, output, args)
actual = output.getvalue()
assert expected == actual
self.assertEqual(expected, actual)
def test_shell_formatter_with_non_bash_friendly_values():
def test_non_bash_friendly_values(self):
sf = shell.ShellFormatter()
c = ('a', 'foo-bar', 'provider:network_type')
d = (True, 'baz', 'vxlan')
@ -93,4 +93,4 @@ def test_shell_formatter_with_non_bash_friendly_values():
args.prefix = ''
sf.emit_one(c, d, output, args)
actual = output.getvalue()
assert expected == actual
self.assertEqual(expected, actual)

View File

@ -12,12 +12,15 @@
# License for the specific language governing permissions and limitations
# under the License.
import argparse
import os
import textwrap
import mock
from six import StringIO
import os
import argparse
from cliff.formatters import table
from cliff.tests import base
from cliff.tests import test_columns
@ -61,487 +64,548 @@ def _table_tester_helper(tags, data, extra_args=None):
return output.getvalue()
@mock.patch('cliff.utils.terminal_width')
def test_table_formatter(tw):
class TestTableFormatter(base.TestBase):
@mock.patch('cliff.utils.terminal_width')
def test(self, tw):
tw.return_value = 80
c = ('a', 'b', 'c', 'd')
d = ('A', 'B', 'C', 'test\rcarriage\r\nreturn')
expected = '''\
+-------+---------------+
| Field | Value |
+-------+---------------+
| a | A |
| b | B |
| c | C |
| d | test carriage |
| | return |
+-------+---------------+
'''
assert expected == _table_tester_helper(c, d)
expected = textwrap.dedent('''\
+-------+---------------+
| Field | Value |
+-------+---------------+
| a | A |
| b | B |
| c | C |
| d | test carriage |
| | return |
+-------+---------------+
''')
self.assertEqual(expected, _table_tester_helper(c, d))
# Multi-line output when width is restricted to 42 columns
expected_ml_val = '''\
+-------+--------------------------------+
| Field | Value |
+-------+--------------------------------+
| a | A |
| b | B |
| c | C |
| d | dddddddddddddddddddddddddddddd |
| | dddddddddddddddddddddddddddddd |
| | ddddddddddddddddd |
+-------+--------------------------------+
'''
class TestTerminalWidth(base.TestBase):
# Multi-line output when width is restricted to 80 columns
expected_ml_80_val = '''\
+-------+----------------------------------------------------------------------+
| Field | Value |
+-------+----------------------------------------------------------------------+
| a | A |
| b | B |
| c | C |
| d | dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd |
| | ddddddddd |
+-------+----------------------------------------------------------------------+
''' # noqa
# Multi-line output when width is restricted to 42 columns
expected_ml_val = textwrap.dedent('''\
+-------+--------------------------------+
| Field | Value |
+-------+--------------------------------+
| a | A |
| b | B |
| c | C |
| d | dddddddddddddddddddddddddddddd |
| | dddddddddddddddddddddddddddddd |
| | ddddddddddddddddd |
+-------+--------------------------------+
''')
# Single-line output, for when no line length restriction apply
expected_sl_val = '''\
+-------+-------------------------------------------------------------------------------+
| Field | Value |
+-------+-------------------------------------------------------------------------------+
| a | A |
| b | B |
| c | C |
| d | ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd |
+-------+-------------------------------------------------------------------------------+
''' # noqa
# Multi-line output when width is restricted to 80 columns
expected_ml_80_val = textwrap.dedent('''\
+-------+----------------------------------------------------------------------+
| Field | Value |
+-------+----------------------------------------------------------------------+
| a | A |
| b | B |
| c | C |
| d | dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd |
| | ddddddddd |
+-------+----------------------------------------------------------------------+
''') # noqa
# Single-line output, for when no line length restriction apply
expected_sl_val = textwrap.dedent('''\
+-------+-------------------------------------------------------------------------------+
| Field | Value |
+-------+-------------------------------------------------------------------------------+
| a | A |
| b | B |
| c | C |
| d | ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd |
+-------+-------------------------------------------------------------------------------+
''') # noqa
@mock.patch('cliff.utils.terminal_width')
def test_table_formatter_no_cli_param(tw):
@mock.patch('cliff.utils.terminal_width')
def test_table_formatter_no_cli_param(self, tw):
tw.return_value = 80
c = ('a', 'b', 'c', 'd')
d = ('A', 'B', 'C', 'd' * 77)
assert expected_ml_80_val == _table_tester_helper(c, d, extra_args=args())
self.assertEqual(
self.expected_ml_80_val,
_table_tester_helper(c, d, extra_args=args()),
)
@mock.patch('cliff.utils.terminal_width')
def test_table_formatter_cli_param(tw):
@mock.patch('cliff.utils.terminal_width')
def test_table_formatter_cli_param(self, tw):
tw.return_value = 80
c = ('a', 'b', 'c', 'd')
d = ('A', 'B', 'C', 'd' * 77)
assert (expected_ml_val ==
_table_tester_helper(c, d, extra_args=['--max-width', '42']))
self.assertEqual(
self.expected_ml_val,
_table_tester_helper(c, d, extra_args=['--max-width', '42']),
)
@mock.patch('cliff.utils.terminal_width')
def test_table_formatter_no_cli_param_unlimited_tw(tw):
@mock.patch('cliff.utils.terminal_width')
def test_table_formatter_no_cli_param_unlimited_tw(self, tw):
tw.return_value = 0
c = ('a', 'b', 'c', 'd')
d = ('A', 'B', 'C', 'd' * 77)
# output should not be wrapped to multiple lines
assert expected_sl_val == _table_tester_helper(c, d, extra_args=args())
self.assertEqual(
self.expected_sl_val,
_table_tester_helper(c, d, extra_args=args()),
)
@mock.patch('cliff.utils.terminal_width')
def test_table_formatter_cli_param_unlimited_tw(tw):
@mock.patch('cliff.utils.terminal_width')
def test_table_formatter_cli_param_unlimited_tw(self, tw):
tw.return_value = 0
c = ('a', 'b', 'c', 'd')
d = ('A', 'B', 'C', 'd' * 77)
assert (expected_ml_val ==
_table_tester_helper(c, d, extra_args=['--max-width', '42']))
self.assertEqual(
self.expected_ml_val,
_table_tester_helper(c, d, extra_args=['--max-width', '42']),
)
@mock.patch('cliff.utils.terminal_width')
@mock.patch.dict(os.environ, {'CLIFF_MAX_TERM_WIDTH': '666'})
def test_table_formatter_cli_param_envvar_big(tw):
@mock.patch('cliff.utils.terminal_width')
@mock.patch.dict(os.environ, {'CLIFF_MAX_TERM_WIDTH': '666'})
def test_table_formatter_cli_param_envvar_big(self, tw):
tw.return_value = 80
c = ('a', 'b', 'c', 'd')
d = ('A', 'B', 'C', 'd' * 77)
assert (expected_ml_val ==
_table_tester_helper(c, d, extra_args=['--max-width', '42']))
self.assertEqual(
self.expected_ml_val,
_table_tester_helper(c, d, extra_args=['--max-width', '42']),
)
@mock.patch('cliff.utils.terminal_width')
@mock.patch.dict(os.environ, {'CLIFF_MAX_TERM_WIDTH': '23'})
def test_table_formatter_cli_param_envvar_tiny(tw):
@mock.patch('cliff.utils.terminal_width')
@mock.patch.dict(os.environ, {'CLIFF_MAX_TERM_WIDTH': '23'})
def test_table_formatter_cli_param_envvar_tiny(self, tw):
tw.return_value = 80
c = ('a', 'b', 'c', 'd')
d = ('A', 'B', 'C', 'd' * 77)
assert (expected_ml_val ==
_table_tester_helper(c, d, extra_args=['--max-width', '42']))
self.assertEqual(
self.expected_ml_val,
_table_tester_helper(c, d, extra_args=['--max-width', '42']),
)
@mock.patch('cliff.utils.terminal_width')
def test_table_formatter_max_width(tw):
class TestMaxWidth(base.TestBase):
expected_80 = textwrap.dedent('''\
+--------------------------+---------------------------------------------+
| Field | Value |
+--------------------------+---------------------------------------------+
| field_name | the value |
| a_really_long_field_name | a value significantly longer than the field |
+--------------------------+---------------------------------------------+
''')
@mock.patch('cliff.utils.terminal_width')
def test_80(self, tw):
tw.return_value = 80
c = ('field_name', 'a_really_long_field_name')
d = ('the value', 'a value significantly longer than the field')
expected = '''\
+--------------------------+---------------------------------------------+
| Field | Value |
+--------------------------+---------------------------------------------+
| field_name | the value |
| a_really_long_field_name | a value significantly longer than the field |
+--------------------------+---------------------------------------------+
'''
assert expected == _table_tester_helper(c, d)
self.assertEqual(self.expected_80, _table_tester_helper(c, d))
@mock.patch('cliff.utils.terminal_width')
def test_70(self, tw):
# resize value column
tw.return_value = 70
expected = '''\
+--------------------------+-----------------------------------------+
| Field | Value |
+--------------------------+-----------------------------------------+
| field_name | the value |
| a_really_long_field_name | a value significantly longer than the |
| | field |
+--------------------------+-----------------------------------------+
'''
assert expected == _table_tester_helper(c, d)
c = ('field_name', 'a_really_long_field_name')
d = ('the value', 'a value significantly longer than the field')
expected = textwrap.dedent('''\
+--------------------------+-----------------------------------------+
| Field | Value |
+--------------------------+-----------------------------------------+
| field_name | the value |
| a_really_long_field_name | a value significantly longer than the |
| | field |
+--------------------------+-----------------------------------------+
''')
self.assertEqual(expected, _table_tester_helper(c, d))
@mock.patch('cliff.utils.terminal_width')
def test_50(self, tw):
# resize both columns
tw.return_value = 50
expected = '''\
+-----------------------+------------------------+
| Field | Value |
+-----------------------+------------------------+
| field_name | the value |
| a_really_long_field_n | a value significantly |
| ame | longer than the field |
+-----------------------+------------------------+
'''
assert expected == _table_tester_helper(c, d)
c = ('field_name', 'a_really_long_field_name')
d = ('the value', 'a value significantly longer than the field')
expected = textwrap.dedent('''\
+-----------------------+------------------------+
| Field | Value |
+-----------------------+------------------------+
| field_name | the value |
| a_really_long_field_n | a value significantly |
| ame | longer than the field |
+-----------------------+------------------------+
''')
self.assertEqual(expected, _table_tester_helper(c, d))
@mock.patch('cliff.utils.terminal_width')
def test_10(self, tw):
# resize all columns limited by min_width=16
tw.return_value = 10
expected = '''\
+------------------+------------------+
| Field | Value |
+------------------+------------------+
| field_name | the value |
| a_really_long_fi | a value |
| eld_name | significantly |
| | longer than the |
| | field |
+------------------+------------------+
'''
assert expected == _table_tester_helper(c, d)
c = ('field_name', 'a_really_long_field_name')
d = ('the value', 'a value significantly longer than the field')
expected = textwrap.dedent('''\
+------------------+------------------+
| Field | Value |
+------------------+------------------+
| field_name | the value |
| a_really_long_fi | a value |
| eld_name | significantly |
| | longer than the |
| | field |
+------------------+------------------+
''')
self.assertEqual(expected, _table_tester_helper(c, d))
@mock.patch('cliff.utils.terminal_width')
def test_table_list_formatter(tw):
class TestListFormatter(base.TestBase):
_col_names = ('one', 'two', 'three')
_col_data = [(
'one one one one one',
'two two two two',
'three three')]
_expected_mv = {
80: textwrap.dedent('''\
+---------------------+-----------------+-------------+
| one | two | three |
+---------------------+-----------------+-------------+
| one one one one one | two two two two | three three |
+---------------------+-----------------+-------------+
'''),
50: textwrap.dedent('''\
+----------------+-----------------+-------------+
| one | two | three |
+----------------+-----------------+-------------+
| one one one | two two two two | three three |
| one one | | |
+----------------+-----------------+-------------+
'''),
47: textwrap.dedent('''\
+---------------+---------------+-------------+
| one | two | three |
+---------------+---------------+-------------+
| one one one | two two two | three three |
| one one | two | |
+---------------+---------------+-------------+
'''),
45: textwrap.dedent('''\
+--------------+--------------+-------------+
| one | two | three |
+--------------+--------------+-------------+
| one one one | two two two | three three |
| one one | two | |
+--------------+--------------+-------------+
'''),
40: textwrap.dedent('''\
+------------+------------+------------+
| one | two | three |
+------------+------------+------------+
| one one | two two | three |
| one one | two two | three |
| one | | |
+------------+------------+------------+
'''),
10: textwrap.dedent('''\
+----------+----------+----------+
| one | two | three |
+----------+----------+----------+
| one one | two two | three |
| one one | two two | three |
| one | | |
+----------+----------+----------+
'''),
}
@mock.patch('cliff.utils.terminal_width')
def test_table_list_formatter(self, tw):
tw.return_value = 80
c = ('a', 'b', 'c')
d1 = ('A', 'B', 'C')
d2 = ('D', 'E', 'test\rcarriage\r\nreturn')
data = [d1, d2]
expected = '''\
+---+---+---------------+
| a | b | c |
+---+---+---------------+
| A | B | C |
| D | E | test carriage |
| | | return |
+---+---+---------------+
'''
assert expected == _table_tester_helper(c, data)
expected = textwrap.dedent('''\
+---+---+---------------+
| a | b | c |
+---+---+---------------+
| A | B | C |
| D | E | test carriage |
| | | return |
+---+---+---------------+
''')
self.assertEqual(expected, _table_tester_helper(c, data))
@mock.patch('cliff.utils.terminal_width')
def test_table_formatter_formattable_column(tw):
@mock.patch('cliff.utils.terminal_width')
def test_table_formatter_formattable_column(self, tw):
tw.return_value = 0
c = ('a', 'b', 'c', 'd')
d = ('A', 'B', 'C', test_columns.FauxColumn(['the', 'value']))
expected = '''\
+-------+---------------------------------------------+
| Field | Value |
+-------+---------------------------------------------+
| a | A |
| b | B |
| c | C |
| d | I made this string myself: ['the', 'value'] |
+-------+---------------------------------------------+
'''
assert expected == _table_tester_helper(c, d)
expected = textwrap.dedent('''\
+-------+---------------------------------------------+
| Field | Value |
+-------+---------------------------------------------+
| a | A |
| b | B |
| c | C |
| d | I made this string myself: ['the', 'value'] |
+-------+---------------------------------------------+
''')
self.assertEqual(expected, _table_tester_helper(c, d))
_col_names = ('one', 'two', 'three')
_col_data = [(
'one one one one one',
'two two two two',
'three three')]
_expected_mv = {
80: '''\
+---------------------+-----------------+-------------+
| one | two | three |
+---------------------+-----------------+-------------+
| one one one one one | two two two two | three three |
+---------------------+-----------------+-------------+
''',
50: '''\
+----------------+-----------------+-------------+
| one | two | three |
+----------------+-----------------+-------------+
| one one one | two two two two | three three |
| one one | | |
+----------------+-----------------+-------------+
''',
47: '''\
+---------------+---------------+-------------+
| one | two | three |
+---------------+---------------+-------------+
| one one one | two two two | three three |
| one one | two | |
+---------------+---------------+-------------+
''',
45: '''\
+--------------+--------------+-------------+
| one | two | three |
+--------------+--------------+-------------+
| one one one | two two two | three three |
| one one | two | |
+--------------+--------------+-------------+
''',
40: '''\
+------------+------------+------------+
| one | two | three |
+------------+------------+------------+
| one one | two two | three |
| one one | two two | three |
| one | | |
+------------+------------+------------+
''',
10: '''\
+----------+----------+----------+
| one | two | three |
+----------+----------+----------+
| one one | two two | three |
| one one | two two | three |
| one | | |
+----------+----------+----------+
''',
}
@mock.patch('cliff.utils.terminal_width')
def test_table_list_formatter_formattable_column(tw):
@mock.patch('cliff.utils.terminal_width')
def test_formattable_column(self, tw):
tw.return_value = 80
c = ('a', 'b', 'c')
d1 = ('A', 'B', test_columns.FauxColumn(['the', 'value']))
data = [d1]
expected = '''\
+---+---+---------------------------------------------+
| a | b | c |
+---+---+---------------------------------------------+
| A | B | I made this string myself: ['the', 'value'] |
+---+---+---------------------------------------------+
'''
assert expected == _table_tester_helper(c, data)
expected = textwrap.dedent('''\
+---+---+---------------------------------------------+
| a | b | c |
+---+---+---------------------------------------------+
| A | B | I made this string myself: ['the', 'value'] |
+---+---+---------------------------------------------+
''')
self.assertEqual(expected, _table_tester_helper(c, data))
@mock.patch('cliff.utils.terminal_width')
def test_table_list_formatter_max_width(tw):
@mock.patch('cliff.utils.terminal_width')
def test_max_width_80(self, tw):
# no resize
l = tw.return_value = 80
assert _expected_mv[l] == _table_tester_helper(_col_names, _col_data)
self.assertEqual(
self._expected_mv[l],
_table_tester_helper(self._col_names, self._col_data),
)
@mock.patch('cliff.utils.terminal_width')
def test_max_width_50(self, tw):
# resize 1 column
l = tw.return_value = 50
actual = _table_tester_helper(_col_names, _col_data)
assert _expected_mv[l] == actual
assert len(actual.splitlines()[0]) == l
actual = _table_tester_helper(self._col_names, self._col_data)
self.assertEqual(self._expected_mv[l], actual)
self.assertEqual(l, len(actual.splitlines()[0]))
@mock.patch('cliff.utils.terminal_width')
def test_max_width_45(self, tw):
# resize 2 columns
l = tw.return_value = 45
actual = _table_tester_helper(_col_names, _col_data)
assert _expected_mv[l] == actual
assert len(actual.splitlines()[0]) == l
actual = _table_tester_helper(self._col_names, self._col_data)
self.assertEqual(self._expected_mv[l], actual)
self.assertEqual(l, len(actual.splitlines()[0]))
@mock.patch('cliff.utils.terminal_width')
def test_max_width_40(self, tw):
# resize all columns
l = tw.return_value = 40
actual = _table_tester_helper(_col_names, _col_data)
assert _expected_mv[l] == actual
assert len(actual.splitlines()[0]) == l
actual = _table_tester_helper(self._col_names, self._col_data)
self.assertEqual(self._expected_mv[l], actual)
self.assertEqual(l, len(actual.splitlines()[0]))
@mock.patch('cliff.utils.terminal_width')
def test_max_width_10(self, tw):
# resize all columns limited by min_width=8
l = tw.return_value = 10
actual = _table_tester_helper(_col_names, _col_data)
assert _expected_mv[l] == actual
actual = _table_tester_helper(self._col_names, self._col_data)
self.assertEqual(self._expected_mv[l], actual)
# 3 columns each 8 wide, plus table spacing and borders
expected_width = 11 * 3 + 1
assert len(actual.splitlines()[0]) == expected_width
self.assertEqual(expected_width, len(actual.splitlines()[0]))
# Force a wide terminal by overriding its width with envvar
@mock.patch('cliff.utils.terminal_width')
@mock.patch.dict(os.environ, {'CLIFF_MAX_TERM_WIDTH': '666'})
def test_table_list_formatter_max_width_and_envvar_max(tw):
# Force a wide terminal by overriding its width with envvar
@mock.patch('cliff.utils.terminal_width')
@mock.patch.dict(os.environ, {'CLIFF_MAX_TERM_WIDTH': '666'})
def test_max_width_and_envvar_max(self, tw):
# no resize
tw.return_value = 80
assert _expected_mv[80] == _table_tester_helper(_col_names, _col_data)
self.assertEqual(
self._expected_mv[80],
_table_tester_helper(self._col_names, self._col_data),
)
# resize 1 column
tw.return_value = 50
assert _expected_mv[80] == _table_tester_helper(_col_names, _col_data)
self.assertEqual(
self._expected_mv[80],
_table_tester_helper(self._col_names, self._col_data),
)
# resize 2 columns
tw.return_value = 45
assert _expected_mv[80] == _table_tester_helper(_col_names, _col_data)
self.assertEqual(
self._expected_mv[80],
_table_tester_helper(self._col_names, self._col_data),
)
# resize all columns
tw.return_value = 40
assert _expected_mv[80] == _table_tester_helper(_col_names, _col_data)
self.assertEqual(
self._expected_mv[80],
_table_tester_helper(self._col_names, self._col_data),
)
# resize all columns limited by min_width=8
tw.return_value = 10
assert _expected_mv[80] == _table_tester_helper(_col_names, _col_data)
self.assertEqual(
self._expected_mv[80],
_table_tester_helper(self._col_names, self._col_data),
)
# Force a narrow terminal by overriding its width with envvar
@mock.patch('cliff.utils.terminal_width')
@mock.patch.dict(os.environ, {'CLIFF_MAX_TERM_WIDTH': '47'})
def test_table_list_formatter_max_width_and_envvar_mid(tw):
# Force a narrow terminal by overriding its width with envvar
@mock.patch('cliff.utils.terminal_width')
@mock.patch.dict(os.environ, {'CLIFF_MAX_TERM_WIDTH': '47'})
def test_max_width_and_envvar_mid(self, tw):
# no resize
tw.return_value = 80
assert _expected_mv[47] == _table_tester_helper(_col_names, _col_data)
self.assertEqual(
self._expected_mv[47],
_table_tester_helper(self._col_names, self._col_data),
)
# resize 1 column
tw.return_value = 50
actual = _table_tester_helper(_col_names, _col_data)
assert _expected_mv[47] == actual
assert len(actual.splitlines()[0]) == 47
actual = _table_tester_helper(self._col_names, self._col_data)
self.assertEqual(self._expected_mv[47], actual)
self.assertEqual(47, len(actual.splitlines()[0]))
# resize 2 columns
tw.return_value = 45
actual = _table_tester_helper(_col_names, _col_data)
assert _expected_mv[47] == actual
assert len(actual.splitlines()[0]) == 47
actual = _table_tester_helper(self._col_names, self._col_data)
self.assertEqual(self._expected_mv[47], actual)
self.assertEqual(47, len(actual.splitlines()[0]))
# resize all columns
tw.return_value = 40
actual = _table_tester_helper(_col_names, _col_data)
assert _expected_mv[47] == actual
assert len(actual.splitlines()[0]) == 47
actual = _table_tester_helper(self._col_names, self._col_data)
self.assertEqual(self._expected_mv[47], actual)
self.assertEqual(47, len(actual.splitlines()[0]))
# resize all columns limited by min_width=8
tw.return_value = 10
actual = _table_tester_helper(_col_names, _col_data)
assert _expected_mv[47] == actual
assert len(actual.splitlines()[0]) == 47
actual = _table_tester_helper(self._col_names, self._col_data)
self.assertEqual(self._expected_mv[47], actual)
self.assertEqual(47, len(actual.splitlines()[0]))
@mock.patch.dict(os.environ, {'CLIFF_MAX_TERM_WIDTH': '80'})
def test_table_list_formatter_env_maxwidth_noresize():
@mock.patch.dict(os.environ, {'CLIFF_MAX_TERM_WIDTH': '80'})
def test_env_maxwidth_noresize(self):
# no resize
assert _expected_mv[80] == _table_tester_helper(_col_names, _col_data)
self.assertEqual(
self._expected_mv[80],
_table_tester_helper(self._col_names, self._col_data),
)
@mock.patch.dict(os.environ, {'CLIFF_MAX_TERM_WIDTH': '50'})
def test_table_list_formatter_env_maxwidth_resize_one():
@mock.patch.dict(os.environ, {'CLIFF_MAX_TERM_WIDTH': '50'})
def test_env_maxwidth_resize_one(self):
# resize 1 column
actual = _table_tester_helper(_col_names, _col_data)
assert _expected_mv[50] == actual
assert len(actual.splitlines()[0]) == 50
actual = _table_tester_helper(self._col_names, self._col_data)
self.assertEqual(self._expected_mv[50], actual)
self.assertEqual(50, len(actual.splitlines()[0]))
@mock.patch.dict(os.environ, {'CLIFF_MAX_TERM_WIDTH': '45'})
def test_table_list_formatter_env_maxwidth_resize_two():
@mock.patch.dict(os.environ, {'CLIFF_MAX_TERM_WIDTH': '45'})
def test_env_maxwidth_resize_two(self):
# resize 2 columns
actual = _table_tester_helper(_col_names, _col_data)
assert _expected_mv[45] == actual
assert len(actual.splitlines()[0]) == 45
actual = _table_tester_helper(self._col_names, self._col_data)
self.assertEqual(self._expected_mv[45], actual)
self.assertEqual(45, len(actual.splitlines()[0]))
@mock.patch.dict(os.environ, {'CLIFF_MAX_TERM_WIDTH': '40'})
def test_table_list_formatter_env_maxwidth_resize_all():
@mock.patch.dict(os.environ, {'CLIFF_MAX_TERM_WIDTH': '40'})
def test_env_maxwidth_resize_all(self):
# resize all columns
actual = _table_tester_helper(_col_names, _col_data)
assert _expected_mv[40] == actual
assert len(actual.splitlines()[0]) == 40
actual = _table_tester_helper(self._col_names, self._col_data)
self.assertEqual(self._expected_mv[40], actual)
self.assertEqual(40, len(actual.splitlines()[0]))
@mock.patch.dict(os.environ, {'CLIFF_MAX_TERM_WIDTH': '8'})
def test_table_list_formatter_env_maxwidth_resize_all_tiny():
@mock.patch.dict(os.environ, {'CLIFF_MAX_TERM_WIDTH': '8'})
def test_env_maxwidth_resize_all_tiny(self):
# resize all columns limited by min_width=8
actual = _table_tester_helper(_col_names, _col_data)
assert _expected_mv[10] == actual
actual = _table_tester_helper(self._col_names, self._col_data)
self.assertEqual(self._expected_mv[10], actual)
# 3 columns each 8 wide, plus table spacing and borders
expected_width = 11 * 3 + 1
assert len(actual.splitlines()[0]) == expected_width
self.assertEqual(expected_width, len(actual.splitlines()[0]))
@mock.patch.dict(os.environ, {'CLIFF_MAX_TERM_WIDTH': '42'})
def test_env_maxwidth_args_big(self):
self.assertEqual(
self._expected_mv[80],
_table_tester_helper(self._col_names, self._col_data,
extra_args=args(666)),
)
@mock.patch.dict(os.environ, {'CLIFF_MAX_TERM_WIDTH': '42'})
def test_table_list_formatter_env_maxwidth_args_big():
assert _expected_mv[80] == _table_tester_helper(_col_names, _col_data,
extra_args=args(666))
@mock.patch.dict(os.environ, {'CLIFF_MAX_TERM_WIDTH': '42'})
def test_env_maxwidth_args_tiny(self):
self.assertEqual(
self._expected_mv[40],
_table_tester_helper(self._col_names, self._col_data,
extra_args=args(40)),
)
@mock.patch.dict(os.environ, {'CLIFF_MAX_TERM_WIDTH': '42'})
def test_table_list_formatter_env_maxwidth_args_tiny():
assert _expected_mv[40] == _table_tester_helper(_col_names, _col_data,
extra_args=args(40))
@mock.patch('cliff.utils.terminal_width')
def test_table_list_formatter_empty(tw):
@mock.patch('cliff.utils.terminal_width')
def test_empty(self, tw):
tw.return_value = 80
c = ('a', 'b', 'c')
data = []
expected = '\n'
assert expected == _table_tester_helper(c, data)
self.assertEqual(expected, _table_tester_helper(c, data))
@mock.patch('cliff.utils.terminal_width')
def test_table_list_formatter_empty_table(tw):
@mock.patch('cliff.utils.terminal_width')
def test_empty_table(self, tw):
tw.return_value = 80
c = ('a', 'b', 'c')
data = []
expected = '''\
+---+---+---+
| a | b | c |
+---+---+---+
+---+---+---+
'''
assert expected == _table_tester_helper(c, data,
extra_args=['--print-empty'])
expected = textwrap.dedent('''\
+---+---+---+
| a | b | c |
+---+---+---+
+---+---+---+
''')
self.assertEqual(
expected,
_table_tester_helper(c, data,
extra_args=['--print-empty']),
)
def test_field_widths():
class TestFieldWidths(base.TestBase):
def test(self):
tf = table.TableFormatter
assert {
self.assertEqual(
{
'a': 1,
'b': 2,
'c': 3,
'd': 10
} == tf._field_widths(
},
tf._field_widths(
('a', 'b', 'c', 'd'),
'+---+----+-----+------------+')
'+---+----+-----+------------+'),
)
def test_field_widths_zero():
def test_zero(self):
tf = table.TableFormatter
assert {
self.assertEqual(
{
'a': 0,
'b': 0,
'c': 0
} == tf._field_widths(
},
tf._field_widths(
('a', 'b', 'c'),
'+--+-++')
'+--+-++'),
)
def test_width_info():
def test_info(self):
tf = table.TableFormatter
assert (49, 4) == (tf._width_info(80, 10))
assert (76, 76) == (tf._width_info(80, 1))
assert (79, 0) == (tf._width_info(80, 0))
assert (0, 0) == (tf._width_info(0, 80))
self.assertEqual((49, 4), (tf._width_info(80, 10)))
self.assertEqual((76, 76), (tf._width_info(80, 1)))
self.assertEqual((79, 0), (tf._width_info(80, 0)))
self.assertEqual((0, 0), (tf._width_info(0, 80)))

View File

@ -15,10 +15,13 @@
import six
from cliff.formatters import value
from cliff.tests import base
from cliff.tests import test_columns
def test_value_formatter():
class TestValueFormatter(base.TestBase):
def test(self):
sf = value.ValueFormatter()
c = ('a', 'b', 'c', 'd')
d = ('A', 'B', 'C', '"no escape me"')
@ -26,10 +29,9 @@ def test_value_formatter():
output = six.StringIO()
sf.emit_one(c, d, output, None)
actual = output.getvalue()
assert expected == actual
self.assertEqual(expected, actual)
def test_value_formatter_formattable_column():
def test_formattable_column(self):
sf = value.ValueFormatter()
c = ('a', 'b', 'c', 'd')
d = ('A', 'B', 'C', test_columns.FauxColumn(['the', 'value']))
@ -37,10 +39,9 @@ def test_value_formatter_formattable_column():
output = six.StringIO()
sf.emit_one(c, d, output, None)
actual = output.getvalue()
assert expected == actual
self.assertEqual(expected, actual)
def test_value_list_formatter():
def test_list_formatter(self):
sf = value.ValueFormatter()
c = ('a', 'b', 'c')
d1 = ('A', 'B', 'C')
@ -50,10 +51,9 @@ def test_value_list_formatter():
output = six.StringIO()
sf.emit_list(c, data, output, None)
actual = output.getvalue()
assert expected == actual
self.assertEqual(expected, actual)
def test_value_list_formatter_formattable_column():
def test_list_formatter_formattable_column(self):
sf = value.ValueFormatter()
c = ('a', 'b', 'c')
d1 = ('A', 'B', test_columns.FauxColumn(['the', 'value']))
@ -62,4 +62,4 @@ def test_value_list_formatter_formattable_column():
output = six.StringIO()
sf.emit_list(c, data, output, None)
actual = output.getvalue()
assert expected == actual
self.assertEqual(expected, actual)

View File

@ -16,12 +16,15 @@ import six
import yaml
from cliff.formatters import yaml_format
from cliff.tests import base
from cliff.tests import test_columns
import mock
def test_yaml_format_one():
class TestYAMLFormatter(base.TestBase):
def test_format_one(self):
sf = yaml_format.YAMLFormatter()
c = ('a', 'b', 'c', 'd')
d = ('A', 'B', 'C', '"escape me"')
@ -35,10 +38,9 @@ def test_yaml_format_one():
args = mock.Mock()
sf.emit_one(c, d, output, args)
actual = yaml.safe_load(output.getvalue())
assert expected == actual
self.assertEqual(expected, actual)
def test_yaml_format_formattablecolumn_one():
def test_formattablecolumn_one(self):
sf = yaml_format.YAMLFormatter()
c = ('a', 'b', 'c', 'd')
d = ('A', 'B', 'C', test_columns.FauxColumn(['the', 'value']))
@ -57,10 +59,9 @@ def test_yaml_format_formattablecolumn_one():
value = output.getvalue()
print(len(value.splitlines()))
actual = yaml.safe_load(output.getvalue())
assert expected == actual
self.assertEqual(expected, actual)
def test_yaml_format_list():
def test_list(self):
sf = yaml_format.YAMLFormatter()
c = ('a', 'b', 'c')
d = (
@ -78,10 +79,9 @@ def test_yaml_format_list():
sf.add_argument_group(args)
sf.emit_list(c, d, output, args)
actual = yaml.safe_load(output.getvalue())
assert expected == actual
self.assertEqual(expected, actual)
def test_yaml_format_formattablecolumn_list():
def test_formattablecolumn_list(self):
sf = yaml_format.YAMLFormatter()
c = ('a', 'b', 'c')
d = (
@ -97,4 +97,4 @@ def test_yaml_format_formattablecolumn_list():
output = six.StringIO()
sf.emit_list(c, d, output, args)
actual = yaml.safe_load(output.getvalue())
assert expected == actual
self.assertEqual(expected, actual)

View File

@ -22,10 +22,13 @@ import mock
from cliff import app as application
from cliff import commandmanager
from cliff import help
from cliff.tests import base
from cliff.tests import utils
def test_show_help_for_command():
class TestHelp(base.TestBase):
def test_show_help_for_command(self):
# FIXME(dhellmann): Are commands tied too closely to the app? Or
# do commands know too much about apps by using them to get to the
# command manager?
@ -41,10 +44,9 @@ def test_show_help_for_command():
help_cmd.run(parsed_args)
except SystemExit:
pass
assert stdout.getvalue() == 'TestParser'
self.assertEqual('TestParser', stdout.getvalue())
def test_list_matching_commands():
def test_list_matching_commands(self):
# FIXME(dhellmann): Are commands tied too closely to the app? Or
# do commands know too much about apps by using them to get to the
# command manager?
@ -61,11 +63,10 @@ def test_list_matching_commands():
except SystemExit:
pass
help_output = stdout.getvalue()
assert 'Command "t" matches:' in help_output
assert 'three word command\n two words\n' in help_output
self.assertIn('Command "t" matches:', help_output)
self.assertIn('three word command\n two words\n', help_output)
def test_list_matching_commands_no_match():
def test_list_matching_commands_no_match(self):
# FIXME(dhellmann): Are commands tied too closely to the app? Or
# do commands know too much about apps by using them to get to the
# command manager?
@ -77,17 +78,13 @@ def test_list_matching_commands_no_match():
help_cmd = help.HelpCommand(app, mock.Mock())
parser = help_cmd.get_parser('test')
parsed_args = parser.parse_args(['z'])
try:
help_cmd.run(parsed_args)
except SystemExit:
pass
except ValueError:
pass
else:
assert False, 'Should have seen a ValueError'
self.assertRaises(
ValueError,
help_cmd.run,
parsed_args,
)
def test_show_help_for_help():
def test_show_help_for_help(self):
# FIXME(dhellmann): Are commands tied too closely to the app? Or
# do commands know too much about apps by using them to get to the
# command manager?
@ -106,16 +103,15 @@ def test_show_help_for_help():
pass
help_text = stdout.getvalue()
basecommand = os.path.split(sys.argv[0])[1]
assert 'usage: %s [--version]' % basecommand in help_text
assert 'optional arguments:\n --version' in help_text
self.assertIn('usage: %s [--version]' % basecommand, help_text)
self.assertIn('optional arguments:\n --version', help_text)
expected = (
' one Test command.\n'
' three word command Test command.\n'
)
assert expected in help_text
self.assertIn(expected, help_text)
def test_list_deprecated_commands():
def test_list_deprecated_commands(self):
# FIXME(dhellmann): Are commands tied too closely to the app? Or
# do commands know too much about apps by using them to get to the
# command manager?
@ -129,14 +125,13 @@ def test_list_deprecated_commands():
except SystemExit:
pass
help_output = stdout.getvalue()
assert 'two words' in help_output
assert 'three word command' in help_output
assert 'old cmd' not in help_output
self.assertIn('two words', help_output)
self.assertIn('three word command', help_output)
self.assertNotIn('old cmd', help_output)
@mock.patch.object(commandmanager.EntryPointWrapper, 'load',
@mock.patch.object(commandmanager.EntryPointWrapper, 'load',
side_effect=Exception('Could not load EntryPoint'))
def test_show_help_with_ep_load_fail(mock_load):
def test_show_help_with_ep_load_fail(self, mock_load):
stdout = StringIO()
app = application.App('testing', '1',
utils.TestCommandManager(utils.TEST_NAMESPACE),
@ -152,14 +147,13 @@ def test_show_help_with_ep_load_fail(mock_load):
except SystemExit:
pass
help_output = stdout.getvalue()
assert 'Commands:' in help_output
assert 'Could not load' in help_output
assert 'Exception: Could not load EntryPoint' not in help_output
self.assertIn('Commands:', help_output)
self.assertIn('Could not load', help_output)
self.assertNotIn('Exception: Could not load EntryPoint', help_output)
@mock.patch.object(commandmanager.EntryPointWrapper, 'load',
@mock.patch.object(commandmanager.EntryPointWrapper, 'load',
side_effect=Exception('Could not load EntryPoint'))
def test_show_help_print_exc_with_ep_load_fail(mock_load):
def test_show_help_print_exc_with_ep_load_fail(self, mock_load):
stdout = StringIO()
app = application.App('testing', '1',
utils.TestCommandManager(utils.TEST_NAMESPACE),
@ -175,6 +169,6 @@ def test_show_help_print_exc_with_ep_load_fail(mock_load):
except SystemExit:
pass
help_output = stdout.getvalue()
assert 'Commands:' in help_output
assert 'Could not load' in help_output
assert 'Exception: Could not load EntryPoint' in help_output
self.assertIn('Commands:', help_output)
self.assertIn('Could not load', help_output)
self.assertIn('Exception: Could not load EntryPoint', help_output)

View File

@ -15,69 +15,65 @@
import cmd2
from cliff.interactive import InteractiveApp
from cliff.tests import base
class FakeApp(object):
NAME = 'Fake'
def make_interactive_app(*command_names):
class TestInteractive(base.TestBase):
def make_interactive_app(self, *command_names):
fake_command_manager = [(x, None) for x in command_names]
return InteractiveApp(FakeApp, fake_command_manager,
stdin=None, stdout=None)
def _test_completenames(self, expecteds, prefix):
app = self.make_interactive_app('hips', 'hippo', 'nonmatching')
self.assertEqual(set(app.completenames(prefix)), set(expecteds))
def _test_completenames(expecteds, prefix):
app = make_interactive_app('hips', 'hippo', 'nonmatching')
assert set(app.completenames(prefix)) == set(expecteds)
def test_cmd2_completenames():
def test_cmd2_completenames(self):
# cmd2.Cmd define do_help method
_test_completenames(['help'], 'he')
self._test_completenames(['help'], 'he')
def test_cliff_completenames(self):
self._test_completenames(['hips', 'hippo'], 'hip')
def test_cliff_completenames():
_test_completenames(['hips', 'hippo'], 'hip')
def test_no_completenames(self):
self._test_completenames([], 'taz')
def test_no_completenames():
_test_completenames([], 'taz')
def test_both_completenames():
def test_both_completenames(self):
# cmd2.Cmd define do_history method
# NOTE(dtroyer): Before release 0.7.0 do_hi was also defined so we need
# to account for that in the list of possible responses.
# Remove this check after cmd2 0.7.0 is the minimum
# requirement.
if hasattr(cmd2.Cmd, "do_hi"):
_test_completenames(['hi', 'history', 'hips', 'hippo'], 'hi')
self._test_completenames(['hi', 'history', 'hips', 'hippo'], 'hi')
else:
_test_completenames(['history', 'hips', 'hippo'], 'hi')
self._test_completenames(['history', 'hips', 'hippo'], 'hi')
def _test_completedefault(expecteds, line, begidx):
command_names = set(['show file', 'show folder', 'show long', 'list all'])
app = make_interactive_app(*command_names)
def _test_completedefault(self, expecteds, line, begidx):
command_names = set(['show file', 'show folder', 'show long',
'list all'])
app = self.make_interactive_app(*command_names)
observeds = app.completedefault(None, line, begidx, None)
assert set(observeds) == set(expecteds)
assert set([line[:begidx] + x for x in observeds]) <= command_names
self.assertEqual(set(expecteds), set(observeds))
self.assertTrue(
set([line[:begidx] + x for x in observeds]) <= command_names
)
def test_empty_text_completedefault():
def test_empty_text_completedefault(self):
# line = 'show ' + begidx = 5 implies text = ''
_test_completedefault(['file', 'folder', ' long'], 'show ', 5)
self._test_completedefault(['file', 'folder', ' long'], 'show ', 5)
def test_nonempty_text_completedefault2():
def test_nonempty_text_completedefault2(self):
# line = 'show f' + begidx = 6 implies text = 'f'
_test_completedefault(['file', 'folder'], 'show f', 5)
self._test_completedefault(['file', 'folder'], 'show f', 5)
def test_long_completedefault(self):
self._test_completedefault(['long'], 'show ', 6)
def test_long_completedefault():
_test_completedefault(['long'], 'show ', 6)
def test_no_completedefault():
_test_completedefault([], 'taz ', 4)
def test_no_completedefault(self):
self._test_completedefault([], 'taz ', 4)

View File

@ -15,6 +15,7 @@
import weakref
from cliff import lister
from cliff.tests import base
import mock
@ -43,7 +44,9 @@ class ExerciseLister(lister.Lister):
)
def test_formatter_args():
class TestLister(base.TestBase):
def test_formatter_args(self):
app = mock.Mock()
test_lister = ExerciseLister(app, [])
@ -53,23 +56,21 @@ def test_formatter_args():
test_lister.run(parsed_args)
f = test_lister._formatter_plugins['test']
assert len(f.args) == 1
self.assertEqual(1, len(f.args))
args = f.args[0]
assert args[0] == list(parsed_args.columns)
self.assertEqual(list(parsed_args.columns), args[0])
data = list(args[1])
assert data == [['a', 'A'], ['b', 'B']]
self.assertEqual([['a', 'A'], ['b', 'B']], data)
def test_no_exist_column():
def test_no_exist_column(self):
test_lister = ExerciseLister(mock.Mock(), [])
parsed_args = mock.Mock()
parsed_args.columns = ('no_exist_column',)
parsed_args.formatter = 'test'
with mock.patch.object(test_lister, 'take_action') as mock_take_action:
mock_take_action.return_value = (('Col1', 'Col2', 'Col3'), [])
try:
test_lister.run(parsed_args)
except ValueError:
pass
else:
assert False, 'Should have had an exception'
self.assertRaises(
ValueError,
test_lister.run,
parsed_args,
)

View File

@ -15,6 +15,7 @@
import weakref
from cliff import show
from cliff.tests import base
import mock
@ -43,7 +44,9 @@ class ExerciseShowOne(show.ShowOne):
)
def test_formatter_args():
class TestShow(base.TestBase):
def test_formatter_args(self):
app = mock.Mock()
test_show = ExerciseShowOne(app, [])
@ -53,32 +56,29 @@ def test_formatter_args():
test_show.run(parsed_args)
f = test_show._formatter_plugins['test']
assert len(f.args) == 1
self.assertEqual(1, len(f.args))
args = f.args[0]
assert args[0] == list(parsed_args.columns)
self.assertEqual(list(parsed_args.columns), args[0])
data = list(args[1])
assert data == [('a', 'A'), ('b', 'B')]
self.assertEqual([('a', 'A'), ('b', 'B')], data)
def test_dict2columns():
def test_dict2columns(self):
app = mock.Mock()
test_show = ExerciseShowOne(app, [])
d = {'a': 'A', 'b': 'B', 'c': 'C'}
expected = [('a', 'b', 'c'), ('A', 'B', 'C')]
actual = list(test_show.dict2columns(d))
assert expected == actual
self.assertEqual(expected, actual)
def test_no_exist_column():
def test_no_exist_column(self):
test_show = ExerciseShowOne(mock.Mock(), [])
parsed_args = mock.Mock()
parsed_args.columns = ('no_exist_column',)
parsed_args.formatter = 'test'
with mock.patch.object(test_show, 'take_action') as mock_take_action:
mock_take_action.return_value = (('Col1', 'Col2', 'Col3'), [])
try:
test_show.run(parsed_args)
except ValueError:
pass
else:
assert False, 'Should have had an exception'
self.assertRaises(
ValueError,
test_show.run,
parsed_args,
)

View File

@ -15,19 +15,20 @@
import argparse
import textwrap
from nose.tools import assert_equals
from cliff import sphinxext
from cliff.tests import base
def test_empty_help():
class TestSphinxExtension(base.TestBase):
def test_empty_help(self):
"""Handle positional and optional actions without help messages."""
parser = argparse.ArgumentParser(prog='hello-world', add_help=False)
parser.add_argument('name', action='store')
parser.add_argument('--language', dest='lang')
output = '\n'.join(sphinxext._format_parser(parser))
assert_equals(textwrap.dedent("""
self.assertEqual(textwrap.dedent("""
.. program:: hello-world
.. code-block:: shell
@ -38,15 +39,15 @@ def test_empty_help():
.. option:: name
""").lstrip(), output)
def test_nonempty_help():
def test_nonempty_help(self):
"""Handle positional and optional actions with help messages."""
parser = argparse.ArgumentParser(prog='hello-world', add_help=False)
parser.add_argument('name', help='user name')
parser.add_argument('--language', dest='lang', help='greeting language')
parser.add_argument('--language', dest='lang',
help='greeting language')
output = '\n'.join(sphinxext._format_parser(parser))
assert_equals(textwrap.dedent("""
self.assertEqual(textwrap.dedent("""
.. program:: hello-world
.. code-block:: shell
@ -61,8 +62,7 @@ def test_nonempty_help():
user name
""").lstrip(), output)
def test_flag():
def test_flag(self):
"""Handle a boolean argparse action."""
parser = argparse.ArgumentParser(prog='hello-world', add_help=False)
parser.add_argument('name', help='user name')
@ -70,7 +70,7 @@ def test_flag():
help='translate to local language')
output = '\n'.join(sphinxext._format_parser(parser))
assert_equals(textwrap.dedent("""
self.assertEqual(textwrap.dedent("""
.. program:: hello-world
.. code-block:: shell
@ -85,15 +85,14 @@ def test_flag():
user name
""").lstrip(), output)
def test_supressed():
def test_supressed(self):
"""Handle a supressed action."""
parser = argparse.ArgumentParser(prog='hello-world', add_help=False)
parser.add_argument('name', help='user name')
parser.add_argument('--variable', help=argparse.SUPPRESS)
output = '\n'.join(sphinxext._format_parser(parser))
assert_equals(textwrap.dedent("""
self.assertEqual(textwrap.dedent("""
.. program:: hello-world
.. code-block:: shell

View File

@ -15,65 +15,63 @@
import os
import struct
import sys
import unittest
import mock
import nose
from cliff import utils
from cliff.tests import base
def test_utils_terminal_width():
class TestTerminalWidth(base.TestBase):
def test(self):
width = utils.terminal_width(sys.stdout)
# Results are specific to the execution environment, so only assert
# that no error is raised.
assert width is None or isinstance(width, int)
if width is not None:
self.assertIsInstance(width, int)
@mock.patch('cliff.utils.os')
def test_utils_terminal_width_get_terminal_size(mock_os):
if not hasattr(os, 'get_terminal_size'):
raise nose.SkipTest('only needed for python 3.3 onwards')
@unittest.skipIf(not hasattr(os, 'get_terminal_size'),
'only needed for python 3.3 onwards')
@mock.patch('cliff.utils.os')
def test_get_terminal_size(self, mock_os):
ts = os.terminal_size((10, 5))
mock_os.get_terminal_size.return_value = ts
width = utils.terminal_width(sys.stdout)
assert width == 10
self.assertEqual(10, width)
mock_os.get_terminal_size.side_effect = OSError()
width = utils.terminal_width(sys.stdout)
assert width is None
self.assertIs(None, width)
@mock.patch('fcntl.ioctl')
def test_utils_terminal_width_ioctl(mock_ioctl):
if hasattr(os, 'get_terminal_size'):
raise nose.SkipTest('only needed for python 3.2 and before')
@unittest.skipIf(hasattr(os, 'get_terminal_size'),
'only needed for python 3.2 and before')
@mock.patch('fcntl.ioctl')
def test_ioctl(self, mock_ioctl):
mock_ioctl.return_value = struct.pack('hhhh', 57, 101, 0, 0)
width = utils.terminal_width(sys.stdout)
assert width == 101
self.assertEqual(101, width)
mock_ioctl.side_effect = IOError()
width = utils.terminal_width(sys.stdout)
assert width is None
@mock.patch('cliff.utils.ctypes')
@mock.patch('sys.platform', 'win32')
def test_utils_terminal_width_windows(mock_ctypes):
if hasattr(os, 'get_terminal_size'):
raise nose.SkipTest('only needed for python 3.2 and before')
self.assertIs(None, width)
@unittest.skipIf(hasattr(os, 'get_terminal_size'),
'only needed for python 3.2 and before')
@mock.patch('cliff.utils.ctypes')
@mock.patch('sys.platform', 'win32')
def test_windows(self, mock_ctypes):
mock_ctypes.create_string_buffer.return_value.raw = struct.pack(
'hhhhHhhhhhh', 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
mock_ctypes.windll.kernel32.GetStdHandle.return_value = -11
mock_ctypes.windll.kernel32.GetConsoleScreenBufferInfo.return_value = 1
width = utils.terminal_width(sys.stdout)
assert width == 101
self.assertEqual(101, width)
mock_ctypes.windll.kernel32.GetConsoleScreenBufferInfo.return_value = 0
width = utils.terminal_width(sys.stdout)
assert width is None
self.assertIs(None, width)
width = utils.terminal_width('foo')
assert width is None
self.assertIs(None, width)

View File

@ -1,9 +1,15 @@
# The order of packages is significant, because pip processes them in the order
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
nose # LGPL
python-subunit>=0.0.18 # Apache-2.0/BSD
testrepository>=0.0.18 # Apache-2.0/BSD
testtools>=1.4.0 # MIT
mock>=2.0 # BSD
testscenarios>=0.4 # Apache-2.0/BSD
coverage>=4.0 # Apache-2.0
# this is required for the docs build jobs
sphinx>=1.5.1 # BSD
oslosphinx>=4.7.0 # Apache-2.0

View File

@ -1,6 +1,6 @@
[tox]
minversion = 2.0
envlist = py35,py27,pypy,pep8
envlist = py35,py27,pep8
[testenv]
setenv =
@ -11,7 +11,9 @@ passenv =
ZUUL_CACHE_DIR
distribute = False
install_command = {toxinidir}/tools/tox_install.sh {env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} {opts} {packages}
commands = nosetests -d --with-coverage --cover-inclusive --cover-package cliff []
commands =
python setup.py test --coverage --coverage-package-name=cliff --slowest --testr-args='{posargs}'
coverage report --show-missing
deps = -r{toxinidir}/test-requirements.txt
[testenv:pep8]