diff --git a/jirate/decor.py b/jirate/decor.py index f99a05b..a8557b2 100644 --- a/jirate/decor.py +++ b/jirate/decor.py @@ -81,6 +81,16 @@ def parse_params(arg): return ret +def comma_separated(item_list): + out = [] + for item in item_list: + if item and ',' in item: + out.append(f'"{item}"') + else: + out.append(item) + return ', '.join(out) + + def truncate(arg, maxlen): if arg and maxlen and len(arg) > maxlen: arg = arg[:maxlen - 1] + '…' diff --git a/jirate/jira_cli.py b/jirate/jira_cli.py index c046188..0191925 100644 --- a/jirate/jira_cli.py +++ b/jirate/jira_cli.py @@ -16,7 +16,7 @@ from jirate.args import ComplicatedArgs, GenericArgs from jirate.jboard import JiraProject, get_jira -from jirate.decor import md_print, pretty_date, color_string, hbar_under, hbar, hbar_over, nym, vsep_print, vseparator, parse_params, truncate, render_matrix +from jirate.decor import md_print, pretty_date, color_string, hbar_under, hbar, hbar_over, nym, vsep_print, vseparator, parse_params, truncate, render_matrix, comma_separated from jirate.decor import pretty_print # NOQA from jirate.config import get_config from jirate.jira_fields import apply_field_renderers, render_issue_fields, max_field_width, render_field_data @@ -290,7 +290,7 @@ def issue_fields(args): values.append(val['value']) else: values.append(val['id']) - fvalue = ', '.join(values) + fvalue = comma_separated(values) vsep_print(' ', fname, nlen, fvalue) return (0, False) @@ -399,7 +399,7 @@ def print_creation_fields(metadata): values.append(val['value']) else: values.append(val['id']) - fvalue = ', '.join(values) + fvalue = comma_separated(values) vsep_print(' ', fname, nlen, req, 1, fvalue) diff --git a/jirate/jira_fields.py b/jirate/jira_fields.py index c4f22fe..b866a1f 100644 --- a/jirate/jira_fields.py +++ b/jirate/jira_fields.py @@ -2,7 +2,7 @@ import re # NOQA from collections import OrderedDict -from jirate.decor import pretty_date, vsep_print +from jirate.decor import pretty_date, vsep_print, comma_separated # @@ -10,7 +10,7 @@ # suppressed. # def _list_of_key(field, key): - return ', '.join([item[key] for item in field]) + return comma_separated([item[key] for item in field]) def string(field, fields): @@ -21,7 +21,7 @@ def auto_field(field, fields): if isinstance(field, str): return field if isinstance(field, list): - return ', '.join([str(item) for item in field]) + return comma_separated([str(item) for item in field]) if isinstance(field, dict): for key in ['name', 'value']: if key in field: @@ -61,7 +61,7 @@ def user_list(field, fields): def array(field, fields): - return ', '.join(field) + return comma_separated(field) def value_list(field, fields): diff --git a/jirate/tests/__init__.py b/jirate/tests/__init__.py index d38a949..3b3d59b 100644 --- a/jirate/tests/__init__.py +++ b/jirate/tests/__init__.py @@ -281,7 +281,7 @@ 'timeZone': 'America/New_York'}, 'attachment': [], 'comment': [], - 'components': [], + 'components': [{'name': 'food, pork'}, {'name': 'food, carrot'}], 'created': '2023-08-03T10:28:48.366+0000', 'description': 'Test Description 1', 'duedate': '2024-01-30', @@ -358,7 +358,7 @@ {'name': 'Version2', 'value': 'version_two'}], 'customfield_1234571': [{'key': 'user1', 'name': 'user-one', 'displayName': 'One', 'emailAddress': 'one@two.com'}, {'key': 'user2', 'name': 'two@other.eml', 'displayName': 'Two', 'emailAddress': 'two@two.com'}], - 'customfield_1234572': ['one', 'two', 'three'], + 'customfield_1234572': ['one', 'two', 'three, and four'], 'customfield_1234573': [{'name': 'group1'}, {'name': 'group2'}], 'customfield_1234574': ['one', 2.0], 'customfield_1234575': '2022-08-01', @@ -389,7 +389,7 @@ 'assignee': None, 'attachment': [], 'comment': [], - 'components': ['porkchop'], + 'components': [], 'created': '2023-08-03T10:28:48.366+0000', 'customfield_1234567': None, 'customfield_1234568': None, diff --git a/jirate/tests/test_decor.py b/jirate/tests/test_decor.py index 2bceb07..e4ea03a 100644 --- a/jirate/tests/test_decor.py +++ b/jirate/tests/test_decor.py @@ -1,6 +1,6 @@ #!/usr/bin/python3 -from jirate.decor import truncate, parse_params +from jirate.decor import truncate, parse_params, comma_separated def test_parse_simple(): @@ -9,7 +9,7 @@ def test_parse_simple(): def test_parse_commas(): assert parse_params('arg,barg') == ['arg', 'barg'] - assert parse_params('"Comma,Test, ", 2') == ['Comma,Test,', "2"] + assert parse_params('"Comma, Test, ", 2') == ['Comma, Test,', "2"] def test_parse_spaces(): @@ -30,3 +30,18 @@ def test_truncate_identity(): def test_truncate_exceed(): assert truncate('abc', 3) == 'abc' assert truncate('abcd', 3) == 'ab…' + + +def test_comma_separated(): + str_val = 'one, two, "three, and four"' + list_val = ['one', 'two', 'three, and four'] + + assert comma_separated(list_val) == str_val + + +def test_parse_and_unparse(): + str_val = 'one, two, "three, and four"' + list_val = ['one', 'two', 'three, and four'] + + assert parse_params(comma_separated(list_val)) == list_val + assert comma_separated(parse_params(str_val)) == str_val diff --git a/jirate/tests/test_render.py b/jirate/tests/test_render.py index 7ebb579..f16fc15 100644 --- a/jirate/tests/test_render.py +++ b/jirate/tests/test_render.py @@ -69,6 +69,7 @@ def test_render_code_override(): field_test_params = 'field_id,field_name,value' field_test_info = [ + pytest.param('components', 'Component/s', '"food, pork", "food, carrot"'), # Fixed in build (string) pytest.param('customfield_1234567', 'Fixed in Build', 'test-build-1'), @@ -86,7 +87,7 @@ def test_render_code_override(): pytest.param('customfield_1234571', 'Array of Users', 'user-one, two@other.eml'), # Array of strings - pytest.param('customfield_1234572', 'Array of Strings', 'one, two, three'), + pytest.param('customfield_1234572', 'Array of Strings', 'one, two, "three, and four"'), # Array of groups (name?), pytest.param('customfield_1234573', 'Array of Groups', 'group1, group2'),