Tests: add ability to write custom stepping tests

This commit is contained in:
Natalia Ukhorskaya
2015-05-22 17:32:06 +03:00
parent 403ca00a63
commit 2538ebe407
5 changed files with 75 additions and 36 deletions
@@ -617,6 +617,7 @@ fun main(args: Array<String>) {
model("debugger/tinyApp/src/stepping/stepInto", testMethod = "doStepIntoTest", testClassName = "StepIntoOnly")
model("debugger/tinyApp/src/stepping/stepOut", testMethod = "doStepOutTest")
model("debugger/tinyApp/src/stepping/filters", testMethod = "doStepIntoTest")
model("debugger/tinyApp/src/stepping/custom", testMethod = "doCustomTest")
}
testClass(javaClass<AbstractKotlinEvaluateExpressionTest>()) {
@@ -43,6 +43,29 @@ public abstract class AbstractKotlinSteppingTest : KotlinDebuggerTestBase() {
doTest(path, "SMART_STEP_INTO")
}
protected fun doCustomTest(path: String) {
val fileText = FileUtil.loadFile(File(path))
configureSettings(fileText)
createAdditionalBreakpoints(fileText)
createDebugProcess(path)
fun repeat(indexPrefix: String, f: SuspendContextImpl.() -> Unit) {
for (i in 1..(getPrefixedInt(fileText, indexPrefix) ?: 1)) {
onBreakpoint(f)
}
}
File(path).readLines().forEach {
when {
it.startsWith("// STEP_INTO") -> repeat("// STEP_INTO: ") { stepInto() }
it.startsWith("// STEP_OUT") -> repeat("// STEP_OUT: ") { stepOut() }
it.startsWith("// SMART_STEP_INTO") -> repeat("// SMART_STEP_INTO: ") { smartStepInto() }
}
}
finish()
}
private fun doTest(path: String, command: String) {
val fileText = FileUtil.loadFile(File(path))
@@ -232,4 +232,40 @@ abstract class KotlinDebuggerTestBase : KotlinDebuggerTestCase() {
runnable.invoke()
}
}
protected fun createAdditionalBreakpoints(fileText: String) {
val breakpoints = InTextDirectivesUtils.findLinesWithPrefixesRemoved(fileText, "// ADDITIONAL_BREAKPOINT: ")
for (breakpoint in breakpoints) {
val position = breakpoint.split(".kt:")
assert(position.size() == 2) { "Couldn't parse position from test directive: directive = $breakpoint" }
createBreakpoint(position[0], position[1])
}
}
private fun createBreakpoint(fileName: String, lineMarker: String) {
val project = getProject()!!
val sourceFiles = FilenameIndex.getAllFilesByExt(project, "kt").filter {
it.getName().contains(fileName) &&
it.contentsToByteArray().toString("UTF-8").contains(lineMarker)
}
assert(sourceFiles.size() == 1) { "One source file should be found: name = $fileName, sourceFiles = $sourceFiles" }
val runnable = Runnable() {
val psiSourceFile = PsiManager.getInstance(project).findFile(sourceFiles.first())!!
val breakpointManager = DebuggerManagerEx.getInstanceEx(project)?.getBreakpointManager()!!
val document = PsiDocumentManager.getInstance(project).getDocument(psiSourceFile)!!
val index = psiSourceFile.getText()!!.indexOf(lineMarker)
val lineNumber = document.getLineNumber(index) + 1
val breakpoint = breakpointManager.addLineBreakpoint(document, lineNumber)
if (breakpoint != null) {
println("LineBreakpoint created at " + psiSourceFile.getName() + ":" + lineNumber, ProcessOutputTypes.SYSTEM);
}
}
DebuggerInvocationUtil.invokeAndWait(project, runnable, ModalityState.defaultModalityState())
}
}
@@ -367,4 +367,19 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest {
doStepIntoTest(fileName);
}
}
@TestMetadata("idea/testData/debugger/tinyApp/src/stepping/custom")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Custom extends AbstractKotlinSteppingTest {
public void testAllFilesPresentInCustom() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/debugger/tinyApp/src/stepping/custom"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("stepIntoStdlibInlineFun2step.kt")
public void testStepIntoStdlibInlineFun2step() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/custom/stepIntoStdlibInlineFun2step.kt");
doCustomTest(fileName);
}
}
}
@@ -176,42 +176,6 @@ public abstract class AbstractKotlinEvaluateExpressionTest : KotlinDebuggerTestB
finish()
}
private fun createAdditionalBreakpoints(fileText: String) {
val breakpoints = InTextDirectivesUtils.findLinesWithPrefixesRemoved(fileText, "// ADDITIONAL_BREAKPOINT: ")
for (breakpoint in breakpoints) {
val position = breakpoint.split(".kt:")
assert(position.size() == 2) { "Couldn't parse position from test directive: directive = $breakpoint" }
createBreakpoint(position[0], position[1])
}
}
private fun createBreakpoint(fileName: String, lineMarker: String) {
val project = getProject()!!
val sourceFiles = FilenameIndex.getAllFilesByExt(project, "kt").filter {
it.getName().contains(fileName) &&
it.contentsToByteArray().toString("UTF-8").contains(lineMarker)
}
assert(sourceFiles.size() == 1) { "One source file should be found: name = $fileName, sourceFiles = $sourceFiles" }
val runnable = Runnable() {
val psiSourceFile = PsiManager.getInstance(project).findFile(sourceFiles.first())!!
val breakpointManager = DebuggerManagerEx.getInstanceEx(project)?.getBreakpointManager()!!
val document = PsiDocumentManager.getInstance(project).getDocument(psiSourceFile)!!
val index = psiSourceFile.getText()!!.indexOf(lineMarker)
val lineNumber = document.getLineNumber(index) + 1
val breakpoint = breakpointManager.addLineBreakpoint(document, lineNumber)
if (breakpoint != null) {
println("LineBreakpoint created at " + psiSourceFile.getName() + ":" + lineNumber, ProcessOutputTypes.SYSTEM);
}
}
DebuggerInvocationUtil.invokeAndWait(project, runnable, ModalityState.defaultModalityState())
}
private fun SuspendContextImpl.printFrame() {
val tree = FrameVariablesTree(getProject()!!)
Disposer.register(getTestRootDisposable()!!, tree);