Skip to content

Commit 10393cb

Browse files
authored
Split wrong-case-in-keyword-name into itself and wrong-case-in-keyword-call rules (#1552)
feat: Split wrong-case-in-keyword-name into itself and wrong-case-in-keyword-call
1 parent 8bb27f7 commit 10393cb

File tree

26 files changed

+641
-251
lines changed

26 files changed

+641
-251
lines changed

docs/releasenotes/changelog.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@
44

55
### Features
66

7+
- **Breaking change** Split ``wrong-case-in-keyword-name`` rule into two separate rules ([issue #1471](https://github.com/MarketSquare/robotframework-robocop/issues/1471)):
8+
9+
``wrong-case-in-keyword-name`` which checks case convention in keyword definition name
10+
``wrong-case-in-keyword-call`` which checks case convention in keyword call name
11+
12+
It allows configuring different conventions for keyword definition and keyword call names. If you have existing
13+
configuration for ``wrong-case-in-keyword-name`` (you are ignoring it or configuring) you need to apply the same
14+
config to ``wrong-case-in-keyword-call`` to retain old behaviour.
15+
716
- Extend robocop disablers to the whole node ([issue #1515](https://github.com/MarketSquare/robotframework-robocop/issues/1515)
817

918
Robocop will now ignore issues in the whole node (keyword, test case, for loop, keyword call, etc.) when the disabler

src/robocop/linter/rules/naming.py

Lines changed: 79 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class WrongCaseInKeywordNameRule(Rule):
6363
Keyword name does not follow case convention.
6464
6565
Keyword names need to follow a specific case convention.
66-
The convention can be set using ``convention`` parameter and accepts
66+
The convention can be set using the `` convention `` parameter and accepts
6767
one of the 2 values: ``each_word_capitalized`` or ``first_word_capitalized``.
6868
6969
By default, it's configured to ``each_word_capitalized``, which requires each keyword to follow such
@@ -76,7 +76,7 @@ class WrongCaseInKeywordNameRule(Rule):
7676
Click 'Next' Button
7777
[Teardown] Log Form Data
7878
79-
You can also set it to ``first_word_capitalized`` which requires first word to have first letter capital:
79+
You can also set it to ``first_word_capitalized`` which requires capitalising the first word of the keyword:
8080
8181
*** Keywords ***
8282
Fill out the form
@@ -89,10 +89,12 @@ class WrongCaseInKeywordNameRule(Rule):
8989
that are accepted in the keyword name, even though they violate the case convention.
9090
9191
``pattern`` parameter accepts a regex pattern. For example, configuring it to ``robocop\.readthedocs\.io``
92-
would make such keyword legal:
92+
would make the following keyword legal:
9393
9494
Go To robocop.readthedocs.io Page
9595
96+
See the sibling rule [wrong-case-in-keyword-call](#wrong-case-in-keyword-call) that checks keyword call
97+
naming convention.
9698
"""
9799

98100
name = "wrong-case-in-keyword-name"
@@ -563,6 +565,70 @@ class MixedTaskTestSettingsRule(Rule):
563565
deprecated_names = ("0326",)
564566

565567

568+
class WrongCaseInKeywordCallRule(Rule):
569+
r"""
570+
Keyword call name does not follow case convention.
571+
572+
Keyword names need to follow a specific case convention.
573+
The convention can be set using the `` convention `` parameter and accepts
574+
one of the 2 values: ``each_word_capitalized`` or ``first_word_capitalized``.
575+
576+
By default, it's configured to ``each_word_capitalized``, which requires each keyword to follow such
577+
convention:
578+
579+
*** Keywords ***
580+
Fill out the form
581+
Provide Shipping Address
582+
Provide Payment Method
583+
Click 'Next' Button
584+
[Teardown] Log Form Data
585+
586+
You can also set it to ``first_word_capitalized`` which requires capitalising the first word of the keyword:
587+
588+
*** Keywords ***
589+
Fill out the form
590+
Provide shipping address
591+
Provide payment method
592+
Click 'Next' button
593+
[Teardown] Log form data
594+
595+
The rule also accepts another parameter ``pattern`` which can be used to configure words
596+
that are accepted in the keyword name, even though they violate the case convention.
597+
598+
``pattern`` parameter accepts a regex pattern. For example, configuring it to ``robocop\.readthedocs\.io``
599+
would make the following keyword legal:
600+
601+
Go To robocop.readthedocs.io Page
602+
603+
See the sibling rule [wrong-case-in-keyword-name](#wrong-case-in-keyword-name) that checks keyword definition
604+
naming convention.
605+
"""
606+
607+
name = "wrong-case-in-keyword-call"
608+
rule_id = "NAME18"
609+
message = "Keyword name '{keyword_name}' does not follow case convention"
610+
severity = RuleSeverity.WARNING
611+
parameters = [
612+
RuleParam(
613+
name="convention",
614+
default="each_word_capitalized",
615+
converter=str,
616+
desc="possible values: 'each_word_capitalized' (default) or 'first_word_capitalized'",
617+
),
618+
RuleParam(
619+
name="pattern",
620+
default=re.compile(r""),
621+
converter=utils.pattern_type,
622+
show_type="regex",
623+
desc="pattern for accepted words in keyword",
624+
),
625+
]
626+
added_in_version = "7.0.0"
627+
sonar_qube_attrs = sonar_qube.SonarQubeAttributes(
628+
clean_code=sonar_qube.CleanCodeAttribute.IDENTIFIABLE, issue_type=sonar_qube.SonarQubeIssueType.CODE_SMELL
629+
)
630+
631+
566632
SET_VARIABLE_VARIANTS = {
567633
"settaskvariable",
568634
"settestvariable",
@@ -647,6 +713,7 @@ class KeywordNamingChecker(VisitorChecker):
647713
"""Checker for keyword naming violations."""
648714

649715
wrong_case_in_keyword_name: WrongCaseInKeywordNameRule
716+
wrong_case_in_keyword_call: WrongCaseInKeywordCallRule
650717
keyword_name_is_reserved_word: KeywordNameIsReservedWordRule
651718
underscore_in_keyword_name: UnderscoreInKeywordNameRule
652719
else_not_upper_case: ElseNotUpperCaseRule
@@ -697,7 +764,7 @@ def visit_Keyword(self, node) -> None: # noqa: N802
697764
if not node.name:
698765
self.report(self.keyword_name_is_empty, node=node)
699766
else:
700-
self.check_keyword_naming(node.name, node)
767+
self.check_keyword_naming(node.name, node, is_keyword_definition=True)
701768
self.generic_visit(node)
702769

703770
def visit_KeywordCall(self, node) -> None: # noqa: N802
@@ -713,15 +780,19 @@ def visit_If(self, node) -> None: # noqa: N802
713780
self.generic_visit(node)
714781
self.inside_if_block = False
715782

716-
def check_keyword_naming(self, keyword_name, node) -> None:
783+
def check_keyword_naming(self, keyword_name, node, is_keyword_definition: bool = False) -> None:
717784
if not keyword_name or keyword_name.lstrip().startswith("#"):
718785
return
719786
if keyword_name == r"/": # old for loop, / are interpreted as keywords
720787
return
721788
if self.check_if_keyword_is_reserved(keyword_name, node):
722789
return
790+
if is_keyword_definition:
791+
case_naming_rule = self.wrong_case_in_keyword_name
792+
else:
793+
case_naming_rule = self.wrong_case_in_keyword_call
723794
normalized = utils.remove_robot_vars(keyword_name)
724-
normalized = self.wrong_case_in_keyword_name.pattern.sub("", normalized)
795+
normalized = case_naming_rule.pattern.sub("", normalized)
725796
normalized = normalized.split(".")[-1] # remove any imports ie ExternalLib.SubLib.Log -> Log
726797
normalized = normalized.replace("'", "") # replace ' apostrophes
727798
if "_" in normalized:
@@ -733,11 +804,11 @@ def check_keyword_naming(self, keyword_name, node) -> None:
733804
end_col=node.col_offset + len(keyword_name.rstrip()) + 1,
734805
)
735806
words = self.letter_pattern.sub(" ", normalized).split(" ")
736-
if self.wrong_case_in_keyword_name.convention == "first_word_capitalized":
807+
if case_naming_rule.convention == "first_word_capitalized":
737808
words = words[:1]
738809
if any(word[0].islower() for word in words if word):
739810
self.report(
740-
self.wrong_case_in_keyword_name,
811+
case_naming_rule,
741812
keyword_name=keyword_name,
742813
node=node,
743814
col=node.col_offset + 1,

tests/linter/rules/misc/unused_disabler/expected_extended.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ test.robot:3:21 MISC15 Disabler directive found for 'NAME01' rule(s) but no viol
1616
2 | Inline disablers - not used
1717
3 | No Operation # robocop: off=NAME01
1818
| ^^^^^^^^^^^^^^^^^^^ MISC15
19-
4 | No Operation # robocop: off=wrong-case-in-keyword-name
19+
4 | No Operation # robocop: off=wrong-case-in-keyword-call
2020
5 | FOR ${var} IN @{LIST} # robocop: off=unused-variable
2121
|
2222

23-
test.robot:4:21 MISC15 Disabler directive found for 'wrong-case-in-keyword-name' rule(s) but no violation found
23+
test.robot:4:21 MISC15 Disabler directive found for 'wrong-case-in-keyword-call' rule(s) but no violation found
2424
|
2525
2 | Inline disablers - not used
2626
3 | No Operation # robocop: off=NAME01
27-
4 | No Operation # robocop: off=wrong-case-in-keyword-name
27+
4 | No Operation # robocop: off=wrong-case-in-keyword-call
2828
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ MISC15
2929
5 | FOR ${var} IN @{LIST} # robocop: off=unused-variable
3030
6 | Log ${var}
@@ -33,7 +33,7 @@ test.robot:4:21 MISC15 Disabler directive found for 'wrong-case-in-keyword-name'
3333
test.robot:5:41 MISC15 Disabler directive found for 'unused-variable' rule(s) but no violation found
3434
|
3535
3 | No Operation # robocop: off=NAME01
36-
4 | No Operation # robocop: off=wrong-case-in-keyword-name
36+
4 | No Operation # robocop: off=wrong-case-in-keyword-call
3737
5 | FOR ${var} IN @{LIST} # robocop: off=unused-variable
3838
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ MISC15
3939
6 | Log ${var}

tests/linter/rules/misc/unused_disabler/expected_output.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
test.robot:3:21 [I] MISC15 Disabler directive found for 'NAME01' rule(s) but no violation found
2-
test.robot:4:21 [I] MISC15 Disabler directive found for 'wrong-case-in-keyword-name' rule(s) but no violation found
2+
test.robot:4:21 [I] MISC15 Disabler directive found for 'wrong-case-in-keyword-call' rule(s) but no violation found
33
test.robot:5:41 [I] MISC15 Disabler directive found for 'unused-variable' rule(s) but no violation found
44
test.robot:8:21 [I] MISC15 Disabler directive found for 'all' rule(s) but no violation found
55
test.robot:17:21 [I] MISC15 Disabler directive found for 'NAME01' rule(s) but no violation found

tests/linter/rules/misc/unused_disabler/expected_output_rf4.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
test.robot:3:21 [I] MISC15 Disabler directive found for 'NAME01' rule(s) but no violation found
2-
test.robot:4:21 [I] MISC15 Disabler directive found for 'wrong-case-in-keyword-name' rule(s) but no violation found
2+
test.robot:4:21 [I] MISC15 Disabler directive found for 'wrong-case-in-keyword-call' rule(s) but no violation found
33
test.robot:5:41 [I] MISC15 Disabler directive found for 'unused-variable' rule(s) but no violation found
44
test.robot:8:21 [I] MISC15 Disabler directive found for 'all' rule(s) but no violation found
55
test.robot:17:21 [I] MISC15 Disabler directive found for 'NAME01' rule(s) but no violation found

tests/linter/rules/misc/unused_disabler/test.robot

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
*** Test Cases ***
22
Inline disablers - not used
33
No Operation # robocop: off=NAME01
4-
No Operation # robocop: off=wrong-case-in-keyword-name
4+
No Operation # robocop: off=wrong-case-in-keyword-call
55
FOR ${var} IN @{LIST} # robocop: off=unused-variable
66
Log ${var}
77
END
88
Log ${var} # robocop: off
99
1010
Inline disablers - .used # robocop: off=NAME01
11-
No operation # robocop: off=wrong-case-in-keyword-name
11+
No operation # robocop: off=wrong-case-in-keyword-call
1212
FOR ${var} IN @{LIST} # robocop: off=unused-variable
1313
Log I dont use var
1414
END

tests/linter/rules/misc/unused_disabler/test_rule.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"multiline-inline-if",
66
"duplicated-variable",
77
"NAME01",
8-
"NAME02",
8+
"NAME18",
99
"VAR02",
1010
]
1111

tests/linter/rules/naming/wrong_case_in_keyword_call/__init__.py

Whitespace-only changes.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
configure_pattern${/}test.robot:4:3 [W] NAME18 Keyword name 'Not Allowed Dot In Keyword Foo.baz' does not follow case convention
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
*** Test Cases ***
2+
Test
3+
Allowed Dot In Name Foo.bar
4+
Not Allowed Dot In Keyword Foo.baz
5+
6+
*** Keywords ***
7+
Allowed Dot In Name Foo.bar
8+
No Operation
9+
10+
Not Allowed Dot In Keyword Foo.baz
11+
No Operation

0 commit comments

Comments
 (0)