Files
codeql/python/ql/src/Testing/ImpreciseAssert.ql
Taus Brock-Nannestad f07a7bf8cf Python: Autoformat everything using qlformat.
Will need subsequent PRs fixing up test failures (due to deprecated
methods moving around), but other than that everything should be
straight-forward.
2020-07-07 15:43:52 +02:00

93 lines
2.8 KiB
Plaintext

/**
* @name Imprecise assert
* @description Using 'assertTrue' or 'assertFalse' rather than a more specific assertion can give uninformative failure messages.
* @kind problem
* @tags maintainability
* testability
* @problem.severity recommendation
* @sub-severity high
* @precision very-high
* @id py/imprecise-assert
*/
import python
/* Helper predicate for CallToAssertOnComparison class */
predicate callToAssertOnComparison(Call call, string assertName, Cmpop op) {
call.getFunc().(Attribute).getName() = assertName and
(assertName = "assertTrue" or assertName = "assertFalse") and
exists(Compare cmp |
cmp = call.getArg(0) and
/* Exclude complex comparisons like: a < b < c */
not exists(cmp.getOp(1)) and
op = cmp.getOp(0)
)
}
class CallToAssertOnComparison extends Call {
CallToAssertOnComparison() { callToAssertOnComparison(this, _, _) }
Cmpop getOperator() { callToAssertOnComparison(this, _, result) }
string getMethodName() { callToAssertOnComparison(this, result, _) }
string getBetterName() {
exists(Cmpop op |
callToAssertOnComparison(this, "assertTrue", op) and
(
op instanceof Eq and result = "assertEqual"
or
op instanceof NotEq and result = "assertNotEqual"
or
op instanceof Lt and result = "assertLess"
or
op instanceof LtE and result = "assertLessEqual"
or
op instanceof Gt and result = "assertGreater"
or
op instanceof GtE and result = "assertGreaterEqual"
or
op instanceof In and result = "assertIn"
or
op instanceof NotIn and result = "assertNotIn"
or
op instanceof Is and result = "assertIs"
or
op instanceof IsNot and result = "assertIsNot"
)
or
callToAssertOnComparison(this, "assertFalse", op) and
(
op instanceof NotEq and result = "assertEqual"
or
op instanceof Eq and result = "assertNotEqual"
or
op instanceof GtE and result = "assertLess"
or
op instanceof Gt and result = "assertLessEqual"
or
op instanceof LtE and result = "assertGreater"
or
op instanceof Lt and result = "assertGreaterEqual"
or
op instanceof NotIn and result = "assertIn"
or
op instanceof In and result = "assertNotIn"
or
op instanceof IsNot and result = "assertIs"
or
op instanceof Is and result = "assertIsNot"
)
)
}
}
from CallToAssertOnComparison call
where
/* Exclude cases where an explicit message is provided*/
not exists(call.getArg(1))
select call,
call.getMethodName() + "(a " + call.getOperator().getSymbol() + " b) " +
"cannot provide an informative message. Using " + call.getBetterName() +
"(a, b) instead will give more informative messages."