Skip to content

Commit

Permalink
Add RenameTestCases transformer (#191)
Browse files Browse the repository at this point in the history
* do not order Remote libraries together with standard libs

* update contributing docs

* Add RenameTestCases transformer; refactor descriptions

Co-authored-by: Mateusz Nojek <[email protected]>
  • Loading branch information
bhirsz and mnojek authored Aug 31, 2021
1 parent 53d1e69 commit 462b6dc
Show file tree
Hide file tree
Showing 32 changed files with 360 additions and 30 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
### Features
- It is now possible to provide source paths in configuration file [#154](https://github.com/MarketSquare/robotframework-tidy/issues/154)
- Non default transformers can be enabled using ``enabled=True`` parameter [#182](https://github.com/MarketSquare/robotframework-tidy/issues/182)
- New non default transformer `RenameTestCases`. It capitalizes first letter of the test case name, removes trailing dot and can replace provided regex pattern with substitute string [#183](https://github.com/MarketSquare/robotframework-tidy/issues/183)
- Semicolon in parameter value can now be escaped with `\:` [#190](https://github.com/MarketSquare/robotframework-tidy/issues/190)

## 1.5.1

Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Contribution guideline

Getting started
----------------
Did you spot bug or you really want to see some feature implemented? It's always best to start with create issue in github.
Did you spot a bug or you really want to see some feature implemented? It's always best to start with creating issue in GitHub.
It doesn't matter if you're actually willing to make change on your own. Creating issue allow us to discuss proposed changes (
and cover possible edge cases) and also prevents multiple people from working on the same problem.

Expand Down Expand Up @@ -33,7 +33,7 @@ TRANSFORMERS lists. This list determines the order of transformers that will be
you're not sure how your transformer will work with others just leave the default order.

If you don't want to run your transformer with default ones (so it could be run only when selected with
`--transform` or configured with `enabled=True`) add following flag to invoke script:
`--transform` or configured with `enabled=True`) add the following flag to invoke script:
```
invoke add-transformer TRANSFORMER-NAME --disabled
```
Expand Down
38 changes: 38 additions & 0 deletions docs/source/transformers/RenameTestCases.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
.. _RenameTestCases:

RenameTestCases
================================

Enforce test case naming.

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

robotidy --transform RenameTestCases src

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':

.. tabs::

.. code-tab:: robotframework Before

*** Test Cases ***
test ABC-123
No Operation

.. code-tab:: robotframework After
*** Test Cases ***
Test foo
No Operation

Supports global formatting params: ``--startline`` and ``--endline``.
4 changes: 4 additions & 0 deletions docs/source/transformers/SmartSortKeywords.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ SmartSortKeywords is not included in default transformers that's why you need to

robotidy --transform SmartSortKeywords src

Or configure `enable` parameter::

robotidy --configure SmartSortKeywords:enabled=True

By default sorting is case insensitive, but keywords with leading underscore go to the bottom. Other underscores are
treated as spaces.
Empty lines (or lack of them) between keywords are preserved.
Expand Down
2 changes: 2 additions & 0 deletions robotidy/transformers/AlignSettingsSection.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ class AlignSettingsSection(ModelTransformer):
Supports global formatting params: ``--startline``, ``--endline`` and ``--space_count``
(for columns with fixed length).
See https://robotidy.readthedocs.io/en/latest/transformers/AlignSettingsSection.html for more examples.
"""
TOKENS_WITH_KEYWORDS = {Token.SUITE_SETUP, Token.SUITE_TEARDOWN, Token.TEST_SETUP, Token.TEST_TEARDOWN}

Expand Down
8 changes: 5 additions & 3 deletions robotidy/transformers/AlignVariablesSection.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ class AlignVariablesSection(ModelTransformer):
"""
Align variables in *** Variables *** section to columns.
Following code::
Following code:
*** Variables ***
${VAR} 1
${LONGER_NAME} 2
&{MULTILINE} a=b
... b=c
will be transformed to::
will be transformed to:
*** Variables ***
${VAR} 1
Expand All @@ -36,13 +36,15 @@ class AlignVariablesSection(ModelTransformer):
You can configure how many columns should be aligned to longest token in given column. The remaining columns
will use fixed length separator length ``--space_count``. By default only first two columns are aligned.
To align first three columns::
To align first three columns:
robotidy --transform AlignVariablesSection:up_to_column=3
To align all columns set ``up_to_column`` to 0.
Supports global formatting params: ``--startline`` and ``--endline``.
See https://robotidy.readthedocs.io/en/latest/transformers/AlignVariablesSection.html for more examples.
"""
def __init__(self, up_to_column: int = 2):
self.up_to_column = up_to_column - 1
Expand Down
2 changes: 2 additions & 0 deletions robotidy/transformers/DiscardEmptySections.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class DiscardEmptySections(ModelTransformer):
# this section would be removed if not for ``alow_only_comments`` parameter
Supports global formatting params: ``--startline`` and ``--endline``.
See https://robotidy.readthedocs.io/en/latest/transformers/DiscardEmptySections.html for more examples.
"""
def __init__(self, allow_only_comments: bool = False):
# If True then sections only with comments are not is considered to be empty
Expand Down
2 changes: 2 additions & 0 deletions robotidy/transformers/MergeAndOrderSections.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ class MergeAndOrderSections(ModelTransformer):
*** Settings ***
You can disable this behaviour by setting ``create_comment_section`` to False.
See https://robotidy.readthedocs.io/en/latest/transformers/MergeAndOrderSections.html for more examples.
"""
def __init__(self, order: str = '', create_comment_section: bool = True):
self.sections_order = self.parse_order(order)
Expand Down
5 changes: 3 additions & 2 deletions robotidy/transformers/NormalizeAssignments.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class NormalizeAssignments(ModelTransformer):
Normalize assignments. By default it detects most common assignment sign
and apply it to every assignment in given file.
In this code most common is no equal sign at all. We should remove ``=`` signs from all lines::
In this code most common is no equal sign at all. We should remove ``=`` signs from all lines:
*** Variables ***
${var} = ${1}
Expand All @@ -32,7 +32,7 @@ class NormalizeAssignments(ModelTransformer):
${var} Keyword2
${var}= Keyword
To::
To:
*** Variables ***
${var} ${1}
Expand All @@ -52,6 +52,7 @@ class NormalizeAssignments(ModelTransformer):
You can configure that behaviour to automatically add desired equal sign with ``equal_sign_type`` parameter
(possible types are: ``autodetect`` (default), ``remove``, ``equal_sign`` ('='), ``space_and_equal_sign`` (' =').
See https://robotidy.readthedocs.io/en/latest/transformers/NormalizeAssignments.html for more examples.
"""
def __init__(self, equal_sign_type: str = 'autodetect'):
self.remove_equal_sign = re.compile(r'\s?=$')
Expand Down
2 changes: 2 additions & 0 deletions robotidy/transformers/NormalizeNewLines.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ class NormalizeNewLines(ModelTransformer):
If the suite contains Test Template tests will not be separated by empty lines unless ``separate_templated_tests``
is set to True.
See https://robotidy.readthedocs.io/en/latest/transformers/NormalizeNewLines.html for more examples.
"""
def __init__(self, test_case_lines: int = 1, keyword_lines: Optional[int] = None, section_lines: int = 1,
separate_templated_tests: bool = False, consecutive_lines: int = 1):
Expand Down
8 changes: 5 additions & 3 deletions robotidy/transformers/NormalizeSectionHeaderName.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
class NormalizeSectionHeaderName(ModelTransformer):
"""
Normalize section headers names.
Robot Framework is quite flexible with the section header naming. Following lines are equal::
Robot Framework is quite flexible with the section header naming. Following lines are equal:
*setting
*** SETTINGS
*** SettingS ***
This transformer normalize naming to follow ``*** SectionName ***`` format (with plurar variant)::
This transformer normalizes naming to follow ``*** SectionName ***`` format (with plural variant):
*** Settings ***
*** Keywords ***
Expand All @@ -24,11 +24,13 @@ class NormalizeSectionHeaderName(ModelTransformer):
*** Comments ***
Optional data after section header (for example data driven column names) is preserved.
It is possible to upper case section header names by passing ``uppercase=True`` parameter::
It is possible to upper case section header names by passing ``uppercase=True`` parameter:
*** SETTINGS ***
Supports global formatting params: ``--startline`` and ``--endline``.
See https://robotidy.readthedocs.io/en/latest/transformers/NormalizeSectionHeaderName.html for more examples.
"""
def __init__(self, uppercase: bool = False):
self.uppercase = uppercase
Expand Down
2 changes: 2 additions & 0 deletions robotidy/transformers/NormalizeSeparators.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class NormalizeSeparators(ModelTransformer):
``sections = comments,settings,variables,keywords,testcases`` param.
Supports global formatting params: ``--startline`` and ``--endline``.
See https://robotidy.readthedocs.io/en/latest/transformers/NormalizeSeparators.html for more examples.
"""
def __init__(self, sections: str = None):
self.indent = 0
Expand Down
6 changes: 4 additions & 2 deletions robotidy/transformers/NormalizeSettingName.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
class NormalizeSettingName(ModelTransformer):
"""
Normalize setting name.
Ensure that setting names are title case without leading or trailing whitespace. For example from::
Ensure that setting names are title case without leading or trailing whitespace. For example from:
*** Settings ***
library library.py
Expand All @@ -22,7 +22,7 @@ class NormalizeSettingName(ModelTransformer):
[arguments] ${arg}
[ SETUP] Setup Keyword
To::
To:
*** Settings ***
Library library.py
Expand All @@ -35,6 +35,8 @@ class NormalizeSettingName(ModelTransformer):
[Setup] Setup Keyword
Supports global formatting params: ``--startline`` and ``--endline``.
See https://robotidy.readthedocs.io/en/latest/transformers/NormalizeSettingName.html for more examples.
"""
@check_start_end_line
def visit_Statement(self, node): # noqa
Expand Down
6 changes: 4 additions & 2 deletions robotidy/transformers/OrderSettings.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class OrderSettings(ModelTransformer):
Order settings like [Arguments], [Setup], [Return] inside Keywords and Test Cases.
Keyword settings [Documentation], [Tags], [Timeout], [Arguments] are put before keyword body and
settings like [Teardown], [Return] are moved to the end of keyword::
settings like [Teardown], [Return] are moved to the end of the keyword:
*** Keywords ***
Keyword
Expand All @@ -26,7 +26,7 @@ class OrderSettings(ModelTransformer):
[Tags] sanity
Pass
To::
To:
*** Keywords ***
Keyword
Expand Down Expand Up @@ -54,6 +54,8 @@ class OrderSettings(ModelTransformer):
It will order only test cases because all setting names for keywords are missing.
Supports global formatting params: ``--startline`` and ``--endline``.
See https://robotidy.readthedocs.io/en/latest/transformers/OrderSettings.html for more examples.
"""
def __init__(self, keyword_before: str = None, keyword_after: str = None, test_before: str = None,
test_after: str = None):
Expand Down
6 changes: 3 additions & 3 deletions robotidy/transformers/OrderSettingsSection.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,16 @@ class OrderSettingsSection(ModelTransformer):
- ``imports_order = preserved``
- ``settings_order = suite_setup,suite_teardown,test_setup,test_teardown,test_timeout,test_template``
By default order of imports is preserved. You can overwrite this behaviour::
By default order of imports is preserved. You can overwrite this behaviour:
robotidy --configure OrderSettingsSections:imports_order=library,resource,variables
You can also preserve order inside any group by passing ``preserved`` instead of setting names::
You can also preserve order inside any group by passing ``preserved`` instead of setting names:
robotidy --configure OrderSettingsSections:settings_order=preserved
Setting names omitted from custom order will be removed from the file. In following example we are missing metadata
therefore all metadata will be removed::
therefore all metadata will be removed:
robotidy --configure OrderSettingsSection:documentation_order=documentation
Expand Down
2 changes: 2 additions & 0 deletions robotidy/transformers/RemoveEmptySettings.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class RemoveEmptySettings(ModelTransformer):
You can disable that behavior by changing ``more_explicit`` parameter value to ``False``.
Supports global formatting params: ``--startline`` and ``--endline``.
See https://robotidy.readthedocs.io/en/latest/transformers/RemoveEmptySettings.html for more examples.
"""
def __init__(self, work_mode: str = 'overwrite_ok', more_explicit: bool = True):
if work_mode not in ('overwrite_ok', 'always'):
Expand Down
61 changes: 61 additions & 0 deletions robotidy/transformers/RenameTestCases.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import re
import random
import string
from typing import Optional

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

from robotidy.decorators import check_start_end_line


class RenameTestCases(ModelTransformer):
r"""
Enforce test case naming.
Capitalize first letter of test case name, remove trailing dot and strip leading/trailing whitespace.
It is also possible to configure `replace_pattern` parameter to find and replace regex pattern. Use `replace_to`
to set replacement value. This configuration:
robotidy --transform RenameTestCases -c RenameTestCases:replace_pattern=[A-Z]{3,}-\d{2,}:replace_to=foo
will transform following code:
*** Test Cases ***
test ABC-123
No Operation
To:
*** Test Cases ***
Test foo
No Operation
Supports global formatting params: ``--startline`` and ``--endline``.
See https://robotidy.readthedocs.io/en/latest/transformers/RenameTestCases.html for more examples.
"""
ENABLED = False

def __init__(self, replace_pattern: Optional[str] = None, replace_to: Optional[str] = None):
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 RenameTestCases"
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 visit_TestCaseName(self, node): # noqa
token = node.get_token(Token.TESTCASE_NAME)
if token.value:
token.value = token.value[0].upper() + token.value[1:]
if self.replace_pattern is not None:
token.value = self.replace_pattern.sub(repl=self.replace_to, string=token.value)
if token.value.endswith('.'):
token.value = token.value[:-1]
token.value = token.value.strip()
return node
Loading

0 comments on commit 462b6dc

Please sign in to comment.