diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md new file mode 100644 index 0000000..713a508 --- /dev/null +++ b/docs/CHANGELOG.md @@ -0,0 +1,8 @@ +# Changelog + +## [Unreleased] + +### Added + +- Add class for existing directories +- Add function to format a list human-readable \ No newline at end of file diff --git a/src/jcloud_docsgen/utils.py b/src/jcloud_docsgen/utils.py index 76f2219..3e91789 100644 --- a/src/jcloud_docsgen/utils.py +++ b/src/jcloud_docsgen/utils.py @@ -19,6 +19,8 @@ The utilities for jcloud_docsgen import pathlib import os import errno +from typing import Union +import types class ExistingDirectory(pathlib.Path): ''' @@ -33,4 +35,51 @@ class ExistingDirectory(pathlib.Path): raise FileNotFoundError(errno.ENOENT, 'no such file or directory', path) if not os.path.isdir(path): raise NotADirectoryError(errno.ENOTDIR, 'not a directory', path) - super().__init__(*(path, *args), **kwargs) \ No newline at end of file + super().__init__(*(path, *args), **kwargs) + +def _quote(string: str, quotation_mark: str) -> str: + ''' + Quotes a string. + + :param string: The string to quote + :type string: str + :param quotation_mark: The quotation mark + :type quotation_mark: str + + :return: The quoted string + :rtype: str + ''' + + return quotation_mark + string + quotation_mark + +def human_readable_list(ls: list, final_separator: str = 'and', quotation_mark: str = '') -> str: + ''' + Generates a human-readable list from a list. + + :param ls: The list. + :type ls: list + :param final_separator: The seperator between the last and the + second-to-last element of the list. Default + is 'and'. + :type final_separator: str + :param quotation_mark: The characters that are inserted before and + after an element. Default is ''. + + :return: The human-readable list. + :rtype: str + ''' + + # empty list + if not ls: + return '' + + # list with one element + if len(ls) == 1: + return _quote(str(ls[0]), quotation_mark) + + return ', '.join( + [ + _quote(str(obj), quotation_mark) # quote the string representation of the object + for obj in ls[:-1] # do not include the last element of the list + ] + ) + ' ' + final_separator + ' ' + _quote(str(ls[-1]), quotation_mark) \ No newline at end of file diff --git a/tests/unit/_utils/test_human_readable_list.py b/tests/unit/_utils/test_human_readable_list.py new file mode 100644 index 0000000..6665f3f --- /dev/null +++ b/tests/unit/_utils/test_human_readable_list.py @@ -0,0 +1,40 @@ +from src.jcloud_docsgen.utils import human_readable_list +import pytest + +@pytest.mark.parametrize('ls,final_separator,quotation_mark,expected', [ + ([], '', '', ''), + ([], 'and', '', ''), + ([], 'and', '\'', ''), + ([1], '', '', '1'), + ([-1], '', '', '-1'), + ([0], '', '', '0'), + ([0.0], '', '', '0.0'), + ([-0.0], '', '', '-0.0'), + ([4.2], '', '', '4.2'), + ([-4.2], '', '', '-4.2'), + (['a'], '', '', 'a'), + ([1], 'and', '', '1'), + (['a'], 'and', '', 'a'), + ([1], 'and', '\'', '\'1\''), + (['a'], 'and', '\'', '\'a\''), + ([1, 2], 'and', '', '1 and 2'), + ([1, 2], 'and', '\'', '\'1\' and \'2\''), + ([1, 'a'], 'and', '', '1 and a'), + ([1, 'a'], 'and', '\'', '\'1\' and \'a\''), + ([1, 'a'], 'and', '', '1 and a'), + ([1, 'a'], 'and', '\'', '\'1\' and \'a\''), + ([1, 'a'], 'and', '\'', '\'1\' and \'a\''), + ([1, 'a'], '', '', '1 a'), + ([1, 'a'], '', '\'', '\'1\' \'a\''), + ([1, 'a'], '', '', '1 a'), + ([1, 'a'], '', '\'', '\'1\' \'a\''), + ([1, 'a'], '', '\'', '\'1\' \'a\''), + ([1, 2, 3], 'and', '', '1, 2 and 3'), + ([1, 2, 3], '', '', '1, 2 3'), + ([1, 2, 3], 'and', '\'', '\'1\', \'2\' and \'3\''), + ([1, 2, 3], '', '\'', '\'1\', \'2\' \'3\''), + ([1, 2, 3, 42, 'a', 23], 'and', '', '1, 2, 3, 42, a and 23'), + ([1, 2, 3, 42, 'a', 23], 'and', '\'', '\'1\', \'2\', \'3\', \'42\', \'a\' and \'23\''), +]) +def test_human_readable_list(ls, final_separator, quotation_mark, expected): + assert human_readable_list(ls, final_separator, quotation_mark) == expected \ No newline at end of file