diff --git a/docs/releasenotes/4.4.1.rst b/docs/releasenotes/4.4.1.rst index 232ad5e1..b7d9ed53 100644 --- a/docs/releasenotes/4.4.1.rst +++ b/docs/releasenotes/4.4.1.rst @@ -38,3 +38,13 @@ it was transformed to:: Additionally, number of spaces before `ELSE` and `ELSE IF` in Inline IFs should now be calculated correctly (based on the separator length and not indentation). + +Invalid variable case with extended syntax in RenameVariables (#551) +-------------------------------------------------------------------- + +Robotidy should now be able to recognize variables using extended variable syntax and set variable case accordingly:: + + *** Test Cases *** + Simple math operations + ${i} Set Variable ${0} + Log ${i+1} # i+1 instead of previous I+1 diff --git a/robotidy/transformers/RenameVariables.py b/robotidy/transformers/RenameVariables.py index 407dcea6..3c5d7cfd 100644 --- a/robotidy/transformers/RenameVariables.py +++ b/robotidy/transformers/RenameVariables.py @@ -162,6 +162,7 @@ class RenameVariables(Transformer): HANDLES_SKIP = frozenset({"skip_sections"}) MORE_THAN_2_SPACES: Pattern = re.compile(r"\s{2,}") CAMEL_CASE: Pattern = re.compile(r"((?<=[a-z0-9])[A-Z]|(?!^)[A-Z](?=[a-z]))") + EXTENDED_SYNTAX: Pattern = re.compile(r"(.+?)([^\s\w].+)", re.UNICODE) DEFAULT_IGNORE_CASE = {"\\n"} def __init__( @@ -424,13 +425,20 @@ def set_name_case(self, name: str, case: str): if case == "lower": return name.lower() if case == "auto": - if self.variables_scope.is_local(name): - return name.lower() - if self.variables_scope.is_global(name): - return name.upper() - return self.set_name_case(name, self.unknown_variables_case) + return self.set_case_for_local_and_global(name) return name + def set_case_for_local_and_global(self, name): + if self.variables_scope.is_local(name): + return name.lower() + if self.variables_scope.is_global(name): + return name.upper() + extended_syntax = self.EXTENDED_SYNTAX.match(name) + if extended_syntax is None: + return self.set_name_case(name, self.unknown_variables_case) + base_name, extended = extended_syntax.groups() + return self.set_case_for_local_and_global(base_name) + extended + def rename(self, variable_value: str, case: str, strip_fn: str = "strip"): if not variable_value: return variable_value diff --git a/tests/atest/transformers/RenameVariables/expected/math_operations.robot b/tests/atest/transformers/RenameVariables/expected/math_operations.robot new file mode 100644 index 00000000..79e24bdd --- /dev/null +++ b/tests/atest/transformers/RenameVariables/expected/math_operations.robot @@ -0,0 +1,12 @@ +*** Test Cases *** +Simple math operations + ${i} Set Variable ${0} + Log ${i+1} + +Global Value + Log ${I-1} + +Invalid syntax + ${i} Set Variable ${0} + ${y} Set Variable ${1} + Log ${i+y+1} diff --git a/tests/atest/transformers/RenameVariables/source/math_operations.robot b/tests/atest/transformers/RenameVariables/source/math_operations.robot new file mode 100644 index 00000000..5f761d31 --- /dev/null +++ b/tests/atest/transformers/RenameVariables/source/math_operations.robot @@ -0,0 +1,12 @@ +*** Test Cases *** +Simple math operations + ${i} Set Variable ${0} + Log ${i+1} + +Global Value + Log ${i-1} + +Invalid syntax + ${i} Set Variable ${0} + ${y} Set Variable ${1} + Log ${i+y+1} diff --git a/tests/atest/transformers/RenameVariables/test_transformer.py b/tests/atest/transformers/RenameVariables/test_transformer.py index 98a8a5b4..8ce76418 100644 --- a/tests/atest/transformers/RenameVariables/test_transformer.py +++ b/tests/atest/transformers/RenameVariables/test_transformer.py @@ -100,3 +100,6 @@ def test_exclude_configure_ignore_vars(self): expected="configure_ignore_vars.robot", config=":ignore_case=global_arg,env_var,False", ) + + def test_extended_variables_syntax(self): + self.compare(source="math_operations.robot")