Refine our modelling of test functions and split it out into a separate library.

This commit is contained in:
Max Schaefer
2020-04-06 14:45:59 +01:00
parent 4a1071cac6
commit 42bc5353e3
4 changed files with 54 additions and 7 deletions

View File

@@ -12,19 +12,16 @@ string generatorCommentRegex() {
result = "Generated By\\b.*\\bDo not edit" or
result = "This (file|class|interface|art[ei]fact) (was|is|(has been)) (?:auto[ -]?)?gener(e?)ated" or
result = "Any modifications to this file will be lost" or
result = "This (file|class|interface|art[ei]fact) (was|is) (?:mechanically|automatically) generated" or
result =
"This (file|class|interface|art[ei]fact) (was|is) (?:mechanically|automatically) generated" or
result = "The following code was (?:auto[ -]?)?generated (?:by|from)" or
result = "Autogenerated by Thrift" or
result = "(Code g|G)enerated from .* by ANTLR"
}
predicate classify(File f, string category) {
// `go test`-style test
f.getBaseName().regexpMatch(".*_test.go") and
exists(FuncDecl fn |
fn.getName().regexpMatch("(Test|Benchmark|Example)[^a-z].*") and
fn.getFile() = f
) and
// tests
f = any(TestCase tc).getFile() and
category = "test"
or
// vendored code

View File

@@ -28,5 +28,6 @@ import semmle.go.frameworks.SystemCommandExecutors
import semmle.go.frameworks.SQL
import semmle.go.frameworks.XPath
import semmle.go.frameworks.Stdlib
import semmle.go.frameworks.Testing
import semmle.go.security.FlowSources
import semmle.go.Util

View File

@@ -129,6 +129,13 @@ class FuncDef extends @funcdef, StmtParent, ExprParent {
result.getFunction() = this
}
/**
* Gets the number of parameters of this function.
*/
int getNumParameter() {
result = count(getAParameter())
}
/**
* Gets a call to this function.
*/

View File

@@ -0,0 +1,42 @@
/** Provides classes for working with tests. */
import go
/**
* A program element that represents a test case.
*
* Extend this class to refine existing models of testing frameworks. If you want to model new
* frameworks, extend `TestCase::Range` instead.
*/
class TestCase extends AstNode {
TestCase::Range self;
TestCase() { this = self }
}
/** Provides classes for working with test cases. */
module TestCase {
/**
* A program element that represents a test case.
*
* Extend this class to model new testing frameworks. If you want to refine existing models,
* extend `TestCase` instead.
*/
abstract class Range extends AstNode { }
/** A `go test` style test (including benchmarks and examples). */
private class GoTestFunction extends Range, FuncDef {
GoTestFunction() {
getName().regexpMatch("Test[^a-z].*") and
getNumParameter() = 1 and
getParameter(0).getType().(PointerType).getBaseType().hasQualifiedName("testing", "T")
or
getName().regexpMatch("Benchmark[^a-z].*") and
getNumParameter() = 1 and
getParameter(0).getType().(PointerType).getBaseType().hasQualifiedName("testing", "B")
or
getName().regexpMatch("Example[^a-z].*") and
getNumParameter() = 0
}
}
}