From e9132d5b40f10a5055e81a07b94e2f2ddc49b636 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Fri, 4 Oct 2024 13:19:48 +0200 Subject: [PATCH 01/48] Update utils datasets functions --- .gitignore | 1 + CHANGELOG.rst | 8 ++ requirements.txt | 1 + .../utils/test_dataset_map_param_context.py | 26 ++++++ .../test/utils/test_dataset_replace_param.py | 27 +++++++ toolium/utils/dataset.py | 81 +++++++++++++++---- 6 files changed, 129 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index bdc60f50..c4c0c5af 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ target .vscode # virtualenv +.venv venv/ VENV/ ENV/ diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 62f102ed..34204f62 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,6 +5,14 @@ v3.2.1 ------ *Release date: In development* +- Fix `get_value_from_context` allow negative numbers. Example: element.-1 +- Update `_replace_param_date`remove deprecated function .utcnow(), update with pytz.timezone('Europe/Madrid') +- Update `_replace_param_transform_string_replace_param_transform_string` include new options + * JSON -> format string to json. Example: [JSON:{'key': 'value'}] + * REPLACE -> replace elements in string. Example: [REPLACE:[CONTEXT:some_url]::https::http] + * DATE -> format date. Example: [DATE:[CONTEXT:actual_date]::%d %b %Y] + * TITLE -> apply .title() to string value. Example: [TITLE:the title] + v3.2.0 ------ diff --git a/requirements.txt b/requirements.txt index 7edfa80b..3433d4a6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,3 +6,4 @@ screeninfo~=0.8 lxml~=5.1 Faker~=25.9 phonenumbers~=8.13 +pytz diff --git a/toolium/test/utils/test_dataset_map_param_context.py b/toolium/test/utils/test_dataset_map_param_context.py index 222d91ff..c2fd6790 100644 --- a/toolium/test/utils/test_dataset_map_param_context.py +++ b/toolium/test/utils/test_dataset_map_param_context.py @@ -428,7 +428,33 @@ class Context(object): dataset.behave_context = context assert map_param("[CONTEXT:list.cmsScrollableActions.1.id]") == 'ask-for-qa' +def test_a_context_param_list_correct_negative_index(): + """ + Verification of a list with a correct negative index (In bounds) as CONTEXT + """ + class Context(object): + pass + context = Context() + context.list = { + 'cmsScrollableActions': [ + { + 'id': 'ask-for-duplicate', + 'text': 'QA duplica' + }, + { + 'id': 'ask-for-qa', + 'text': 'QA no duplica' + }, + { + 'id': 'ask-for-negative', + 'text': 'QA negative index' + } + ] + } + dataset.behave_context = context + assert map_param("[CONTEXT:list.cmsScrollableActions.-1.id]") == 'ask-for-negative' + def test_a_context_param_list_oob_index(): """ Verification of a list with an incorrect index (Out of bounds) as CONTEXT diff --git a/toolium/test/utils/test_dataset_replace_param.py b/toolium/test/utils/test_dataset_replace_param.py index ce5361f8..1a9dad29 100644 --- a/toolium/test/utils/test_dataset_replace_param.py +++ b/toolium/test/utils/test_dataset_replace_param.py @@ -438,3 +438,30 @@ def test_replace_param_partial_string_with_length(): assert param == 'aaaaa is string' param = replace_param('parameter [STRING_WITH_LENGTH_5] is string') assert param == 'parameter aaaaa is string' + +def test_replace_param_json(): + test_json = '{"key": "value", "key_1": true}' + param = replace_param(f'[JSON:{test_json}]') + assert param == {"key": "value", "key_1": True} + +def test_replace_param_json(): + param = replace_param(f'[REPLACE:https://url.com::https::http]') + assert param == "http://url.com" + param = replace_param(f'[REPLACE:https://url.com::https://]') + assert param == "url.com" + +def test_replace_param_date(): + param = replace_param(f'[DATE:1994-06-13T07:00:00::%d %m %Y]') + assert param == "13 06 1994" + param = replace_param(f'[DATE:1994-06-13T07:00:00::%d %b %Y]') + assert param == "13 JUN 1994" + param = replace_param(f'[DATE:1994-06-13T07:00:00::%H:%M]') + assert param == "07:00" + +def test_replace_param_title(): + param = replace_param(f'[TITLE:hola hola]') + assert param == "Hola Hola" + param = replace_param(f'[TITLE:holahola]') + assert param == "Holahola" + param = replace_param(f'[TITLE:hOlA]') + assert param == "Hola" \ No newline at end of file diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index 42774160..c87d8697 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -26,6 +26,8 @@ import re import string import uuid +import pytz +import locale from ast import literal_eval from copy import deepcopy @@ -88,6 +90,10 @@ def replace_param(param, language='es', infer_param_type=True): [DICT:xxxx] Cast xxxx to a dict [UPPER:xxxx] Converts xxxx to upper case [LOWER:xxxx] Converts xxxx to lower case + [JSON:xxxxx] Format string to json. Example: [JSON:{'key': 'value'}] + [REPLACE:xxxxx::xx::zz] Replace elements in string. Example: [REPLACE:[CONTEXT:some_url]::https::http] + [DATE:xxxx::{date-format}] Format date. Example: [DATE:[CONTEXT:actual_date]::%d %b %Y] + [TITLE:xxxxx] Apply .title() to string value. Example: [TITLE:the title] If infer_param_type is True and the result of the replacement process is a string, this function also tries to infer and cast the result to the most appropriate data type, attempting first the direct conversion to a Python built-in data type and then, @@ -223,31 +229,76 @@ def _get_random_phone_number(): return DataGenerator().phone_number +def _format_date_spanish(date, date_expected_format, date_actual_format='%Y-%m-%dT%H:%M:%SZ', capitalize=True): + """_format_date_spanish + Format date to spanish + + :param str date: actual date + :param str date_expected_format: expected returned date format + :param str date_actual_format: date acual format, defaults to '%Y-%m-%dT%H:%M:%SZ' + :param bool capitalize: capitalize month result, defaults to True + :return str: Date with expected format + """ + if '%p' not in date_expected_format and '%P' not in date_expected_format: + locale.setlocale(locale.LC_TIME, 'es_ES.UTF-8') + date = datetime.strptime(date, date_actual_format) + formated_date = date.strftime(date_expected_format) + if capitalize: + position = next((idx for idx, letter in enumerate(formated_date) if letter.isalpha()), None) + if position is not None: + formated_date = formated_date.replace(formated_date[position], formated_date[position].upper(), 1) + formated_date = formated_date if formated_date[0] != '0' else formated_date[1:] + + return formated_date + def _replace_param_transform_string(param): """ Transform param value according to the specified prefix. - Available transformations: DICT, LIST, INT, FLOAT, STR, UPPER, LOWER + Available transformations: DICT, LIST, INT, FLOAT, JSON, STR, UPPER, LOWER, REPLACE, DATE, TITLE :param param: parameter value :return: tuple with replaced value and boolean to know if replacement has been done """ - type_mapping_regex = r'\[(DICT|LIST|INT|FLOAT|STR|UPPER|LOWER):(.*)\]' + type_mapping_regex = r'\[(DICT|LIST|INT|FLOAT|JSON|STR|UPPER|LOWER|REPLACE|DATE|TITLE):([\w\W]*)\]' type_mapping_match_group = re.match(type_mapping_regex, param) new_param = param param_transformed = False if type_mapping_match_group: param_transformed = True - if type_mapping_match_group.group(1) == 'STR': - new_param = type_mapping_match_group.group(2) - elif type_mapping_match_group.group(1) in ['LIST', 'DICT', 'INT', 'FLOAT']: - exec('exec_param = {type}({value})'.format(type=type_mapping_match_group.group(1).lower(), - value=type_mapping_match_group.group(2))) - new_param = locals()['exec_param'] - elif type_mapping_match_group.group(1) == 'UPPER': - new_param = type_mapping_match_group.group(2).upper() - elif type_mapping_match_group.group(1) == 'LOWER': - new_param = type_mapping_match_group.group(2).lower() + if type_mapping_match_group.group(1) in ['DICT', 'LIST', 'INT', 'FLOAT', 'JSON']: + if '::' in type_mapping_match_group.group() and 'FLOAT' in type_mapping_match_group.group(): + params_to_replace = type_mapping_match_group.group( + 2).split('::') + float_formatted = "{:.2f}".format(round(float(params_to_replace[0]), int(params_to_replace[1]))) + new_param = float_formatted + elif type_mapping_match_group.group(1) == 'JSON': + new_param = json.loads(type_mapping_match_group.group(2)) + else: + exec(f'exec_param = {type_mapping_match_group.group(1).lower()}({type_mapping_match_group.group(2)})') + new_param = locals()['exec_param'] + else: + if type_mapping_match_group.group(1) == 'STR': + replace_param = type_mapping_match_group.group(2) + elif type_mapping_match_group.group(1) == 'UPPER': + replace_param = type_mapping_match_group.group(2).upper() + elif type_mapping_match_group.group(1) == 'LOWER': + replace_param = type_mapping_match_group.group(2).lower() + elif type_mapping_match_group.group(1) == 'REPLACE': + params_to_replace = type_mapping_match_group.group(2).split('::') + replace_param = params_to_replace[2] if len(params_to_replace) > 2 else '' + param_to_replace = params_to_replace[1] if params_to_replace[1] != '\\n' else '\n' + param_to_replace = params_to_replace[1] if params_to_replace[1] != '\\r' else '\r' + replace_param = params_to_replace[0].replace(param_to_replace, replace_param).replace(' ', ' ').replace(' ', ' ') + elif type_mapping_match_group.group(1) == 'DATE': + params_to_replace = type_mapping_match_group.group(2).split('::') + date_actual_format='%Y/%m/%d %H:%M:%S' + replace_param = _format_date_spanish(params_to_replace[0], params_to_replace[1], date_actual_format, capitalize=False) + elif type_mapping_match_group.group(1) == 'TITLE': + replace_param = "".join(map(min, zip(type_mapping_match_group.group(2), + type_mapping_match_group.group(2).title()))) + new_param = new_param.replace( + type_mapping_match_group.group(), replace_param) return new_param, param_transformed @@ -266,8 +317,8 @@ def _replace_param_date(param, language): def _date_matcher(): return re.match(r'\[(NOW(?:\((?:.*)\)|)|TODAY)(?:\s*([\+|-]\s*\d+)\s*(\w+)\s*)?\]', param) - def _offset_datetime(amount, units): - now = datetime.datetime.utcnow() + def _offset_datetime(amount, units): + now = datetime.datetime.now(pytz.timezone('Europe/Madrid')) if not amount or not units: return now the_amount = int(amount.replace(' ', '')) @@ -611,7 +662,7 @@ def get_value_from_context(param, context): if isinstance(value, dict) and part in value: value = value[part] # evaluate if in an array, access is requested by index - elif isinstance(value, list) and part.isdigit() and int(part) < len(value): + elif isinstance(value, list) and part.lstrip('-+').isdigit() and int(part) < len(value): value = value[int(part)] # or by a key=value expression elif isinstance(value, list) and (element := _select_element_in_list(value, part)): From d689d5ddf7db343b1e812df194211811a443ecc8 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Fri, 4 Oct 2024 13:29:33 +0200 Subject: [PATCH 02/48] Fix linter issues --- .../utils/test_dataset_map_param_context.py | 3 +- .../test/utils/test_dataset_replace_param.py | 28 +++++++++++-------- toolium/utils/dataset.py | 10 ++++--- 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/toolium/test/utils/test_dataset_map_param_context.py b/toolium/test/utils/test_dataset_map_param_context.py index c2fd6790..56fe259d 100644 --- a/toolium/test/utils/test_dataset_map_param_context.py +++ b/toolium/test/utils/test_dataset_map_param_context.py @@ -454,7 +454,8 @@ class Context(object): } dataset.behave_context = context assert map_param("[CONTEXT:list.cmsScrollableActions.-1.id]") == 'ask-for-negative' - + + def test_a_context_param_list_oob_index(): """ Verification of a list with an incorrect index (Out of bounds) as CONTEXT diff --git a/toolium/test/utils/test_dataset_replace_param.py b/toolium/test/utils/test_dataset_replace_param.py index 1a9dad29..04a3e742 100644 --- a/toolium/test/utils/test_dataset_replace_param.py +++ b/toolium/test/utils/test_dataset_replace_param.py @@ -439,29 +439,33 @@ def test_replace_param_partial_string_with_length(): param = replace_param('parameter [STRING_WITH_LENGTH_5] is string') assert param == 'parameter aaaaa is string' + def test_replace_param_json(): test_json = '{"key": "value", "key_1": true}' param = replace_param(f'[JSON:{test_json}]') assert param == {"key": "value", "key_1": True} -def test_replace_param_json(): - param = replace_param(f'[REPLACE:https://url.com::https::http]') + +def test_replace_param_replace(): + param = replace_param('[REPLACE:https://url.com::https::http]') assert param == "http://url.com" - param = replace_param(f'[REPLACE:https://url.com::https://]') + param = replace_param('[REPLACE:https://url.com::https://]') assert param == "url.com" - + + def test_replace_param_date(): - param = replace_param(f'[DATE:1994-06-13T07:00:00::%d %m %Y]') + param = replace_param('[DATE:1994-06-13T07:00:00::%d %m %Y]') assert param == "13 06 1994" - param = replace_param(f'[DATE:1994-06-13T07:00:00::%d %b %Y]') + param = replace_param('[DATE:1994-06-13T07:00:00::%d %b %Y]') assert param == "13 JUN 1994" - param = replace_param(f'[DATE:1994-06-13T07:00:00::%H:%M]') + param = replace_param('[DATE:1994-06-13T07:00:00::%H:%M]') assert param == "07:00" - + + def test_replace_param_title(): - param = replace_param(f'[TITLE:hola hola]') + param = replace_param('[TITLE:hola hola]') assert param == "Hola Hola" - param = replace_param(f'[TITLE:holahola]') + param = replace_param('[TITLE:holahola]') assert param == "Holahola" - param = replace_param(f'[TITLE:hOlA]') - assert param == "Hola" \ No newline at end of file + param = replace_param('[TITLE:hOlA]') + assert param == "Hola" diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index c87d8697..a0d8ce1a 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -230,7 +230,7 @@ def _get_random_phone_number(): def _format_date_spanish(date, date_expected_format, date_actual_format='%Y-%m-%dT%H:%M:%SZ', capitalize=True): - """_format_date_spanish + """_format_date_spanish Format date to spanish :param str date: actual date @@ -251,6 +251,7 @@ def _format_date_spanish(date, date_expected_format, date_actual_format='%Y-%m-% return formated_date + def _replace_param_transform_string(param): """ Transform param value according to the specified prefix. @@ -292,8 +293,9 @@ def _replace_param_transform_string(param): replace_param = params_to_replace[0].replace(param_to_replace, replace_param).replace(' ', ' ').replace(' ', ' ') elif type_mapping_match_group.group(1) == 'DATE': params_to_replace = type_mapping_match_group.group(2).split('::') - date_actual_format='%Y/%m/%d %H:%M:%S' - replace_param = _format_date_spanish(params_to_replace[0], params_to_replace[1], date_actual_format, capitalize=False) + date_actual_format = '%Y/%m/%d %H:%M:%S' + replace_param = _format_date_spanish(params_to_replace[0], params_to_replace[1], date_actual_format,\ + capitalize=False) elif type_mapping_match_group.group(1) == 'TITLE': replace_param = "".join(map(min, zip(type_mapping_match_group.group(2), type_mapping_match_group.group(2).title()))) @@ -317,7 +319,7 @@ def _replace_param_date(param, language): def _date_matcher(): return re.match(r'\[(NOW(?:\((?:.*)\)|)|TODAY)(?:\s*([\+|-]\s*\d+)\s*(\w+)\s*)?\]', param) - def _offset_datetime(amount, units): + def _offset_datetime(amount, units): now = datetime.datetime.now(pytz.timezone('Europe/Madrid')) if not amount or not units: return now From 29776187ad4af3cec5a900efc7e51f34a60f8ea9 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Fri, 4 Oct 2024 13:51:00 +0200 Subject: [PATCH 03/48] Fix linter issue C901 --- toolium/utils/dataset.py | 55 ++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index a0d8ce1a..df5e6d50 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -279,31 +279,42 @@ def _replace_param_transform_string(param): exec(f'exec_param = {type_mapping_match_group.group(1).lower()}({type_mapping_match_group.group(2)})') new_param = locals()['exec_param'] else: - if type_mapping_match_group.group(1) == 'STR': - replace_param = type_mapping_match_group.group(2) - elif type_mapping_match_group.group(1) == 'UPPER': - replace_param = type_mapping_match_group.group(2).upper() - elif type_mapping_match_group.group(1) == 'LOWER': - replace_param = type_mapping_match_group.group(2).lower() - elif type_mapping_match_group.group(1) == 'REPLACE': - params_to_replace = type_mapping_match_group.group(2).split('::') - replace_param = params_to_replace[2] if len(params_to_replace) > 2 else '' - param_to_replace = params_to_replace[1] if params_to_replace[1] != '\\n' else '\n' - param_to_replace = params_to_replace[1] if params_to_replace[1] != '\\r' else '\r' - replace_param = params_to_replace[0].replace(param_to_replace, replace_param).replace(' ', ' ').replace(' ', ' ') - elif type_mapping_match_group.group(1) == 'DATE': - params_to_replace = type_mapping_match_group.group(2).split('::') - date_actual_format = '%Y/%m/%d %H:%M:%S' - replace_param = _format_date_spanish(params_to_replace[0], params_to_replace[1], date_actual_format,\ - capitalize=False) - elif type_mapping_match_group.group(1) == 'TITLE': - replace_param = "".join(map(min, zip(type_mapping_match_group.group(2), - type_mapping_match_group.group(2).title()))) - new_param = new_param.replace( - type_mapping_match_group.group(), replace_param) + replace_param = _update_param_transform_string(type_mapping_match_group) + new_param = new_param.replace(type_mapping_match_group.group(), replace_param) return new_param, param_transformed +def _update_param_transform_string(type_mapping_match_group): + """ + Transform param value according to the specified prefix. + Available transformations: STR, UPPER, LOWER, REPLACE, DATE, TITLE + + :param type_mapping_match_group: match group + :return: return the string with the replaced param + """ + if type_mapping_match_group.group(1) == 'STR': + replace_param = type_mapping_match_group.group(2) + elif type_mapping_match_group.group(1) == 'UPPER': + replace_param = type_mapping_match_group.group(2).upper() + elif type_mapping_match_group.group(1) == 'LOWER': + replace_param = type_mapping_match_group.group(2).lower() + elif type_mapping_match_group.group(1) == 'REPLACE': + params_to_replace = type_mapping_match_group.group(2).split('::') + replace_param = params_to_replace[2] if len(params_to_replace) > 2 else '' + param_to_replace = params_to_replace[1] if params_to_replace[1] != '\\n' else '\n' + param_to_replace = params_to_replace[1] if params_to_replace[1] != '\\r' else '\r' + replace_param = params_to_replace[0].replace(param_to_replace, replace_param)\ + .replace(' ', ' ').replace(' ', ' ') + elif type_mapping_match_group.group(1) == 'DATE': + params_to_replace = type_mapping_match_group.group(2).split('::') + date_actual_format = '%Y/%m/%d %H:%M:%S' + replace_param = _format_date_spanish(params_to_replace[0], params_to_replace[1], date_actual_format, \ + capitalize=False) + elif type_mapping_match_group.group(1) == 'TITLE': + replace_param = "".join(map(min, zip(type_mapping_match_group.group(2), type_mapping_match_group.group(2).title()))) + return replace_param + + def _replace_param_date(param, language): """ Transform param value in a date after applying the specified delta. From 7892e3108c4936e1074da9604aec5608c88bcbd1 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Fri, 4 Oct 2024 13:54:36 +0200 Subject: [PATCH 04/48] Fix linter issues --- .../utils/test_dataset_map_param_context.py | 1 + toolium/utils/dataset.py | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/toolium/test/utils/test_dataset_map_param_context.py b/toolium/test/utils/test_dataset_map_param_context.py index 56fe259d..449056e3 100644 --- a/toolium/test/utils/test_dataset_map_param_context.py +++ b/toolium/test/utils/test_dataset_map_param_context.py @@ -428,6 +428,7 @@ class Context(object): dataset.behave_context = context assert map_param("[CONTEXT:list.cmsScrollableActions.1.id]") == 'ask-for-qa' + def test_a_context_param_list_correct_negative_index(): """ Verification of a list with a correct negative index (In bounds) as CONTEXT diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index df5e6d50..a43c8a6c 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -288,30 +288,31 @@ def _update_param_transform_string(type_mapping_match_group): """ Transform param value according to the specified prefix. Available transformations: STR, UPPER, LOWER, REPLACE, DATE, TITLE - + :param type_mapping_match_group: match group :return: return the string with the replaced param """ if type_mapping_match_group.group(1) == 'STR': replace_param = type_mapping_match_group.group(2) - elif type_mapping_match_group.group(1) == 'UPPER': + elif type_mapping_match_group.group(1) == 'UPPER': replace_param = type_mapping_match_group.group(2).upper() - elif type_mapping_match_group.group(1) == 'LOWER': + elif type_mapping_match_group.group(1) == 'LOWER': replace_param = type_mapping_match_group.group(2).lower() - elif type_mapping_match_group.group(1) == 'REPLACE': + elif type_mapping_match_group.group(1) == 'REPLACE': params_to_replace = type_mapping_match_group.group(2).split('::') replace_param = params_to_replace[2] if len(params_to_replace) > 2 else '' param_to_replace = params_to_replace[1] if params_to_replace[1] != '\\n' else '\n' param_to_replace = params_to_replace[1] if params_to_replace[1] != '\\r' else '\r' replace_param = params_to_replace[0].replace(param_to_replace, replace_param)\ .replace(' ', ' ').replace(' ', ' ') - elif type_mapping_match_group.group(1) == 'DATE': + elif type_mapping_match_group.group(1) == 'DATE': params_to_replace = type_mapping_match_group.group(2).split('::') date_actual_format = '%Y/%m/%d %H:%M:%S' - replace_param = _format_date_spanish(params_to_replace[0], params_to_replace[1], date_actual_format, \ - capitalize=False) - elif type_mapping_match_group.group(1) == 'TITLE': - replace_param = "".join(map(min, zip(type_mapping_match_group.group(2), type_mapping_match_group.group(2).title()))) + replace_param = _format_date_spanish(params_to_replace[0], params_to_replace[1], date_actual_format, + capitalize=False) + elif type_mapping_match_group.group(1) == 'TITLE': + replace_param = "".join(map(min, zip(type_mapping_match_group.group(2), + type_mapping_match_group.group(2).title()))) return replace_param From c946775137a13b7ac7484632690d8dfa0e0c3ae0 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Fri, 4 Oct 2024 13:58:07 +0200 Subject: [PATCH 05/48] Fix linter issues --- toolium/utils/dataset.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index a43c8a6c..531513a0 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -309,9 +309,9 @@ def _update_param_transform_string(type_mapping_match_group): params_to_replace = type_mapping_match_group.group(2).split('::') date_actual_format = '%Y/%m/%d %H:%M:%S' replace_param = _format_date_spanish(params_to_replace[0], params_to_replace[1], date_actual_format, - capitalize=False) + capitalize=False) elif type_mapping_match_group.group(1) == 'TITLE': - replace_param = "".join(map(min, zip(type_mapping_match_group.group(2), + replace_param = "".join(map(min, zip(type_mapping_match_group.group(2), type_mapping_match_group.group(2).title()))) return replace_param From 93c6e447dc548cf21fbe4ebcfbb784fb267c2a21 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Fri, 4 Oct 2024 14:02:41 +0200 Subject: [PATCH 06/48] Fix linter issues --- toolium/utils/dataset.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index 531513a0..0099cc95 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -308,7 +308,7 @@ def _update_param_transform_string(type_mapping_match_group): elif type_mapping_match_group.group(1) == 'DATE': params_to_replace = type_mapping_match_group.group(2).split('::') date_actual_format = '%Y/%m/%d %H:%M:%S' - replace_param = _format_date_spanish(params_to_replace[0], params_to_replace[1], date_actual_format, + replace_param = _format_date_spanish(params_to_replace[0], params_to_replace[1], date_actual_format, capitalize=False) elif type_mapping_match_group.group(1) == 'TITLE': replace_param = "".join(map(min, zip(type_mapping_match_group.group(2), From e6953e45eebcf9da01134a3264466f6c84b25370 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Fri, 4 Oct 2024 14:21:59 +0200 Subject: [PATCH 07/48] Restore some changes --- CHANGELOG.rst | 4 +--- toolium/utils/dataset.py | 46 ++++++++++------------------------------ 2 files changed, 12 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 34204f62..bd1b7b63 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,12 +5,10 @@ v3.2.1 ------ *Release date: In development* -- Fix `get_value_from_context` allow negative numbers. Example: element.-1 -- Update `_replace_param_date`remove deprecated function .utcnow(), update with pytz.timezone('Europe/Madrid') +- Update `get_value_from_context` allow negative numbers, and dictionaries elements. Example: element.-1 or element.0.value.1.key - Update `_replace_param_transform_string_replace_param_transform_string` include new options * JSON -> format string to json. Example: [JSON:{'key': 'value'}] * REPLACE -> replace elements in string. Example: [REPLACE:[CONTEXT:some_url]::https::http] - * DATE -> format date. Example: [DATE:[CONTEXT:actual_date]::%d %b %Y] * TITLE -> apply .title() to string value. Example: [TITLE:the title] diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index 0099cc95..d7bb7c7f 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -26,8 +26,8 @@ import re import string import uuid -import pytz -import locale + + from ast import literal_eval from copy import deepcopy @@ -228,39 +228,15 @@ def _get_random_phone_number(): # Method to avoid executing data generator when it is not needed return DataGenerator().phone_number - -def _format_date_spanish(date, date_expected_format, date_actual_format='%Y-%m-%dT%H:%M:%SZ', capitalize=True): - """_format_date_spanish - Format date to spanish - - :param str date: actual date - :param str date_expected_format: expected returned date format - :param str date_actual_format: date acual format, defaults to '%Y-%m-%dT%H:%M:%SZ' - :param bool capitalize: capitalize month result, defaults to True - :return str: Date with expected format - """ - if '%p' not in date_expected_format and '%P' not in date_expected_format: - locale.setlocale(locale.LC_TIME, 'es_ES.UTF-8') - date = datetime.strptime(date, date_actual_format) - formated_date = date.strftime(date_expected_format) - if capitalize: - position = next((idx for idx, letter in enumerate(formated_date) if letter.isalpha()), None) - if position is not None: - formated_date = formated_date.replace(formated_date[position], formated_date[position].upper(), 1) - formated_date = formated_date if formated_date[0] != '0' else formated_date[1:] - - return formated_date - - def _replace_param_transform_string(param): """ Transform param value according to the specified prefix. - Available transformations: DICT, LIST, INT, FLOAT, JSON, STR, UPPER, LOWER, REPLACE, DATE, TITLE + Available transformations: DICT, LIST, INT, FLOAT, JSON, STR, UPPER, LOWER, REPLACE, TITLE :param param: parameter value :return: tuple with replaced value and boolean to know if replacement has been done """ - type_mapping_regex = r'\[(DICT|LIST|INT|FLOAT|JSON|STR|UPPER|LOWER|REPLACE|DATE|TITLE):([\w\W]*)\]' + type_mapping_regex = r'\[(DICT|LIST|INT|FLOAT|JSON|STR|UPPER|LOWER|REPLACE|TITLE):([\w\W]*)\]' type_mapping_match_group = re.match(type_mapping_regex, param) new_param = param param_transformed = False @@ -305,11 +281,6 @@ def _update_param_transform_string(type_mapping_match_group): param_to_replace = params_to_replace[1] if params_to_replace[1] != '\\r' else '\r' replace_param = params_to_replace[0].replace(param_to_replace, replace_param)\ .replace(' ', ' ').replace(' ', ' ') - elif type_mapping_match_group.group(1) == 'DATE': - params_to_replace = type_mapping_match_group.group(2).split('::') - date_actual_format = '%Y/%m/%d %H:%M:%S' - replace_param = _format_date_spanish(params_to_replace[0], params_to_replace[1], date_actual_format, - capitalize=False) elif type_mapping_match_group.group(1) == 'TITLE': replace_param = "".join(map(min, zip(type_mapping_match_group.group(2), type_mapping_match_group.group(2).title()))) @@ -332,7 +303,7 @@ def _date_matcher(): return re.match(r'\[(NOW(?:\((?:.*)\)|)|TODAY)(?:\s*([\+|-]\s*\d+)\s*(\w+)\s*)?\]', param) def _offset_datetime(amount, units): - now = datetime.datetime.now(pytz.timezone('Europe/Madrid')) + now = datetime.datetime.utcnow() if not amount or not units: return now the_amount = int(amount.replace(' ', '')) @@ -677,7 +648,12 @@ def get_value_from_context(param, context): value = value[part] # evaluate if in an array, access is requested by index elif isinstance(value, list) and part.lstrip('-+').isdigit() and int(part) < len(value): - value = value[int(part)] + try: + value = value[int(part)] if part.lstrip('-+').isdigit() else value[part] + except (TypeError, KeyError): + value = getattr(value, part) + except AttributeError as exc: + raise AttributeError(context.logger.info) from exc # or by a key=value expression elif isinstance(value, list) and (element := _select_element_in_list(value, part)): value = element From 833d7c77995b0a2ecc359d3776efd6d03cdde05e Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Fri, 4 Oct 2024 14:23:57 +0200 Subject: [PATCH 08/48] Restore some changes --- toolium/utils/dataset.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index d7bb7c7f..f9d8c022 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -27,8 +27,6 @@ import string import uuid - - from ast import literal_eval from copy import deepcopy from inspect import isfunction @@ -648,12 +646,7 @@ def get_value_from_context(param, context): value = value[part] # evaluate if in an array, access is requested by index elif isinstance(value, list) and part.lstrip('-+').isdigit() and int(part) < len(value): - try: - value = value[int(part)] if part.lstrip('-+').isdigit() else value[part] - except (TypeError, KeyError): - value = getattr(value, part) - except AttributeError as exc: - raise AttributeError(context.logger.info) from exc + value = value[int(part)] # or by a key=value expression elif isinstance(value, list) and (element := _select_element_in_list(value, part)): value = element From 0a6ca46efe2808b7dd364a664dc84cb653f19dc8 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Fri, 4 Oct 2024 14:24:42 +0200 Subject: [PATCH 09/48] Remove test --- toolium/test/utils/test_dataset_replace_param.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/toolium/test/utils/test_dataset_replace_param.py b/toolium/test/utils/test_dataset_replace_param.py index 04a3e742..34ceaff8 100644 --- a/toolium/test/utils/test_dataset_replace_param.py +++ b/toolium/test/utils/test_dataset_replace_param.py @@ -453,15 +453,6 @@ def test_replace_param_replace(): assert param == "url.com" -def test_replace_param_date(): - param = replace_param('[DATE:1994-06-13T07:00:00::%d %m %Y]') - assert param == "13 06 1994" - param = replace_param('[DATE:1994-06-13T07:00:00::%d %b %Y]') - assert param == "13 JUN 1994" - param = replace_param('[DATE:1994-06-13T07:00:00::%H:%M]') - assert param == "07:00" - - def test_replace_param_title(): param = replace_param('[TITLE:hola hola]') assert param == "Hola Hola" From f2db21cd19347cc773835dc65c32f67756ad673f Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Fri, 4 Oct 2024 14:25:07 +0200 Subject: [PATCH 10/48] Remove test --- CHANGELOG.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index bd1b7b63..adcd543d 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,7 +5,7 @@ v3.2.1 ------ *Release date: In development* -- Update `get_value_from_context` allow negative numbers, and dictionaries elements. Example: element.-1 or element.0.value.1.key +- Update `get_value_from_context` allow negative numbers. Example: element.-1 - Update `_replace_param_transform_string_replace_param_transform_string` include new options * JSON -> format string to json. Example: [JSON:{'key': 'value'}] * REPLACE -> replace elements in string. Example: [REPLACE:[CONTEXT:some_url]::https::http] From 98b4509575ba7b1deb000dc3aeaa825344828c73 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Fri, 4 Oct 2024 14:25:34 +0200 Subject: [PATCH 11/48] Remove requirement --- requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 3433d4a6..7edfa80b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,4 +6,3 @@ screeninfo~=0.8 lxml~=5.1 Faker~=25.9 phonenumbers~=8.13 -pytz From ecdb84c3ab23f5ec86db324de32be648b787ad6f Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Fri, 4 Oct 2024 14:26:48 +0200 Subject: [PATCH 12/48] Fix linter issues --- toolium/utils/dataset.py | 1 + 1 file changed, 1 insertion(+) diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index f9d8c022..4cda6ca4 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -226,6 +226,7 @@ def _get_random_phone_number(): # Method to avoid executing data generator when it is not needed return DataGenerator().phone_number + def _replace_param_transform_string(param): """ Transform param value according to the specified prefix. From a24e2bfa919def27b38f2c159f3111c018e1419f Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Fri, 4 Oct 2024 14:30:07 +0200 Subject: [PATCH 13/48] Fix tests issue --- toolium/test/utils/test_dataset_replace_param.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolium/test/utils/test_dataset_replace_param.py b/toolium/test/utils/test_dataset_replace_param.py index 34ceaff8..39e1433c 100644 --- a/toolium/test/utils/test_dataset_replace_param.py +++ b/toolium/test/utils/test_dataset_replace_param.py @@ -459,4 +459,4 @@ def test_replace_param_title(): param = replace_param('[TITLE:holahola]') assert param == "Holahola" param = replace_param('[TITLE:hOlA]') - assert param == "Hola" + assert param == "HOlA" From 87e2bc364ba7025dee666c9d1c026662ac5458c2 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez <58507180+promans718@users.noreply.github.com> Date: Mon, 7 Oct 2024 08:39:35 +0200 Subject: [PATCH 14/48] Update CHANGELOG.rst Co-authored-by: Pablo Guijarro --- CHANGELOG.rst | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index adcd543d..8e64bb1d 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,11 +5,10 @@ v3.2.1 ------ *Release date: In development* -- Update `get_value_from_context` allow negative numbers. Example: element.-1 -- Update `_replace_param_transform_string_replace_param_transform_string` include new options - * JSON -> format string to json. Example: [JSON:{'key': 'value'}] - * REPLACE -> replace elements in string. Example: [REPLACE:[CONTEXT:some_url]::https::http] - * TITLE -> apply .title() to string value. Example: [TITLE:the title] +- Allow negative indexes for list elements in context searches. Example: [CONTEXT:element.-1] +- Add support for JSON strings to the `DICT` replacement. Example: [DICT:{"key": true}] +- Add `REPLACE` replacement, to replace a substring with another. Example: [REPLACE:[CONTEXT:some_url]::https::http] +- Add `TITLE` replacement, to apply Python's title() function. Example: [TITLE:the title] v3.2.0 From 100aea2eb2659bd58406ea88588cb8efede8ad52 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez <58507180+promans718@users.noreply.github.com> Date: Mon, 7 Oct 2024 08:40:35 +0200 Subject: [PATCH 15/48] Update toolium/utils/dataset.py Co-authored-by: Pablo Guijarro --- toolium/utils/dataset.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index 4cda6ca4..35284a14 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -646,7 +646,7 @@ def get_value_from_context(param, context): if isinstance(value, dict) and part in value: value = value[part] # evaluate if in an array, access is requested by index - elif isinstance(value, list) and part.lstrip('-+').isdigit() and int(part) < len(value): + elif isinstance(value, list) and part.lstrip('-+').isdigit() and int(part) <= len(value): value = value[int(part)] # or by a key=value expression elif isinstance(value, list) and (element := _select_element_in_list(value, part)): From ca620476f2f8bc1f6900a7a21249a8ae8a938dcc Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Mon, 7 Oct 2024 08:49:53 +0200 Subject: [PATCH 16/48] Fix pull request issues --- toolium/utils/dataset.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index 35284a14..7ac68796 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -90,7 +90,6 @@ def replace_param(param, language='es', infer_param_type=True): [LOWER:xxxx] Converts xxxx to lower case [JSON:xxxxx] Format string to json. Example: [JSON:{'key': 'value'}] [REPLACE:xxxxx::xx::zz] Replace elements in string. Example: [REPLACE:[CONTEXT:some_url]::https::http] - [DATE:xxxx::{date-format}] Format date. Example: [DATE:[CONTEXT:actual_date]::%d %b %Y] [TITLE:xxxxx] Apply .title() to string value. Example: [TITLE:the title] If infer_param_type is True and the result of the replacement process is a string, this function also tries to infer and cast the result to the most appropriate data type, @@ -262,7 +261,7 @@ def _replace_param_transform_string(param): def _update_param_transform_string(type_mapping_match_group): """ Transform param value according to the specified prefix. - Available transformations: STR, UPPER, LOWER, REPLACE, DATE, TITLE + Available transformations: STR, UPPER, LOWER, REPLACE, TITLE :param type_mapping_match_group: match group :return: return the string with the replaced param @@ -278,8 +277,7 @@ def _update_param_transform_string(type_mapping_match_group): replace_param = params_to_replace[2] if len(params_to_replace) > 2 else '' param_to_replace = params_to_replace[1] if params_to_replace[1] != '\\n' else '\n' param_to_replace = params_to_replace[1] if params_to_replace[1] != '\\r' else '\r' - replace_param = params_to_replace[0].replace(param_to_replace, replace_param)\ - .replace(' ', ' ').replace(' ', ' ') + replace_param = params_to_replace[0].replace(param_to_replace, replace_param) elif type_mapping_match_group.group(1) == 'TITLE': replace_param = "".join(map(min, zip(type_mapping_match_group.group(2), type_mapping_match_group.group(2).title()))) From 4b3161f3be1aa3ad9390da81b09f3a25db837cac Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Mon, 7 Oct 2024 09:15:40 +0200 Subject: [PATCH 17/48] Fix pull request issues --- toolium/utils/dataset.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index 7ac68796..941dc261 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -88,7 +88,6 @@ def replace_param(param, language='es', infer_param_type=True): [DICT:xxxx] Cast xxxx to a dict [UPPER:xxxx] Converts xxxx to upper case [LOWER:xxxx] Converts xxxx to lower case - [JSON:xxxxx] Format string to json. Example: [JSON:{'key': 'value'}] [REPLACE:xxxxx::xx::zz] Replace elements in string. Example: [REPLACE:[CONTEXT:some_url]::https::http] [TITLE:xxxxx] Apply .title() to string value. Example: [TITLE:the title] If infer_param_type is True and the result of the replacement process is a string, @@ -229,26 +228,29 @@ def _get_random_phone_number(): def _replace_param_transform_string(param): """ Transform param value according to the specified prefix. - Available transformations: DICT, LIST, INT, FLOAT, JSON, STR, UPPER, LOWER, REPLACE, TITLE + Available transformations: DICT, LIST, INT, FLOAT, STR, UPPER, LOWER, REPLACE, TITLE :param param: parameter value :return: tuple with replaced value and boolean to know if replacement has been done """ - type_mapping_regex = r'\[(DICT|LIST|INT|FLOAT|JSON|STR|UPPER|LOWER|REPLACE|TITLE):([\w\W]*)\]' + type_mapping_regex = r'\[(DICT|LIST|INT|FLOAT|STR|UPPER|LOWER|REPLACE|TITLE):([\w\W]*)\]' type_mapping_match_group = re.match(type_mapping_regex, param) new_param = param param_transformed = False if type_mapping_match_group: param_transformed = True - if type_mapping_match_group.group(1) in ['DICT', 'LIST', 'INT', 'FLOAT', 'JSON']: + if type_mapping_match_group.group(1) in ['DICT', 'LIST', 'INT', 'FLOAT']: if '::' in type_mapping_match_group.group() and 'FLOAT' in type_mapping_match_group.group(): params_to_replace = type_mapping_match_group.group( 2).split('::') float_formatted = "{:.2f}".format(round(float(params_to_replace[0]), int(params_to_replace[1]))) new_param = float_formatted - elif type_mapping_match_group.group(1) == 'JSON': - new_param = json.loads(type_mapping_match_group.group(2)) + elif type_mapping_match_group.group(1) == 'DICT': + try: + new_param = json.loads(type_mapping_match_group.group(2).strip()) + except json.decoder.JSONDecodeError: + new_param = eval(type_mapping_match_group.group(2)) else: exec(f'exec_param = {type_mapping_match_group.group(1).lower()}({type_mapping_match_group.group(2)})') new_param = locals()['exec_param'] From d3f17a81fec8c45de6a2cf827c8e7e8317928472 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Mon, 7 Oct 2024 09:18:39 +0200 Subject: [PATCH 18/48] Restore incorrect pr requested change --- toolium/utils/dataset.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index 941dc261..0eafb24b 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -646,7 +646,7 @@ def get_value_from_context(param, context): if isinstance(value, dict) and part in value: value = value[part] # evaluate if in an array, access is requested by index - elif isinstance(value, list) and part.lstrip('-+').isdigit() and int(part) <= len(value): + elif isinstance(value, list) and part.lstrip('-+').isdigit() and int(part) < len(value): value = value[int(part)] # or by a key=value expression elif isinstance(value, list) and (element := _select_element_in_list(value, part)): From 858b2179e20847720a6c99866b510fd3caf1c968 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Mon, 7 Oct 2024 10:37:35 +0200 Subject: [PATCH 19/48] Remove unrequired tests --- toolium/test/utils/test_dataset_replace_param.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/toolium/test/utils/test_dataset_replace_param.py b/toolium/test/utils/test_dataset_replace_param.py index 39e1433c..0ba7d065 100644 --- a/toolium/test/utils/test_dataset_replace_param.py +++ b/toolium/test/utils/test_dataset_replace_param.py @@ -440,12 +440,6 @@ def test_replace_param_partial_string_with_length(): assert param == 'parameter aaaaa is string' -def test_replace_param_json(): - test_json = '{"key": "value", "key_1": true}' - param = replace_param(f'[JSON:{test_json}]') - assert param == {"key": "value", "key_1": True} - - def test_replace_param_replace(): param = replace_param('[REPLACE:https://url.com::https::http]') assert param == "http://url.com" From ada58fbeb3d518e40fa0a042f75c71f49c3a7a6e Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Tue, 8 Oct 2024 12:07:35 +0200 Subject: [PATCH 20/48] Fix pull request issue --- CHANGELOG.rst | 2 +- .../utils/test_dataset_map_param_context.py | 27 +++++++++++++++++++ .../test/utils/test_dataset_replace_param.py | 14 ++++++++++ toolium/utils/dataset.py | 18 ++++++------- 4 files changed, 51 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 8e64bb1d..13617b77 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -9,7 +9,7 @@ v3.2.1 - Add support for JSON strings to the `DICT` replacement. Example: [DICT:{"key": true}] - Add `REPLACE` replacement, to replace a substring with another. Example: [REPLACE:[CONTEXT:some_url]::https::http] - Add `TITLE` replacement, to apply Python's title() function. Example: [TITLE:the title] - +- Add `ROUND` replacement, float number to a string with the expected decimals. Example: [ROUND:3.3333::2] v3.2.0 ------ diff --git a/toolium/test/utils/test_dataset_map_param_context.py b/toolium/test/utils/test_dataset_map_param_context.py index 449056e3..292c1ffd 100644 --- a/toolium/test/utils/test_dataset_map_param_context.py +++ b/toolium/test/utils/test_dataset_map_param_context.py @@ -456,6 +456,33 @@ class Context(object): dataset.behave_context = context assert map_param("[CONTEXT:list.cmsScrollableActions.-1.id]") == 'ask-for-negative' +def test_a_context_param_list_incorrect_negative_index(): + """ + Verification of a list with a correct negative index (In bounds) as CONTEXT + """ + class Context(object): + pass + context = Context() + + context.list = { + 'cmsScrollableActions': [ + { + 'id': 'ask-for-duplicate', + 'text': 'QA duplica' + }, + { + 'id': 'ask-for-qa', + 'text': 'QA no duplica' + }, + { + 'id': 'ask-for-negative', + 'text': 'QA negative index' + } + ] + } + dataset.behave_context = context + assert map_param("[CONTEXT:list.cmsScrollableActions.-5.id]") + def test_a_context_param_list_oob_index(): """ diff --git a/toolium/test/utils/test_dataset_replace_param.py b/toolium/test/utils/test_dataset_replace_param.py index 0ba7d065..bec1eb64 100644 --- a/toolium/test/utils/test_dataset_replace_param.py +++ b/toolium/test/utils/test_dataset_replace_param.py @@ -375,6 +375,13 @@ def test_replace_param_dict(): assert param == {'a': 'test1', 'b': 'test2', 'c': 'test3'} +def test_replace_param_dict_json_format(): + param = replace_param('[DICT:{"key": "value", "key_2": true}]') + assert param == '{"key": "value", "key_2": true}' + param = replace_param('[DICT:{"key": "value", "key_2": null}]') + assert param == '{"key": "value", "key_2": null}' + + def test_replace_param_upper(): param = replace_param('[UPPER:test]') assert param == 'TEST' @@ -454,3 +461,10 @@ def test_replace_param_title(): assert param == "Holahola" param = replace_param('[TITLE:hOlA]') assert param == "HOlA" + + +def test_replace_param_round(): + param = replace_param('[ROUND:7.5::2]') + assert param == "7.50" + param = replace_param('[ROUND:3.33333333::3]') + assert param == "3.333" diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index 0eafb24b..781eb687 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -84,6 +84,7 @@ def replace_param(param, language='es', infer_param_type=True): [STR:xxxx] Cast xxxx to a string [INT:xxxx] Cast xxxx to an int [FLOAT:xxxx] Cast xxxx to a float + [ROUND:xxxx::2] String float with the expected decimals [LIST:xxxx] Cast xxxx to a list [DICT:xxxx] Cast xxxx to a dict [UPPER:xxxx] Converts xxxx to upper case @@ -228,24 +229,22 @@ def _get_random_phone_number(): def _replace_param_transform_string(param): """ Transform param value according to the specified prefix. - Available transformations: DICT, LIST, INT, FLOAT, STR, UPPER, LOWER, REPLACE, TITLE + Available transformations: DICT, LIST, INT, FLOAT, ROUND, STR, UPPER, LOWER, REPLACE, TITLE :param param: parameter value :return: tuple with replaced value and boolean to know if replacement has been done """ - type_mapping_regex = r'\[(DICT|LIST|INT|FLOAT|STR|UPPER|LOWER|REPLACE|TITLE):([\w\W]*)\]' + type_mapping_regex = r'\[(DICT|LIST|INT|FLOAT|STR|UPPER|LOWER|REPLACE|TITLE|ROUND):([\w\W]*)\]' type_mapping_match_group = re.match(type_mapping_regex, param) new_param = param param_transformed = False if type_mapping_match_group: param_transformed = True - if type_mapping_match_group.group(1) in ['DICT', 'LIST', 'INT', 'FLOAT']: - if '::' in type_mapping_match_group.group() and 'FLOAT' in type_mapping_match_group.group(): - params_to_replace = type_mapping_match_group.group( - 2).split('::') - float_formatted = "{:.2f}".format(round(float(params_to_replace[0]), int(params_to_replace[1]))) - new_param = float_formatted + if type_mapping_match_group.group(1) in ['DICT', 'LIST', 'INT', 'FLOAT', 'ROUND']: + if '::' in type_mapping_match_group.group() and 'ROUND' in type_mapping_match_group.group(): + params_to_replace = type_mapping_match_group.group(2).split('::') + new_param = f"{round(float(params_to_replace[0]), int(params_to_replace[1])):.{int(params_to_replace[1])}f}" elif type_mapping_match_group.group(1) == 'DICT': try: new_param = json.loads(type_mapping_match_group.group(2).strip()) @@ -646,7 +645,8 @@ def get_value_from_context(param, context): if isinstance(value, dict) and part in value: value = value[part] # evaluate if in an array, access is requested by index - elif isinstance(value, list) and part.lstrip('-+').isdigit() and int(part) < len(value): + elif isinstance(value, list) and part.lstrip('-+').isdigit() \ + and int(part) < (len(value) + 1 if part.startswith("-") else len(value)): value = value[int(part)] # or by a key=value expression elif isinstance(value, list) and (element := _select_element_in_list(value, part)): From 6c767a6f0b5922e80cb0d14adc5def9845aaa7f8 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Tue, 8 Oct 2024 12:07:57 +0200 Subject: [PATCH 21/48] Fix typo --- toolium/test/utils/test_dataset_map_param_context.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolium/test/utils/test_dataset_map_param_context.py b/toolium/test/utils/test_dataset_map_param_context.py index 292c1ffd..5a001336 100644 --- a/toolium/test/utils/test_dataset_map_param_context.py +++ b/toolium/test/utils/test_dataset_map_param_context.py @@ -458,7 +458,7 @@ class Context(object): def test_a_context_param_list_incorrect_negative_index(): """ - Verification of a list with a correct negative index (In bounds) as CONTEXT + Verification of a list with a incorrect negative index (In bounds) as CONTEXT """ class Context(object): pass From 2f3875c0ee0510d36c9376eb97a3db9b47f069de Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Tue, 8 Oct 2024 12:14:16 +0200 Subject: [PATCH 22/48] Fix linter issues --- toolium/test/utils/test_dataset_map_param_context.py | 3 ++- toolium/utils/dataset.py | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/toolium/test/utils/test_dataset_map_param_context.py b/toolium/test/utils/test_dataset_map_param_context.py index 5a001336..d13442eb 100644 --- a/toolium/test/utils/test_dataset_map_param_context.py +++ b/toolium/test/utils/test_dataset_map_param_context.py @@ -456,6 +456,7 @@ class Context(object): dataset.behave_context = context assert map_param("[CONTEXT:list.cmsScrollableActions.-1.id]") == 'ask-for-negative' + def test_a_context_param_list_incorrect_negative_index(): """ Verification of a list with a incorrect negative index (In bounds) as CONTEXT @@ -482,7 +483,7 @@ class Context(object): } dataset.behave_context = context assert map_param("[CONTEXT:list.cmsScrollableActions.-5.id]") - + def test_a_context_param_list_oob_index(): """ diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index 781eb687..3c4e4346 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -241,11 +241,8 @@ def _replace_param_transform_string(param): if type_mapping_match_group: param_transformed = True - if type_mapping_match_group.group(1) in ['DICT', 'LIST', 'INT', 'FLOAT', 'ROUND']: - if '::' in type_mapping_match_group.group() and 'ROUND' in type_mapping_match_group.group(): - params_to_replace = type_mapping_match_group.group(2).split('::') - new_param = f"{round(float(params_to_replace[0]), int(params_to_replace[1])):.{int(params_to_replace[1])}f}" - elif type_mapping_match_group.group(1) == 'DICT': + if type_mapping_match_group.group(1) in ['DICT', 'LIST', 'INT', 'FLOAT']: + if type_mapping_match_group.group(1) == 'DICT': try: new_param = json.loads(type_mapping_match_group.group(2).strip()) except json.decoder.JSONDecodeError: @@ -282,6 +279,9 @@ def _update_param_transform_string(type_mapping_match_group): elif type_mapping_match_group.group(1) == 'TITLE': replace_param = "".join(map(min, zip(type_mapping_match_group.group(2), type_mapping_match_group.group(2).title()))) + elif type_mapping_match_group.group(1) == 'ROUND': + replace_params = type_mapping_match_group.group(2).split('::') + replace_param = f"{round(float(replace_params[0]), int(replace_params[1])):.{int(replace_params[1])} f }" return replace_param From 80d2f53e25c922a6d926748e7b2a9cb2aa1dafb6 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Tue, 8 Oct 2024 12:24:50 +0200 Subject: [PATCH 23/48] Fix test issue --- toolium/test/utils/test_dataset_map_param_context.py | 7 ++++--- toolium/test/utils/test_dataset_replace_param.py | 2 +- toolium/utils/dataset.py | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/toolium/test/utils/test_dataset_map_param_context.py b/toolium/test/utils/test_dataset_map_param_context.py index d13442eb..3fda8916 100644 --- a/toolium/test/utils/test_dataset_map_param_context.py +++ b/toolium/test/utils/test_dataset_map_param_context.py @@ -481,9 +481,10 @@ class Context(object): } ] } - dataset.behave_context = context - assert map_param("[CONTEXT:list.cmsScrollableActions.-5.id]") - + with pytest.raises(Exception) as excinfo: + map_param("[CONTEXT:list.cmsScrollableActions.-5.id]") + assert "IndexError: list index out of range" == str(excinfo.value) + def test_a_context_param_list_oob_index(): """ diff --git a/toolium/test/utils/test_dataset_replace_param.py b/toolium/test/utils/test_dataset_replace_param.py index bec1eb64..59f413c0 100644 --- a/toolium/test/utils/test_dataset_replace_param.py +++ b/toolium/test/utils/test_dataset_replace_param.py @@ -377,7 +377,7 @@ def test_replace_param_dict(): def test_replace_param_dict_json_format(): param = replace_param('[DICT:{"key": "value", "key_2": true}]') - assert param == '{"key": "value", "key_2": true}' + assert param == '{"key": "value", "key_2": True}' param = replace_param('[DICT:{"key": "value", "key_2": null}]') assert param == '{"key": "value", "key_2": null}' diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index 3c4e4346..b7ac78f7 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -259,7 +259,7 @@ def _replace_param_transform_string(param): def _update_param_transform_string(type_mapping_match_group): """ Transform param value according to the specified prefix. - Available transformations: STR, UPPER, LOWER, REPLACE, TITLE + Available transformations: STR, UPPER, LOWER, REPLACE, TITLE, ROUND :param type_mapping_match_group: match group :return: return the string with the replaced param @@ -281,7 +281,7 @@ def _update_param_transform_string(type_mapping_match_group): type_mapping_match_group.group(2).title()))) elif type_mapping_match_group.group(1) == 'ROUND': replace_params = type_mapping_match_group.group(2).split('::') - replace_param = f"{round(float(replace_params[0]), int(replace_params[1])):.{int(replace_params[1])} f }" + replace_param = f"{round(float(replace_params[0]), int(replace_params[1])):.{int(replace_params[1])}f}" return replace_param From 2a579a532a9f30cef517deb6d040e443873332db Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Tue, 8 Oct 2024 12:26:09 +0200 Subject: [PATCH 24/48] Fix linter issues --- toolium/test/utils/test_dataset_map_param_context.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolium/test/utils/test_dataset_map_param_context.py b/toolium/test/utils/test_dataset_map_param_context.py index 3fda8916..185451cc 100644 --- a/toolium/test/utils/test_dataset_map_param_context.py +++ b/toolium/test/utils/test_dataset_map_param_context.py @@ -484,7 +484,7 @@ class Context(object): with pytest.raises(Exception) as excinfo: map_param("[CONTEXT:list.cmsScrollableActions.-5.id]") assert "IndexError: list index out of range" == str(excinfo.value) - + def test_a_context_param_list_oob_index(): """ From b03b631ef4a85a8a45c10f6dddda14510aabbdb0 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Tue, 8 Oct 2024 12:30:45 +0200 Subject: [PATCH 25/48] Fix tests issue --- toolium/test/utils/test_dataset_map_param_context.py | 2 +- toolium/test/utils/test_dataset_replace_param.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/toolium/test/utils/test_dataset_map_param_context.py b/toolium/test/utils/test_dataset_map_param_context.py index 185451cc..753940b2 100644 --- a/toolium/test/utils/test_dataset_map_param_context.py +++ b/toolium/test/utils/test_dataset_map_param_context.py @@ -483,7 +483,7 @@ class Context(object): } with pytest.raises(Exception) as excinfo: map_param("[CONTEXT:list.cmsScrollableActions.-5.id]") - assert "IndexError: list index out of range" == str(excinfo.value) + assert "list index out of range" == str(excinfo.value) def test_a_context_param_list_oob_index(): diff --git a/toolium/test/utils/test_dataset_replace_param.py b/toolium/test/utils/test_dataset_replace_param.py index 59f413c0..19fbd446 100644 --- a/toolium/test/utils/test_dataset_replace_param.py +++ b/toolium/test/utils/test_dataset_replace_param.py @@ -377,9 +377,9 @@ def test_replace_param_dict(): def test_replace_param_dict_json_format(): param = replace_param('[DICT:{"key": "value", "key_2": true}]') - assert param == '{"key": "value", "key_2": True}' + assert param == {"key": "value", "key_2": True} param = replace_param('[DICT:{"key": "value", "key_2": null}]') - assert param == '{"key": "value", "key_2": null}' + assert param == {"key": "value", "key_2": None} def test_replace_param_upper(): From cef0c6f22c6d47badfa136a1042811710d116d71 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez <58507180+promans718@users.noreply.github.com> Date: Tue, 8 Oct 2024 13:17:00 +0200 Subject: [PATCH 26/48] Update CHANGELOG.rst Co-authored-by: Pablo Guijarro --- CHANGELOG.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 13617b77..694a1003 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -9,7 +9,7 @@ v3.2.1 - Add support for JSON strings to the `DICT` replacement. Example: [DICT:{"key": true}] - Add `REPLACE` replacement, to replace a substring with another. Example: [REPLACE:[CONTEXT:some_url]::https::http] - Add `TITLE` replacement, to apply Python's title() function. Example: [TITLE:the title] -- Add `ROUND` replacement, float number to a string with the expected decimals. Example: [ROUND:3.3333::2] +- Add `ROUND` replacement, float number to a string with the indicated number of decimals. Example: [ROUND:3.3333::2] v3.2.0 ------ From 9bc711bc95598744ba32d07ca8eb0d910fc5aa5f Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez <58507180+promans718@users.noreply.github.com> Date: Tue, 8 Oct 2024 13:17:15 +0200 Subject: [PATCH 27/48] Update toolium/test/utils/test_dataset_replace_param.py Co-authored-by: Pablo Guijarro --- toolium/test/utils/test_dataset_replace_param.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/toolium/test/utils/test_dataset_replace_param.py b/toolium/test/utils/test_dataset_replace_param.py index 19fbd446..362c0e3b 100644 --- a/toolium/test/utils/test_dataset_replace_param.py +++ b/toolium/test/utils/test_dataset_replace_param.py @@ -376,10 +376,8 @@ def test_replace_param_dict(): def test_replace_param_dict_json_format(): - param = replace_param('[DICT:{"key": "value", "key_2": true}]') - assert param == {"key": "value", "key_2": True} - param = replace_param('[DICT:{"key": "value", "key_2": null}]') - assert param == {"key": "value", "key_2": None} + param = replace_param('[DICT:{"key": "value", "key_2": true, "key_3": null}]') + assert param == {"key": "value", "key_2": True, "key_3": None} def test_replace_param_upper(): From 7fc1b51ff6db2fa9390996f931352acc5c552b9f Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez <58507180+promans718@users.noreply.github.com> Date: Tue, 8 Oct 2024 13:17:32 +0200 Subject: [PATCH 28/48] Update toolium/utils/dataset.py Co-authored-by: Pablo Guijarro --- toolium/utils/dataset.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index b7ac78f7..63d7c837 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -89,7 +89,7 @@ def replace_param(param, language='es', infer_param_type=True): [DICT:xxxx] Cast xxxx to a dict [UPPER:xxxx] Converts xxxx to upper case [LOWER:xxxx] Converts xxxx to lower case - [REPLACE:xxxxx::xx::zz] Replace elements in string. Example: [REPLACE:[CONTEXT:some_url]::https::http] + [REPLACE:xxxxx::yy::zz] Replace elements in string. Example: [REPLACE:[CONTEXT:some_url]::https::http] [TITLE:xxxxx] Apply .title() to string value. Example: [TITLE:the title] If infer_param_type is True and the result of the replacement process is a string, this function also tries to infer and cast the result to the most appropriate data type, From 1bcdae4ff595522417b4f5e659b212f4d0ef76ad Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Tue, 8 Oct 2024 13:20:23 +0200 Subject: [PATCH 29/48] Fix pull request issue --- toolium/utils/dataset.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index 63d7c837..87f2e8d9 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -251,12 +251,12 @@ def _replace_param_transform_string(param): exec(f'exec_param = {type_mapping_match_group.group(1).lower()}({type_mapping_match_group.group(2)})') new_param = locals()['exec_param'] else: - replace_param = _update_param_transform_string(type_mapping_match_group) + replace_param = _get_substring_replacement(type_mapping_match_group) new_param = new_param.replace(type_mapping_match_group.group(), replace_param) return new_param, param_transformed -def _update_param_transform_string(type_mapping_match_group): +def _get_substring_replacement(type_mapping_match_group): """ Transform param value according to the specified prefix. Available transformations: STR, UPPER, LOWER, REPLACE, TITLE, ROUND @@ -646,7 +646,7 @@ def get_value_from_context(param, context): value = value[part] # evaluate if in an array, access is requested by index elif isinstance(value, list) and part.lstrip('-+').isdigit() \ - and int(part) < (len(value) + 1 if part.startswith("-") else len(value)): + and abs(int(part)) < (len(value) + 1 if part.startswith("-") else len(value)): value = value[int(part)] # or by a key=value expression elif isinstance(value, list) and (element := _select_element_in_list(value, part)): From 867d8d0cd3b788e2443b3b51204c7b3744a9b6f1 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Tue, 8 Oct 2024 13:42:48 +0200 Subject: [PATCH 30/48] Fix pull request issue --- toolium/utils/dataset.py | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index 87f2e8d9..e70ac727 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -84,7 +84,7 @@ def replace_param(param, language='es', infer_param_type=True): [STR:xxxx] Cast xxxx to a string [INT:xxxx] Cast xxxx to an int [FLOAT:xxxx] Cast xxxx to a float - [ROUND:xxxx::2] String float with the expected decimals + [ROUND:xxxx::d] String float with the expected decimals [LIST:xxxx] Cast xxxx to a list [DICT:xxxx] Cast xxxx to a dict [UPPER:xxxx] Converts xxxx to upper case @@ -203,7 +203,9 @@ def _replace_param_replacement(param, language): '[TIMESTAMP]': str(int(datetime.datetime.timestamp(datetime.datetime.utcnow()))), '[DATETIME]': str(datetime.datetime.utcnow()), '[NOW]': str(datetime.datetime.utcnow().strftime(date_format)), - '[TODAY]': str(datetime.datetime.utcnow().strftime(date_day_format)) + '[TODAY]': str(datetime.datetime.utcnow().strftime(date_day_format)), + '[ROUND:.*::.*]': _get_rounded_float_number(param) + } # append date expressions found in param to the replacement dict @@ -220,6 +222,20 @@ def _replace_param_replacement(param, language): param_replaced = True return new_param, param_replaced +def _get_rounded_float_number(param): + """ + Round float number with the expected decimals + + :param param: param to format + :return: float as string with the expected decimals + """ + type_mapping_regex = r'\[(ROUND):([\w\W]*)::(\d)\]' + type_mapping_match_group = re.match(type_mapping_regex, param) + + replace_params = type_mapping_match_group.group(2).split('::') + replace_param = f"{round(float(replace_params[0]), int(replace_params[1])):.{int(replace_params[1])}f}" + return replace_param + def _get_random_phone_number(): # Method to avoid executing data generator when it is not needed @@ -229,12 +245,12 @@ def _get_random_phone_number(): def _replace_param_transform_string(param): """ Transform param value according to the specified prefix. - Available transformations: DICT, LIST, INT, FLOAT, ROUND, STR, UPPER, LOWER, REPLACE, TITLE + Available transformations: DICT, LIST, INT, FLOAT, STR, UPPER, LOWER, REPLACE, TITLE :param param: parameter value :return: tuple with replaced value and boolean to know if replacement has been done """ - type_mapping_regex = r'\[(DICT|LIST|INT|FLOAT|STR|UPPER|LOWER|REPLACE|TITLE|ROUND):([\w\W]*)\]' + type_mapping_regex = r'\[(DICT|LIST|INT|FLOAT|STR|UPPER|LOWER|REPLACE|TITLE):([\w\W]*)\]' type_mapping_match_group = re.match(type_mapping_regex, param) new_param = param param_transformed = False @@ -259,7 +275,7 @@ def _replace_param_transform_string(param): def _get_substring_replacement(type_mapping_match_group): """ Transform param value according to the specified prefix. - Available transformations: STR, UPPER, LOWER, REPLACE, TITLE, ROUND + Available transformations: STR, UPPER, LOWER, REPLACE, TITLE :param type_mapping_match_group: match group :return: return the string with the replaced param @@ -279,9 +295,6 @@ def _get_substring_replacement(type_mapping_match_group): elif type_mapping_match_group.group(1) == 'TITLE': replace_param = "".join(map(min, zip(type_mapping_match_group.group(2), type_mapping_match_group.group(2).title()))) - elif type_mapping_match_group.group(1) == 'ROUND': - replace_params = type_mapping_match_group.group(2).split('::') - replace_param = f"{round(float(replace_params[0]), int(replace_params[1])):.{int(replace_params[1])}f}" return replace_param From d6d2321ad9770e63a6abea9b9bac625cf96c32ab Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Tue, 8 Oct 2024 14:19:04 +0200 Subject: [PATCH 31/48] Fix linter issues --- toolium/utils/dataset.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index e70ac727..77dceffa 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -84,7 +84,7 @@ def replace_param(param, language='es', infer_param_type=True): [STR:xxxx] Cast xxxx to a string [INT:xxxx] Cast xxxx to an int [FLOAT:xxxx] Cast xxxx to a float - [ROUND:xxxx::d] String float with the expected decimals + [ROUND:xxxx::y] Generates a string from a float number (xxxx) with the indicated number of decimals (y) [LIST:xxxx] Cast xxxx to a list [DICT:xxxx] Cast xxxx to a dict [UPPER:xxxx] Converts xxxx to upper case @@ -222,6 +222,7 @@ def _replace_param_replacement(param, language): param_replaced = True return new_param, param_replaced + def _get_rounded_float_number(param): """ Round float number with the expected decimals From bdf11c783dcb2fbd88c503725f85a4ed26daea69 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Tue, 8 Oct 2024 14:20:17 +0200 Subject: [PATCH 32/48] Fix linter issues --- toolium/utils/dataset.py | 1 - 1 file changed, 1 deletion(-) diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index 77dceffa..b26120bd 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -205,7 +205,6 @@ def _replace_param_replacement(param, language): '[NOW]': str(datetime.datetime.utcnow().strftime(date_format)), '[TODAY]': str(datetime.datetime.utcnow().strftime(date_day_format)), '[ROUND:.*::.*]': _get_rounded_float_number(param) - } # append date expressions found in param to the replacement dict From 281a77ec29d8f9cdc3a6f2a51addbb2448ecb02f Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Tue, 8 Oct 2024 14:21:24 +0200 Subject: [PATCH 33/48] Fix pull request issues --- toolium/utils/dataset.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index b26120bd..26003bbd 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -81,10 +81,10 @@ def replace_param(param, language='es', infer_param_type=True): [NOW(%Y-%m-%dT%H:%M:%SZ) - 7 DAYS] Similar to NOW but seven days before and with the indicated format [TODAY] Similar to NOW without time; the format depends on the language [TODAY + 2 DAYS] Similar to NOW, but two days later + [ROUND:xxxx::y] Generates a string from a float number (xxxx) with the indicated number of decimals (y) [STR:xxxx] Cast xxxx to a string [INT:xxxx] Cast xxxx to an int [FLOAT:xxxx] Cast xxxx to a float - [ROUND:xxxx::y] Generates a string from a float number (xxxx) with the indicated number of decimals (y) [LIST:xxxx] Cast xxxx to a list [DICT:xxxx] Cast xxxx to a dict [UPPER:xxxx] Converts xxxx to upper case From 2eba63024ca5f5a925b49cf758b882dba813307c Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Tue, 8 Oct 2024 14:34:31 +0200 Subject: [PATCH 34/48] Fix issue --- toolium/test/utils/test_dataset_map_param_context.py | 2 +- toolium/utils/dataset.py | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/toolium/test/utils/test_dataset_map_param_context.py b/toolium/test/utils/test_dataset_map_param_context.py index 753940b2..bbf08cb8 100644 --- a/toolium/test/utils/test_dataset_map_param_context.py +++ b/toolium/test/utils/test_dataset_map_param_context.py @@ -483,7 +483,7 @@ class Context(object): } with pytest.raises(Exception) as excinfo: map_param("[CONTEXT:list.cmsScrollableActions.-5.id]") - assert "list index out of range" == str(excinfo.value) + assert "the expression '-5' was not able to select an element in the list" == str(excinfo.value) def test_a_context_param_list_oob_index(): diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index 26003bbd..afe79dae 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -229,12 +229,13 @@ def _get_rounded_float_number(param): :param param: param to format :return: float as string with the expected decimals """ - type_mapping_regex = r'\[(ROUND):([\w\W]*)::(\d)\]' + type_mapping_regex = r'\[(ROUND):([\w\W]*)\]' type_mapping_match_group = re.match(type_mapping_regex, param) - - replace_params = type_mapping_match_group.group(2).split('::') - replace_param = f"{round(float(replace_params[0]), int(replace_params[1])):.{int(replace_params[1])}f}" - return replace_param + if type_mapping_match_group and type_mapping_match_group.group(1) == 'ROUND': + replace_params = type_mapping_match_group.group(2).split('::') + replace_param = f"{round(float(replace_params[0]), int(replace_params[1])):.{int(replace_params[1])}f}" + return replace_param + return '' def _get_random_phone_number(): From a53e5c3f487bc9e966d89dd5ddd32e992146a0e6 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Tue, 8 Oct 2024 14:40:35 +0200 Subject: [PATCH 35/48] Fix linter issues --- toolium/utils/dataset.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index afe79dae..2a559dd0 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -231,7 +231,7 @@ def _get_rounded_float_number(param): """ type_mapping_regex = r'\[(ROUND):([\w\W]*)\]' type_mapping_match_group = re.match(type_mapping_regex, param) - if type_mapping_match_group and type_mapping_match_group.group(1) == 'ROUND': + if type_mapping_match_group and type_mapping_match_group.group(1) == 'ROUND': replace_params = type_mapping_match_group.group(2).split('::') replace_param = f"{round(float(replace_params[0]), int(replace_params[1])):.{int(replace_params[1])}f}" return replace_param From d19b12cccae7723bd63395e7b68aa816aac24dfc Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Tue, 8 Oct 2024 18:26:00 +0200 Subject: [PATCH 36/48] Fix fuction issue --- toolium/utils/dataset.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index 2a559dd0..6c03be9e 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -229,13 +229,12 @@ def _get_rounded_float_number(param): :param param: param to format :return: float as string with the expected decimals """ - type_mapping_regex = r'\[(ROUND):([\w\W]*)\]' - type_mapping_match_group = re.match(type_mapping_regex, param) - if type_mapping_match_group and type_mapping_match_group.group(1) == 'ROUND': - replace_params = type_mapping_match_group.group(2).split('::') - replace_param = f"{round(float(replace_params[0]), int(replace_params[1])):.{int(replace_params[1])}f}" - return replace_param - return '' + type_regex = r'\[(ROUND):(.*)::(\d)*\]' + type_match = re.match(type_regex, param) + if type_match and type_match.group(1) == 'ROUND': + if type_match.group(3).isdigit(): + replace_param = f"{round(float(type_match.group(2)), int(type_match.group(3))):.{int(type_match.group(3))}f}" + return replace_param def _get_random_phone_number(): From 384c9428511c8e26f4d0a9066ae8d8d119800319 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Wed, 9 Oct 2024 09:24:39 +0200 Subject: [PATCH 37/48] Fix issue --- toolium/utils/dataset.py | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index 6c03be9e..aa77019b 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -184,7 +184,7 @@ def _replace_param_replacement(param, language): """ Replace param with a new param value. Available replacements: [EMPTY], [B], [UUID], [RANDOM], [RANDOM_PHONE_NUMBER], - [TIMESTAMP], [DATETIME], [NOW], [TODAY] + [TIMESTAMP], [DATETIME], [NOW], [TODAY], [ROUND:xxxxx::d] :param param: parameter value :param language: language to configure date format for NOW and TODAY @@ -204,7 +204,7 @@ def _replace_param_replacement(param, language): '[DATETIME]': str(datetime.datetime.utcnow()), '[NOW]': str(datetime.datetime.utcnow().strftime(date_format)), '[TODAY]': str(datetime.datetime.utcnow().strftime(date_day_format)), - '[ROUND:.*::.*]': _get_rounded_float_number(param) + r'\[ROUND:(.*?)::(\d*)\]': _get_rounded_float_number } # append date expressions found in param to the replacement dict @@ -214,27 +214,28 @@ def _replace_param_replacement(param, language): new_param = param param_replaced = False - for key in replacements.keys(): - if key in new_param: - new_value = replacements[key]() if isfunction(replacements[key]) else replacements[key] - new_param = new_param.replace(key, new_value) + for key, value in replacements.items(): + if key.startswith('['): # tags without placeholders + if key in new_param: + new_value = value() if isfunction(value) else value + new_param = new_param.replace(key, new_value) + param_replaced = True + elif match := re.search(key, new_param): # tags with placeholders + new_value = value(match) # a function to parse the values is always required + new_param = new_param.replace(match.group(), new_value) param_replaced = True + print(new_param) + print(param_replaced) return new_param, param_replaced -def _get_rounded_float_number(param): +def _get_rounded_float_number(match): """ Round float number with the expected decimals - - :param param: param to format + :param match: match object of the regex for this transformation: [ROUND:(.*?)::(d*)] :return: float as string with the expected decimals """ - type_regex = r'\[(ROUND):(.*)::(\d)*\]' - type_match = re.match(type_regex, param) - if type_match and type_match.group(1) == 'ROUND': - if type_match.group(3).isdigit(): - replace_param = f"{round(float(type_match.group(2)), int(type_match.group(3))):.{int(type_match.group(3))}f}" - return replace_param + return f"{round(float(match.group(1)), int(match.group(2))):.{int(match.group(2))}f}" def _get_random_phone_number(): From 715922f2906bd573f064810bca6a4eb89f50b343 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Wed, 9 Oct 2024 09:36:13 +0200 Subject: [PATCH 38/48] Fix pull request issues --- toolium/utils/dataset.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index aa77019b..100b61fd 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -224,8 +224,6 @@ def _replace_param_replacement(param, language): new_value = value(match) # a function to parse the values is always required new_param = new_param.replace(match.group(), new_value) param_replaced = True - print(new_param) - print(param_replaced) return new_param, param_replaced From 0d6cd556e6ae2c3e2596de178949659621ab0620 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Wed, 9 Oct 2024 09:36:27 +0200 Subject: [PATCH 39/48] Fix pull request issues --- toolium/test/utils/test_dataset_map_param_context.py | 1 - toolium/test/utils/test_dataset_replace_param.py | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/toolium/test/utils/test_dataset_map_param_context.py b/toolium/test/utils/test_dataset_map_param_context.py index bbf08cb8..8f6d4339 100644 --- a/toolium/test/utils/test_dataset_map_param_context.py +++ b/toolium/test/utils/test_dataset_map_param_context.py @@ -568,7 +568,6 @@ def __init__(self): context.list = ExampleClass() dataset.behave_context = context - print(context) with pytest.raises(Exception) as excinfo: map_param("[CONTEXT:list.cmsScrollableActions.prueba.id]") assert "the expression 'prueba' was not able to select an element in the list" == str(excinfo.value) diff --git a/toolium/test/utils/test_dataset_replace_param.py b/toolium/test/utils/test_dataset_replace_param.py index 362c0e3b..ca19c220 100644 --- a/toolium/test/utils/test_dataset_replace_param.py +++ b/toolium/test/utils/test_dataset_replace_param.py @@ -463,6 +463,6 @@ def test_replace_param_title(): def test_replace_param_round(): param = replace_param('[ROUND:7.5::2]') - assert param == "7.50" + assert param == 7.5 param = replace_param('[ROUND:3.33333333::3]') - assert param == "3.333" + assert param == 3.333 From 39be4e7260777de19c9fd41a99dfb8ebd5115261 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez <58507180+promans718@users.noreply.github.com> Date: Wed, 9 Oct 2024 10:00:05 +0200 Subject: [PATCH 40/48] Update toolium/test/utils/test_dataset_map_param_context.py Co-authored-by: Pablo Guijarro --- toolium/test/utils/test_dataset_map_param_context.py | 1 + 1 file changed, 1 insertion(+) diff --git a/toolium/test/utils/test_dataset_map_param_context.py b/toolium/test/utils/test_dataset_map_param_context.py index 8f6d4339..8b8aeca6 100644 --- a/toolium/test/utils/test_dataset_map_param_context.py +++ b/toolium/test/utils/test_dataset_map_param_context.py @@ -455,6 +455,7 @@ class Context(object): } dataset.behave_context = context assert map_param("[CONTEXT:list.cmsScrollableActions.-1.id]") == 'ask-for-negative' + assert map_param("[CONTEXT:list.cmsScrollableActions.-3.id]") == 'ask-for-duplicate' def test_a_context_param_list_incorrect_negative_index(): From 8b8be2587f4980d593d9806435e6fcb20d5de91f Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez <58507180+promans718@users.noreply.github.com> Date: Wed, 9 Oct 2024 10:00:24 +0200 Subject: [PATCH 41/48] Update toolium/test/utils/test_dataset_replace_param.py Co-authored-by: Pablo Guijarro --- toolium/test/utils/test_dataset_replace_param.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/toolium/test/utils/test_dataset_replace_param.py b/toolium/test/utils/test_dataset_replace_param.py index ca19c220..6a6e8444 100644 --- a/toolium/test/utils/test_dataset_replace_param.py +++ b/toolium/test/utils/test_dataset_replace_param.py @@ -461,8 +461,15 @@ def test_replace_param_title(): assert param == "HOlA" -def test_replace_param_round(): +def test_replace_param_round_with_type_inference(): param = replace_param('[ROUND:7.5::2]') assert param == 7.5 param = replace_param('[ROUND:3.33333333::3]') assert param == 3.333 + + +def test_replace_param_round_without_type_inference(): + param = replace_param('[ROUND:7.500::2]', infer_param_type=False) + assert param == '7.50' + param = replace_param('[ROUND:3.33333333::3]', infer_param_type=False) + assert param == '3.333' From 8a3c2400211c2b0a776d747be783e9536f916748 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Wed, 9 Oct 2024 10:42:40 +0200 Subject: [PATCH 42/48] Reorder tests --- .../test/utils/test_dataset_replace_param.py | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/toolium/test/utils/test_dataset_replace_param.py b/toolium/test/utils/test_dataset_replace_param.py index 6a6e8444..019bb904 100644 --- a/toolium/test/utils/test_dataset_replace_param.py +++ b/toolium/test/utils/test_dataset_replace_param.py @@ -333,6 +333,13 @@ def test_replace_param_now_offsets_with_and_without_format_and_more(): assert param == f'The date {offset_date} was yesterday and I have an appointment at {offset_datetime}' +def test_replace_param_round_without_type_inference(): + param = replace_param('[ROUND:7.5::2]') + assert param == 7.5 + param = replace_param('[ROUND:3.33333333::3]') + assert param == 3.333 + + def test_replace_param_str_int(): param = replace_param('[STR:28]') assert isinstance(param, str) @@ -459,17 +466,3 @@ def test_replace_param_title(): assert param == "Holahola" param = replace_param('[TITLE:hOlA]') assert param == "HOlA" - - -def test_replace_param_round_with_type_inference(): - param = replace_param('[ROUND:7.5::2]') - assert param == 7.5 - param = replace_param('[ROUND:3.33333333::3]') - assert param == 3.333 - - -def test_replace_param_round_without_type_inference(): - param = replace_param('[ROUND:7.500::2]', infer_param_type=False) - assert param == '7.50' - param = replace_param('[ROUND:3.33333333::3]', infer_param_type=False) - assert param == '3.333' From 7a4ff534acce988898e291b3fa8a7d267ded8f9c Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Wed, 9 Oct 2024 10:50:57 +0200 Subject: [PATCH 43/48] Restore missing tests --- toolium/test/utils/test_dataset_replace_param.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/toolium/test/utils/test_dataset_replace_param.py b/toolium/test/utils/test_dataset_replace_param.py index 019bb904..22b71e54 100644 --- a/toolium/test/utils/test_dataset_replace_param.py +++ b/toolium/test/utils/test_dataset_replace_param.py @@ -333,13 +333,20 @@ def test_replace_param_now_offsets_with_and_without_format_and_more(): assert param == f'The date {offset_date} was yesterday and I have an appointment at {offset_datetime}' -def test_replace_param_round_without_type_inference(): +def test_replace_param_round_with_type_inference(): param = replace_param('[ROUND:7.5::2]') assert param == 7.5 param = replace_param('[ROUND:3.33333333::3]') assert param == 3.333 +def test_replace_param_round_without_type_inference(): + param = replace_param('[ROUND:7.500::2]', infer_param_type=False) + assert param == '7.50' + param = replace_param('[ROUND:3.33333333::3]', infer_param_type=False) + assert param == '3.333' + + def test_replace_param_str_int(): param = replace_param('[STR:28]') assert isinstance(param, str) From 7242af60b5380e263222a54f6122319920567668 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Wed, 9 Oct 2024 18:53:04 +0200 Subject: [PATCH 44/48] Fix pull request issue --- toolium/utils/dataset.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index 100b61fd..b96c35af 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -256,15 +256,14 @@ def _replace_param_transform_string(param): if type_mapping_match_group: param_transformed = True - if type_mapping_match_group.group(1) in ['DICT', 'LIST', 'INT', 'FLOAT']: - if type_mapping_match_group.group(1) == 'DICT': - try: - new_param = json.loads(type_mapping_match_group.group(2).strip()) - except json.decoder.JSONDecodeError: - new_param = eval(type_mapping_match_group.group(2)) - else: - exec(f'exec_param = {type_mapping_match_group.group(1).lower()}({type_mapping_match_group.group(2)})') - new_param = locals()['exec_param'] + if type_mapping_match_group.group(1) == 'DICT': + try: + new_param = json.loads(type_mapping_match_group.group(2).strip()) + except json.decoder.JSONDecodeError: + new_param = eval(type_mapping_match_group.group(2)) + elif type_mapping_match_group.group(1) in ['DICT', 'LIST', 'INT', 'FLOAT']: + exec(f'exec_param = {type_mapping_match_group.group(1).lower()}({type_mapping_match_group.group(2)})') + new_param = locals()['exec_param'] else: replace_param = _get_substring_replacement(type_mapping_match_group) new_param = new_param.replace(type_mapping_match_group.group(), replace_param) From 5512678da78d8ab5d8cc1ac04843c89324074a38 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Wed, 9 Oct 2024 18:53:22 +0200 Subject: [PATCH 45/48] Fix pull request issue --- toolium/utils/dataset.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index b96c35af..c439159a 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -261,7 +261,7 @@ def _replace_param_transform_string(param): new_param = json.loads(type_mapping_match_group.group(2).strip()) except json.decoder.JSONDecodeError: new_param = eval(type_mapping_match_group.group(2)) - elif type_mapping_match_group.group(1) in ['DICT', 'LIST', 'INT', 'FLOAT']: + elif type_mapping_match_group.group(1) in ['LIST', 'INT', 'FLOAT']: exec(f'exec_param = {type_mapping_match_group.group(1).lower()}({type_mapping_match_group.group(2)})') new_param = locals()['exec_param'] else: From 9fa86104438894a9c722116a95d83ca7cbd8ea40 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Wed, 9 Oct 2024 18:57:24 +0200 Subject: [PATCH 46/48] Include json option to list element --- CHANGELOG.rst | 2 +- toolium/test/utils/test_dataset_replace_param.py | 5 +++++ toolium/utils/dataset.py | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 694a1003..560363df 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,7 +6,7 @@ v3.2.1 *Release date: In development* - Allow negative indexes for list elements in context searches. Example: [CONTEXT:element.-1] -- Add support for JSON strings to the `DICT` replacement. Example: [DICT:{"key": true}] +- Add support for JSON strings to the `DICT` and `LIST`` replacement. Example: [DICT:{"key": true}], [LIST: null] - Add `REPLACE` replacement, to replace a substring with another. Example: [REPLACE:[CONTEXT:some_url]::https::http] - Add `TITLE` replacement, to apply Python's title() function. Example: [TITLE:the title] - Add `ROUND` replacement, float number to a string with the indicated number of decimals. Example: [ROUND:3.3333::2] diff --git a/toolium/test/utils/test_dataset_replace_param.py b/toolium/test/utils/test_dataset_replace_param.py index 22b71e54..716caa08 100644 --- a/toolium/test/utils/test_dataset_replace_param.py +++ b/toolium/test/utils/test_dataset_replace_param.py @@ -383,6 +383,11 @@ def test_replace_param_list_strings(): assert param == ['1', '2', '3'] +def test_replace_param_list_json_format(): + param = replace_param('[LIST:["value", true, null]]') + assert param == ["value", True, None] + + def test_replace_param_dict(): param = replace_param("[DICT:{'a':'test1','b':'test2','c':'test3'}]") assert isinstance(param, dict) diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index c439159a..35ddafdd 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -256,12 +256,12 @@ def _replace_param_transform_string(param): if type_mapping_match_group: param_transformed = True - if type_mapping_match_group.group(1) == 'DICT': + if type_mapping_match_group.group(1) == ['DICT', 'LIST']: try: new_param = json.loads(type_mapping_match_group.group(2).strip()) except json.decoder.JSONDecodeError: new_param = eval(type_mapping_match_group.group(2)) - elif type_mapping_match_group.group(1) in ['LIST', 'INT', 'FLOAT']: + elif type_mapping_match_group.group(1) in ['INT', 'FLOAT']: exec(f'exec_param = {type_mapping_match_group.group(1).lower()}({type_mapping_match_group.group(2)})') new_param = locals()['exec_param'] else: From 4e8d860a048a9b62c9b4ccc4e5719f1dade0a237 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Wed, 9 Oct 2024 19:00:14 +0200 Subject: [PATCH 47/48] Fix tests issue --- toolium/utils/dataset.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolium/utils/dataset.py b/toolium/utils/dataset.py index 35ddafdd..58ab089d 100644 --- a/toolium/utils/dataset.py +++ b/toolium/utils/dataset.py @@ -256,7 +256,7 @@ def _replace_param_transform_string(param): if type_mapping_match_group: param_transformed = True - if type_mapping_match_group.group(1) == ['DICT', 'LIST']: + if type_mapping_match_group.group(1) in ['DICT', 'LIST']: try: new_param = json.loads(type_mapping_match_group.group(2).strip()) except json.decoder.JSONDecodeError: From b650606e3124391b234b303eb2daae43136533b3 Mon Sep 17 00:00:00 2001 From: Patricia Roman Sanchez Date: Thu, 10 Oct 2024 09:18:16 +0200 Subject: [PATCH 48/48] Fix pull request issue --- CHANGELOG.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 560363df..b00f317c 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -6,7 +6,7 @@ v3.2.1 *Release date: In development* - Allow negative indexes for list elements in context searches. Example: [CONTEXT:element.-1] -- Add support for JSON strings to the `DICT` and `LIST`` replacement. Example: [DICT:{"key": true}], [LIST: null] +- Add support for JSON strings to the `DICT` and `LIST`` replacement. Example: [DICT:{"key": true}], [LIST:[null]] - Add `REPLACE` replacement, to replace a substring with another. Example: [REPLACE:[CONTEXT:some_url]::https::http] - Add `TITLE` replacement, to apply Python's title() function. Example: [TITLE:the title] - Add `ROUND` replacement, float number to a string with the indicated number of decimals. Example: [ROUND:3.3333::2]