Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add RenameKeywords transformer #194

Merged
merged 11 commits into from
Sep 14, 2021
Merged
44 changes: 44 additions & 0 deletions docs/source/transformers/RenameKeywords.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
.. _RenameKeywords:

RenameKeywords
================================

Enforce keyword naming. Title Case is applied to keyword name and underscores are replaced by spaces. It have only basic
bhirsz marked this conversation as resolved.
Show resolved Hide resolved
support for keywords with embedded variables - use it on your own risk.

RenameKeywords is not included in default transformers, that's why you need to call it with ``--transform`` explicitly::

robotidy --transform RenameKeywords src

Or configure `enable` parameter::

robotidy --configure RenameKeywords:enabled=True

You can keep underscores if you set remove_underscores to False::

robotidy --transform RenameKeywords -c RenameKeywords:remove_underscores=False .

It is also possible to configure `replace_pattern` parameter to find and replace regex pattern. Use `replace_to`
to set replacement value. This configuration (underscores are used instead of spaces)::

robotidy --transform RenameKeywords -c RenameKeywords:replace_pattern=(?i)^rename\s?me$:replace_to=New_Shining_Name .

replaces all occurrences of name `Rename Me` (case insensitive thanks to `(?i)` flag) to `New Shining Name`:

.. tabs::

.. code-tab:: robotframework Before

*** Keywords ***
rename Me
Keyword Call

.. code-tab:: robotframework After

*** Keywords ***
New Shining Name
Keyword Call

This feature makes this transformer convenient tool for renaming your keywords across Robot Framework project.

Supports global formatting params: ``--startline`` and ``--endline``.
8 changes: 4 additions & 4 deletions docs/source/transformers/RenameTestCases.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
RenameTestCases
================================

Enforce test case naming.
Enforce test case naming. This transformer capitalizes first letter of test case name, removes trailing dot and
strips leading/trailing whitespace.
bhirsz marked this conversation as resolved.
Show resolved Hide resolved

RenameTestCases is not included in default transformers, that's why you need to call it with ``--transform`` explicitly::

Expand All @@ -13,14 +14,12 @@ Or configure `enable` parameter::

robotidy --configure RenameTestCases:enabled=True

This transformer capitalizes first letter of test case name, removes trailing dot and strips leading/trailing whitespace.

It is also possible to configure `replace_pattern` parameter to find and replace regex pattern. Use `replace_to`
to set a replacement value. This configuration::

robotidy --transform RenameTestCases -c RenameTestCases:replace_pattern=[A-Z]{3,}-\d{2,}:replace_to=foo

Replaces all occurrences of given pattern with string 'foo':
replaces all occurrences of given pattern with string 'foo':

.. tabs::

Expand All @@ -31,6 +30,7 @@ Replaces all occurrences of given pattern with string 'foo':
No Operation

.. code-tab:: robotframework After

*** Test Cases ***
Test foo
No Operation
Expand Down
4 changes: 2 additions & 2 deletions robotidy/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def check_start_end_line(func):
Do not transform node if it's not within passed start_line and end_line.
"""
@functools.wraps(func)
def wrapper(self, node):
def wrapper(self, node, *args):
if not node:
return return_node_untouched(node)
if not node_within_lines(
Expand All @@ -22,5 +22,5 @@ def wrapper(self, node):
self.formatting_config.end_line
):
return return_node_untouched(node)
return func(self, node)
return func(self, node, *args)
return wrapper
74 changes: 74 additions & 0 deletions robotidy/transformers/RenameKeywords.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import re
from typing import Optional
import string

import click
from robot.api.parsing import ModelTransformer, Token

from robotidy.decorators import check_start_end_line


class RenameKeywords(ModelTransformer):
"""
Enforce keyword naming.

Title Case is applied to keyword name and underscores are replaced by spaces.

You can keep underscores if you set remove_underscores to False:

robotidy --transform RenameKeywords -c RenameKeywords:remove_underscores=False .

It is also possible to configure `replace_pattern` parameter to find and replace regex pattern. Use `replace_to`
to set replacement value. This configuration (underscores are used instead of spaces):

robotidy --transform RenameKeywords -c RenameKeywords:replace_pattern=^(?i)rename\s?me$:replace_to=New_Shining_Name .

will transform following code:

*** Keywords ***
rename Me
Keyword Call

To:

*** Keywords ***
New Shining Name
Keyword Call

Supports global formatting params: ``--startline`` and ``--endline``.

