Repl: enhance test framework to wait for commands to be processed, not some text to appear

This commit is contained in:
Pavel V. Talanov
2015-10-26 15:19:07 +03:00
parent 03c3fd2c2b
commit d0097c85d3
3 changed files with 35 additions and 27 deletions
@@ -25,7 +25,8 @@ class CommandHistory {
) )
private val entries = arrayListOf<Entry>() private val entries = arrayListOf<Entry>()
private var processedEntriesCount: Int = 0 var processedEntriesCount: Int = 0
private set
val listeners = arrayListOf<HistoryUpdateListener>() val listeners = arrayListOf<HistoryUpdateListener>()
@@ -67,7 +67,7 @@ public class KotlinConsoleRunner(
title: String, title: String,
path: String? path: String?
) : AbstractConsoleRunnerWithHistory<LanguageConsoleView>(myProject, title, path) { ) : AbstractConsoleRunnerWithHistory<LanguageConsoleView>(myProject, title, path) {
internal val commandHistory = CommandHistory() val commandHistory = CommandHistory()
var isReadLineMode: Boolean = false var isReadLineMode: Boolean = false
set(value) { set(value) {
@@ -31,6 +31,7 @@ import kotlin.test.assertTrue
@FixMethodOrder(MethodSorters.JVM) @FixMethodOrder(MethodSorters.JVM)
public class KotlinReplTest : PlatformTestCase() { public class KotlinReplTest : PlatformTestCase() {
private var consoleRunner: KotlinConsoleRunner by Delegates.notNull() private var consoleRunner: KotlinConsoleRunner by Delegates.notNull()
private var commandsSent = 0
override fun setUp() { override fun setUp() {
super.setUp() super.setUp()
@@ -45,45 +46,51 @@ public class KotlinReplTest : PlatformTestCase() {
private fun sendCommand(command: String) { private fun sendCommand(command: String) {
consoleRunner.consoleView.editorDocument.setText(command) consoleRunner.consoleView.editorDocument.setText(command)
consoleRunner.executor.executeCommand() consoleRunner.executor.executeCommand()
commandsSent++
} }
private fun waitForExpectedOutput(expectedOutput: String) { private fun checkOutput(expectedOutput: String) {
val endsWithPredicate = { x: String -> x.trim().endsWith(expectedOutput) } val output = getReplOutput(textOnTimeOut = { "Only ${consoleRunner.commandHistory.processedEntriesCount} commands were processed" }) {
consoleRunner.commandHistory.processedEntriesCount >= commandsSent
val historyText = checkHistoryUpdate { endsWithPredicate(it) } }
assertTrue(output.trim().endsWith(expectedOutput), "'$expectedOutput' should be printed but document text is:\n$output")
assertTrue(endsWithPredicate(historyText), "'$expectedOutput' should be printed but document text is:\n$historyText")
} }
private fun checkHistoryUpdate(maxIterations: Int = 50, sleepTime: Long = 500, stopPredicate: (String) -> Boolean): String { private fun getReplOutput(maxIterations: Int = 50, sleepTime: Long = 500, textOnTimeOut: () -> String, predicate: () -> Boolean): String {
val consoleView = consoleRunner.consoleView as LanguageConsoleImpl
for (i in 1..maxIterations) { for (i in 1..maxIterations) {
UIUtil.dispatchAllInvocationEvents() UIUtil.dispatchAllInvocationEvents()
consoleView.flushDeferredText() if (predicate()) {
return refreshAndGetHistoryEditorText()
val historyText = consoleView.historyViewer.document.text }
if (stopPredicate(historyText)) return historyText
Thread.sleep(sleepTime) Thread.sleep(sleepTime)
} }
return "<empty text>" return textOnTimeOut()
}
private fun refreshAndGetHistoryEditorText(): String {
val consoleView = consoleRunner.consoleView as LanguageConsoleImpl
consoleView.flushDeferredText()
return consoleView.historyViewer.document.text
} }
private fun testSimpleCommand(command: String, expectedOutput: String) { private fun testSimpleCommand(command: String, expectedOutput: String) {
sendCommand(command) sendCommand(command)
waitForExpectedOutput(expectedOutput) checkOutput(expectedOutput)
} }
@Test fun testRunPossibility() { @Test fun testRunPossibility() {
val allOk = { x: String -> x.contains(":help for help") } val allOk = { x: String -> x.contains(":help for help") }
val hasErrors = { x: String -> x.contains("Process finished with exit code 1") || x.contains("Exception in") || x.contains("Error") } val hasErrors = { x: String -> x.contains("Process finished with exit code 1") || x.contains("Exception in") || x.contains("Error") }
val historyText = checkHistoryUpdate { hasErrors(it) || allOk(it) } val output = getReplOutput(textOnTimeOut = { "Repl startup timed out" }) {
val editorText = refreshAndGetHistoryEditorText()
hasErrors(editorText) || allOk(editorText)
}
assertFalse(hasErrors(historyText), "Cannot run kotlin repl") assertFalse(hasErrors(output), "Cannot run kotlin repl")
assertTrue(allOk(historyText), "Successful run should contain text: ':help for help'") assertTrue(allOk(output), "Successful run should contain text: ':help for help'")
assertFalse(consoleRunner.processHandler.isProcessTerminated, "Process accidentally terminated") assertFalse(consoleRunner.processHandler.isProcessTerminated, "Process accidentally terminated")
} }
@@ -99,7 +106,7 @@ public class KotlinReplTest : PlatformTestCase() {
"}\n") "}\n")
sendCommand("f()") sendCommand("f()")
waitForExpectedOutput(printText) checkOutput(printText)
} }
@Test fun testReadLineSingle() { @Test fun testReadLineSingle() {
@@ -108,7 +115,7 @@ public class KotlinReplTest : PlatformTestCase() {
sendCommand("val a = readLine()") sendCommand("val a = readLine()")
sendCommand(readLineText) sendCommand(readLineText)
sendCommand("a") sendCommand("a")
waitForExpectedOutput(readLineText) checkOutput(readLineText)
} }
@Test fun testReadLineMultiple() { @Test fun testReadLineMultiple() {
@@ -121,16 +128,16 @@ public class KotlinReplTest : PlatformTestCase() {
sendCommand(readLineTextB) sendCommand(readLineTextB)
sendCommand("a") sendCommand("a")
waitForExpectedOutput(readLineTextA) checkOutput(readLineTextA)
sendCommand("b") sendCommand("b")
waitForExpectedOutput(readLineTextB) checkOutput(readLineTextB)
} }
@Test fun testCorrectAfterError() { @Test fun testCorrectAfterError() {
val message = "MyMessage" val message = "MyMessage"
sendCommand("fun f() { println(x)\n println(y) ") sendCommand("fun f() { println(x)\n println(y) ")
sendCommand("println(\"$message\")") sendCommand("println(\"$message\")")
waitForExpectedOutput(message) checkOutput(message)
} }
@Test fun testMultipleErrorsHandling() { @Test fun testMultipleErrorsHandling() {
@@ -139,6 +146,6 @@ public class KotlinReplTest : PlatformTestCase() {
sendCommand(veryLongTextWithErrors) sendCommand(veryLongTextWithErrors)
sendCommand(veryLongTextWithErrors) sendCommand(veryLongTextWithErrors)
sendCommand("println(\"OK\")") sendCommand("println(\"OK\")")
waitForExpectedOutput("OK") checkOutput("OK")
} }
} }