From 8ea258c544df34654b15ffc5e3306bd559696b44 Mon Sep 17 00:00:00 2001 From: Suhas Date: Thu, 28 Jan 2021 20:38:25 -0500 Subject: [PATCH] refactor deserialization organize test_parse_args make format --- jrnl/args.py | 34 +++++++++++++++- tests/test_parse_args.py | 83 +++++++++++++++++++++++++--------------- 2 files changed, 84 insertions(+), 33 deletions(-) diff --git a/jrnl/args.py b/jrnl/args.py index f2ea288c..046d29a8 100644 --- a/jrnl/args.py +++ b/jrnl/args.py @@ -18,10 +18,34 @@ from .plugins import util def deserialize_config_args(input: str) -> dict: - _kvpairs = input.strip(" ").split(",") + """Convert a delimited list of configuration key-value pairs into a flat dict + + Example: + An input of + `colors.title: blue, display_format: json, colors.date: green` + will return + ```json + { + 'colors.title': 'blue', + 'display_format': 'json', + 'colors.date': 'green' + } + ``` + + Args: + input (str): list of configuration keys in dot-notation and their respective values. + + Returns: + dict: A single level dict of the configuration keys in dot-notation and their respective desired values + """ + slug_delimiter = "," + key_value_separator = ":" + _kvpairs = _split_at_delimiter( + input, slug_delimiter, " " + ) # Strip away all whitespace in input, not just leading runtime_modifications = {} for _p in _kvpairs: - l, r = _p.strip().split(":") + l, r = _split_at_delimiter(_p, key_value_separator) r = r.strip() if r.isdigit(): r = int(r) @@ -33,6 +57,12 @@ def deserialize_config_args(input: str) -> dict: return runtime_modifications +def _split_at_delimiter( + input: str, slug_delimiter: str, whitespace_to_strip=None +) -> list: + return input.strip(whitespace_to_strip).split(slug_delimiter) + + class WrappingFormatter(argparse.RawTextHelpFormatter): """Used in help screen""" diff --git a/tests/test_parse_args.py b/tests/test_parse_args.py index a49c99cb..5c469e47 100644 --- a/tests/test_parse_args.py +++ b/tests/test_parse_args.py @@ -207,37 +207,6 @@ def test_version_alone(): assert cli_as_dict("--version") == expected_args(preconfig_cmd=preconfig_version) -class TestDeserialization: - @pytest.mark.parametrize( - "input_str", - [ - 'editor:"nano", colors.title:blue, default:"/tmp/egg.txt"', - 'editor:"vi -c startinsert", colors.title:blue, default:"/tmp/egg.txt"', - 'editor:"nano", colors.title:blue, default:"/tmp/eg\ g.txt"', - ], - ) - def test_deserialize_multiword_strings(self, input_str): - - runtime_config = deserialize_config_args(input_str) - assert runtime_config.__class__ == dict - assert "editor" in runtime_config.keys() - assert "colors.title" in runtime_config.keys() - assert "default" in runtime_config.keys() - - def test_deserialize_int(self): - input = "linewrap: 23, default_hour: 19" - runtime_config = deserialize_config_args(input) - assert runtime_config["linewrap"] == 23 - assert runtime_config["default_hour"] == 19 - - def test_deserialize_multiple_datatypes(self): - input = 'linewrap: 23, encrypt: false, editor:"vi -c startinsert"' - cfg = deserialize_config_args(input) - assert cfg["encrypt"] == False - assert cfg["linewrap"] == 23 - assert cfg["editor"] == '"vi -c startinsert"' - - def test_editor_override(): parsed_args = cli_as_dict('--config-override editor:"nano"') @@ -291,3 +260,55 @@ def test_and_ordering(cli): def test_edit_ordering(cli): result = expected_args(edit=True, text=["second", "@oldtag", "@newtag"]) assert cli_as_dict(cli) == result + + +class TestDeserialization: + @pytest.mark.parametrize( + "input_str", + [ + 'editor:"nano", colors.title:blue, default:"/tmp/egg.txt"', + 'editor:"vi -c startinsert", colors.title:blue, default:"/tmp/egg.txt"', + 'editor:"nano", colors.title:blue, default:"/tmp/eg\ g.txt"', + ], + ) + def test_deserialize_multiword_strings(self, input_str): + + runtime_config = deserialize_config_args(input_str) + assert runtime_config.__class__ == dict + assert "editor" in runtime_config.keys() + assert "colors.title" in runtime_config.keys() + assert "default" in runtime_config.keys() + + def test_deserialize_int(self): + input = "linewrap: 23, default_hour: 19" + runtime_config = deserialize_config_args(input) + assert runtime_config["linewrap"] == 23 + assert runtime_config["default_hour"] == 19 + + def test_deserialize_multiple_datatypes(self): + input = ( + 'linewrap: 23, encrypt: false, editor:"vi -c startinsert", highlight: true' + ) + cfg = deserialize_config_args(input) + assert cfg["encrypt"] == False + assert cfg["highlight"] == True + assert cfg["linewrap"] == 23 + assert cfg["editor"] == '"vi -c startinsert"' + + @pytest.mark.parametrize( + "delimiter", + [ + ".", + ":", + ", ", # note the whitespaces + "-|-", # no reason not to handle multi-character delimiters + ], + ) + def test_split_at_delimiter(self, delimiter): + input = delimiter.join( + ["eggs ", "ba con", "ham"] + ) # The whitespaces are deliberate + from jrnl.args import _split_at_delimiter + + assert _split_at_delimiter(input, delimiter) == ["eggs ", "ba con", "ham"] + assert _split_at_delimiter(input, delimiter, " ") == ["eggs ", "ba con", "ham"]