[Bug] Rule unnecessary-string-conversion is inherently bad
vfuksa-cen89549 opened this issue · comments
What happened?
Hi,
"${status}" == "200"
and $status == 200
give different results in many cases and you can never know in which case they are equivalent. The situation is even worse when there is a less/greater-than operation instead of the equivalence (the rule applies even to these cases).
What command/code did you try to run?
See the following test:
*** Keywords ***
Check Equal
[Arguments] ${value}
${match} Set Variable True
IF "${value}" == "1"
${match} Set Variable not ${match}
END
IF $value == 1
${match} Set Variable not ${match}
END
Should Be True ${match} msg=Expressions do not match for value "${value}"
Check Greater Than
[Arguments] ${value}
${match} Set Variable True
IF "${value}" > "5"
${match} Set Variable not ${match}
END
IF $value > 5
${match} Set Variable not ${match}
END
Should Be True ${match} msg=Expressions do not match for value "${value}"
*** Test Cases ***
Test 1
Check Equal 1
Test 2
Check Greater Than 6
Test 3
Check Greater Than 40
Test 4
Check Greater Than ${40}
All the test cases fail, and that is for various causes.
- When comparing two strings, you can be sure that they are comparable: they are of the same type. When you remove the string conversion, possibly different types of the two expressions come into play and the comparison can fail because of their mismatching types (as in Test 2 and Test 3). To be sure the two expressions are of compatibile types, you should employ dynamic analysis, I guess.
- Even if the two expressions are comparable without string conversion, their comparison with and without it do not need to yield the same results. In Test 1,
"1" == "1"
, but"1" != 1
(because of different types, although values are equal). In Test 4,40 > 5
but"40" < "5"
(because of the different ways the things are ordered for various data types).
I am afraid it is very tedious or impossible to fix the rule or restrict it to cases when it is always correct, so that I suggest to delete it.
Operating System
WIndows
Robocop version
4.2.0
The problem is that Robot Framework is too lenient with the types (for a reason, more flexibility comes with a price) . If we want such condition to work, we would need to be really strict with types and always pass 200 as ${200}, use custom converters in libraries etc. I agree that this makes this rule too fragile and we could easily lead someone to modify code to the point it doesn't work and debugging could take time.
But what about moving this rule to community rules? There is this idea in the progress that we could have community added rules which may not work for all but still be useful for someone. For that reason those rules will be disabled by default (so you need to either --include or --configure rule:enabled=True the rule). As first step we could deprecated this rule in our core rules and then when community rules are fully ready (with Robocop 5.0.0) we could re-add it. Though if the rule doesn't hold much value for most we can think about removing it altogether.
As regards community rules, I thought these are the rules someone 100% wants for their specific tasks (e.g. every test case' name should start with its number) while the others do not want. In other words, the community rule is (hopefully :)) 100% correct but is needed by some while totally unneeded by the others.
We have another case here: the rule is correct sometimes (although many do not need to care :) ), but sometimes it gives bad advice to everyone. IMHO we should not retain rules giving bad advice (when we do not plan or even know how to fix it). It seems this would break values of Robocop otherwise. ;)
Yeah , I agree. We still want 100% correct rule for given issue. For this rule to truly work it should work as mypy and follow the types. It's more of dynamic check at this point, which is not feasible at this moment.
After #1027 is merged I will move this rule into deprecation. Our next release will be 5.0 (for different reasons) so it may be good idea to use 'breaking release' to deprecate this rule.