summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--.testr.conf7
-rw-r--r--cliff/tests/base.py29
-rw-r--r--cliff/tests/test_app.py828
-rw-r--r--cliff/tests/test_columns.py19
-rw-r--r--cliff/tests/test_command.py69
-rw-r--r--cliff/tests/test_commandmanager.py240
-rw-r--r--cliff/tests/test_complete.py272
-rw-r--r--cliff/tests/test_formatters_csv.py119
-rw-r--r--cliff/tests/test_formatters_json.py214
-rw-r--r--cliff/tests/test_formatters_shell.py136
-rw-r--r--cliff/tests/test_formatters_table.py1036
-rw-r--r--cliff/tests/test_formatters_value.py82
-rw-r--r--cliff/tests/test_formatters_yaml.py142
-rw-r--r--cliff/tests/test_help.py300
-rw-r--r--cliff/tests/test_interactive.py116
-rw-r--r--cliff/tests/test_lister.py61
-rw-r--r--cliff/tests/test_show.py78
-rw-r--r--cliff/tests/test_sphinxext.py121
-rw-r--r--cliff/tests/test_utils.py114
-rw-r--r--test-requirements.txt8
-rw-r--r--tox.ini6
22 files changed, 2065 insertions, 1935 deletions
diff --git a/.gitignore b/.gitignore
index ba52b1e..28420f9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,3 +38,6 @@ ChangeLog
# Editors
*~
.*.swp
+/.testrepository/
+/cover/
+.coverage.* \ No newline at end of file
diff --git a/.testr.conf b/.testr.conf
new file mode 100644
index 0000000..faf55cf
--- /dev/null
+++ b/.testr.conf
@@ -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
diff --git a/cliff/tests/base.py b/cliff/tests/base.py
new file mode 100644
index 0000000..7afce02
--- /dev/null
+++ b/cliff/tests/base.py
@@ -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))
diff --git a/cliff/tests/test_app.py b/cliff/tests/test_app.py
index 26149a2..4430d77 100644
--- a/cliff/tests/test_app.py
+++ b/cliff/tests/test_app.py
@@ -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,440 +60,441 @@ def make_app(**kwargs):
return app, command
-def test_no_args_triggers_interactive_mode():
- app, command = make_app()
- app.interact = mock.MagicMock(name='inspect')
- app.run([])
- app.interact.assert_called_once_with()
-
-
-def test_interactive_mode_cmdloop():
- app, command = make_app()
- app.interactive_app_factory = mock.MagicMock(
- name='interactive_app_factory'
- )
- assert app.interpreter is None
- app.run([])
- assert app.interpreter is not None
- app.interactive_app_factory.return_value.cmdloop.assert_called_once_with()
-
-
-def test_initialize_app():
- 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():
- app, command = make_app()
- 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():
- 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():
- app, command = make_app()
-
- app.clean_up = mock.MagicMock(name='clean_up')
- app.run(['error'])
+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(self):
+ app, command = make_app()
+ app.interactive_app_factory = mock.MagicMock(
+ name='interactive_app_factory'
+ )
+ self.assertIs(None, app.interpreter)
+ app.run([])
+ self.assertIsNot(None, app.interpreter)
+ cmdloop = app.interactive_app_factory.return_value.cmdloop
+ cmdloop.assert_called_once_with()
+
+
+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(self):
+ app, command = make_app()
+ 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(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(self):
+ app, command = make_app()
+
+ app.clean_up = mock.MagicMock(name='clean_up')
+ app.run(['error'])
+
+ app.clean_up.assert_called_once_with(mock.ANY, mock.ANY, mock.ANY)
+ call_args = app.clean_up.call_args_list[0]
+ self.assertEqual(mock.call(mock.ANY, 1, mock.ANY), call_args)
+ args, kwargs = call_args
+ self.assertIsInstance(args[2], RuntimeError)
+ self.assertEqual(('test exception',), args[2].args)
+
+ 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:
+ self.assertIs(err, app.clean_up.call_args_list[0][0][2])
+ else:
+ self.fail('Should have had an exception')
+
+ self.assertTrue(app.clean_up.called)
+ call_args = app.clean_up.call_args_list[0]
+ self.assertEqual(mock.call(mock.ANY, 1, mock.ANY), call_args)
+ args, kwargs = call_args
+ self.assertIsInstance(args[2], RuntimeError)
+ self.assertEqual(('test exception',), args[2].args)
+
+ def test_error_handling_clean_up_raises_exception(self):
+ app, command = make_app()
+
+ app.clean_up = mock.MagicMock(
+ name='clean_up',
+ side_effect=RuntimeError('within clean_up'),
+ )
+ app.run(['error'])
+
+ self.assertTrue(app.clean_up.called)
+ call_args = app.clean_up.call_args_list[0]
+ self.assertEqual(mock.call(mock.ANY, 1, mock.ANY), call_args)
+ args, kwargs = call_args
+ self.assertIsInstance(args[2], RuntimeError)
+ self.assertEqual(('test exception',), args[2].args)
+
+ def test_error_handling_clean_up_raises_exception_debug(self):
+ app, command = make_app()
+
+ app.clean_up = mock.MagicMock(
+ name='clean_up',
+ side_effect=RuntimeError('within clean_up'),
+ )
+ try:
+ app.run(['--debug', 'error'])
+ except RuntimeError as err:
+ if not hasattr(err, '__context__'):
+ # The exception passed to clean_up is not the exception
+ # 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.
+ self.assertIsNot(err, app.clean_up.call_args_list[0][0][2])
+ else:
+ self.fail('Should have had an exception')
+
+ self.assertTrue(app.clean_up.called)
+ call_args = app.clean_up.call_args_list[0]
+ self.assertEqual(mock.call(mock.ANY, 1, mock.ANY), call_args)
+ args, kwargs = call_args
+ self.assertIsInstance(args[2], RuntimeError)
+ self.assertEqual(('test exception',), args[2].args)
+
+ def test_normal_clean_up_raises_exception(self):
+ app, command = make_app()
+
+ app.clean_up = mock.MagicMock(
+ name='clean_up',
+ side_effect=RuntimeError('within clean_up'),
+ )
+ app.run(['mock'])
+
+ self.assertTrue(app.clean_up.called)
+ call_args = app.clean_up.call_args_list[0]
+ self.assertEqual(mock.call(mock.ANY, 0, None), call_args)
+
+ def test_normal_clean_up_raises_exception_debug(self):
+ app, command = make_app()
+
+ app.clean_up = mock.MagicMock(
+ name='clean_up',
+ side_effect=RuntimeError('within clean_up'),
+ )
+ app.run(['--debug', 'mock'])
+
+ self.assertTrue(app.clean_up.called)
+ call_args = app.clean_up.call_args_list[0]
+ self.assertEqual(mock.call(mock.ANY, 0, None), call_args)
+
+
+class TestOptionParser(base.TestBase):
+
+ def test_conflicting_option_should_throw(self):
+ class MyApp(application.App):
+ def __init__(self):
+ super(MyApp, self).__init__(
+ description='testing',
+ version='0.1',
+ command_manager=commandmanager.CommandManager('tests'),
+ )
+
+ def build_option_parser(self, description, version):
+ parser = super(MyApp, self).build_option_parser(description,
+ version)
+ parser.add_argument(
+ '-h', '--help',
+ default=self, # tricky
+ help="Show help message and exit.",
+ )
+
+ self.assertRaises(
+ argparse.ArgumentError,
+ MyApp,
+ )
+
+ def test_conflicting_option_custom_arguments_should_not_throw(self):
+ class MyApp(application.App):
+ def __init__(self):
+ super(MyApp, self).__init__(
+ description='testing',
+ version='0.1',
+ command_manager=commandmanager.CommandManager('tests'),
+ )
+
+ def build_option_parser(self, description, version):
+ argparse_kwargs = {'conflict_handler': 'resolve'}
+ parser = super(MyApp, self).build_option_parser(
+ description,
+ version,
+ argparse_kwargs=argparse_kwargs)
+ parser.add_argument(
+ '-h', '--help',
+ default=self, # tricky
+ help="Show help message and exit.",
+ )
- 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)
- args, kwargs = call_args
- assert isinstance(args[2], RuntimeError)
- assert args[2].args == ('test exception',)
+ MyApp()
+ 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)
+ parser.add_argument("--end")
+ return parser
-def test_clean_up_error_debug():
- app, command = make_app()
+ def take_action(self, parsed_args):
+ assert(parsed_args.end == '123')
- 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
- else:
- assert False, 'Should have had an exception'
+ class MyCommandManager(commandmanager.CommandManager):
+ def load_commands(self, namespace):
+ self.add_command("mycommand", MyCommand)
- assert app.clean_up.called
- call_args = app.clean_up.call_args_list[0]
- assert call_args == mock.call(mock.ANY, 1, mock.ANY)
- args, kwargs = call_args
- assert isinstance(args[2], RuntimeError)
- assert args[2].args == ('test exception',)
+ class MyApp(application.App):
+ def __init__(self):
+ super(MyApp, self).__init__(
+ description='testing',
+ version='0.1',
+ command_manager=MyCommandManager(None),
+ )
+ def build_option_parser(self, description, version):
+ parser = super(MyApp, self).build_option_parser(
+ description,
+ version,
+ argparse_kwargs={'allow_abbrev': False})
+ parser.add_argument('--endpoint')
+ return parser
-def test_error_handling_clean_up_raises_exception():
- app, command = make_app()
+ app = MyApp()
+ # NOTE(jd) --debug is necessary so assert in take_action()
+ # raises correctly here
+ app.run(['--debug', 'mycommand', '--end', '123'])
- app.clean_up = mock.MagicMock(
- name='clean_up',
- side_effect=RuntimeError('within clean_up'),
- )
- app.run(['error'])
- assert app.clean_up.called
- call_args = app.clean_up.call_args_list[0]
- assert call_args == mock.call(mock.ANY, 1, mock.ANY)
- args, kwargs = call_args
- assert isinstance(args[2], RuntimeError)
- assert args[2].args == ('test exception',)
+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:
+ self.assertRaises(
+ SystemExit,
+ app.run,
+ ['--help'],
+ )
+ self.assertTrue(helper.called)
+ self.assertEqual(deferred_help, init.called)
-def test_error_handling_clean_up_raises_exception_debug():
- app, command = make_app()
+ def test_help(self):
+ self._test_help(False)
- app.clean_up = mock.MagicMock(
- name='clean_up',
- side_effect=RuntimeError('within clean_up'),
- )
- try:
- app.run(['--debug', 'error'])
- except RuntimeError as err:
- if not hasattr(err, '__context__'):
- # The exception passed to clean_up is not the exception
- # 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
- else:
- assert False, 'Should have had an exception'
-
- assert app.clean_up.called
- call_args = app.clean_up.call_args_list[0]
- assert call_args == mock.call(mock.ANY, 1, mock.ANY)
- args, kwargs = call_args
- assert isinstance(args[2], RuntimeError)
- assert args[2].args == ('test exception',)
-
-
-def test_normal_clean_up_raises_exception():
- app, command = make_app()
-
- app.clean_up = mock.MagicMock(
- name='clean_up',
- side_effect=RuntimeError('within clean_up'),
- )
- app.run(['mock'])
-
- assert app.clean_up.called
- call_args = app.clean_up.call_args_list[0]
- assert call_args == mock.call(mock.ANY, 0, None)
+ def test_deferred_help(self):
+ self._test_help(True)
+ def test_subcommand_help(self):
+ app, _ = make_app(deferred_help=False)
-def test_normal_clean_up_raises_exception_debug():
- app, command = make_app()
-
- app.clean_up = mock.MagicMock(
- name='clean_up',
- side_effect=RuntimeError('within clean_up'),
- )
- app.run(['--debug', 'mock'])
+ # Help is called immediately
+ with mock.patch('cliff.help.HelpAction.__call__') as helper:
+ app.run(['show', 'files', '--help'])
- assert app.clean_up.called
- call_args = app.clean_up.call_args_list[0]
- assert call_args == mock.call(mock.ANY, 0, None)
-
-
-def test_build_option_parser_conflicting_option_should_throw():
- class MyApp(application.App):
- def __init__(self):
- super(MyApp, self).__init__(
- description='testing',
- version='0.1',
- command_manager=commandmanager.CommandManager('tests'),
- )
-
- def build_option_parser(self, description, version):
- parser = super(MyApp, self).build_option_parser(description,
- version)
- parser.add_argument(
- '-h', '--help',
- default=self, # tricky
- 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')
-
-
-def test_option_parser_conflicting_option_custom_arguments_should_not_throw():
- class MyApp(application.App):
- def __init__(self):
- super(MyApp, self).__init__(
- description='testing',
- version='0.1',
- command_manager=commandmanager.CommandManager('tests'),
- )
+ self.assertTrue(helper.called)
- def build_option_parser(self, description, version):
- argparse_kwargs = {'conflict_handler': 'resolve'}
- parser = super(MyApp, self).build_option_parser(
- description,
- version,
- argparse_kwargs=argparse_kwargs)
- parser.add_argument(
- '-h', '--help',
- default=self, # tricky
- help="Show help message and exit.",
- )
+ def test_subcommand_deferred_help(self):
+ app, _ = make_app(deferred_help=True)
- MyApp()
+ # Show that provide_help_if_requested() did not show help and exit
+ with mock.patch.object(app, 'run_subcommand') as helper:
+ app.run(['show', 'files', '--help'])
+ helper.assert_called_once_with(['help', 'show', 'files'])
-def test_option_parser_abbrev_issue():
- class MyCommand(c_cmd.Command):
- def get_parser(self, prog_name):
- parser = super(MyCommand, self).get_parser(prog_name)
- parser.add_argument("--end")
- return parser
- def take_action(self, parsed_args):
- assert(parsed_args.end == '123')
+class TestCommandLookup(base.TestBase):
- class MyCommandManager(commandmanager.CommandManager):
- def load_commands(self, namespace):
- self.add_command("mycommand", MyCommand)
+ def test_unknown_cmd(self):
+ app, command = make_app()
+ self.assertEqual(2, app.run(['hell']))
- class MyApp(application.App):
- def __init__(self):
- super(MyApp, self).__init__(
- description='testing',
- version='0.1',
- command_manager=MyCommandManager(None),
+ def test_unknown_cmd_debug(self):
+ app, command = make_app()
+ try:
+ self.assertEqual(2, app.run(['--debug', 'hell']))
+ except ValueError as err:
+ self.assertIn("['hell']", str(err))
+
+ def test_list_matching_commands(self):
+ stdout = StringIO()
+ app = application.App('testing', '1',
+ test_utils.TestCommandManager(
+ test_utils.TEST_NAMESPACE),
+ stdout=stdout)
+ app.NAME = 'test'
+ try:
+ self.assertEqual(2, app.run(['t']))
+ except SystemExit:
+ pass
+ output = stdout.getvalue()
+ 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(self):
+ cmd_mgr = commandmanager.CommandManager('cliff.fuzzy')
+ app = application.App('test', '1.0', cmd_mgr)
+ cmd_mgr.commands = {}
+ matches = app.get_fuzzy_matches('foo')
+ self.assertEqual([], matches)
+
+ 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)
+ cmd_mgr.commands = {}
+ cmd_mgr.add_command('user list', test_utils.TestCommand)
+ cmd_mgr.add_command('user show', test_utils.TestCommand)
+ matches = app.get_fuzzy_matches('user')
+ self.assertEqual(['user list', 'user show'], matches)
+
+ 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():
+ self.assertEqual(
+ 8,
+ utils.damerau_levenshtein('node', cmd, utils.COST),
)
+ matches = app.get_fuzzy_matches('node')
+ self.assertEqual(['complete', 'help', 'user'], matches)
+
+ 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')
+ self.assertEqual(['user'], matches)
+
+
+class TestVerboseMode(base.TestBase):
+
+ def test_verbose(self):
+ app, command = make_app()
+ app.clean_up = mock.MagicMock(name='clean_up')
+ app.run(['--verbose', 'mock'])
+ app.clean_up.assert_called_once_with(command.return_value, 0, None)
+ app.clean_up.reset_mock()
+ app.run(['--quiet', 'mock'])
+ app.clean_up.assert_called_once_with(command.return_value, 0, None)
+ self.assertRaises(
+ SystemExit,
+ app.run,
+ ['--verbose', '--quiet', 'mock'],
+ )
+
+
+class TestIO(base.TestBase):
+
+ def test_io_streams(self):
+ cmd_mgr = commandmanager.CommandManager('cliff.tests')
+ io = mock.Mock()
+
+ if six.PY2:
+ stdin_save = sys.stdin
+ stdout_save = sys.stdout
+ stderr_save = sys.stderr
+ encoding = locale.getpreferredencoding() or 'utf-8'
+
+ app = application.App('no io streams', 1, cmd_mgr)
+ 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)
+ 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)
+ 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)
+ self.assertIsInstance(app.stdin, codecs.StreamReader)
+ self.assertIsInstance(app.stdout, codecs.StreamWriter)
+ self.assertIs(io, app.stderr)
- def build_option_parser(self, description, version):
- parser = super(MyApp, self).build_option_parser(
- description,
- version,
- argparse_kwargs={'allow_abbrev': False})
- parser.add_argument('--endpoint')
- return parser
-
- app = MyApp()
- # NOTE(jd) --debug is necessary so assert in take_action() raises correctly
- # here
- app.run(['--debug', 'mycommand', '--end', '123'])
-
-
-def _test_help(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
-
-
-def test_help():
- _test_help(False)
-
-
-def test_deferred_help():
- _test_help(True)
-
-
-def test_subcommand_help():
- 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
-
-
-def test_subcommand_deferred_help():
- app, _ = make_app(deferred_help=True)
-
- # Show that provide_help_if_requested() did not show help and exit
- with mock.patch.object(app, 'run_subcommand') as helper:
- app.run(['show', 'files', '--help'])
-
- helper.assert_called_once_with(['help', 'show', 'files'])
-
-
-def test_unknown_cmd():
- app, command = make_app()
- assert app.run(['hell']) == 2
-
-
-def test_unknown_cmd_debug():
- app, command = make_app()
- try:
- app.run(['--debug', 'hell']) == 2
- except ValueError as err:
- assert "['hell']" in ('%s' % err)
-
-
-def test_list_matching_commands():
- stdout = StringIO()
- app = application.App('testing', '1',
- test_utils.TestCommandManager(
- test_utils.TEST_NAMESPACE),
- stdout=stdout)
- app.NAME = 'test'
- try:
- assert app.run(['t']) == 2
- 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
+ sys.stdin = codecs.getreader(encoding)(sys.stdin)
+ app = application.App(
+ 'with wrapped sys.stdin io stream', 1, cmd_mgr)
+ 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)
+ self.assertIsInstance(app.stdin, codecs.StreamReader)
+ self.assertIs(sys.stdout, app.stdout)
+ self.assertIsInstance(app.stderr, codecs.StreamWriter)
+ finally:
+ sys.stdout = stdout_save
-def test_fuzzy_no_commands():
- 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 == []
-
-
-def test_fuzzy_common_prefix():
- # searched string is a prefix of all commands
- cmd_mgr = commandmanager.CommandManager('cliff.fuzzy')
- app = application.App('test', '1.0', cmd_mgr)
- cmd_mgr.commands = {}
- 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']
-
-
-def test_fuzzy_same_distance():
- # 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
- matches = app.get_fuzzy_matches('node')
- assert matches == ['complete', 'help', 'user']
-
-
-def test_fuzzy_no_prefix():
- # 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']
-
-
-def test_verbose():
- app, command = make_app()
- app.clean_up = mock.MagicMock(name='clean_up')
- app.run(['--verbose', 'mock'])
- app.clean_up.assert_called_once_with(command.return_value, 0, None)
- 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')
-
-
-def test_io_streams():
- cmd_mgr = commandmanager.CommandManager('cliff.tests')
- io = mock.Mock()
-
- if six.PY2:
- stdin_save = sys.stdin
- stdout_save = sys.stdout
- stderr_save = sys.stderr
- 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)
-
- 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)
-
- 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 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
-
- 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)
- 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)
- 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
- 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
-
- 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
-
- 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 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
+ try:
+ sys.stderr = codecs.getwriter(encoding)(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)
+ 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)
+ 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)
+ 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)
+ self.assertIs(sys.stdin, app.stdin)
+ self.assertIs(sys.stdout, app.stdout)
+ self.assertIs(io, app.stderr)
diff --git a/cliff/tests/test_columns.py b/cliff/tests/test_columns.py
index d7bb2b0..fef1128 100644
--- a/cliff/tests/test_columns.py
+++ b/cliff/tests/test_columns.py
@@ -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_machine(self):
+ c = FauxColumn(['list', 'of', 'values'])
+ self.assertEqual(['list', 'of', 'values'], c.machine_readable())
-def test_faux_column_human():
- c = FauxColumn(['list', 'of', 'values'])
- assert c.human_readable() == \
- u"I made this string myself: ['list', 'of', 'values']"
+ 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(),
+ )
diff --git a/cliff/tests/test_command.py b/cliff/tests/test_command.py
index 55bb61c..4bc03aa 100644
--- a/cliff/tests/test_command.py
+++ b/cliff/tests/test_command.py
@@ -11,6 +11,7 @@
# under the License.
from cliff import command
+from cliff.tests import base
class TestCommand(command.Command):
@@ -51,47 +52,44 @@ class TestCommandNoDocstring(command.Command):
return 42
-def test_get_description_docstring():
- cmd = TestCommand(None, None)
- desc = cmd.get_description()
- assert desc == "Description of command.\n "
+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():
- cmd = TestCommand(None, None)
- # Artificially inject a value for _description to verify that it
- # overrides the docstring.
- cmd._description = 'this is not the default'
- desc = cmd.get_description()
- assert desc == 'this is not the default'
+ def test_get_description_attribute(self):
+ cmd = TestCommand(None, None)
+ # Artificially inject a value for _description to verify that it
+ # overrides the docstring.
+ cmd._description = 'this is not the default'
+ desc = cmd.get_description()
+ assert desc == 'this is not the default'
+ def test_get_description_default(self):
+ cmd = TestCommandNoDocstring(None, None)
+ desc = cmd.get_description()
+ assert desc == ''
-def test_get_description_default():
- cmd = TestCommandNoDocstring(None, None)
- desc = cmd.get_description()
- assert desc == ''
+class TestBasicValues(base.TestBase):
-def test_get_parser():
- cmd = TestCommand(None, None)
- parser = cmd.get_parser('NAME')
- assert parser.prog == 'NAME'
+ def test_get_parser(self):
+ cmd = TestCommand(None, None)
+ parser = cmd.get_parser('NAME')
+ assert parser.prog == 'NAME'
+ def test_get_name(self):
+ cmd = TestCommand(None, None, cmd_name='object action')
+ assert cmd.cmd_name == 'object action'
-def test_get_name():
- cmd = TestCommand(None, None, cmd_name='object action')
- assert cmd.cmd_name == 'object action'
+ def test_run_return(self):
+ cmd = TestCommand(None, None, cmd_name='object action')
+ assert cmd.run(None) == 42
-def test_run_return():
- 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())
diff --git a/cliff/tests/test_commandmanager.py b/cliff/tests/test_commandmanager.py
index 7f5ce0c..e4ba225 100644
--- a/cliff/tests/test_commandmanager.py
+++ b/cliff/tests/test_commandmanager.py
@@ -11,122 +11,142 @@
# 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
- mgr = utils.TestCommandManager(utils.TEST_NAMESPACE)
- for expected in [['one'],
- ['two', 'words'],
- ['three', 'word', 'command'],
- ]:
- yield check, mgr, expected
- return
-
-
-def test_lookup_with_remainder():
- def check(mgr, argv):
- cmd, name, remaining = mgr.find_command(argv)
- assert cmd
- assert remaining == ['--opt']
- mgr = utils.TestCommandManager(utils.TEST_NAMESPACE)
- for expected in [['one', '--opt'],
- ['two', 'words', '--opt'],
- ['three', 'word', 'command', '--opt'],
- ]:
- yield check, mgr, expected
- return
-
-
-def test_find_invalid_command():
- mgr = utils.TestCommandManager(utils.TEST_NAMESPACE)
-
- def check_one(argv):
+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)
+ cmd, name, remaining = mgr.find_command(self.argv)
+ self.assertTrue(cmd)
+ self.assertEqual(' '.join(self.argv), name)
+ self.assertFalse(remaining)
+
+
+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)
+ cmd, name, remaining = mgr.find_command(self.argv)
+ self.assertTrue(cmd)
+ self.assertEqual(['--opt'], remaining)
+
+
+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)
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:
+ self.fail('expected a failure')
+
+
+class TestFindUnknownCommand(base.TestBase):
+
+ def test(self):
+ mgr = utils.TestCommandManager(utils.TEST_NAMESPACE)
+ try:
+ mgr.find_command(['a', 'b'])
+ except ValueError as err:
+ self.assertIn("['a', 'b']", str(err))
else:
- assert False, 'expected a failure'
- for argv in [['a', '-b'],
- ['-b'],
- ]:
- yield check_one, argv
-
-
-def test_find_unknown_command():
- mgr = utils.TestCommandManager(utils.TEST_NAMESPACE)
- try:
- mgr.find_command(['a', 'b'])
- except ValueError as err:
- assert "['a', 'b']" in ('%s' % err)
- else:
- assert False, 'expected a failure'
-
-
-def test_add_command():
- 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
-
-
-def test_intersected_commands():
- def foo(arg):
- pass
-
- def foo_bar():
- pass
-
- mgr = utils.TestCommandManager(utils.TEST_NAMESPACE)
- 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
-
-
-def test_load_commands():
- testcmd = mock.Mock(name='testcmd')
- testcmd.name.replace.return_value = 'test'
- 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')
- iter_entry_points.assert_called_once_with('test')
- names = [n for n, v in mgr]
- assert names == ['test']
-
-
-def test_load_commands_keep_underscores():
- 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)
- iter_entry_points.assert_called_once_with('test')
- names = [n for n, v in mgr]
- assert names == ['test_cmd']
-
-
-def test_load_commands_replace_underscores():
- 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)
- iter_entry_points.assert_called_once_with('test')
- names = [n for n, v in mgr]
- assert names == ['test cmd']
+ self.fail('expected a failure')
+
+
+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'])
+ self.assertIs(mock_cmd, found_cmd)
+
+ def test_intersected_commands(self):
+ def foo(arg):
+ pass
+
+ def foo_bar():
+ pass
+
+ mgr = utils.TestCommandManager(utils.TEST_NAMESPACE)
+ mgr.add_command('foo', foo)
+ mgr.add_command('foo bar', foo_bar)
+
+ self.assertIs(foo_bar, mgr.find_command(['foo', 'bar'])[0])
+ self.assertIs(
+ foo,
+ mgr.find_command(['foo', 'arg0'])[0],
+ )
+
+
+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])
+ with mock.patch('pkg_resources.iter_entry_points',
+ mock_pkg_resources) as iter_entry_points:
+ mgr = commandmanager.CommandManager('test')
+ iter_entry_points.assert_called_once_with('test')
+ names = [n for n, v in mgr]
+ self.assertEqual(['test'], names)
+
+ 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,
+ )
+ iter_entry_points.assert_called_once_with('test')
+ names = [n for n, v in mgr]
+ self.assertEqual(['test_cmd'], names)
+
+ 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,
+ )
+ iter_entry_points.assert_called_once_with('test')
+ names = [n for n, v in mgr]
+ self.assertEqual(['test cmd'], names)
diff --git a/cliff/tests/test_complete.py b/cliff/tests/test_complete.py
index b1523ec..a4f8dc4 100644
--- a/cliff/tests/test_complete.py
+++ b/cliff/tests/test_complete.py
@@ -18,50 +18,52 @@ import mock
from cliff import app as application
from cliff import commandmanager
from cliff import complete
-
-
-def test_complete_dictionary():
- sot = complete.CompleteDictionary()
- sot.add_command("image delete".split(),
- [mock.Mock(option_strings=["1"])])
- sot.add_command("image list".split(),
- [mock.Mock(option_strings=["2"])])
- sot.add_command("image create".split(),
- [mock.Mock(option_strings=["3"])])
- sot.add_command("volume type create".split(),
- [mock.Mock(option_strings=["4"])])
- sot.add_command("volume type delete".split(),
- [mock.Mock(option_strings=["5"])])
- assert "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]
-
-
-def test_complete_dictionary_subcmd():
- sot = complete.CompleteDictionary()
- sot.add_command("image delete".split(),
- [mock.Mock(option_strings=["1"])])
- sot.add_command("image list".split(),
- [mock.Mock(option_strings=["2"])])
- sot.add_command("image list better".split(),
- [mock.Mock(option_strings=["3"])])
- assert "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]
+from cliff.tests import base
+
+
+class TestCompletion(base.TestBase):
+
+ def test_dictionary(self):
+ sot = complete.CompleteDictionary()
+ sot.add_command("image delete".split(),
+ [mock.Mock(option_strings=["1"])])
+ sot.add_command("image list".split(),
+ [mock.Mock(option_strings=["2"])])
+ sot.add_command("image create".split(),
+ [mock.Mock(option_strings=["3"])])
+ sot.add_command("volume type create".split(),
+ [mock.Mock(option_strings=["4"])])
+ sot.add_command("volume type delete".split(),
+ [mock.Mock(option_strings=["5"])])
+ self.assertEqual("image volume", sot.get_commands())
+ result = sot.get_data()
+ 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(self):
+ sot = complete.CompleteDictionary()
+ sot.add_command("image delete".split(),
+ [mock.Mock(option_strings=["1"])])
+ sot.add_command("image list".split(),
+ [mock.Mock(option_strings=["2"])])
+ sot.add_command("image list better".split(),
+ [mock.Mock(option_strings=["3"])])
+ self.assertEqual("image", sot.get_commands())
+ result = sot.get_data()
+ 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,96 +80,92 @@ class FakeStdout:
return result
-def given_cmdo_data():
- cmdo = "image server"
- data = [("image", "create"),
- ("image_create", "--eolus"),
- ("server", "meta ssh"),
- ("server_meta_delete", "--wilson"),
- ("server_ssh", "--sunlight")]
- return cmdo, data
-
-
-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():
- output = FakeStdout()
- sot = complete.CompleteNoCode("doesNotMatter", output)
- sot.write(*given_cmdo_data())
- then_data(output.content)
-
-
-def test_complete_bash():
- 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]
-
-
-def test_complete_command_parser():
- sot = complete.CompleteCommand(mock.Mock(), mock.Mock())
- parser = sot.get_parser('nothing')
- assert "nothing" == parser.prog
- assert "print bash completion command\n " == parser.description
-
-
-def given_complete_command():
- 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):
- optstr = ' '.join(opt for action in actions
- for opt in action.option_strings)
- assert '-h --help --name --shell' == optstr
-
-
-def test_complete_command_get_actions():
- sot, app, cmd_mgr = given_complete_command()
- app.interactive_mode = False
- actions = sot.get_actions(["complete"])
- then_actions_equal(actions)
-
-
-def test_complete_command_get_actions_interactive():
- sot, app, cmd_mgr = given_complete_command()
- app.interactive_mode = True
- actions = sot.get_actions(["complete"])
- then_actions_equal(actions)
-
-
-def test_complete_command_take_action():
- sot, app, cmd_mgr = 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
-
-
-def test_complete_command_remove_dashes():
- sot, app, cmd_mgr = 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]
+class TestCompletionAlternatives(base.TestBase):
+
+ def given_cmdo_data(self):
+ cmdo = "image server"
+ data = [("image", "create"),
+ ("image_create", "--eolus"),
+ ("server", "meta ssh"),
+ ("server_meta_delete", "--wilson"),
+ ("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 test_complete_no_code(self):
+ output = FakeStdout()
+ sot = complete.CompleteNoCode("doesNotMatter", output)
+ sot.write(*self.given_cmdo_data())
+ self.then_data(output.content)
+
+ def test_complete_bash(self):
+ output = FakeStdout()
+ sot = complete.CompleteBash("openstack", output)
+ 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(self):
+ sot = complete.CompleteCommand(mock.Mock(), mock.Mock())
+ parser = sot.get_parser('nothing')
+ self.assertEqual("nothing", parser.prog)
+ self.assertEqual("print bash completion command\n ",
+ parser.description)
+
+
+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(self, actions):
+ optstr = ' '.join(opt for action in actions
+ for opt in action.option_strings)
+ self.assertEqual('-h --help --name --shell', optstr)
+
+ def test_complete_command_get_actions(self):
+ sot, app, cmd_mgr = self.given_complete_command()
+ app.interactive_mode = False
+ actions = sot.get_actions(["complete"])
+ self.then_actions_equal(actions)
+
+ 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"])
+ self.then_actions_equal(actions)
+
+ 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
+ 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(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
+ 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])
diff --git a/cliff/tests/test_formatters_csv.py b/cliff/tests/test_formatters_csv.py
index 27c6f84..001f169 100644
--- a/cliff/tests/test_formatters_csv.py
+++ b/cliff/tests/test_formatters_csv.py
@@ -13,73 +13,74 @@
# 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():
- sf = commaseparated.CSVLister()
- c = ('a', 'b', 'c')
- d1 = ('A', 'B', 'C')
- d2 = ('D', 'E', 'F')
- data = [d1, d2]
- expected = 'a,b,c\nA,B,C\nD,E,F\n'
- output = six.StringIO()
- parsed_args = mock.Mock()
- parsed_args.quote_mode = 'none'
- sf.emit_list(c, data, output, parsed_args)
- actual = output.getvalue()
- assert expected == actual
-
-
-def test_commaseparated_list_formatter_quoted():
- sf = commaseparated.CSVLister()
- c = ('a', 'b', 'c')
- d1 = ('A', 'B', 'C')
- d2 = ('D', 'E', 'F')
- data = [d1, d2]
- expected = '"a","b","c"\n"A","B","C"\n"D","E","F"\n'
- output = six.StringIO()
- # Parse arguments as if passed on the command-line
- parser = argparse.ArgumentParser(description='Testing...')
- sf.add_argument_group(parser)
- parsed_args = parser.parse_args(['--quote', 'all'])
- sf.emit_list(c, data, output, parsed_args)
- actual = output.getvalue()
- assert expected == actual
+class TestCSVFormatter(unittest.TestCase):
+ def test_commaseparated_list_formatter(self):
+ sf = commaseparated.CSVLister()
+ c = ('a', 'b', 'c')
+ d1 = ('A', 'B', 'C')
+ d2 = ('D', 'E', 'F')
+ data = [d1, d2]
+ expected = 'a,b,c\nA,B,C\nD,E,F\n'
+ output = six.StringIO()
+ parsed_args = mock.Mock()
+ parsed_args.quote_mode = 'none'
+ sf.emit_list(c, data, output, parsed_args)
+ actual = output.getvalue()
+ self.assertEqual(expected, actual)
-def test_commaseparated_list_formatter_formattable_column():
- sf = commaseparated.CSVLister()
- c = ('a', 'b', 'c')
- d1 = ('A', 'B', test_columns.FauxColumn(['the', 'value']))
- data = [d1]
- expected = 'a,b,c\nA,B,[\'the\'\\, \'value\']\n'
- output = six.StringIO()
- parsed_args = mock.Mock()
- parsed_args.quote_mode = 'none'
- sf.emit_list(c, data, output, parsed_args)
- actual = output.getvalue()
- assert expected == actual
+ def test_commaseparated_list_formatter_quoted(self):
+ sf = commaseparated.CSVLister()
+ c = ('a', 'b', 'c')
+ d1 = ('A', 'B', 'C')
+ d2 = ('D', 'E', 'F')
+ data = [d1, d2]
+ expected = '"a","b","c"\n"A","B","C"\n"D","E","F"\n'
+ output = six.StringIO()
+ # Parse arguments as if passed on the command-line
+ parser = argparse.ArgumentParser(description='Testing...')
+ sf.add_argument_group(parser)
+ parsed_args = parser.parse_args(['--quote', 'all'])
+ sf.emit_list(c, data, output, parsed_args)
+ actual = output.getvalue()
+ self.assertEqual(expected, actual)
+ def test_commaseparated_list_formatter_formattable_column(self):
+ sf = commaseparated.CSVLister()
+ c = ('a', 'b', 'c')
+ d1 = ('A', 'B', test_columns.FauxColumn(['the', 'value']))
+ data = [d1]
+ expected = 'a,b,c\nA,B,[\'the\'\\, \'value\']\n'
+ output = six.StringIO()
+ parsed_args = mock.Mock()
+ parsed_args.quote_mode = 'none'
+ sf.emit_list(c, data, output, parsed_args)
+ actual = output.getvalue()
+ self.assertEqual(expected, actual)
-def test_commaseparated_list_formatter_unicode():
- sf = commaseparated.CSVLister()
- c = (u'a', u'b', u'c')
- d1 = (u'A', u'B', u'C')
- happy = u'高兴'
- d2 = (u'D', u'E', happy)
- data = [d1, d2]
- expected = u'a,b,c\nA,B,C\nD,E,%s\n' % happy
- output = six.StringIO()
- parsed_args = mock.Mock()
- parsed_args.quote_mode = 'none'
- sf.emit_list(c, data, output, parsed_args)
- actual = output.getvalue()
- if six.PY2:
- actual = actual.decode('utf-8')
- assert expected == actual
+ def test_commaseparated_list_formatter_unicode(self):
+ sf = commaseparated.CSVLister()
+ c = (u'a', u'b', u'c')
+ d1 = (u'A', u'B', u'C')
+ happy = u'高兴'
+ d2 = (u'D', u'E', happy)
+ data = [d1, d2]
+ expected = u'a,b,c\nA,B,C\nD,E,%s\n' % happy
+ output = six.StringIO()
+ parsed_args = mock.Mock()
+ parsed_args.quote_mode = 'none'
+ sf.emit_list(c, data, output, parsed_args)
+ actual = output.getvalue()
+ if six.PY2:
+ actual = actual.decode('utf-8')
+ self.assertEqual(expected, actual)
diff --git a/cliff/tests/test_formatters_json.py b/cliff/tests/test_formatters_json.py
index eb7397d..2f3a6e9 100644
--- a/cliff/tests/test_formatters_json.py
+++ b/cliff/tests/test_formatters_json.py
@@ -13,117 +13,117 @@
# 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():
- sf = json_format.JSONFormatter()
- c = ('a', 'b', 'c', 'd')
- d = ('A', 'B', 'C', '"escape me"')
- expected = {
- 'a': 'A',
- 'b': 'B',
- 'c': 'C',
- 'd': '"escape me"'
- }
- args = mock.Mock()
- sf.add_argument_group(args)
-
- args.noindent = True
- output = six.StringIO()
- sf.emit_one(c, d, output, args)
- value = output.getvalue()
- print(len(value.splitlines()))
- assert 1 == len(value.splitlines())
- actual = json.loads(value)
- assert expected == actual
-
- args.noindent = False
- output = six.StringIO()
- sf.emit_one(c, d, output, args)
- value = output.getvalue()
- assert 6 == len(value.splitlines())
- actual = json.loads(value)
- assert expected == actual
-
-
-def test_json_format_formattablecolumn_one():
- sf = json_format.JSONFormatter()
- c = ('a', 'b', 'c', 'd')
- d = ('A', 'B', 'C', test_columns.FauxColumn(['the', 'value']))
- expected = {
- 'a': 'A',
- 'b': 'B',
- 'c': 'C',
- 'd': ['the', 'value'],
- }
- args = mock.Mock()
- sf.add_argument_group(args)
-
- args.noindent = True
- output = six.StringIO()
- sf.emit_one(c, d, output, args)
- value = output.getvalue()
- print(len(value.splitlines()))
- assert 1 == len(value.splitlines())
- actual = json.loads(value)
- assert expected == actual
-
-
-def test_json_format_list():
- sf = json_format.JSONFormatter()
- c = ('a', 'b', 'c')
- d = (
- ('A1', 'B1', 'C1'),
- ('A2', 'B2', 'C2'),
- ('A3', 'B3', 'C3')
- )
- expected = [
- {'a': 'A1', 'b': 'B1', 'c': 'C1'},
- {'a': 'A2', 'b': 'B2', 'c': 'C2'},
- {'a': 'A3', 'b': 'B3', 'c': 'C3'}
- ]
- args = mock.Mock()
- sf.add_argument_group(args)
-
- args.noindent = True
- output = six.StringIO()
- sf.emit_list(c, d, output, args)
- value = output.getvalue()
- assert 1 == len(value.splitlines())
- actual = json.loads(value)
- assert expected == actual
-
- args.noindent = False
- output = six.StringIO()
- sf.emit_list(c, d, output, args)
- value = output.getvalue()
- assert 17 == len(value.splitlines())
- actual = json.loads(value)
- assert expected == actual
-
-
-def test_json_format_formattablecolumn_list():
- sf = json_format.JSONFormatter()
- c = ('a', 'b', 'c')
- d = (
- ('A1', 'B1', test_columns.FauxColumn(['the', 'value'])),
- )
- expected = [
- {'a': 'A1', 'b': 'B1', 'c': ['the', 'value']},
- ]
- args = mock.Mock()
- sf.add_argument_group(args)
-
- args.noindent = True
- output = six.StringIO()
- sf.emit_list(c, d, output, args)
- value = output.getvalue()
- assert 1 == len(value.splitlines())
- actual = json.loads(value)
- assert expected == actual
+class TestJSONFormatter(base.TestBase):
+
+ def test_one(self):
+ sf = json_format.JSONFormatter()
+ c = ('a', 'b', 'c', 'd')
+ d = ('A', 'B', 'C', '"escape me"')
+ expected = {
+ 'a': 'A',
+ 'b': 'B',
+ 'c': 'C',
+ 'd': '"escape me"'
+ }
+ args = mock.Mock()
+ sf.add_argument_group(args)
+
+ args.noindent = True
+ output = six.StringIO()
+ sf.emit_one(c, d, output, args)
+ value = output.getvalue()
+ print(len(value.splitlines()))
+ self.assertEqual(1, len(value.splitlines()))
+ actual = json.loads(value)
+ self.assertEqual(expected, actual)
+
+ args.noindent = False
+ output = six.StringIO()
+ sf.emit_one(c, d, output, args)
+ value = output.getvalue()
+ self.assertEqual(6, len(value.splitlines()))
+ actual = json.loads(value)
+ self.assertEqual(expected, actual)
+
+ def test_formattablecolumn_one(self):
+ sf = json_format.JSONFormatter()
+ c = ('a', 'b', 'c', 'd')
+ d = ('A', 'B', 'C', test_columns.FauxColumn(['the', 'value']))
+ expected = {
+ 'a': 'A',
+ 'b': 'B',
+ 'c': 'C',
+ 'd': ['the', 'value'],
+ }
+ args = mock.Mock()
+ sf.add_argument_group(args)
+
+ args.noindent = True
+ output = six.StringIO()
+ sf.emit_one(c, d, output, args)
+ value = output.getvalue()
+ print(len(value.splitlines()))
+ self.assertEqual(1, len(value.splitlines()))
+ actual = json.loads(value)
+ self.assertEqual(expected, actual)
+
+ def test_list(self):
+ sf = json_format.JSONFormatter()
+ c = ('a', 'b', 'c')
+ d = (
+ ('A1', 'B1', 'C1'),
+ ('A2', 'B2', 'C2'),
+ ('A3', 'B3', 'C3')
+ )
+ expected = [
+ {'a': 'A1', 'b': 'B1', 'c': 'C1'},
+ {'a': 'A2', 'b': 'B2', 'c': 'C2'},
+ {'a': 'A3', 'b': 'B3', 'c': 'C3'}
+ ]
+ args = mock.Mock()
+ sf.add_argument_group(args)
+
+ args.noindent = True
+ output = six.StringIO()
+ sf.emit_list(c, d, output, args)
+ value = output.getvalue()
+ self.assertEqual(1, len(value.splitlines()))
+ actual = json.loads(value)
+ self.assertEqual(expected, actual)
+
+ args.noindent = False
+ output = six.StringIO()
+ sf.emit_list(c, d, output, args)
+ value = output.getvalue()
+ self.assertEqual(17, len(value.splitlines()))
+ actual = json.loads(value)
+ self.assertEqual(expected, actual)
+
+ def test_formattablecolumn_list(self):
+ sf = json_format.JSONFormatter()
+ c = ('a', 'b', 'c')
+ d = (
+ ('A1', 'B1', test_columns.FauxColumn(['the', 'value'])),
+ )
+ expected = [
+ {'a': 'A1', 'b': 'B1', 'c': ['the', 'value']},
+ ]
+ args = mock.Mock()
+ sf.add_argument_group(args)
+
+ args.noindent = True
+ output = six.StringIO()
+ sf.emit_list(c, d, output, args)
+ value = output.getvalue()
+ self.assertEqual(1, len(value.splitlines()))
+ actual = json.loads(value)
+ self.assertEqual(expected, actual)
diff --git a/cliff/tests/test_formatters_shell.py b/cliff/tests/test_formatters_shell.py
index 7689f73..a6929a3 100644
--- a/cliff/tests/test_formatters_shell.py
+++ b/cliff/tests/test_formatters_shell.py
@@ -16,81 +16,81 @@ 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():
- sf = shell.ShellFormatter()
- c = ('a', 'b', 'c', 'd')
- d = ('A', 'B', 'C', '"escape me"')
- expected = 'a="A"\nb="B"\nd="\\"escape me\\""\n'
- output = six.StringIO()
- args = mock.Mock()
- args.variables = ['a', 'b', 'd']
- args.prefix = ''
- sf.emit_one(c, d, output, args)
- actual = output.getvalue()
- assert expected == actual
+class TestShellFormatter(base.TestBase):
+ def test(self):
+ sf = shell.ShellFormatter()
+ c = ('a', 'b', 'c', 'd')
+ d = ('A', 'B', 'C', '"escape me"')
+ expected = 'a="A"\nb="B"\nd="\\"escape me\\""\n'
+ output = six.StringIO()
+ args = mock.Mock()
+ args.variables = ['a', 'b', 'd']
+ args.prefix = ''
+ sf.emit_one(c, d, output, args)
+ actual = output.getvalue()
+ self.assertEqual(expected, actual)
-def test_shell_formatter_args():
- sf = shell.ShellFormatter()
- c = ('a', 'b', 'c', 'd')
- d = ('A', 'B', 'C', '"escape me"')
- expected = 'Xd="\\"escape me\\""\n'
- output = six.StringIO()
- # Parse arguments as if passed on the command-line
- parser = argparse.ArgumentParser(description='Testing...')
- sf.add_argument_group(parser)
- parsed_args = parser.parse_args(['--variable', 'd', '--prefix', 'X'])
- sf.emit_one(c, d, output, parsed_args)
- actual = output.getvalue()
- assert expected == actual
+ def test_args(self):
+ sf = shell.ShellFormatter()
+ c = ('a', 'b', 'c', 'd')
+ d = ('A', 'B', 'C', '"escape me"')
+ expected = 'Xd="\\"escape me\\""\n'
+ output = six.StringIO()
+ # Parse arguments as if passed on the command-line
+ parser = argparse.ArgumentParser(description='Testing...')
+ sf.add_argument_group(parser)
+ parsed_args = parser.parse_args(['--variable', 'd', '--prefix', 'X'])
+ sf.emit_one(c, d, output, parsed_args)
+ actual = output.getvalue()
+ self.assertEqual(expected, actual)
+ def test_formattable_column(self):
+ sf = shell.ShellFormatter()
+ c = ('a', 'b', 'c')
+ d = ('A', 'B', test_columns.FauxColumn(['the', 'value']))
+ expected = '\n'.join([
+ 'a="A"',
+ 'b="B"',
+ 'c="[\'the\', \'value\']"\n',
+ ])
+ output = six.StringIO()
+ args = mock.Mock()
+ args.variables = ['a', 'b', 'c']
+ args.prefix = ''
+ sf.emit_one(c, d, output, args)
+ actual = output.getvalue()
+ self.assertEqual(expected, actual)
-def test_shell_formatter_formattable_column():
- sf = shell.ShellFormatter()
- c = ('a', 'b', 'c')
- d = ('A', 'B', test_columns.FauxColumn(['the', 'value']))
- expected = '\n'.join([
- 'a="A"',
- 'b="B"',
- 'c="[\'the\', \'value\']"\n',
- ])
- output = six.StringIO()
- args = mock.Mock()
- args.variables = ['a', 'b', 'c']
- args.prefix = ''
- sf.emit_one(c, d, output, args)
- actual = output.getvalue()
- assert expected == actual
+ 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"\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()
+ self.assertEqual(expected, actual)
-
-def test_shell_formatter_with_non_string_values():
- 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'
- 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
-
-
-def test_shell_formatter_with_non_bash_friendly_values():
- sf = shell.ShellFormatter()
- c = ('a', 'foo-bar', 'provider:network_type')
- d = (True, 'baz', 'vxlan')
- expected = 'a="True"\nfoo_bar="baz"\nprovider_network_type="vxlan"\n'
- output = six.StringIO()
- args = mock.Mock()
- args.variables = ['a', 'foo-bar', 'provider:network_type']
- args.prefix = ''
- sf.emit_one(c, d, output, args)
- actual = output.getvalue()
- assert expected == actual
+ def test_non_bash_friendly_values(self):
+ sf = shell.ShellFormatter()
+ c = ('a', 'foo-bar', 'provider:network_type')
+ d = (True, 'baz', 'vxlan')
+ expected = 'a="True"\nfoo_bar="baz"\nprovider_network_type="vxlan"\n'
+ output = six.StringIO()
+ args = mock.Mock()
+ args.variables = ['a', 'foo-bar', 'provider:network_type']
+ args.prefix = ''
+ sf.emit_one(c, d, output, args)
+ actual = output.getvalue()
+ self.assertEqual(expected, actual)
diff --git a/cliff/tests/test_formatters_table.py b/cliff/tests/test_formatters_table.py
index 7e8cf97..e1b2f09 100644
--- a/cliff/tests/test_formatters_table.py
+++ b/cliff/tests/test_formatters_table.py
@@ -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):
- 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)
-
-
-# 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 |
-+-------+--------------------------------+
-'''
-
-# 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
-
-# Single-line output, for when no line length restriction apply
-expected_sl_val = '''\
-+-------+-------------------------------------------------------------------------------+
-| 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):
- 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())
-
-
-@mock.patch('cliff.utils.terminal_width')
-def test_table_formatter_cli_param(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']))
-
-
-@mock.patch('cliff.utils.terminal_width')
-def test_table_formatter_no_cli_param_unlimited_tw(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())
-
-
-@mock.patch('cliff.utils.terminal_width')
-def test_table_formatter_cli_param_unlimited_tw(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']))
-
-
-@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):
- 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']))
-
-
-@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):
- 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']))
-
-
-@mock.patch('cliff.utils.terminal_width')
-def test_table_formatter_max_width(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)
-
- # 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)
-
- # 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)
-
- # 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)
-
-
-@mock.patch('cliff.utils.terminal_width')
-def test_table_list_formatter(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)
-
-
-@mock.patch('cliff.utils.terminal_width')
-def test_table_formatter_formattable_column(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)
-
-
-_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):
- 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)
-
-
-@mock.patch('cliff.utils.terminal_width')
-def test_table_list_formatter_max_width(tw):
- # no resize
- l = tw.return_value = 80
- assert _expected_mv[l] == _table_tester_helper(_col_names, _col_data)
-
- # 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
-
- # 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
-
- # 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
-
- # 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
- # 3 columns each 8 wide, plus table spacing and borders
- expected_width = 11 * 3 + 1
- assert len(actual.splitlines()[0]) == expected_width
-
-
-# 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):
- # no resize
- tw.return_value = 80
- assert _expected_mv[80] == _table_tester_helper(_col_names, _col_data)
-
- # resize 1 column
- tw.return_value = 50
- assert _expected_mv[80] == _table_tester_helper(_col_names, _col_data)
-
- # resize 2 columns
- tw.return_value = 45
- assert _expected_mv[80] == _table_tester_helper(_col_names, _col_data)
-
- # resize all columns
- tw.return_value = 40
- assert _expected_mv[80] == _table_tester_helper(_col_names, _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)
-
-
-# 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):
- # no resize
- tw.return_value = 80
- assert _expected_mv[47] == _table_tester_helper(_col_names, _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
-
- # 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
-
- # 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
-
- # 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
-
-
-@mock.patch.dict(os.environ, {'CLIFF_MAX_TERM_WIDTH': '80'})
-def test_table_list_formatter_env_maxwidth_noresize():
- # no resize
- assert _expected_mv[80] == _table_tester_helper(_col_names, _col_data)
-
-
-@mock.patch.dict(os.environ, {'CLIFF_MAX_TERM_WIDTH': '50'})
-def test_table_list_formatter_env_maxwidth_resize_one():
- # resize 1 column
- actual = _table_tester_helper(_col_names, _col_data)
- assert _expected_mv[50] == actual
- assert len(actual.splitlines()[0]) == 50
-
-
-@mock.patch.dict(os.environ, {'CLIFF_MAX_TERM_WIDTH': '45'})
-def test_table_list_formatter_env_maxwidth_resize_two():
- # resize 2 columns
- actual = _table_tester_helper(_col_names, _col_data)
- assert _expected_mv[45] == actual
- assert len(actual.splitlines()[0]) == 45
-
-
-@mock.patch.dict(os.environ, {'CLIFF_MAX_TERM_WIDTH': '40'})
-def test_table_list_formatter_env_maxwidth_resize_all():
- # resize all columns
- actual = _table_tester_helper(_col_names, _col_data)
- assert _expected_mv[40] == actual
- assert len(actual.splitlines()[0]) == 40
-
-
-@mock.patch.dict(os.environ, {'CLIFF_MAX_TERM_WIDTH': '8'})
-def test_table_list_formatter_env_maxwidth_resize_all_tiny():
- # resize all columns limited by min_width=8
- actual = _table_tester_helper(_col_names, _col_data)
- assert _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
-
-
-@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_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):
- tw.return_value = 80
- c = ('a', 'b', 'c')
- data = []
- expected = '\n'
- assert expected == _table_tester_helper(c, data)
-
-
-@mock.patch('cliff.utils.terminal_width')
-def test_table_list_formatter_empty_table(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'])
-
-
-def test_field_widths():
- tf = table.TableFormatter
- assert {
- 'a': 1,
- 'b': 2,
- 'c': 3,
- 'd': 10
- } == tf._field_widths(
- ('a', 'b', 'c', 'd'),
- '+---+----+-----+------------+')
-
-
-def test_field_widths_zero():
- tf = table.TableFormatter
- assert {
- 'a': 0,
- 'b': 0,
- 'c': 0
- } == tf._field_widths(
- ('a', 'b', 'c'),
- '+--+-++')
-
-
-def test_width_info():
- 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))
+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 = textwrap.dedent('''\
+ +-------+---------------+
+ | Field | Value |
+ +-------+---------------+
+ | a | A |
+ | b | B |
+ | c | C |
+ | d | test carriage |
+ | | return |
+ +-------+---------------+
+ ''')
+ self.assertEqual(expected, _table_tester_helper(c, d))
+
+
+class TestTerminalWidth(base.TestBase):
+
+ # 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 |
+ +-------+--------------------------------+
+ ''')
+
+ # 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(self, tw):
+ tw.return_value = 80
+ c = ('a', 'b', 'c', 'd')
+ d = ('A', 'B', 'C', 'd' * 77)
+ 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(self, tw):
+ tw.return_value = 80
+ c = ('a', 'b', 'c', 'd')
+ d = ('A', 'B', 'C', 'd' * 77)
+ 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(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
+ 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(self, tw):
+ tw.return_value = 0
+ c = ('a', 'b', 'c', 'd')
+ d = ('A', 'B', 'C', 'd' * 77)
+ 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(self, tw):
+ tw.return_value = 80
+ c = ('a', 'b', 'c', 'd')
+ d = ('A', 'B', 'C', 'd' * 77)
+ 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(self, tw):
+ tw.return_value = 80
+ c = ('a', 'b', 'c', 'd')
+ d = ('A', 'B', 'C', 'd' * 77)
+ self.assertEqual(
+ self.expected_ml_val,
+ _table_tester_helper(c, d, extra_args=['--max-width', '42']),
+ )
+
+
+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')
+ 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
+ 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
+ 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
+ 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))
+
+
+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 = 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(self, tw):
+ tw.return_value = 0
+ c = ('a', 'b', 'c', 'd')
+ d = ('A', 'B', 'C', test_columns.FauxColumn(['the', 'value']))
+ 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))
+
+ @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 = 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_max_width_80(self, tw):
+ # no resize
+ l = tw.return_value = 80
+ 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(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(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(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(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
+ 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_max_width_and_envvar_max(self, tw):
+ # no resize
+ tw.return_value = 80
+ self.assertEqual(
+ self._expected_mv[80],
+ _table_tester_helper(self._col_names, self._col_data),
+ )
+
+ # resize 1 column
+ tw.return_value = 50
+ self.assertEqual(
+ self._expected_mv[80],
+ _table_tester_helper(self._col_names, self._col_data),
+ )
+
+ # resize 2 columns
+ tw.return_value = 45
+ self.assertEqual(
+ self._expected_mv[80],
+ _table_tester_helper(self._col_names, self._col_data),
+ )
+
+ # resize all columns
+ tw.return_value = 40
+ 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
+ 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_max_width_and_envvar_mid(self, tw):
+ # no resize
+ tw.return_value = 80
+ 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(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(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(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(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_env_maxwidth_noresize(self):
+ # no resize
+ 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_env_maxwidth_resize_one(self):
+ # resize 1 column
+ 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_env_maxwidth_resize_two(self):
+ # resize 2 columns
+ 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_env_maxwidth_resize_all(self):
+ # resize all columns
+ 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_env_maxwidth_resize_all_tiny(self):
+ # resize all columns limited by min_width=8
+ 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
+ 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_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('cliff.utils.terminal_width')
+ def test_empty(self, tw):
+ tw.return_value = 80
+ c = ('a', 'b', 'c')
+ data = []
+ expected = '\n'
+ self.assertEqual(expected, _table_tester_helper(c, data))
+
+ @mock.patch('cliff.utils.terminal_width')
+ def test_empty_table(self, tw):
+ tw.return_value = 80
+ c = ('a', 'b', 'c')
+ data = []
+ expected = textwrap.dedent('''\
+ +---+---+---+
+ | a | b | c |
+ +---+---+---+
+ +---+---+---+
+ ''')
+ self.assertEqual(
+ expected,
+ _table_tester_helper(c, data,
+ extra_args=['--print-empty']),
+ )
+
+
+class TestFieldWidths(base.TestBase):
+
+ def test(self):
+ tf = table.TableFormatter
+ self.assertEqual(
+ {
+ 'a': 1,
+ 'b': 2,
+ 'c': 3,
+ 'd': 10
+ },
+ tf._field_widths(
+ ('a', 'b', 'c', 'd'),
+ '+---+----+-----+------------+'),
+ )
+
+ def test_zero(self):
+ tf = table.TableFormatter
+ self.assertEqual(
+ {
+ 'a': 0,
+ 'b': 0,
+ 'c': 0
+ },
+ tf._field_widths(
+ ('a', 'b', 'c'),
+ '+--+-++'),
+ )
+
+ def test_info(self):
+ tf = table.TableFormatter
+ 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)))
diff --git a/cliff/tests/test_formatters_value.py b/cliff/tests/test_formatters_value.py
index f704b08..6053dd3 100644
--- a/cliff/tests/test_formatters_value.py
+++ b/cliff/tests/test_formatters_value.py
@@ -15,51 +15,51 @@
import six
from cliff.formatters import value
+from cliff.tests import base
from cliff.tests import test_columns
-def test_value_formatter():
- sf = value.ValueFormatter()
- c = ('a', 'b', 'c', 'd')
- d = ('A', 'B', 'C', '"no escape me"')
- expected = 'A\nB\nC\n"no escape me"\n'
- output = six.StringIO()
- sf.emit_one(c, d, output, None)
- actual = output.getvalue()
- assert expected == actual
+class TestValueFormatter(base.TestBase):
+ def test(self):
+ sf = value.ValueFormatter()
+ c = ('a', 'b', 'c', 'd')
+ d = ('A', 'B', 'C', '"no escape me"')
+ expected = 'A\nB\nC\n"no escape me"\n'
+ output = six.StringIO()
+ sf.emit_one(c, d, output, None)
+ actual = output.getvalue()
+ self.assertEqual(expected, actual)
-def test_value_formatter_formattable_column():
- sf = value.ValueFormatter()
- c = ('a', 'b', 'c', 'd')
- d = ('A', 'B', 'C', test_columns.FauxColumn(['the', 'value']))
- expected = "A\nB\nC\n['the', 'value']\n"
- output = six.StringIO()
- sf.emit_one(c, d, output, None)
- actual = output.getvalue()
- assert expected == actual
+ def test_formattable_column(self):
+ sf = value.ValueFormatter()
+ c = ('a', 'b', 'c', 'd')
+ d = ('A', 'B', 'C', test_columns.FauxColumn(['the', 'value']))
+ expected = "A\nB\nC\n['the', 'value']\n"
+ output = six.StringIO()
+ sf.emit_one(c, d, output, None)
+ actual = output.getvalue()
+ self.assertEqual(expected, actual)
+ def test_list_formatter(self):
+ sf = value.ValueFormatter()
+ c = ('a', 'b', 'c')
+ d1 = ('A', 'B', 'C')
+ d2 = ('D', 'E', 'F')
+ data = [d1, d2]
+ expected = 'A B C\nD E F\n'
+ output = six.StringIO()
+ sf.emit_list(c, data, output, None)
+ actual = output.getvalue()
+ self.assertEqual(expected, actual)
-def test_value_list_formatter():
- sf = value.ValueFormatter()
- c = ('a', 'b', 'c')
- d1 = ('A', 'B', 'C')
- d2 = ('D', 'E', 'F')
- data = [d1, d2]
- expected = 'A B C\nD E F\n'
- output = six.StringIO()
- sf.emit_list(c, data, output, None)
- actual = output.getvalue()
- assert expected == actual
-
-
-def test_value_list_formatter_formattable_column():
- sf = value.ValueFormatter()
- c = ('a', 'b', 'c')
- d1 = ('A', 'B', test_columns.FauxColumn(['the', 'value']))
- data = [d1]
- expected = "A B ['the', 'value']\n"
- output = six.StringIO()
- sf.emit_list(c, data, output, None)
- actual = output.getvalue()
- assert expected == actual
+ def test_list_formatter_formattable_column(self):
+ sf = value.ValueFormatter()
+ c = ('a', 'b', 'c')
+ d1 = ('A', 'B', test_columns.FauxColumn(['the', 'value']))
+ data = [d1]
+ expected = "A B ['the', 'value']\n"
+ output = six.StringIO()
+ sf.emit_list(c, data, output, None)
+ actual = output.getvalue()
+ self.assertEqual(expected, actual)
diff --git a/cliff/tests/test_formatters_yaml.py b/cliff/tests/test_formatters_yaml.py
index 61db5d8..b6147d8 100644
--- a/cliff/tests/test_formatters_yaml.py
+++ b/cliff/tests/test_formatters_yaml.py
@@ -16,85 +16,85 @@ 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():
- sf = yaml_format.YAMLFormatter()
- c = ('a', 'b', 'c', 'd')
- d = ('A', 'B', 'C', '"escape me"')
- expected = {
- 'a': 'A',
- 'b': 'B',
- 'c': 'C',
- 'd': '"escape me"'
- }
- output = six.StringIO()
- args = mock.Mock()
- sf.emit_one(c, d, output, args)
- actual = yaml.safe_load(output.getvalue())
- assert expected == actual
+class TestYAMLFormatter(base.TestBase):
+ def test_format_one(self):
+ sf = yaml_format.YAMLFormatter()
+ c = ('a', 'b', 'c', 'd')
+ d = ('A', 'B', 'C', '"escape me"')
+ expected = {
+ 'a': 'A',
+ 'b': 'B',
+ 'c': 'C',
+ 'd': '"escape me"'
+ }
+ output = six.StringIO()
+ args = mock.Mock()
+ sf.emit_one(c, d, output, args)
+ actual = yaml.safe_load(output.getvalue())
+ self.assertEqual(expected, actual)
-def test_yaml_format_formattablecolumn_one():
- sf = yaml_format.YAMLFormatter()
- c = ('a', 'b', 'c', 'd')
- d = ('A', 'B', 'C', test_columns.FauxColumn(['the', 'value']))
- expected = {
- 'a': 'A',
- 'b': 'B',
- 'c': 'C',
- 'd': ['the', 'value'],
- }
- args = mock.Mock()
- sf.add_argument_group(args)
+ def test_formattablecolumn_one(self):
+ sf = yaml_format.YAMLFormatter()
+ c = ('a', 'b', 'c', 'd')
+ d = ('A', 'B', 'C', test_columns.FauxColumn(['the', 'value']))
+ expected = {
+ 'a': 'A',
+ 'b': 'B',
+ 'c': 'C',
+ 'd': ['the', 'value'],
+ }
+ args = mock.Mock()
+ sf.add_argument_group(args)
- args.noindent = True
- output = six.StringIO()
- sf.emit_one(c, d, output, args)
- value = output.getvalue()
- print(len(value.splitlines()))
- actual = yaml.safe_load(output.getvalue())
- assert expected == actual
+ args.noindent = True
+ output = six.StringIO()
+ sf.emit_one(c, d, output, args)
+ value = output.getvalue()
+ print(len(value.splitlines()))
+ actual = yaml.safe_load(output.getvalue())
+ self.assertEqual(expected, actual)
+ def test_list(self):
+ sf = yaml_format.YAMLFormatter()
+ c = ('a', 'b', 'c')
+ d = (
+ ('A1', 'B1', 'C1'),
+ ('A2', 'B2', 'C2'),
+ ('A3', 'B3', 'C3')
+ )
+ expected = [
+ {'a': 'A1', 'b': 'B1', 'c': 'C1'},
+ {'a': 'A2', 'b': 'B2', 'c': 'C2'},
+ {'a': 'A3', 'b': 'B3', 'c': 'C3'}
+ ]
+ output = six.StringIO()
+ args = mock.Mock()
+ sf.add_argument_group(args)
+ sf.emit_list(c, d, output, args)
+ actual = yaml.safe_load(output.getvalue())
+ self.assertEqual(expected, actual)
-def test_yaml_format_list():
- sf = yaml_format.YAMLFormatter()
- c = ('a', 'b', 'c')
- d = (
- ('A1', 'B1', 'C1'),
- ('A2', 'B2', 'C2'),
- ('A3', 'B3', 'C3')
- )
- expected = [
- {'a': 'A1', 'b': 'B1', 'c': 'C1'},
- {'a': 'A2', 'b': 'B2', 'c': 'C2'},
- {'a': 'A3', 'b': 'B3', 'c': 'C3'}
- ]
- output = six.StringIO()
- args = mock.Mock()
- sf.add_argument_group(args)
- sf.emit_list(c, d, output, args)
- actual = yaml.safe_load(output.getvalue())
- assert expected == actual
+ def test_formattablecolumn_list(self):
+ sf = yaml_format.YAMLFormatter()
+ c = ('a', 'b', 'c')
+ d = (
+ ('A1', 'B1', test_columns.FauxColumn(['the', 'value'])),
+ )
+ expected = [
+ {'a': 'A1', 'b': 'B1', 'c': ['the', 'value']},
+ ]
+ args = mock.Mock()
+ sf.add_argument_group(args)
-
-def test_yaml_format_formattablecolumn_list():
- sf = yaml_format.YAMLFormatter()
- c = ('a', 'b', 'c')
- d = (
- ('A1', 'B1', test_columns.FauxColumn(['the', 'value'])),
- )
- expected = [
- {'a': 'A1', 'b': 'B1', 'c': ['the', 'value']},
- ]
- args = mock.Mock()
- sf.add_argument_group(args)
-
- args.noindent = True
- output = six.StringIO()
- sf.emit_list(c, d, output, args)
- actual = yaml.safe_load(output.getvalue())
- assert expected == actual
+ args.noindent = True
+ output = six.StringIO()
+ sf.emit_list(c, d, output, args)
+ actual = yaml.safe_load(output.getvalue())
+ self.assertEqual(expected, actual)
diff --git a/cliff/tests/test_help.py b/cliff/tests/test_help.py
index 23659a2..8b66fbe 100644
--- a/cliff/tests/test_help.py
+++ b/cliff/tests/test_help.py
@@ -22,159 +22,153 @@ 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():
- # 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?
- stdout = StringIO()
- app = application.App('testing', '1',
- utils.TestCommandManager(utils.TEST_NAMESPACE),
- stdout=stdout)
- app.NAME = 'test'
- help_cmd = help.HelpCommand(app, mock.Mock())
- parser = help_cmd.get_parser('test')
- parsed_args = parser.parse_args(['one'])
- try:
- help_cmd.run(parsed_args)
- except SystemExit:
- pass
- assert stdout.getvalue() == 'TestParser'
-
-
-def test_list_matching_commands():
- # 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?
- stdout = StringIO()
- app = application.App('testing', '1',
- utils.TestCommandManager(utils.TEST_NAMESPACE),
- stdout=stdout)
- app.NAME = 'test'
- help_cmd = help.HelpCommand(app, mock.Mock())
- parser = help_cmd.get_parser('test')
- parsed_args = parser.parse_args(['t'])
- try:
- help_cmd.run(parsed_args)
- 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
-
-
-def test_list_matching_commands_no_match():
- # 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?
- stdout = StringIO()
- app = application.App('testing', '1',
- utils.TestCommandManager(utils.TEST_NAMESPACE),
- stdout=stdout)
- app.NAME = 'test'
- 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'
-
-
-def test_show_help_for_help():
- # 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?
- stdout = StringIO()
- app = application.App('testing', '1',
- utils.TestCommandManager(utils.TEST_NAMESPACE),
- stdout=stdout)
- app.NAME = 'test'
- app.options = mock.Mock()
- help_cmd = help.HelpCommand(app, mock.Mock())
- parser = help_cmd.get_parser('test')
- parsed_args = parser.parse_args([])
- try:
- help_cmd.run(parsed_args)
- except SystemExit:
- 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
- expected = (
- ' one Test command.\n'
- ' three word command Test command.\n'
- )
- assert expected in help_text
-
-
-def test_list_deprecated_commands():
- # 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?
- stdout = StringIO()
- app = application.App('testing', '1',
- utils.TestCommandManager(utils.TEST_NAMESPACE),
- stdout=stdout)
- app.NAME = 'test'
- try:
- app.run(['--help'])
- 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
-
-
-@mock.patch.object(commandmanager.EntryPointWrapper, 'load',
- side_effect=Exception('Could not load EntryPoint'))
-def test_show_help_with_ep_load_fail(mock_load):
- stdout = StringIO()
- app = application.App('testing', '1',
- utils.TestCommandManager(utils.TEST_NAMESPACE),
- stdout=stdout)
- app.NAME = 'test'
- app.options = mock.Mock()
- app.options.debug = False
- help_cmd = help.HelpCommand(app, mock.Mock())
- parser = help_cmd.get_parser('test')
- parsed_args = parser.parse_args([])
- try:
- help_cmd.run(parsed_args)
- 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
-
-
-@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):
- stdout = StringIO()
- app = application.App('testing', '1',
- utils.TestCommandManager(utils.TEST_NAMESPACE),
- stdout=stdout)
- app.NAME = 'test'
- app.options = mock.Mock()
- app.options.debug = True
- help_cmd = help.HelpCommand(app, mock.Mock())
- parser = help_cmd.get_parser('test')
- parsed_args = parser.parse_args([])
- try:
- help_cmd.run(parsed_args)
- 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
+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?
+ stdout = StringIO()
+ app = application.App('testing', '1',
+ utils.TestCommandManager(utils.TEST_NAMESPACE),
+ stdout=stdout)
+ app.NAME = 'test'
+ help_cmd = help.HelpCommand(app, mock.Mock())
+ parser = help_cmd.get_parser('test')
+ parsed_args = parser.parse_args(['one'])
+ try:
+ help_cmd.run(parsed_args)
+ except SystemExit:
+ pass
+ self.assertEqual('TestParser', stdout.getvalue())
+
+ 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?
+ stdout = StringIO()
+ app = application.App('testing', '1',
+ utils.TestCommandManager(utils.TEST_NAMESPACE),
+ stdout=stdout)
+ app.NAME = 'test'
+ help_cmd = help.HelpCommand(app, mock.Mock())
+ parser = help_cmd.get_parser('test')
+ parsed_args = parser.parse_args(['t'])
+ try:
+ help_cmd.run(parsed_args)
+ except SystemExit:
+ pass
+ help_output = stdout.getvalue()
+ 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(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?
+ stdout = StringIO()
+ app = application.App('testing', '1',
+ utils.TestCommandManager(utils.TEST_NAMESPACE),
+ stdout=stdout)
+ app.NAME = 'test'
+ help_cmd = help.HelpCommand(app, mock.Mock())
+ parser = help_cmd.get_parser('test')
+ parsed_args = parser.parse_args(['z'])
+ self.assertRaises(
+ ValueError,
+ help_cmd.run,
+ parsed_args,
+ )
+
+ 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?
+ stdout = StringIO()
+ app = application.App('testing', '1',
+ utils.TestCommandManager(utils.TEST_NAMESPACE),
+ stdout=stdout)
+ app.NAME = 'test'
+ app.options = mock.Mock()
+ help_cmd = help.HelpCommand(app, mock.Mock())
+ parser = help_cmd.get_parser('test')
+ parsed_args = parser.parse_args([])
+ try:
+ help_cmd.run(parsed_args)
+ except SystemExit:
+ pass
+ help_text = stdout.getvalue()
+ basecommand = os.path.split(sys.argv[0])[1]
+ 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'
+ )
+ self.assertIn(expected, help_text)
+
+ 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?
+ stdout = StringIO()
+ app = application.App('testing', '1',
+ utils.TestCommandManager(utils.TEST_NAMESPACE),
+ stdout=stdout)
+ app.NAME = 'test'
+ try:
+ app.run(['--help'])
+ except SystemExit:
+ pass
+ help_output = stdout.getvalue()
+ 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',
+ side_effect=Exception('Could not load EntryPoint'))
+ def test_show_help_with_ep_load_fail(self, mock_load):
+ stdout = StringIO()
+ app = application.App('testing', '1',
+ utils.TestCommandManager(utils.TEST_NAMESPACE),
+ stdout=stdout)
+ app.NAME = 'test'
+ app.options = mock.Mock()
+ app.options.debug = False
+ help_cmd = help.HelpCommand(app, mock.Mock())
+ parser = help_cmd.get_parser('test')
+ parsed_args = parser.parse_args([])
+ try:
+ help_cmd.run(parsed_args)
+ except SystemExit:
+ pass
+ help_output = stdout.getvalue()
+ 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',
+ side_effect=Exception('Could not load EntryPoint'))
+ 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),
+ stdout=stdout)
+ app.NAME = 'test'
+ app.options = mock.Mock()
+ app.options.debug = True
+ help_cmd = help.HelpCommand(app, mock.Mock())
+ parser = help_cmd.get_parser('test')
+ parsed_args = parser.parse_args([])
+ try:
+ help_cmd.run(parsed_args)
+ except SystemExit:
+ pass
+ help_output = stdout.getvalue()
+ self.assertIn('Commands:', help_output)
+ self.assertIn('Could not load', help_output)
+ self.assertIn('Exception: Could not load EntryPoint', help_output)
diff --git a/cliff/tests/test_interactive.py b/cliff/tests/test_interactive.py
index c18e7b3..8dfb5e9 100644
--- a/cliff/tests/test_interactive.py
+++ b/cliff/tests/test_interactive.py
@@ -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):
- fake_command_manager = [(x, None) for x in command_names]
- return InteractiveApp(FakeApp, fake_command_manager,
- stdin=None, stdout=None)
-
-
-def _test_completenames(expecteds, prefix):
- app = make_interactive_app('hips', 'hippo', 'nonmatching')
- assert set(app.completenames(prefix)) == set(expecteds)
-
-
-def test_cmd2_completenames():
- # cmd2.Cmd define do_help method
- _test_completenames(['help'], 'he')
-
-
-def test_cliff_completenames():
- _test_completenames(['hips', 'hippo'], 'hip')
-
-
-def test_no_completenames():
- _test_completenames([], 'taz')
-
-
-def test_both_completenames():
- # 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')
- else:
- _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)
- observeds = app.completedefault(None, line, begidx, None)
- assert set(observeds) == set(expecteds)
- assert set([line[:begidx] + x for x in observeds]) <= command_names
-
-
-def test_empty_text_completedefault():
- # line = 'show ' + begidx = 5 implies text = ''
- _test_completedefault(['file', 'folder', ' long'], 'show ', 5)
-
-
-def test_nonempty_text_completedefault2():
- # line = 'show f' + begidx = 6 implies text = 'f'
- _test_completedefault(['file', 'folder'], 'show f', 5)
-
-
-def test_long_completedefault():
- _test_completedefault(['long'], 'show ', 6)
-
-
-def test_no_completedefault():
- _test_completedefault([], 'taz ', 4)
+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_cmd2_completenames(self):
+ # cmd2.Cmd define do_help method
+ self._test_completenames(['help'], 'he')
+
+ def test_cliff_completenames(self):
+ self._test_completenames(['hips', 'hippo'], 'hip')
+
+ def test_no_completenames(self):
+ self._test_completenames([], 'taz')
+
+ 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"):
+ self._test_completenames(['hi', 'history', 'hips', 'hippo'], 'hi')
+ else:
+ self._test_completenames(['history', 'hips', 'hippo'], 'hi')
+
+ 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)
+ self.assertEqual(set(expecteds), set(observeds))
+ self.assertTrue(
+ set([line[:begidx] + x for x in observeds]) <= command_names
+ )
+
+ def test_empty_text_completedefault(self):
+ # line = 'show ' + begidx = 5 implies text = ''
+ self._test_completedefault(['file', 'folder', ' long'], 'show ', 5)
+
+ def test_nonempty_text_completedefault2(self):
+ # line = 'show f' + begidx = 6 implies text = 'f'
+ self._test_completedefault(['file', 'folder'], 'show f', 5)
+
+ def test_long_completedefault(self):
+ self._test_completedefault(['long'], 'show ', 6)
+
+ def test_no_completedefault(self):
+ self._test_completedefault([], 'taz ', 4)
diff --git a/cliff/tests/test_lister.py b/cliff/tests/test_lister.py
index f2e4a0d..9434ce6 100644
--- a/cliff/tests/test_lister.py
+++ b/cliff/tests/test_lister.py
@@ -15,6 +15,7 @@
import weakref
from cliff import lister
+from cliff.tests import base
import mock
@@ -43,33 +44,33 @@ class ExerciseLister(lister.Lister):
)
-def test_formatter_args():
- app = mock.Mock()
- test_lister = ExerciseLister(app, [])
-
- parsed_args = mock.Mock()
- parsed_args.columns = ('Col1', 'Col2')
- parsed_args.formatter = 'test'
-
- test_lister.run(parsed_args)
- f = test_lister._formatter_plugins['test']
- assert len(f.args) == 1
- args = f.args[0]
- assert args[0] == list(parsed_args.columns)
- data = list(args[1])
- assert data == [['a', 'A'], ['b', 'B']]
-
-
-def test_no_exist_column():
- 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'
+class TestLister(base.TestBase):
+
+ def test_formatter_args(self):
+ app = mock.Mock()
+ test_lister = ExerciseLister(app, [])
+
+ parsed_args = mock.Mock()
+ parsed_args.columns = ('Col1', 'Col2')
+ parsed_args.formatter = 'test'
+
+ test_lister.run(parsed_args)
+ f = test_lister._formatter_plugins['test']
+ self.assertEqual(1, len(f.args))
+ args = f.args[0]
+ self.assertEqual(list(parsed_args.columns), args[0])
+ data = list(args[1])
+ self.assertEqual([['a', 'A'], ['b', 'B']], data)
+
+ 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'), [])
+ self.assertRaises(
+ ValueError,
+ test_lister.run,
+ parsed_args,
+ )
diff --git a/cliff/tests/test_show.py b/cliff/tests/test_show.py
index 9e46c54..ab185e2 100644
--- a/cliff/tests/test_show.py
+++ b/cliff/tests/test_show.py
@@ -15,6 +15,7 @@
import weakref
from cliff import show
+from cliff.tests import base
import mock
@@ -43,42 +44,41 @@ class ExerciseShowOne(show.ShowOne):
)
-def test_formatter_args():
- app = mock.Mock()
- test_show = ExerciseShowOne(app, [])
-
- parsed_args = mock.Mock()
- parsed_args.columns = ('Col1', 'Col2')
- parsed_args.formatter = 'test'
-
- test_show.run(parsed_args)
- f = test_show._formatter_plugins['test']
- assert len(f.args) == 1
- args = f.args[0]
- assert args[0] == list(parsed_args.columns)
- data = list(args[1])
- assert data == [('a', 'A'), ('b', 'B')]
-
-
-def test_dict2columns():
- 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
-
-
-def test_no_exist_column():
- 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'
+class TestShow(base.TestBase):
+
+ def test_formatter_args(self):
+ app = mock.Mock()
+ test_show = ExerciseShowOne(app, [])
+
+ parsed_args = mock.Mock()
+ parsed_args.columns = ('Col1', 'Col2')
+ parsed_args.formatter = 'test'
+
+ test_show.run(parsed_args)
+ f = test_show._formatter_plugins['test']
+ self.assertEqual(1, len(f.args))
+ args = f.args[0]
+ self.assertEqual(list(parsed_args.columns), args[0])
+ data = list(args[1])
+ self.assertEqual([('a', 'A'), ('b', 'B')], data)
+
+ 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))
+ self.assertEqual(expected, actual)
+
+ 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'), [])
+ self.assertRaises(
+ ValueError,
+ test_show.run,
+ parsed_args,
+ )
diff --git a/cliff/tests/test_sphinxext.py b/cliff/tests/test_sphinxext.py
index fe271fa..2720d22 100644
--- a/cliff/tests/test_sphinxext.py
+++ b/cliff/tests/test_sphinxext.py
@@ -15,92 +15,91 @@
import argparse
import textwrap
-from nose.tools import assert_equals
-
from cliff import sphinxext
+from cliff.tests import base
-def test_empty_help():
- """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("""
- .. program:: hello-world
- .. code-block:: shell
-
- hello-world [--language LANG] name
+class TestSphinxExtension(base.TestBase):
- .. option:: --language <LANG>
+ 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')
- .. option:: name
- """).lstrip(), output)
+ output = '\n'.join(sphinxext._format_parser(parser))
+ self.assertEqual(textwrap.dedent("""
+ .. program:: hello-world
+ .. code-block:: shell
+ hello-world [--language LANG] name
-def test_nonempty_help():
- """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')
+ .. option:: --language <LANG>
- output = '\n'.join(sphinxext._format_parser(parser))
- assert_equals(textwrap.dedent("""
- .. program:: hello-world
- .. code-block:: shell
+ .. option:: name
+ """).lstrip(), output)
- hello-world [--language LANG] name
+ 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')
- .. option:: --language <LANG>
+ output = '\n'.join(sphinxext._format_parser(parser))
+ self.assertEqual(textwrap.dedent("""
+ .. program:: hello-world
+ .. code-block:: shell
- greeting language
+ hello-world [--language LANG] name
- .. option:: name
+ .. option:: --language <LANG>
- user name
- """).lstrip(), output)
+ greeting language
+ .. option:: name
-def test_flag():
- """Handle a boolean argparse action."""
- parser = argparse.ArgumentParser(prog='hello-world', add_help=False)
- parser.add_argument('name', help='user name')
- parser.add_argument('--translate', action='store_true',
- help='translate to local language')
+ user name
+ """).lstrip(), output)
- output = '\n'.join(sphinxext._format_parser(parser))
- assert_equals(textwrap.dedent("""
- .. program:: hello-world
- .. code-block:: shell
+ 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')
+ parser.add_argument('--translate', action='store_true',
+ help='translate to local language')
- hello-world [--translate] name
+ output = '\n'.join(sphinxext._format_parser(parser))
+ self.assertEqual(textwrap.dedent("""
+ .. program:: hello-world
+ .. code-block:: shell
- .. option:: --translate
+ hello-world [--translate] name
- translate to local language
+ .. option:: --translate
- .. option:: name
+ translate to local language
- user name
- """).lstrip(), output)
+ .. option:: name
+ user name
+ """).lstrip(), output)
-def test_supressed():
- """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)
+ 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("""
- .. program:: hello-world
- .. code-block:: shell
+ output = '\n'.join(sphinxext._format_parser(parser))
+ self.assertEqual(textwrap.dedent("""
+ .. program:: hello-world
+ .. code-block:: shell
- hello-world name
+ hello-world name
- .. option:: name
+ .. option:: name
- user name
- """).lstrip(), output)
+ user name
+ """).lstrip(), output)
diff --git a/cliff/tests/test_utils.py b/cliff/tests/test_utils.py
index 23c46c4..9d6b1f6 100644
--- a/cliff/tests/test_utils.py
+++ b/cliff/tests/test_utils.py
@@ -15,65 +15,63 @@
import os
import struct
import sys
+import unittest
import mock
-import nose
from cliff import utils
-
-
-def test_utils_terminal_width():
- 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)
-
-
-@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')
- ts = os.terminal_size((10, 5))
- mock_os.get_terminal_size.return_value = ts
- width = utils.terminal_width(sys.stdout)
- assert width == 10
-
- mock_os.get_terminal_size.side_effect = OSError()
- width = utils.terminal_width(sys.stdout)
- assert width is None
-
-
-@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')
- mock_ioctl.return_value = struct.pack('hhhh', 57, 101, 0, 0)
- width = utils.terminal_width(sys.stdout)
- assert width == 101
-
- 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')
-
- 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
-
- mock_ctypes.windll.kernel32.GetConsoleScreenBufferInfo.return_value = 0
-
- width = utils.terminal_width(sys.stdout)
- assert width is None
-
- width = utils.terminal_width('foo')
- assert width is None
+from cliff.tests import base
+
+
+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.
+ if width is not None:
+ self.assertIsInstance(width, int)
+
+ @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)
+ self.assertEqual(10, width)
+ mock_os.get_terminal_size.side_effect = OSError()
+ width = utils.terminal_width(sys.stdout)
+ self.assertIs(None, width)
+
+ @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)
+ self.assertEqual(101, width)
+ mock_ioctl.side_effect = IOError()
+ width = utils.terminal_width(sys.stdout)
+ 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)
+ self.assertEqual(101, width)
+
+ mock_ctypes.windll.kernel32.GetConsoleScreenBufferInfo.return_value = 0
+
+ width = utils.terminal_width(sys.stdout)
+ self.assertIs(None, width)
+
+ width = utils.terminal_width('foo')
+ self.assertIs(None, width)
diff --git a/test-requirements.txt b/test-requirements.txt
index a80bfd6..ee61629 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -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
diff --git a/tox.ini b/tox.ini
index 5740170..470da53 100644
--- a/tox.ini
+++ b/tox.ini
@@ -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]