mirror of
https://github.com/github/codeql.git
synced 2026-01-12 06:00:23 +01:00
160 lines
5.1 KiB
Plaintext
160 lines
5.1 KiB
Plaintext
import java
|
|
import semmle.code.java.deadcode.DeadCode
|
|
import semmle.code.java.frameworks.Cucumber
|
|
import semmle.code.java.deadcode.frameworks.FitNesseEntryPoints
|
|
import semmle.code.java.frameworks.Mockito
|
|
import semmle.code.java.UnitTests
|
|
|
|
/**
|
|
* A test method, suite, or an associated setup/teardown method.
|
|
*/
|
|
class TestMethodEntry extends CallableEntryPoint {
|
|
TestMethodEntry() {
|
|
this instanceof TestMethod and
|
|
// Ignored tests are not run
|
|
not this instanceof JUnitIgnoredMethod
|
|
or
|
|
this instanceof JUnit3TestSuite
|
|
or
|
|
exists(AnnotationType a | a = this.getAnAnnotation().getType() |
|
|
a.hasQualifiedName("org.junit.runners", "Parameterized$Parameters") and
|
|
this.getDeclaringType() instanceof ParameterizedJUnitTest
|
|
)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Methods that are called before or after tests.
|
|
*/
|
|
class BeforeOrAfterEntry extends CallableEntryPoint {
|
|
BeforeOrAfterEntry() {
|
|
this.getAnAnnotation() instanceof TestNGBeforeAnnotation or
|
|
this.getAnAnnotation() instanceof TestNGAfterAnnotation or
|
|
this.getAnAnnotation() instanceof BeforeAnnotation or
|
|
this.getAnAnnotation() instanceof BeforeClassAnnotation or
|
|
this.getAnAnnotation() instanceof AfterAnnotation or
|
|
this.getAnAnnotation() instanceof AfterClassAnnotation
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A method in a test class that is either a JUnit theory, or a method providing data points for a theory.
|
|
*/
|
|
class JUnitTheories extends CallableEntryPoint {
|
|
JUnitTheories() {
|
|
exists(AnnotationType a |
|
|
a = this.getAnAnnotation().getType() and
|
|
this.getDeclaringType() instanceof JUnitTheoryTest
|
|
|
|
|
a.hasQualifiedName("org.junit.experimental.theories", "Theory") or
|
|
a.hasQualifiedName("org.junit.experimental.theories", "DataPoint") or
|
|
a.hasQualifiedName("org.junit.experimental.theories", "DataPoints")
|
|
)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A field which provides a JUnit `DataPoint` for a theory.
|
|
*/
|
|
class JUnitDataPointField extends ReflectivelyReadField {
|
|
JUnitDataPointField() {
|
|
exists(AnnotationType a | a = this.getAnAnnotation().getType() |
|
|
(
|
|
a.hasQualifiedName("org.junit.experimental.theories", "DataPoint") or
|
|
a.hasQualifiedName("org.junit.experimental.theories", "DataPoints")
|
|
) and
|
|
this.getDeclaringType() instanceof JUnitTheoryTest
|
|
)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Any types used as a category in a JUnit `@Category` annotation should be considered live.
|
|
*/
|
|
class JUnitCategory extends WhitelistedLiveClass {
|
|
JUnitCategory() { exists(JUnitCategoryAnnotation ca | ca.getACategory() = this) }
|
|
}
|
|
|
|
/**
|
|
* A listener that will be reflectively constructed by TestNG.
|
|
*/
|
|
class TestNGReflectivelyConstructedListener extends ReflectivelyConstructedClass instanceof TestNGListenerImpl
|
|
{
|
|
// Consider any class that implements a TestNG listener interface to be live. Listeners can be
|
|
// specified on the command line, in `testng.xml` files and in Ant build files, so it is safest
|
|
// to assume that all such listeners are live.
|
|
}
|
|
|
|
/**
|
|
* A `@DataProvider` TestNG method which is live because it is accessed by at least one test.
|
|
*/
|
|
class TestNGDataProvidersEntryPoint extends CallableEntryPoint {
|
|
TestNGDataProvidersEntryPoint() {
|
|
exists(TestNGTestMethod method | this = method.getADataProvider())
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A `@Factory` TestNG method or constructor which is live.
|
|
*/
|
|
class TestNGFactoryEntryPoint extends CallableEntryPoint instanceof TestNGFactoryCallable { }
|
|
|
|
class TestRefectivelyConstructedClass extends ReflectivelyConstructedClass {
|
|
TestRefectivelyConstructedClass() {
|
|
this.getAnAncestor().getACallable() instanceof TestMethodEntry
|
|
}
|
|
}
|
|
|
|
class RunWithReflectivelyConstructedClass extends ReflectivelyConstructedClass {
|
|
RunWithReflectivelyConstructedClass() {
|
|
exists(AnnotationType a | a = this.getAnAnnotation().getType() |
|
|
a.hasQualifiedName("org.junit.runner", "RunWith")
|
|
)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Callables called by Mockito when performing injection.
|
|
*/
|
|
class MockitoCalledByInjection extends CallableEntryPoint {
|
|
MockitoCalledByInjection() {
|
|
exists(MockitoInjectedField field | this = field.getAnInvokedCallable())
|
|
or
|
|
exists(MockitoSpiedField spyField |
|
|
spyField.isConstructed() and
|
|
this = spyField.getType().(RefType).getAConstructor() and
|
|
this.getNumberOfParameters() = 0
|
|
)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Mock fields that are read by Mockito when performing injection.
|
|
*/
|
|
class MockitoReadField extends ReflectivelyReadField {
|
|
MockitoReadField() { this.(MockitoMockedField).isReferencedByInjection() }
|
|
}
|
|
|
|
/**
|
|
* A class constructed by Cucumber.
|
|
*/
|
|
class CucumberConstructedClass extends ReflectivelyConstructedClass {
|
|
CucumberConstructedClass() {
|
|
this instanceof CucumberStepDefinitionClass or
|
|
this.getAnAncestor() instanceof CucumberJava8Language
|
|
}
|
|
|
|
override Callable getALiveCallable() {
|
|
// Consider any constructor to be live - Cucumber calls a runtime-specified dependency
|
|
// injection framework (possibly an in-built one) to construct these instances, so any
|
|
// constructor could be called.
|
|
result = this.getAConstructor()
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A "step definition" that may be called by Cucumber when executing an acceptance test.
|
|
*/
|
|
class CucumberStepDefinitionEntryPoint extends CallableEntryPoint instanceof CucumberStepDefinition {
|
|
}
|