[groovy] tests: move helper methods to traits, compile static
authorDaniil Ovchinnikov <daniil.ovchinnikov@jetbrains.com>
Sat, 18 Jun 2016 18:08:16 +0000 (21:08 +0300)
committerDaniil Ovchinnikov <daniil.ovchinnikov@jetbrains.com>
Sat, 18 Jun 2016 18:18:18 +0000 (21:18 +0300)
plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/CompilerMethods.groovy [new file with mode: 0644]
plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/DebuggerMethods.groovy [new file with mode: 0644]
plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTest.groovy
plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTestCase.groovy [moved from plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTestCase.java with 64% similarity]
plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyDebuggerTest.groovy

diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/CompilerMethods.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/CompilerMethods.groovy
new file mode 100644 (file)
index 0000000..401b920
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2000-2016 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.groovy.compiler
+
+import com.intellij.execution.ExecutionException
+import com.intellij.execution.Executor
+import com.intellij.execution.configurations.RunProfile
+import com.intellij.execution.process.ProcessHandler
+import com.intellij.execution.process.ProcessListener
+import com.intellij.execution.runners.ExecutionEnvironment
+import com.intellij.execution.runners.ExecutionEnvironmentBuilder
+import com.intellij.execution.runners.ProgramRunner
+import com.intellij.execution.ui.RunContentDescriptor
+import com.intellij.openapi.Disposable
+import com.intellij.openapi.project.Project
+import com.intellij.openapi.util.Disposer
+import com.intellij.util.concurrency.Semaphore
+import groovy.transform.CompileStatic
+
+import java.util.concurrent.atomic.AtomicReference
+
+@CompileStatic
+trait CompilerMethods {
+
+  abstract Project getProject()
+
+  abstract <T extends Disposable> T disposeOnTearDown(T disposable)
+
+  ProcessHandler runConfiguration(Class<? extends Executor> executorClass,
+                                  final ProcessListener listener,
+                                  ProgramRunner runner,
+                                  RunProfile configuration) throws ExecutionException {
+    final Executor executor = Executor.EXECUTOR_EXTENSION_NAME.findExtension(executorClass);
+    final ExecutionEnvironment environment = new ExecutionEnvironmentBuilder(getProject(), executor).runProfile(configuration).build();
+    final Semaphore semaphore = new Semaphore();
+    semaphore.down();
+
+    final AtomicReference<ProcessHandler> processHandler = new AtomicReference<ProcessHandler>();
+    runner.execute(environment, { RunContentDescriptor descriptor ->
+      if (descriptor == null) {
+        throw new AssertionError((Object)"Null descriptor!");
+      }
+      disposeOnTearDown({ Disposer.dispose(descriptor) } as Disposable);
+      final ProcessHandler handler = descriptor.getProcessHandler();
+      assert handler != null;
+      handler.addProcessListener(listener);
+      processHandler.set(handler);
+      semaphore.up();
+    });
+    if (!semaphore.waitFor(20000)) {
+      throw new AssertionError((Object)"Process took too long")
+    }
+    return processHandler.get();
+  }
+}
\ No newline at end of file
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/DebuggerMethods.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/DebuggerMethods.groovy
new file mode 100644 (file)
index 0000000..9854aa3
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * Copyright 2000-2016 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.groovy.compiler
+
+import com.intellij.debugger.DebuggerManagerEx
+import com.intellij.debugger.SourcePosition
+import com.intellij.debugger.engine.ContextUtil
+import com.intellij.debugger.engine.DebugProcessImpl
+import com.intellij.debugger.engine.DebuggerUtils
+import com.intellij.debugger.engine.SuspendContextImpl
+import com.intellij.debugger.engine.evaluation.CodeFragmentKind
+import com.intellij.debugger.engine.evaluation.EvaluateException
+import com.intellij.debugger.engine.evaluation.EvaluationContextImpl
+import com.intellij.debugger.engine.evaluation.TextWithImportsImpl
+import com.intellij.debugger.engine.events.DebuggerContextCommandImpl
+import com.intellij.debugger.impl.*
+import com.intellij.debugger.ui.impl.watch.WatchItemDescriptor
+import com.intellij.debugger.ui.tree.render.DescriptorLabelListener
+import com.intellij.execution.configurations.RunProfile
+import com.intellij.execution.executors.DefaultDebugExecutor
+import com.intellij.execution.process.*
+import com.intellij.execution.runners.ProgramRunner
+import com.intellij.openapi.application.ApplicationManager
+import com.intellij.openapi.diagnostic.Logger
+import com.intellij.openapi.fileEditor.FileDocumentManager
+import com.intellij.openapi.fileTypes.FileType
+import com.intellij.openapi.util.Computable
+import com.intellij.openapi.vfs.VirtualFile
+import com.intellij.psi.impl.DebugUtil
+import com.intellij.util.ExceptionUtil
+import com.intellij.util.concurrency.Semaphore
+import groovy.transform.CompileStatic
+import org.jetbrains.annotations.NotNull
+
+import static com.intellij.testFramework.UsefulTestCase.edt
+
+@CompileStatic
+trait DebuggerMethods extends CompilerMethods {
+
+  private static final int ourTimeout = 60000
+
+  abstract Logger getLogger()
+
+  DebugProcessImpl getDebugProcess() {
+    debugSession?.process
+  }
+
+  DebuggerSession getDebugSession() {
+    DebuggerManagerEx.getInstanceEx(project).context.debuggerSession
+  }
+
+  void runDebugger(RunProfile configuration, Closure cl) {
+    edt {
+      ProgramRunner runner = ProgramRunner.PROGRAM_RUNNER_EP.extensions.find { it.class == GenericDebuggerRunner }
+      def listener = [onTextAvailable: { ProcessEvent evt, type ->
+        if (type == ProcessOutputTypes.STDERR) {
+          println evt.text
+        }
+      }] as ProcessAdapter
+      runConfiguration(DefaultDebugExecutor, listener, runner, configuration);
+    }
+    logger.debug("after start")
+    try {
+      cl.call()
+    }
+    catch (Throwable t) {
+      t.printStackTrace()
+      throw t
+    }
+    finally {
+      def handler = debugProcess.processHandler
+      resume()
+      if (!handler.waitFor(ourTimeout)) {
+        if (handler instanceof OSProcessHandler) {
+          OSProcessManager.instance.killProcessTree((handler as OSProcessHandler).process)
+        }
+        else {
+          println "can't terminate $handler"
+        }
+        throw new AssertionError((Object)'too long waiting for process termination')
+      }
+    }
+  }
+
+  void addBreakpoint(VirtualFile file, int line) {
+    edt {
+      DebuggerManagerImpl.getInstanceEx(project).breakpointManager.addLineBreakpoint(FileDocumentManager.instance.getDocument(file), line)
+    }
+  }
+
+  SuspendContextImpl waitForBreakpoint() {
+    logger.debug("waitForBreakpoint")
+    Semaphore semaphore = new Semaphore()
+    semaphore.down()
+    def process = debugProcess
+    // wait for all events processed
+    process.managerThread.schedule {
+      semaphore.up()
+    }
+    def finished = semaphore.waitFor(ourTimeout);
+    assert finished: 'Too long debugger actions'
+
+    int i = 0
+    def suspendManager = process.suspendManager
+    while (i++ < ourTimeout / 10 && !suspendManager.pausedContext && !process.processHandler.processTerminated) {
+      Thread.sleep(10)
+    }
+
+    def context = suspendManager.pausedContext
+    assert context: "too long process, terminated=${process.processHandler.processTerminated}"
+    return context
+  }
+
+  void resume() {
+    if (debugSession == null) return
+    debugProcess.managerThread.invoke(debugProcess.createResumeCommand(debugProcess.suspendManager.pausedContext))
+  }
+
+  SourcePosition getSourcePosition() {
+    managed {
+      EvaluationContextImpl context = evaluationContext()
+      def a = { ContextUtil.getSourcePosition(context) } as Computable<SourcePosition>
+      ApplicationManager.getApplication().runReadAction(a)
+    }
+  }
+
+  EvaluationContextImpl evaluationContext() {
+    final SuspendContextImpl suspendContext = debugProcess.suspendManager.pausedContext
+    new EvaluationContextImpl(suspendContext, suspendContext.frameProxy, suspendContext.frameProxy.thisObject())
+  }
+
+  void eval(final String codeText, String expected) throws EvaluateException {
+    eval(codeText, expected, null);
+  }
+
+  void eval(final String codeText, String expected, FileType fileType) throws EvaluateException {
+    Semaphore semaphore = new Semaphore()
+    semaphore.down()
+
+    EvaluationContextImpl ctx
+    def item = new WatchItemDescriptor(project, new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, codeText, "", fileType))
+    managed {
+      ctx = evaluationContext()
+      item.setContext(ctx)
+      item.updateRepresentation(ctx, {} as DescriptorLabelListener)
+      semaphore.up()
+    }
+    assert semaphore.waitFor(ourTimeout): "too long evaluation: $item.label $item.evaluateException"
+
+    String result = managed {
+      def e = item.evaluateException
+      if (e) {
+        return ExceptionUtil.getThrowableText(e)
+      }
+      return DebuggerUtils.getValueAsString(ctx, item.value)
+    }
+    assert result == expected
+  }
+
+  def <T> T managed(Closure<T> cl) {
+    def ctx = DebuggerContextUtil.createDebuggerContext(debugSession, debugProcess.suspendManager.pausedContext)
+    def command = new ManagedCommand<T>(ctx, cl)
+    debugProcess.managerThread.invoke(command)
+    def finished = command.semaphore.waitFor(ourTimeout)
+    assert finished: 'Too long debugger action'
+    return command.result
+  }
+
+  private static class ManagedCommand<T> extends DebuggerContextCommandImpl {
+
+    private final Semaphore mySemaphore
+    private final Closure<T> myAction
+    private T myResult
+
+    ManagedCommand(@NotNull DebuggerContextImpl debuggerContext, Closure<T> action) {
+      super(debuggerContext)
+      mySemaphore = new Semaphore()
+      mySemaphore.down()
+      myAction = action
+    }
+
+    Semaphore getSemaphore() {
+      mySemaphore
+    }
+
+    T getResult() {
+      myResult
+    }
+
+    @Override
+    void threadAction() {
+      try {
+        myResult = myAction()
+      }
+      finally {
+        mySemaphore.up()
+      }
+    }
+
+    @Override
+    protected void commandCancelled() {
+      println DebugUtil.currentStackTrace()
+    }
+  }
+}
\ No newline at end of file
index 0c4e689dcb8042bc4c6f514fb46b529a659a212b..64d574599e80f215bbc3abde4d05d1f15578ad09 100644 (file)
@@ -43,12 +43,14 @@ import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess
 import com.intellij.psi.PsiFile
 import com.intellij.testFramework.PsiTestUtil
 import com.intellij.testFramework.TestLoggerFactory