See https://robotidy.readthedocs.io/en/latest/transformers/RenameKeywords.html for more examples.
"""
ENABLED = False

def __init__(self, replace_pattern: Optional[str] = None, replace_to: Optional[str] = None,
remove_underscores: bool = True):
self.remove_underscores = remove_underscores
try:
self.replace_pattern = re.compile(replace_pattern) if replace_pattern is not None else None
except re.error as err:
raise click.BadOptionUsage(
option_name='transform',
message=f"Invalid configurable value: '{replace_pattern}' for replace_pattern in RenameKeywords"
f" transformer. It should be a valid regex expression. Regex error: '{err.msg}'")
self.replace_to = '' if replace_to is None else replace_to

@check_start_end_line
def rename_node(self, node, type_of_name):
token = node.get_token(type_of_name)
if not token:
return node
if token.value:
if self.replace_pattern is not None:
token.value = self.replace_pattern.sub(repl=self.replace_to, string=token.value)
if self.remove_underscores and token.value != '_':
token.value = token.value.replace('_', ' ')
token.value = re.sub(r'\s{2,}', ' ', token.value) # replace two or more spaces by one
token.value = string.capwords(token.value.strip())
return node

def visit_KeywordName(self, node): # noqa
return self.rename_node(node, Token.KEYWORD_NAME)

def visit_KeywordCall(self, node): # noqa
return self.rename_node(node, Token.KEYWORD)
4 changes: 1 addition & 3 deletions robotidy/transformers/RenameTestCases.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import re
import random
import string
from typing import Optional

from robot.api.parsing import ModelTransformer, Token
import click
from robot.api.parsing import ModelTransformer, Token

from robotidy.decorators import check_start_end_line

Expand Down
2 changes: 1 addition & 1 deletion robotidy/transformers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
'SplitTooLongLine',
'SmartSortKeywords',
'RenameTestCases',
'RenameTestCases'
'RenameKeywords'
]


Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
*** Test Cases ***
test
Keyword

Rename Me
No Operation

*** Keywords ***
New Shining Name
Also Rename This

New Shining Name 2
No Operation

I Am Fine
But I Am Not

Underscores Are Bad
Looks Like Python

Keyword With Unicode And Non Latin
Eäi Saa Peittää
日本語
_

Ignore ${var} Embedded
Also Ignore ${variable}['key'] Syntax

Structures
FOR ${var} IN 1 2 3
IF condition
Keyword
ELSE IF
Keyword
ELSE
Keyword
END
Keyword
END

Double Underscores
No Operation
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
*** Test Cases ***
test
Keyword

Rename Me
No Operation

*** Keywords ***
New Shining Name
Also Rename This

Rename Me 2
No Operation

I Am Fine
But I Am Not

Underscores Are Bad
Looks Like Python

Keyword With Unicode And Non Latin
Eäi Saa Peittää
日本語
_

Ignore ${var} Embedded
Also Ignore ${variable}['key'] Syntax

Structures
FOR ${var} IN 1 2 3
IF condition
Keyword
ELSE IF
Keyword
ELSE
Keyword
END
Keyword
END

Double Underscores
No Operation
42 changes: 42 additions & 0 deletions tests/atest/transformers/RenameKeywords/expected/test.robot
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
*** Test Cases ***
test
Keyword

Rename Me
No Operation

*** Keywords ***
Rename Me
Also Rename This

Rename Me 2
No Operation

I Am Fine
But I Am Not

Underscores Are Bad
Looks Like Python

Keyword With Unicode And Non Latin
Eäi Saa Peittää
日本語
_

Ignore ${var} Embedded
Also Ignore ${variable}['key'] Syntax

Structures
FOR ${var} IN 1 2 3
IF condition
Keyword
ELSE IF
Keyword
ELSE
Keyword
END
Keyword
END

Double Underscores
No Operation
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
*** Test Cases ***
test
Keyword

Rename Me
No Operation

*** Keywords ***
Rename Me
Also Rename This

Rename Me 2
No Operation

I Am Fine
But I Am Not

Underscores_are_bad
Looks_like_python

Keyword With Unicode And Non Latin
Eäi Saa Peittää
日本語
_

Ignore ${var} Embedded
Also Ignore ${variable}['key'] Syntax

Structures
FOR ${var} IN 1 2 3
IF condition
Keyword
ELSE IF
Keyword
ELSE
Keyword
END
Keyword
END

Double__underscores
No Operation
Loading