[gui-test] let recorder stop tasks; don't recompile code from GuiScriptEditor if code didn't change

This commit is contained in:
Sergey Karashevich
2017-04-29 22:24:43 +03:00
parent 01b65c60f0
commit d6b0ed8fe1
6 changed files with 49 additions and 33 deletions
@@ -22,7 +22,6 @@ import com.intellij.openapi.diagnostic.Logger
import com.intellij.testGuiFramework.recorder.compile.KotlinCompileUtil
import com.intellij.testGuiFramework.recorder.components.GuiRecorderComponent
import com.intellij.testGuiFramework.recorder.ui.Notifier
import java.util.function.Consumer
/**
* @author Sergey Karashevich
@@ -36,13 +35,9 @@ class PerformScriptAction : AnAction(null, "Run GUI Script", AllIcons.Actions.Ex
override fun actionPerformed(p0: AnActionEvent?) {
LOG.info("Compile and evaluate current script buffer")
Notifier.updateStatus("<long>Compiling and performing current script")
Notifier.updateStatus("${Notifier.LONG_OPERATION_PREFIX}Compiling and performing current script")
val editor = GuiRecorderComponent.getEditor()
//we wrapping it in lambda consumer because of different classloader problem in CompileDaemon class.
val myNotifier: Consumer<String> = Consumer<String> { statusMessage -> Notifier.updateStatus(statusMessage) }
// ApplicationManager.getApplication().executeOnPooledThread { KotlinCompileUtil.compileAndEvalCodeWithNotifier(editor.document.text, myNotifier) }
KotlinCompileUtil.compileAndRun(editor.document.text)
}
@@ -20,16 +20,18 @@ import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.testGuiFramework.recorder.GlobalActionRecorder
import com.intellij.testGuiFramework.recorder.ScriptGenerator
import com.intellij.testGuiFramework.recorder.components.GuiRecorderComponent
import com.intellij.testGuiFramework.recorder.ui.Notifier
/**
* @author Sergey Karashevich
*/
class StopRecAction : AnAction(null, "Stop Recording and Clear Buffer", AllIcons.Actions.Suspend) {
class StopRecAction : AnAction(null, "Stop Recording, Compiling, Running and Clear Buffer", AllIcons.Actions.Suspend) {
override fun actionPerformed(p0: AnActionEvent?) {
GlobalActionRecorder.deactivate()
Notifier.updateStatus("Recording stopped")
GuiRecorderComponent.cancelCurrentTask()
Notifier.updateStatus("Stopped")
ScriptGenerator.clearScriptBuffer()
}
@@ -29,13 +29,15 @@ object KotlinCompileUtil {
private val LOG by lazy { Logger.getInstance("#${KotlinCompileUtil::class.qualifiedName}") }
private val localCompiler: LocalCompiler by lazy {LocalCompiler()}
fun compile(codeString: String) {
LocalCompiler().compileOnPooledThread(ScriptGenerator.ScriptWrapper.wrapScript(codeString),
localCompiler.compileOnPooledThread(ScriptGenerator.ScriptWrapper.wrapScript(codeString),
getAllUrls().map { Paths.get(it.toURI()).toFile().path })
}
fun compileAndRun(codeString: String) {
LocalCompiler().compileAndRunOnPooledThread(ScriptGenerator.ScriptWrapper.wrapScript(codeString),
localCompiler.compileAndRunOnPooledThread(ScriptGenerator.ScriptWrapper.wrapScript(codeString),
getAllUrls().map { Paths.get(it.toURI()).toFile().path })
}
@@ -43,6 +43,8 @@ class LocalCompiler {
private val LOG by lazy { Logger.getInstance("#${LocalCompiler::class.qualifiedName}") }
var codeHash: Int? = null
val TEST_CLASS_NAME = "CurrentTest"
val helloKtText = "fun main(args: Array<String>) { \n println(\"Hello, World!\") \n }"
@@ -63,20 +65,26 @@ class LocalCompiler {
}
fun compileAndRunOnPooledThread(code: String, classpath: List<String>) {
ApplicationManager.getApplication().executeOnPooledThread({
try {
compile(code, classpath)
run2()
}
catch (ce: CompilationException) {
LOG.error(ce.message)
}
})
val taskFuture = ApplicationManager.getApplication().executeOnPooledThread({
try {
if (codeHash == null || codeHash != code.hashCode()) {
compile(code, classpath)
codeHash = code.hashCode()
}
run2()
}
catch (ce: CompilationException) {
LOG.error(ce.message)
}
})
GuiRecorderComponent.setCurrentTask(taskFuture)
}
//alternative way to run compiled code with pluginClassloader built especially for this file
private fun run2() {
Notifier.updateStatus("${Notifier.LONG_OPERATION_PREFIX}Script running...")
val testUrl = tempDir.toURI().toURL()
var classLoadersArray: Array<ClassLoader>
try {
@@ -93,7 +101,6 @@ class LocalCompiler {
val testCase = currentTest.newInstance()
val setUpMethod = currentTest.getMethod("setUp")
val testMethod = currentTest.getMethod(ScriptGenerator.ScriptWrapper.TEST_METHOD_NAME)
Notifier.updateStatus("<long>Script running...")
GuiRecorderComponent.setState(GuiRecorderComponent.States.RUNNING)
try {
setUpMethod.invoke(testCase)
@@ -127,7 +134,7 @@ class LocalCompiler {
val testCase = currentTest.newInstance()
val setUpMethod = currentTest.getMethod("setUp")
val testMethod = currentTest.getMethod(ScriptGenerator.ScriptWrapper.TEST_METHOD_NAME)
Notifier.updateStatus("<long>Script running...")
Notifier.updateStatus("${Notifier.LONG_OPERATION_PREFIX}Script running...")
GuiRecorderComponent.setState(GuiRecorderComponent.States.RUNNING)
try {
setUpMethod.invoke(testCase)
@@ -159,7 +166,7 @@ class LocalCompiler {
val kotlinCompilerJar = getKotlinCompilerJar()
val libDirLocation = getApplicationLibDir().parentFile
Notifier.updateStatus("<long>Compiling...")
Notifier.updateStatus("${Notifier.LONG_OPERATION_PREFIX}Compiling...")
GuiRecorderComponent.setState(GuiRecorderComponent.States.COMPILING)
@@ -204,10 +211,10 @@ class LocalCompiler {
private fun getPluginKotlincDir(): File {
// if (ApplicationManager.getApplication().isUnitTestMode || (this.javaClass.classLoader.javaClass.name == "sun.misc.Launcher\$AppClassLoader")) {
val tempPath = PathManager.getTempPath()
val tempDirFile = File(tempPath)
FileUtil.ensureExists(tempDirFile)
return tempDirFile
val tempPath = PathManager.getTempPath()
val tempDirFile = File(tempPath)
FileUtil.ensureExists(tempDirFile)
return tempDirFile
// }
//
// val pluginId = (this.javaClass.classLoader as PluginClassLoader).pluginId
@@ -226,7 +233,7 @@ class LocalCompiler {
fun downloadKotlinCompilerJar(destDirPath: String?): File {
Notifier.updateStatus("<long>Downloading kotlin-compiler.jar...")
Notifier.updateStatus("${Notifier.LONG_OPERATION_PREFIX}Downloading kotlin-compiler.jar...")
val downloader = DownloadableFileService.getInstance()
val description = downloader.createFileDescription(kotlinCompilerJarUrl, kotlinCompilerJarName)
ApplicationManager.getApplication().invokeAndWait({
@@ -18,6 +18,7 @@ package com.intellij.testGuiFramework.recorder.components
import com.intellij.openapi.Disposable
import com.intellij.openapi.components.ApplicationComponent
import com.intellij.testGuiFramework.recorder.ui.GuiScriptEditorFrame
import java.util.concurrent.Future
/**
* @author Sergey Karashevich
@@ -33,6 +34,8 @@ object GuiRecorderComponent : ApplicationComponent, Disposable {
private var myFrame: GuiScriptEditorFrame? = null
private var currentTask: Future<*>? = null
override fun getComponentName() = "GuiRecorderComponent"
override fun disposeComponent() {
@@ -43,6 +46,12 @@ object GuiRecorderComponent : ApplicationComponent, Disposable {
}
fun setCurrentTask(task: Future<*>) { currentTask = task }
fun cancelCurrentTask() {
if (currentTask != null && !currentTask!!.isDone) currentTask!!.cancel(true)
}
fun getState() = myState
fun setState(yaState: States) {
@@ -16,7 +16,6 @@
package com.intellij.testGuiFramework.recorder.ui
import com.intellij.testGuiFramework.recorder.components.GuiRecorderComponent
import com.intellij.util.ui.EdtInvocationManager
import javax.swing.SwingUtilities
/**
@@ -24,21 +23,23 @@ import javax.swing.SwingUtilities
*/
object Notifier {
val LONG_OPERATION_PREFIX = "<long>"
fun updateStatus(statusMessage: String) {
if (GuiRecorderComponent.getFrame() == null) return
val guiScriptEditorPanel = GuiRecorderComponent.getFrame()!!.getGuiScriptEditorPanel()
val statusHandler: (String) -> Unit = { status ->
if (status.startsWith("<long>")) {
guiScriptEditorPanel.updateStatusWithProgress(status.substring(6))
if (status.startsWith(LONG_OPERATION_PREFIX)) {
guiScriptEditorPanel.updateStatusWithProgress(status.removePrefix(LONG_OPERATION_PREFIX))
}
else {
guiScriptEditorPanel.stopProgress()
guiScriptEditorPanel.updateStatus(status)
}
}
if (EdtInvocationManager.getInstance().isEventDispatchThread) statusHandler.invoke(statusMessage)
else SwingUtilities.invokeAndWait { statusHandler.invoke(statusMessage) }
SwingUtilities.invokeLater { statusHandler.invoke(statusMessage) }
}
}