+import groovy.transform.CompileStatic
 import org.jetbrains.annotations.NotNull
 import org.jetbrains.plugins.groovy.config.GroovyFacetUtil
 import org.jetbrains.plugins.groovy.lang.psi.GroovyFile
 /**
  * @author peter
  */
+@CompileStatic
 public abstract class GroovyCompilerTest extends GroovyCompilerTestCase {
   @Override protected void setUp() {
     super.setUp();
@@ -96,8 +98,8 @@ public abstract class GroovyCompilerTest extends GroovyCompilerTestCase {
     assertOutput("Foo", "239");
   }
 
-  protected static void shouldFail(Closure action) {
-    List<CompilerMessage> messages = action()
+  protected static void shouldFail(Closure<List<CompilerMessage>> action) {
+    def messages = action()
     assert messages.find { it.category == CompilerMessageCategory.ERROR }
   }
 
similarity index 64%
rename from plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTestCase.java
rename to plugins/groovy/test/org/jetbrains/plugins/groovy/compiler/GroovyCompilerTestCase.groovy
index 575620a505ffd98566e43c9bd3c9b7c581414bb1..808a8c5ebbe2070238a65d0eb1fa47f162a1f186 100644 (file)
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.jetbrains.plugins.groovy.compiler;
-
-import com.intellij.compiler.server.BuildManager;
-import com.intellij.execution.ExecutionException;
-import com.intellij.execution.Executor;
-import com.intellij.execution.application.ApplicationConfiguration;
-import com.intellij.execution.application.ApplicationConfigurationType;
-import com.intellij.execution.configurations.RunProfile;
-import com.intellij.execution.executors.DefaultRunExecutor;
-import com.intellij.execution.impl.DefaultJavaProgramRunner;
-import com.intellij.execution.process.*;
-import com.intellij.execution.runners.ExecutionEnvironment;
-import com.intellij.execution.runners.ExecutionEnvironmentBuilder;
-import com.intellij.execution.runners.ProgramRunner;
-import com.intellij.execution.ui.RunContentDescriptor;
-import com.intellij.openapi.Disposable;
-import com.intellij.openapi.application.Result;
-import com.intellij.openapi.command.WriteCommandAction;
-import com.intellij.openapi.compiler.CompilerMessage;
-import com.intellij.openapi.module.ModifiableModuleModel;
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.module.ModuleManager;
-import com.intellij.openapi.module.StdModuleTypes;
-import com.intellij.openapi.roots.*;
-import com.intellij.openapi.util.Disposer;
-import com.intellij.openapi.util.Key;
-import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.pom.java.LanguageLevel;
-import com.intellij.psi.PsiFile;
-import com.intellij.testFramework.CompilerTester;
-import com.intellij.testFramework.IdeaTestUtil;
-import com.intellij.testFramework.PlatformTestUtil;
-import com.intellij.testFramework.PsiTestUtil;
-import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
-import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
-import com.intellij.util.concurrency.Semaphore;
-import com.intellij.util.ui.UIUtil;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.plugins.groovy.config.GroovyFacetUtil;
-import org.jetbrains.plugins.groovy.runner.GroovyScriptRunConfiguration;
-import org.jetbrains.plugins.groovy.runner.GroovyScriptRunConfigurationType;
-import org.jetbrains.plugins.groovy.util.Slow;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicReference;
+package org.jetbrains.plugins.groovy.compiler
+
+import com.intellij.compiler.server.BuildManager
+import com.intellij.execution.ExecutionException
+import com.intellij.execution.Executor
+import com.intellij.execution.application.ApplicationConfiguration
+import com.intellij.execution.application.ApplicationConfigurationType
+import com.intellij.execution.executors.DefaultRunExecutor
+import com.intellij.execution.impl.DefaultJavaProgramRunner
+import com.intellij.execution.process.*
+import com.intellij.execution.runners.ProgramRunner
+import com.intellij.openapi.Disposable
+import com.intellij.openapi.application.Result
+import com.intellij.openapi.command.WriteCommandAction
+import com.intellij.openapi.compiler.CompilerMessage
+import com.intellij.openapi.module.ModifiableModuleModel
+import com.intellij.openapi.module.Module
+import com.intellij.openapi.module.ModuleManager
+import com.intellij.openapi.module.StdModuleTypes
+import com.intellij.openapi.project.Project
+import com.intellij.openapi.roots.*
+import com.intellij.openapi.util.Key
+import com.intellij.openapi.util.io.FileUtil
+import com.intellij.openapi.util.text.StringUtil
+import com.intellij.openapi.vfs.VirtualFile
+import com.intellij.pom.java.LanguageLevel
+import com.intellij.psi.PsiFile
+import com.intellij.testFramework.CompilerTester
+import com.intellij.testFramework.IdeaTestUtil
+import com.intellij.testFramework.PlatformTestUtil
+import com.intellij.testFramework.PsiTestUtil
+import com.intellij.testFramework.builders.JavaModuleFixtureBuilder
+import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase
+import com.intellij.util.ui.UIUtil
+import groovy.transform.CompileStatic
+import org.jetbrains.annotations.NotNull
+import org.jetbrains.annotations.Nullable
+import org.jetbrains.plugins.groovy.config.GroovyFacetUtil
+import org.jetbrains.plugins.groovy.runner.GroovyScriptRunConfiguration
+import org.jetbrains.plugins.groovy.runner.GroovyScriptRunConfigurationType
+import org.jetbrains.plugins.groovy.util.Slow
 
 /**
  * @author aalmiray
  * @author peter
  */
 @Slow
-public abstract class GroovyCompilerTestCase extends JavaCodeInsightFixtureTestCase {
-  @SuppressWarnings("AbstractMethodCallInConstructor") private CompilerTester myCompilerTester;
+@CompileStatic
+public abstract class GroovyCompilerTestCase extends JavaCodeInsightFixtureTestCase implements CompilerMethods {
+
+  protected CompilerTester myCompilerTester;
+
+  @Override
+  Project getProject() {
+    return super.getProject();
+  }
+
+  @Override
+  <T extends Disposable> T disposeOnTearDown(T disposable) {
+    return super.disposeOnTearDown(disposable)
+  }
 
   @Override
   protected void setUp() throws Exception {
@@ -101,26 +104,18 @@ public abstract class GroovyCompilerTestCase extends JavaCodeInsightFixtureTestC
   protected void tearDown() throws Exception {
     final File systemRoot = BuildManager.getInstance().getBuildSystemDirectory();
     try {
-      UIUtil.invokeAndWaitIfNeeded(new Runnable() {
-        @Override
-        public void run() {
-          try {
-            myCompilerTester.tearDown();
-            myCompilerTester = null;
-          }
-          catch (Exception e) {
-            throw new RuntimeException(e);
-          }
-          finally {
-            try {
-              GroovyCompilerTestCase.super.tearDown();
-            }
-            catch (Exception e) {
-              throw new RuntimeException(e);
-            }
-          }
+      UIUtil.invokeAndWaitIfNeeded {
+        try {
+          myCompilerTester.tearDown();
+          myCompilerTester = null;
+        }
+        catch (Exception e) {
+          throw new RuntimeException(e);
+        }
+        finally {
+          super.tearDown();
         }
-      });
+      }
     }
     finally {
       FileUtil.delete(systemRoot);
@@ -240,41 +235,6 @@ public abstract class GroovyCompilerTestCase extends JavaCodeInsightFixtureTestC
     return runConfiguration(executorClass, listener, runner, configuration);
   }
 
-  protected ProcessHandler runConfiguration(Class<? extends Executor> executorClass,
-                                          final ProcessListener listener,
-                                          ProgramRunner runner,
-                                          RunProfile configuration) throws ExecutionException {
-    final Executor executor = Executor.EXECUTOR_EXTENSION_NAME.findExtension(executorClass);
-    final ExecutionEnvironment environment = new ExecutionEnvironmentBuilder(getProject(), executor).runProfile(configuration).build();
-    final Semaphore semaphore = new Semaphore();
-    semaphore.down();
-
-    final AtomicReference<ProcessHandler> processHandler = new AtomicReference<ProcessHandler>();
-    runner.execute(environment, new ProgramRunner.Callback() {
-      @Override
-      public void processStarted(final RunContentDescriptor descriptor) {
-        if (descriptor == null) {
-          throw new AssertionError("Null descriptor!");
-        }
-        disposeOnTearDown(new Disposable() {
-          @Override
-          public void dispose() {
-            Disposer.dispose(descriptor);
-          }
-        });
-        final ProcessHandler handler = descriptor.getProcessHandler();
-        assert handler != null;
-        handler.addProcessListener(listener);
-        processHandler.set(handler);
-        semaphore.up();
-      }
-    });
-    if (!semaphore.waitFor(20000)) {
-      fail("Process took too long");
-    }
-    return processHandler.get();
-  }
-
   protected ApplicationConfiguration createApplicationConfiguration(String className, Module module) {
     final ApplicationConfiguration configuration =
       new ApplicationConfiguration("app", getProject(), ApplicationConfigurationType.getInstance());
@@ -290,5 +250,4 @@ public abstract class GroovyCompilerTestCase extends JavaCodeInsightFixtureTestC
     configuration.setScriptPath(scriptPath);
     return configuration;
   }
-
 }
index a626876c72c419a9af78fd202205049f92ad1231..c5c0ef00bcfec130436436796b944024b2ef4f5c 100644 (file)
  * limitations under the License.
  */
 package org.jetbrains.plugins.groovy.compiler
-import com.intellij.debugger.DebuggerManagerEx
-import com.intellij.debugger.SourcePosition
-import com.intellij.debugger.engine.ContextUtil
-import com.intellij.debugger.engine.DebugProcessImpl
-import com.intellij.debugger.engine.DebuggerUtils
-import com.intellij.debugger.engine.SuspendContextImpl
-import com.intellij.debugger.engine.evaluation.CodeFragmentKind
-import com.intellij.debugger.engine.evaluation.EvaluateException
-import com.intellij.debugger.engine.evaluation.EvaluationContextImpl
-import com.intellij.debugger.engine.evaluation.TextWithImportsImpl
-import com.intellij.debugger.engine.events.DebuggerCommandImpl
-import com.intellij.debugger.engine.events.DebuggerContextCommandImpl
-import com.intellij.debugger.impl.DebuggerContextUtil
-import com.intellij.debugger.impl.DebuggerManagerImpl
-import com.intellij.debugger.impl.DebuggerSession
-import com.intellij.debugger.impl.GenericDebuggerRunner
-import com.intellij.debugger.ui.impl.watch.WatchItemDescriptor
-import com.intellij.debugger.ui.tree.render.DescriptorLabelListener
-import com.intellij.execution.executors.DefaultDebugExecutor
-import com.intellij.execution.process.*
-import com.intellij.execution.runners.ProgramRunner
+
 import com.intellij.openapi.Disposable
-import com.intellij.openapi.application.ApplicationManager
 import com.intellij.openapi.diagnostic.Logger
-import com.intellij.openapi.fileEditor.FileDocumentManager
-import com.intellij.openapi.fileTypes.FileType
 import com.intellij.openapi.roots.ModuleRootModificationUtil
-import com.intellij.openapi.util.Computable
 import com.intellij.openapi.util.io.FileUtil
 import com.intellij.openapi.util.text.StringUtil
 import com.intellij.openapi.vfs.VirtualFile
 import com.intellij.psi.JavaPsiFacade
 import com.intellij.psi.PsiFile
-import com.intellij.psi.impl.DebugUtil
 import com.intellij.psi.search.GlobalSearchScope
 import com.intellij.testFramework.PsiTestUtil
 import com.intellij.testFramework.TestLoggerFactory
 import com.intellij.testFramework.builders.JavaModuleFixtureBuilder
 import com.intellij.testFramework.fixtures.impl.TempDirTestFixtureImpl
-import com.intellij.util.ExceptionUtil
 import com.intellij.util.SystemProperties
-import com.intellij.util.concurrency.Semaphore
+import groovy.transform.CompileStatic
 import org.jetbrains.plugins.groovy.GroovyFileType
 
 /**
  * @author peter
  */
-class GroovyDebuggerTest extends GroovyCompilerTestCase {
+@CompileStatic
+class GroovyDebuggerTest extends GroovyCompilerTestCase implements DebuggerMethods {
   private static final Logger LOG = Logger.getInstance("#org.jetbrains.plugins.groovy.compiler.GroovyDebuggerTest");
-  private static final int ourTimeout = 60000
+
+  @Override
+  Logger getLogger() { LOG }
 
   @Override
   protected void setUp() {
@@ -112,37 +89,9 @@ class GroovyDebuggerTest extends GroovyCompilerTestCase {
     moduleBuilder.addJdk(StringUtil.trimEnd(StringUtil.trimEnd(javaHome, '/'), '/jre'))
   }
 
-  private void runDebugger(PsiFile script, Closure cl) {
+  void runDebugger(PsiFile script, Closure cl) {
     def configuration = createScriptConfiguration(script.virtualFile.path, myModule)
-    edt {
-      ProgramRunner runner = ProgramRunner.PROGRAM_RUNNER_EP.extensions.find { it.class == GenericDebuggerRunner }
-      def listener = [onTextAvailable: { ProcessEvent evt, type ->
-        if (type == ProcessOutputTypes.STDERR)
-          println evt.text
-      }] as ProcessAdapter
-      runConfiguration(DefaultDebugExecutor, listener, runner, configuration);
-    }
-    LOG.debug("after start")
-    try {
-      cl.call()
-    }
-    catch (Throwable t) {
-      t.printStackTrace()
-      throw t
-    }
-    finally {
-      def handler = debugProcess.processHandler
-      resume()
-      if (!handler.waitFor(ourTimeout)) {
-        if (handler instanceof OSProcessHandler) {
-          OSProcessManager.instance.killProcessTree(handler.process)
-        }
-        else {
-          println "can't terminate $handler"
-        }
-        fail('too long waiting for process termination')
-      }
-    }
+    runDebugger(configuration, cl)
   }
 
   public void testVariableInScript() {
@@ -351,14 +300,6 @@ int b = 3 //1
     }
   }
 
-  private SourcePosition getSourcePosition() {
-    managed {
-      EvaluationContextImpl context = evaluationContext()
-      Computable<SourcePosition> a = { ContextUtil.getSourcePosition(context) } as Computable<SourcePosition>
-      return ApplicationManager.getApplication().runReadAction(a)
-    }
-  }
-
   void testAnonymousClassInScript() {
     def file = myFixture.addFileToProject('Foo.groovy', '''\
 new Runnable() {
@@ -391,6 +332,7 @@ foo()
       eval 'x', '5'
     }
   }
+
   void "test non-identifier script name"() {
     def file = myFixture.addFileToProject('foo-bar.groovy', '''\
 int x = 1
@@ -576,115 +518,11 @@ public class Main {
     }
   }
 
-  private def addBreakpoint(String fileName, int line) {
+  void addBreakpoint(String fileName, int line) {
     VirtualFile file = null
     edt {
       file = myFixture.tempDirFixture.getFile(fileName)
     }
     addBreakpoint(file, line)
   }
-
-  private def addBreakpoint(VirtualFile file, int line) {
-    edt {
-      DebuggerManagerImpl.getInstanceEx(project).breakpointManager.addLineBreakpoint(FileDocumentManager.instance.getDocument(file), line)
-    }
-  }
-
-  private def resume() {
-    if (debugSession == null) return
-    debugProcess.managerThread.invoke(debugProcess.createResumeCommand(debugProcess.suspendManager.pausedContext))
-  }
-
-  private SuspendContextImpl waitForBreakpoint() {
-    LOG.debug("waitForBreakpoint")
-    Semaphore semaphore = new Semaphore()
-    semaphore.down()
-    def process = debugProcess
-    // wait for all events processed
-    process.managerThread.schedule(new DebuggerCommandImpl() {
-      @Override
-      protected void action() throws Exception {
-        semaphore.up();
-      }
-    });
-    def finished = semaphore.waitFor(ourTimeout);
-    assert finished: 'Too long debugger actions'
-
-    int i = 0
-    def suspendManager = process.suspendManager
-    while (i++ < ourTimeout / 10 && !suspendManager.pausedContext && !process.processHandler.processTerminated) {
-      Thread.sleep(10)
-    }
-
-    def context = suspendManager.pausedContext
-    assert context: "too long process, terminated=${process.processHandler.processTerminated}"
-    return context
-  }
-
-  private DebugProcessImpl getDebugProcess() {
-    return debugSession?.process
-  }
-
-  private DebuggerSession getDebugSession() {
-    return DebuggerManagerEx.getInstanceEx(project).getContext().debuggerSession
-  }
-
-  private <T> T managed(Closure cl) {
-    def result = null
-    def ctx = DebuggerContextUtil.createDebuggerContext(debugSession, debugProcess.suspendManager.pausedContext)
-    Semaphore semaphore = new Semaphore()
-    semaphore.down()
-    debugProcess.managerThread.invoke(new DebuggerContextCommandImpl(ctx) {
-      @Override
-      void threadAction() {
-        try {
-          result = cl()
-        }
-        finally {
-          semaphore.up()
-        }
-      }
-
-      @Override
-      protected void commandCancelled() {
-        println DebugUtil.currentStackTrace()
-      }
-    })
-    def finished = semaphore.waitFor(ourTimeout)
-    assert finished: 'Too long debugger action'
-    return result
-  }
-
-  private void eval(final String codeText, String expected) throws EvaluateException {
-    eval(codeText, expected, null);
-  }
-
-  private void eval(final String codeText, String expected, FileType fileType) throws EvaluateException {
-    Semaphore semaphore = new Semaphore()
-    semaphore.down()
-
-    EvaluationContextImpl ctx
-    def item = new WatchItemDescriptor(project, new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, codeText, "", fileType))
-    managed {
-      ctx = evaluationContext()
-      item.setContext(ctx)
-      item.updateRepresentation(ctx, {} as DescriptorLabelListener)
-      semaphore.up()
-    }
-    assert semaphore.waitFor(ourTimeout): "too long evaluation: $item.label $item.evaluateException"
-
-    String result = managed {
-      def e = item.evaluateException
-      if (e) {
-        return ExceptionUtil.getThrowableText(e)
-      }
-      return DebuggerUtils.getValueAsString(ctx, item.value)
-    }
-    assert result == expected
-  }
-
-  private EvaluationContextImpl evaluationContext() {
-    final SuspendContextImpl suspendContext = debugProcess.suspendManager.pausedContext
-    new EvaluationContextImpl(suspendContext, suspendContext.frameProxy, suspendContext.frameProxy.thisObject())
-  }
 }