diff --git a/idea/idea-repl/src/org/jetbrains/kotlin/console/CommandHistory.kt b/idea/idea-repl/src/org/jetbrains/kotlin/console/CommandHistory.kt index 6d406c9900e..87c111b5680 100644 --- a/idea/idea-repl/src/org/jetbrains/kotlin/console/CommandHistory.kt +++ b/idea/idea-repl/src/org/jetbrains/kotlin/console/CommandHistory.kt @@ -25,7 +25,8 @@ class CommandHistory { ) private val entries = arrayListOf() - private var processedEntriesCount: Int = 0 + var processedEntriesCount: Int = 0 + private set val listeners = arrayListOf() diff --git a/idea/idea-repl/src/org/jetbrains/kotlin/console/KotlinConsoleRunner.kt b/idea/idea-repl/src/org/jetbrains/kotlin/console/KotlinConsoleRunner.kt index 1ccd8e8328c..60a4bad33a0 100644 --- a/idea/idea-repl/src/org/jetbrains/kotlin/console/KotlinConsoleRunner.kt +++ b/idea/idea-repl/src/org/jetbrains/kotlin/console/KotlinConsoleRunner.kt @@ -67,7 +67,7 @@ public class KotlinConsoleRunner( title: String, path: String? ) : AbstractConsoleRunnerWithHistory(myProject, title, path) { - internal val commandHistory = CommandHistory() + val commandHistory = CommandHistory() var isReadLineMode: Boolean = false set(value) { diff --git a/idea/tests/org/jetbrains/kotlin/idea/console/KotlinReplTest.kt b/idea/tests/org/jetbrains/kotlin/idea/console/KotlinReplTest.kt index 7105a72e176..91b5121d2aa 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/console/KotlinReplTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/console/KotlinReplTest.kt @@ -31,6 +31,7 @@ import kotlin.test.assertTrue @FixMethodOrder(MethodSorters.JVM) public class KotlinReplTest : PlatformTestCase() { private var consoleRunner: KotlinConsoleRunner by Delegates.notNull() + private var commandsSent = 0 override fun setUp() { super.setUp() @@ -45,45 +46,51 @@ public class KotlinReplTest : PlatformTestCase() { private fun sendCommand(command: String) { consoleRunner.consoleView.editorDocument.setText(command) consoleRunner.executor.executeCommand() + commandsSent++ } - private fun waitForExpectedOutput(expectedOutput: String) { - val endsWithPredicate = { x: String -> x.trim().endsWith(expectedOutput) } - - val historyText = checkHistoryUpdate { endsWithPredicate(it) } - - assertTrue(endsWithPredicate(historyText), "'$expectedOutput' should be printed but document text is:\n$historyText") + private fun checkOutput(expectedOutput: String) { + val output = getReplOutput(textOnTimeOut = { "Only ${consoleRunner.commandHistory.processedEntriesCount} commands were processed" }) { + consoleRunner.commandHistory.processedEntriesCount >= commandsSent + } + assertTrue(output.trim().endsWith(expectedOutput), "'$expectedOutput' should be printed but document text is:\n$output") } - private fun checkHistoryUpdate(maxIterations: Int = 50, sleepTime: Long = 500, stopPredicate: (String) -> Boolean): String { - val consoleView = consoleRunner.consoleView as LanguageConsoleImpl - + private fun getReplOutput(maxIterations: Int = 50, sleepTime: Long = 500, textOnTimeOut: () -> String, predicate: () -> Boolean): String { for (i in 1..maxIterations) { UIUtil.dispatchAllInvocationEvents() - consoleView.flushDeferredText() - - val historyText = consoleView.historyViewer.document.text - if (stopPredicate(historyText)) return historyText - + if (predicate()) { + return refreshAndGetHistoryEditorText() + } Thread.sleep(sleepTime) } - return "" + 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) { sendCommand(command) - waitForExpectedOutput(expectedOutput) + checkOutput(expectedOutput) } @Test fun testRunPossibility() { 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 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") - assertTrue(allOk(historyText), "Successful run should contain text: ':help for help'") + assertFalse(hasErrors(output), "Cannot run kotlin repl") + assertTrue(allOk(output), "Successful run should contain text: ':help for help'") assertFalse(consoleRunner.processHandler.isProcessTerminated, "Process accidentally terminated") } @@ -99,7 +106,7 @@ public class KotlinReplTest : PlatformTestCase() { "}\n") sendCommand("f()") - waitForExpectedOutput(printText) + checkOutput(printText) } @Test fun testReadLineSingle() { @@ -108,7 +115,7 @@ public class KotlinReplTest : PlatformTestCase() { sendCommand("val a = readLine()") sendCommand(readLineText) sendCommand("a") - waitForExpectedOutput(readLineText) + checkOutput(readLineText) } @Test fun testReadLineMultiple() { @@ -121,16 +128,16 @@ public class KotlinReplTest : PlatformTestCase() { sendCommand(readLineTextB) sendCommand("a") - waitForExpectedOutput(readLineTextA) + checkOutput(readLineTextA) sendCommand("b") - waitForExpectedOutput(readLineTextB) + checkOutput(readLineTextB) } @Test fun testCorrectAfterError() { val message = "MyMessage" sendCommand("fun f() { println(x)\n println(y) ") sendCommand("println(\"$message\")") - waitForExpectedOutput(message) + checkOutput(message) } @Test fun testMultipleErrorsHandling() { @@ -139,6 +146,6 @@ public class KotlinReplTest : PlatformTestCase() { sendCommand(veryLongTextWithErrors) sendCommand(veryLongTextWithErrors) sendCommand("println(\"OK\")") - waitForExpectedOutput("OK") + checkOutput("OK") } } \ No newline at end of file