Repository: MarketSquare/robotframework-robocop
Pull request #1034 (2023-12-29 14:32:20)

Update possible-variable-overwriting and inconsistent-variable-name with VAR support
Related #973

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/MarketSquare/robotframework-robocop/pull/1034?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=MarketSquare) Report
Attention: `1 lines` in your changes are missing coverage. Please review.
> Comparison is base [(`ea98fde`)](https://app.codecov.io/gh/MarketSquare/robotframework-robocop/commit/ea98fde98937b15d4692741639ff294681e58a65?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=MarketSquare) 96.96% compared to head [(`d791c28`)](https://app.codecov.io/gh/MarketSquare/robotframework-robocop/pull/1034?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=MarketSquare) 94.73%.

| [Files](https://app.codecov.io/gh/MarketSquare/robotframework-robocop/pull/1034?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=MarketSquare) | Patch % | Lines |
|---|---|---|
| [robocop/checkers/naming.py](https://app.codecov.io/gh/MarketSquare/robotframework-robocop/pull/1034?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=MarketSquare#diff-cm9ib2NvcC9jaGVja2Vycy9uYW1pbmcucHk=) | 87.50% | [1 Missing :warning: ](https://app.codecov.io/gh/MarketSquare/robotframework-robocop/pull/1034?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=MarketSquare) |

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master    #1034      +/-   ##
==========================================
- Coverage   96.96%   94.73%   -2.23%     
==========================================
  Files          37       37              
  Lines        4608     4616       +8     
==========================================
- Hits         4468     4373      -95     
- Misses        140      243     +103     
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/MarketSquare/robotframework-robocop/pull/1034?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=MarketSquare).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=MarketSquare).


Patch:
diff --git a/docs/releasenotes/unreleased/rules.1.rst b/docs/releasenotes/unreleased/rules.1.rst
index 5adb996..91a92ed 100644
--- a/docs/releasenotes/unreleased/rules.1.rst
+++ b/docs/releasenotes/unreleased/rules.1.rst
@@ -4,7 +4,9 @@ Updated existing rules with VAR support (#973)
 Following rules now support ``VAR`` syntax:
 
 - W0310 ``non-local-variables-should-be-uppercase``
+- I0316 ``possible-variable-overwriting``
 - I0317 ``hyphen-in-variable-name``
+- W0323 ``inconsistent-variable-name``
 - W0324 ``overwriting-reserved-variable``
 - W0501 ``too-long-keyword``
 - W0502 ``too-few-calls-in-keyword``
diff --git a/robocop/checkers/naming.py b/robocop/checkers/naming.py
index 66040be..1d2b6d5 100644
--- a/robocop/checkers/naming.py
+++ b/robocop/checkers/naming.py
@@ -1187,6 +1187,15 @@ class SimilarVariableChecker(VisitorChecker):
         tokens = node.get_tokens(Token.ASSIGN)
         self.find_similar_variables(tokens, node)
 
+    def visit_Var(self, node):  # noqa
+        if node.errors:  # for example invalid variable definition like $var}
+            return
+        for arg in node.get_tokens(Token.ARGUMENT):
+            self.find_not_nested_variable(arg, arg.value, is_var=False)
+        variable = node.get_token(Token.VARIABLE)
+        if variable:
+            self.find_similar_variables([variable], node)
+
     def visit_If(self, node):  # noqa
         for token in node.header.get_tokens(Token.ARGUMENT):
             self.find_not_nested_variable(token, token.value, is_var=False)


Test patch:
diff --git a/tests/atest/rules/naming/inconsistent_variable_name/expected_output.txt b/tests/atest/rules/naming/inconsistent_variable_name/expected_output.txt
index 3c3a2d3..70edf8d 100644
--- a/tests/atest/rules/naming/inconsistent_variable_name/expected_output.txt
+++ b/tests/atest/rules/naming/inconsistent_variable_name/expected_output.txt
@@ -9,4 +9,6 @@ test.robot:27:31:27:43 [W] 0323 Variable '${po_ssible}' has inconsistent naming.
 test.robot:43:24:43:35 [W] 0323 Variable '${VARIABLE}' has inconsistent naming. First used as '${variable}'
 test.robot:47:16:47:28 [W] 0323 Variable '${VARIABLE2}' has inconsistent naming. First used as '${variable2}'
 test.robot:51:41:51:52 [W] 0323 Variable '${VARIABLE}' has inconsistent naming. First used as '${variable}'
-test.robot:52:50:52:61 [W] 0323 Variable '${variable}' has inconsistent naming. First used as '${VARIABLE}'
\ No newline at end of file
+test.robot:52:50:52:61 [W] 0323 Variable '${variable}' has inconsistent naming. First used as '${VARIABLE}'
+test.robot:57:27:57:38 [W] 0323 Variable '${VARIABLE}' has inconsistent naming. First used as '${variable}'
+test.robot:61:52:61:64 [W] 0323 Variable '${variable2}' has inconsistent naming. First used as '${VARIABLE2}'
\ No newline at end of file
diff --git a/tests/atest/rules/naming/inconsistent_variable_name/expected_output_pre_7.txt b/tests/atest/rules/naming/inconsistent_variable_name/expected_output_pre_7.txt
new file mode 100644
index 0000000..bbf0a33
--- /dev/null
+++ b/tests/atest/rules/naming/inconsistent_variable_name/expected_output_pre_7.txt
@@ -0,0 +1,15 @@
+test.robot:11:16:11:27 [W] 0323 Variable '${variablE}' has inconsistent naming. First used as '${variable}'
+test.robot:12:11:12:23 [W] 0323 Variable '${var_iable}' has inconsistent naming. First used as '${variable}'
+test.robot:13:16:13:28 [W] 0323 Variable '${varia ble}' has inconsistent naming. First used as '${variable}'
+test.robot:19:33:19:48 [W] 0323 Variable '${INconsistent}' has inconsistent naming. First used as '${inconsistent}'
+test.robot:20:11:20:28 [W] 0323 Variable '${i_n_consistenT}' has inconsistent naming. First used as '${inconsistent}'
+test.robot:24:33:24:48 [W] 0323 Variable '${INconsistent}' has inconsistent naming. First used as '${inconsistent}'
+test.robot:27:16:27:27 [W] 0323 Variable '${ARGUMENT}' has inconsistent naming. First used as '${argument}'
+test.robot:27:31:27:43 [W] 0323 Variable '${po_ssible}' has inconsistent naming. First used as '${possible}'
+test.robot:43:24:43:35 [W] 0323 Variable '${VARIABLE}' has inconsistent naming. First used as '${variable}'
+test.robot:47:16:47:28 [W] 0323 Variable '${VARIABLE2}' has inconsistent naming. First used as '${variable2}'
+test.robot:51:41:51:52 [W] 0323 Variable '${VARIABLE}' has inconsistent naming. First used as '${variable}'
+test.robot:52:50:52:61 [W] 0323 Variable '${variable}' has inconsistent naming. First used as '${VARIABLE}'
+test.robot:57:12:57:23 [W] 0323 Variable '${VARIABLE}' has inconsistent naming. First used as '${variable}'
+test.robot:57:27:57:38 [W] 0323 Variable '${VARIABLE}' has inconsistent naming. First used as '${variable}'
+test.robot:62:27:62:38 [W] 0323 Variable '${VARIABLE}' has inconsistent naming. First used as '${variable}'
\ No newline at end of file
diff --git a/tests/atest/rules/naming/inconsistent_variable_name/test.robot b/tests/atest/rules/naming/inconsistent_variable_name/test.robot
index 8c319ec..370a932 100644
--- a/tests/atest/rules/naming/inconsistent_variable_name/test.robot
+++ b/tests/atest/rules/naming/inconsistent_variable_name/test.robot
@@ -51,3 +51,12 @@ Set Variable Scope
     Set Test Variable    ${VARIABLE}    ${VARIABLE}  # should report only on second
     BuiltIn.Set Suite Variable    ${VARIABLE}    ${variable}  # should report only on second
     Set Suite Variable    ${VARIABLE}    ${VARIABLE}  # should not report
+
+VAR Syntax
+    ${variable}    Set Variable    value
+    VAR    ${VARIABLE}    ${VARIABLE}  # should report on second
+    VAR    ${variable2}    value    scope=local
+    VAR    ${VARIABLE2}    ${variable2}    scope=TEST  # overwritten,  should not report
+    VAR    ${VARIABLE2}    Value with ${VARIABLE2}    scope=GLOBAL  # should not report
+    VAR    ${VARIABLE3}    Value with inconsistent ${variable2}
+    VAR    ${variable}    ${VARIABLE}  # should not report
diff --git a/tests/atest/rules/naming/inconsistent_variable_name/test_rule.py b/tests/atest/rules/naming/inconsistent_variable_name/test_rule.py
index 6abb757..65f0bee 100644
--- a/tests/atest/rules/naming/inconsistent_variable_name/test_rule.py
+++ b/tests/atest/rules/naming/inconsistent_variable_name/test_rule.py
@@ -2,5 +2,15 @@ from tests.atest.utils import RuleAcceptance
 
 
 class TestRuleAcceptance(RuleAcceptance):
-    def test_rule(self):
-        self.check_rule(src_files=["test.robot"], expected_file="expected_output.txt", issue_format="end_col")
+    def test_rule_pre(self):
+        self.check_rule(
+            src_files=["test.robot"], expected_file="expected_output.txt", issue_format="end_col", target_version=">=7"
+        )
+
+    def test_rule_pre_rf7(self):
+        self.check_rule(
+            src_files=["test.robot"],
+            expected_file="expected_output_pre_7.txt",
+            issue_format="end_col",
+            target_version="<7",
+        )
diff --git a/tests/atest/rules/naming/possible_variable_overwriting/expected_output.txt b/tests/atest/rules/naming/possible_variable_overwriting/expected_output.txt
index 893f78c..6017cc1 100644
--- a/tests/atest/rules/naming/possible_variable_overwriting/expected_output.txt
+++ b/tests/atest/rules/naming/possible_variable_overwriting/expected_output.txt
@@ -23,4 +23,7 @@ test.robot:80:5 [I] 0316 Variable '${_initiaL}' may overwrite similar variable i
 test.robot:84:5 [I] 0316 Variable '${VARiable}' may overwrite similar variable inside 'Assignment Sign' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
 test.robot:92:5 [I] 0316 Variable '${keywordArgs}' may overwrite similar variable inside 'Keyword With Possible Overwritten Kwargs' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
 test.robot:88:5 [I] 0316 Variable '${keyword_args}' may overwrite similar variable inside 'Keyword With Kwargs' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
-test.robot:102:5 [I] 0316 Variable '${VARIABLE}' may overwrite similar variable inside 'Item Assignment' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
\ No newline at end of file
+test.robot:102:5 [I] 0316 Variable '${VARIABLE}' may overwrite similar variable inside 'Item Assignment' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
+test.robot:106:12 [I] 0316 Variable '${variableName}' may overwrite similar variable inside 'VAR Syntax' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
+test.robot:107:12 [I] 0316 Variable '${variable name}' may overwrite similar variable inside 'VAR Syntax' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
+test.robot:108:12 [I] 0316 Variable '${variable namE}' may overwrite similar variable inside 'VAR Syntax' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
\ No newline at end of file
diff --git a/tests/atest/rules/naming/possible_variable_overwriting/expected_output_pre7.txt b/tests/atest/rules/naming/possible_variable_overwriting/expected_output_pre7.txt
new file mode 100644
index 0000000..893f78c
--- /dev/null
+++ b/tests/atest/rules/naming/possible_variable_overwriting/expected_output_pre7.txt
@@ -0,0 +1,26 @@
+test.robot:5:5 [I] 0316 Variable '${MY VAR}' may overwrite similar variable inside 'Test With Overwritten Variables' TestCase. Note that variables are case-insensitive, and also spaces and underscores are ignored.
+test.robot:6:5 [I] 0316 Variable '${myVar}' may overwrite similar variable inside 'Test With Overwritten Variables' TestCase. Note that variables are case-insensitive, and also spaces and underscores are ignored.
+test.robot:8:5 [I] 0316 Variable '${MYVAR}' may overwrite similar variable inside 'Test With Overwritten Variables' TestCase. Note that variables are case-insensitive, and also spaces and underscores are ignored.
+test.robot:9:5 [I] 0316 Variable '${M Y V A R}' may overwrite similar variable inside 'Test With Overwritten Variables' TestCase. Note that variables are case-insensitive, and also spaces and underscores are ignored.
+test.robot:10:5 [I] 0316 Variable '${mYvAr}' may overwrite similar variable inside 'Test With Overwritten Variables' TestCase. Note that variables are case-insensitive, and also spaces and underscores are ignored.
+test.robot:22:9 [I] 0316 Variable '${VAL}' may overwrite similar variable inside 'Keyword With For Loops' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
+test.robot:29:13 [I] 0316 Variable '${this var}' may overwrite similar variable inside 'Keyword With For Loops' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
+test.robot:31:20 [I] 0316 Variable '${myVar}' may overwrite similar variable inside 'Keyword With For Loops' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
+test.robot:41:9 [I] 0316 Variable '${VAL}' may overwrite similar variable inside 'Keyword With If Conditions' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
+test.robot:46:5 [I] 0316 Variable '${MY_VAL}' may overwrite similar variable inside 'Keyword With If Conditions' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
+test.robot:48:38 [I] 0316 Variable '${val}' may overwrite similar variable inside 'Keyword With If Conditions' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
+test.robot:57:5 [I] 0316 Variable '${SOME_VAR}' may overwrite similar variable inside 'Keyword With Overwritten Variables' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
+test.robot:58:5 [I] 0316 Variable '${myvar}' may overwrite similar variable inside 'Keyword With Overwritten Variables' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
+test.robot:60:5 [I] 0316 Variable '${somevar}' may overwrite similar variable inside 'Keyword With Overwritten Variables' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
+test.robot:60:21 [I] 0316 Variable '${some var}' may overwrite similar variable inside 'Keyword With Overwritten Variables' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
+test.robot:65:5 [I] 0316 Variable '${simpleVar}' may overwrite similar variable inside 'Keyword With Different Types Of Variables' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
+test.robot:66:5 [I] 0316 Variable '@{SIMPLE_VAR}' may overwrite similar variable inside 'Keyword With Different Types Of Variables' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
+test.robot:67:5 [I] 0316 Variable '&{SIMPLE_VAR}' may overwrite similar variable inside 'Keyword With Different Types Of Variables' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
+test.robot:71:5 [I] 0316 Variable '${VARIABLE}' may overwrite similar variable inside 'Argument With Default Value' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
+test.robot:75:5 [I] 0316 Variable '${VARIABLE}' may overwrite similar variable inside 'Embedded ${variable} with ${possible:pattern}' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
+test.robot:76:5 [I] 0316 Variable '${poss_ible}' may overwrite similar variable inside 'Embedded ${variable} with ${possible:pattern}' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
+test.robot:80:5 [I] 0316 Variable '${_initiaL}' may overwrite similar variable inside 'IF Assignment' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
+test.robot:84:5 [I] 0316 Variable '${VARiable}' may overwrite similar variable inside 'Assignment Sign' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
+test.robot:92:5 [I] 0316 Variable '${keywordArgs}' may overwrite similar variable inside 'Keyword With Possible Overwritten Kwargs' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
+test.robot:88:5 [I] 0316 Variable '${keyword_args}' may overwrite similar variable inside 'Keyword With Kwargs' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
+test.robot:102:5 [I] 0316 Variable '${VARIABLE}' may overwrite similar variable inside 'Item Assignment' Keyword. Note that variables are case-insensitive, and also spaces and underscores are ignored.
\ No newline at end of file
diff --git a/tests/atest/rules/naming/possible_variable_overwriting/test.robot b/tests/atest/rules/naming/possible_variable_overwriting/test.robot
index 5012871..8f15fa2 100644
--- a/tests/atest/rules/naming/possible_variable_overwriting/test.robot
+++ b/tests/atest/rules/naming/possible_variable_overwriting/test.robot
@@ -100,3 +100,10 @@ Assignment Sign But Not Overwritten
 Item Assignment
     ${variable}    Create Dictionary
     ${VARIABLE}[item]    Set Variable    value
+
+VAR Syntax
+    ${variable_name} =    Set Variable    value
+    VAR    ${variableName}    value
+    VAR    ${variable name}    value    scope=GLOBAL
+    VAR    ${variable namE}=    value    scope=local
+    VAR    ${variable_name}    Value with ${Variable_Name}    scope=SUITE
diff --git a/tests/atest/rules/naming/possible_variable_overwriting/test_rule.py b/tests/atest/rules/naming/possible_variable_overwriting/test_rule.py
index 87ce3ec..bb8d985 100644
--- a/tests/atest/rules/naming/possible_variable_overwriting/test_rule.py
+++ b/tests/atest/rules/naming/possible_variable_overwriting/test_rule.py
@@ -3,7 +3,10 @@ from tests.atest.utils import RuleAcceptance
 
 class TestRuleAcceptance(RuleAcceptance):
     def test_rule(self):
-        self.check_rule(src_files=["test.robot"], expected_file="expected_output.txt", target_version=">=6.1")
+        self.check_rule(src_files=["test.robot"], expected_file="expected_output.txt", target_version=">=7")
+
+    def test_rule_pre_rf7(self):
+        self.check_rule(src_files=["test.robot"], expected_file="expected_output_pre7.txt", target_version=">=6.1;<7")
 
     def test_pre_rf6_1(self):
         self.check_rule(
diff --git a/tests/atest/utils/__init__.py b/tests/atest/utils/__init__.py
index a91c788..a422890 100644
--- a/tests/atest/utils/__init__.py
+++ b/tests/atest/utils/__init__.py
@@ -88,7 +88,7 @@ class RuleAcceptance:
         config: Optional[str] = None,
         rule: Optional[str] = None,
         src_files: Optional[List] = None,
-        target_version: Optional[str] = None,
+        target_version: Optional[Union[str, List[str]]] = None,
         issue_format: str = "default",
         deprecated: bool = False,
     ):
@@ -142,6 +142,14 @@ class RuleAcceptance:
 
     @staticmethod
     def enabled_in_version(target_version: Optional[Union["list", str]]):
+        """
+        Check if rule is enabled for given target version condition.
+
+        If the target version condition is a string it needs to match with RF version.
+        If target version is a string and  contains `;`, the string is split into list and each element is a condition
+        that should match RF version.
+        If the target version is a list of strings, any version conditions need to match.
+        """
         if target_version is None:
             return True
         if isinstance(target_version, list):