Update projects commands to use pluggable formatters
This allows users to specify the formatter they want to use and have the project-* subcommands honor it. Change-Id: I4ea6f0d679f6167a1b4865d8d51f5c6ef07c58cd
This commit is contained in:
@@ -25,8 +25,7 @@ from cratonclient.v1 import projects
|
||||
def do_project_show(cc, args):
|
||||
"""Show detailed information about a project."""
|
||||
project = cc.projects.get(args.id)
|
||||
data = {f: getattr(project, f, '') for f in projects.PROJECT_FIELDS}
|
||||
cliutils.print_dict(data, wrap=72)
|
||||
args.formatter.configure(wrap=72).handle(project)
|
||||
|
||||
|
||||
@cliutils.arg('-n', '--name',
|
||||
@@ -88,7 +87,7 @@ def do_project_list(cc, args):
|
||||
params['autopaginate'] = args.all
|
||||
|
||||
listed_projects = cc.projects.list(**params)
|
||||
cliutils.print_list(listed_projects, list(fields))
|
||||
args.formatter.configure(fields=list(fields)).handle(listed_projects)
|
||||
|
||||
|
||||
@cliutils.arg('-n', '--name',
|
||||
@@ -100,8 +99,7 @@ def do_project_create(cc, args):
|
||||
fields = {k: v for (k, v) in vars(args).items()
|
||||
if k in projects.PROJECT_FIELDS and not (v is None)}
|
||||
project = cc.projects.create(**fields)
|
||||
data = {f: getattr(project, f, '') for f in projects.PROJECT_FIELDS}
|
||||
cliutils.print_dict(data, wrap=72)
|
||||
args.formatter.configure(wrap=72).handle(project)
|
||||
|
||||
|
||||
@cliutils.arg('id',
|
||||
|
||||
@@ -29,14 +29,22 @@ class TestProjectsShell(base.ShellTestCase):
|
||||
|
||||
re_options = re.DOTALL | re.MULTILINE
|
||||
project_valid_fields = None
|
||||
project_invalid_field = None
|
||||
project_invalid_fields = None
|
||||
|
||||
def setUp(self):
|
||||
"""Setup required test fixtures."""
|
||||
super(TestProjectsShell, self).setUp()
|
||||
self.project_valid_fields = Namespace(name='mock_project')
|
||||
self.project_invalid_field = Namespace(name='mock_project',
|
||||
invalid_foo='ignored')
|
||||
self.project_valid_kwargs = {
|
||||
'name': 'mock_project',
|
||||
}
|
||||
self.project_invalid_kwargs = {
|
||||
'name': 'mock_project',
|
||||
'invalid_foo': 'ignored',
|
||||
}
|
||||
self.project_valid_fields = Namespace(**self.project_valid_kwargs)
|
||||
self.project_invalid_fields = Namespace(**self.project_invalid_kwargs)
|
||||
self.project_valid_fields.formatter = mock.Mock()
|
||||
self.project_invalid_fields.formatter = mock.Mock()
|
||||
|
||||
@mock.patch('cratonclient.v1.projects.ProjectManager.list')
|
||||
def test_project_list_success(self, mock_list):
|
||||
@@ -92,17 +100,13 @@ class TestProjectsShell(base.ShellTestCase):
|
||||
)
|
||||
|
||||
@mock.patch('cratonclient.v1.projects.ProjectManager.list')
|
||||
@mock.patch('cratonclient.common.cliutils.print_list')
|
||||
def test_project_list_fields_success(self, mock_printlist, mock_list):
|
||||
def test_project_list_fields_success(self, mock_list):
|
||||
"""Verify --fields argument successfully passed to Client."""
|
||||
self.shell('project-list --fields id name')
|
||||
mock_list.assert_called_once_with(
|
||||
marker=None,
|
||||
autopaginate=False,
|
||||
)
|
||||
mock_printlist.assert_called_once_with(mock.ANY,
|
||||
list({'id': 'ID',
|
||||
'name': 'Name'}))
|
||||
|
||||
def test_project_create_missing_required_args(self):
|
||||
"""Verify that missing required args results in error message."""
|
||||
@@ -126,7 +130,7 @@ class TestProjectsShell(base.ShellTestCase):
|
||||
region_id=mock.ANY,
|
||||
)
|
||||
projects_shell.do_project_create(client, self.project_valid_fields)
|
||||
mock_create.assert_called_once_with(**vars(self.project_valid_fields))
|
||||
mock_create.assert_called_once_with(**self.project_valid_kwargs)
|
||||
|
||||
@mock.patch('cratonclient.v1.projects.ProjectManager.create')
|
||||
def test_do_project_create_ignores_unknown_fields(self, mock_create):
|
||||
@@ -136,8 +140,8 @@ class TestProjectsShell(base.ShellTestCase):
|
||||
mock.ANY, 'http://127.0.0.1/',
|
||||
region_id=mock.ANY,
|
||||
)
|
||||
projects_shell.do_project_create(client, self.project_invalid_field)
|
||||
mock_create.assert_called_once_with(**vars(self.project_valid_fields))
|
||||
projects_shell.do_project_create(client, self.project_invalid_fields)
|
||||
mock_create.assert_called_once_with(**self.project_valid_kwargs)
|
||||
|
||||
def test_project_show_missing_required_args(self):
|
||||
"""Verify that missing required args results in error message."""
|
||||
@@ -159,9 +163,9 @@ class TestProjectsShell(base.ShellTestCase):
|
||||
mock.ANY, 'http://127.0.0.1/',
|
||||
region_id=mock.ANY,
|
||||
)
|
||||
test_args = Namespace(id=1)
|
||||
test_args = Namespace(id=1, formatter=mock.Mock())
|
||||
projects_shell.do_project_show(client, test_args)
|
||||
mock_get.assert_called_once_with(vars(test_args)['id'])
|
||||
mock_get.assert_called_once_with(1)
|
||||
|
||||
def test_project_delete_missing_required_args(self):
|
||||
"""Verify that missing required args results in error message."""
|
||||
|
||||
@@ -35,10 +35,8 @@ class TestDoShellShow(base.TestShellCommandUsingPrintDict):
|
||||
projects_shell.do_project_show(self.craton_client, args)
|
||||
|
||||
self.craton_client.projects.get.assert_called_once_with(456)
|
||||
self.print_dict.assert_called_once_with(
|
||||
{f: mock.ANY for f in projects.PROJECT_FIELDS},
|
||||
wrap=72,
|
||||
)
|
||||
self.formatter.configure.assert_called_once_with(wrap=72)
|
||||
self.assertEqual(1, self.formatter.handle.call_count)
|
||||
|
||||
|
||||
class TestDoProjectList(base.TestShellCommandUsingPrintList):
|
||||
@@ -47,7 +45,8 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
|
||||
def assertNothingWasCalled(self):
|
||||
"""Assert inventory, list, and print_list were not called."""
|
||||
super(TestDoProjectList, self).assertNothingWasCalled()
|
||||
self.assertFalse(self.print_list.called)
|
||||
self.assertFalse(self.formatter.configure.called)
|
||||
self.assertFalse(self.formatter.handle.called)
|
||||
|
||||
def args_for(self, **kwargs):
|
||||
"""Generate the default argument list for project-list."""
|
||||
@@ -69,9 +68,7 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
|
||||
marker=None,
|
||||
autopaginate=False,
|
||||
)
|
||||
self.assertTrue(self.print_list.called)
|
||||
self.assertEqual(['id', 'name'],
|
||||
sorted(self.print_list.call_args[0][-1]))
|
||||
self.assertSortedFieldsEqualTo(['id', 'name'])
|
||||
|
||||
def test_negative_limit(self):
|
||||
"""Ensure we raise an exception for negative limits."""
|
||||
@@ -92,9 +89,7 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
|
||||
autopaginate=False,
|
||||
marker=None,
|
||||
)
|
||||
self.assertTrue(self.print_list.called)
|
||||
self.assertEqual(['id', 'name'],
|
||||
sorted(self.print_list.call_args[0][-1]))
|
||||
self.assertSortedFieldsEqualTo(['id', 'name'])
|
||||
|
||||
def test_detail(self):
|
||||
"""Verify the behaviour of specifying --detail."""
|
||||
@@ -106,8 +101,7 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
|
||||
marker=None,
|
||||
autopaginate=False,
|
||||
)
|
||||
self.assertEqual(sorted(list(projects.PROJECT_FIELDS)),
|
||||
sorted(self.print_list.call_args[0][-1]))
|
||||
self.assertSortedFieldsEqualTo(sorted(list(projects.PROJECT_FIELDS)))
|
||||
|
||||
def test_list_name(self):
|
||||
"""Verify the behaviour of specifying --detail."""
|
||||
@@ -120,8 +114,7 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
|
||||
autopaginate=False,
|
||||
marker=None,
|
||||
)
|
||||
self.assertEqual(['id', 'name'],
|
||||
sorted(self.print_list.call_args[0][-1]))
|
||||
self.assertSortedFieldsEqualTo(['id', 'name'])
|
||||
|
||||
def test_raises_exception_with_detail_and_fields(self):
|
||||
"""Verify that we fail when users specify --detail and --fields."""
|
||||
@@ -143,8 +136,7 @@ class TestDoProjectList(base.TestShellCommandUsingPrintList):
|
||||
autopaginate=False,
|
||||
marker=None,
|
||||
)
|
||||
self.assertEqual(['id', 'name'],
|
||||
sorted(self.print_list.call_args[0][-1]))
|
||||
self.assertSortedFieldsEqualTo(['id', 'name'])
|
||||
|
||||
def test_invalid_fields(self):
|
||||
"""Verify that we error out with invalid fields."""
|
||||
@@ -207,7 +199,8 @@ class TestDoProjectCreate(base.TestShellCommandUsingPrintDict):
|
||||
self.craton_client.projects.create.assert_called_once_with(
|
||||
name='New Project'
|
||||
)
|
||||
self.print_dict.assert_called_once_with(mock.ANY, wrap=72)
|
||||
self.formatter.configure.assert_called_once_with(wrap=72)
|
||||
self.assertEqual(1, self.formatter.handle.call_count)
|
||||
|
||||
|
||||
class TestDoProjectDelete(base.TestShellCommand):
|
||||
|
||||
Reference in New Issue
Block a user