/* * Copyright 2013-2016 consulo.io * * 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 consulo.unity3d.run.test; import java.util.UUID; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import com.intellij.execution.DefaultExecutionResult; import com.intellij.execution.ExecutionException; import com.intellij.execution.ExecutionResult; import com.intellij.execution.Executor; import com.intellij.execution.configurations.RunProfileState; import com.intellij.execution.process.ProcessAdapter; import com.intellij.execution.process.ProcessEvent; import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.process.ProcessOutputTypes; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.runners.ProgramRunner; import com.intellij.execution.testframework.TestConsoleProperties; import com.intellij.execution.testframework.sm.SMTestRunnerConnectionUtil; import com.intellij.execution.testframework.sm.runner.GeneralTestEventsProcessor; import com.intellij.execution.testframework.sm.runner.GeneralToSMTRunnerEventsConvertor; import com.intellij.execution.testframework.sm.runner.OutputToGeneralTestEventsConverter; import com.intellij.execution.testframework.sm.runner.SMTRunnerConsoleProperties; import com.intellij.execution.testframework.sm.runner.ui.AttachToProcessListener; import com.intellij.execution.testframework.sm.runner.ui.SMTRunnerConsoleView; import com.intellij.execution.testframework.sm.runner.ui.SMTRunnerUIActionsHandler; import com.intellij.execution.testframework.sm.runner.ui.SMTestRunnerResultsForm; import com.intellij.execution.testframework.sm.runner.ui.statistics.StatisticsPanel; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Ref; import com.intellij.xdebugger.DefaultDebugProcessHandler; import consulo.annotations.RequiredDispatchThread; import consulo.unity3d.editor.UnityEditorCommunication; import consulo.unity3d.editor.UnityRunTest; /** * @author VISTALL * @since 18.01.2016 */ public class Unity3dTestRunState implements RunProfileState { private static final String TEST_FRAMEWORK_NAME = "Unity Test"; private final ExecutionEnvironment myEnvironment; public Unity3dTestRunState(ExecutionEnvironment environment) { myEnvironment = environment; } @Nullable @Override @RequiredDispatchThread public ExecutionResult execute(Executor executor, @NotNull ProgramRunner runner) throws ExecutionException { Unity3dTestConfiguration profile = (Unity3dTestConfiguration) myEnvironment.getRunProfile(); TestConsoleProperties testConsoleProperties = new SMTRunnerConsoleProperties(profile, TEST_FRAMEWORK_NAME, executor); testConsoleProperties.setIfUndefined(TestConsoleProperties.HIDE_PASSED_TESTS, false); String splitterPropertyName = SMTestRunnerConnectionUtil.getSplitterPropertyName(TEST_FRAMEWORK_NAME); final SMTRunnerConsoleView consoleView = new SMTRunnerConsoleView(testConsoleProperties, splitterPropertyName); final Ref<UUID> ref = Ref.create(); consoleView.addAttachToProcessListener(new AttachToProcessListener() { @Override public void onAttachToProcess(@NotNull ProcessHandler processHandler) { SMTestRunnerResultsForm resultsForm = consoleView.getResultsViewer(); ref.set(attachEventsProcessors(consoleView.getProperties(), resultsForm, resultsForm.getStatisticsPane(), processHandler, TEST_FRAMEWORK_NAME)); } }); consoleView.setHelpId("reference.runToolWindow.testResultsTab"); consoleView.initUI(); final ProcessHandler osProcessHandler = new DefaultDebugProcessHandler(); consoleView.attachToProcess(osProcessHandler); UnityRunTest runTest = new UnityRunTest(); runTest.uuid = ref.get().toString(); runTest.type = ""; if(!UnityEditorCommunication.request(profile.getProject(), runTest, true)) { ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { @Override public void run() { osProcessHandler.notifyTextAvailable("UnityEditor dont received request, maybe is not run", ProcessOutputTypes.STDERR); osProcessHandler.destroyProcess(); } }); } return new DefaultExecutionResult(consoleView, osProcessHandler); } private static UUID attachEventsProcessors(@NotNull final TestConsoleProperties consoleProperties, final SMTestRunnerResultsForm resultsViewer, final StatisticsPanel statisticsPane, final ProcessHandler processHandler, @NotNull final String testFrameworkName) { //build messages consumer final OutputToGeneralTestEventsConverter outputConsumer; outputConsumer = new OutputToGeneralTestEventsConverter(testFrameworkName, consoleProperties); //events processor final GeneralTestEventsProcessor eventsProcessor = new GeneralToSMTRunnerEventsConvertor(consoleProperties.getProject(), resultsViewer.getTestsRootNode(), testFrameworkName); final UUID uuid = Unity3dTestSessionManager.getInstance().newSession(processHandler, eventsProcessor); // ui actions final SMTRunnerUIActionsHandler uiActionsHandler = new SMTRunnerUIActionsHandler(consoleProperties); // subscribes event processor on output consumer events outputConsumer.setProcessor(eventsProcessor); // subscribes result viewer on event processor eventsProcessor.addEventsListener(resultsViewer); // subscribes test runner's actions on results viewer events resultsViewer.addEventsListener(uiActionsHandler); // subscribes statistics tab viewer on event processor eventsProcessor.addEventsListener(statisticsPane.createTestEventsListener()); processHandler.addProcessListener(new ProcessAdapter() { @Override public void processTerminated(final ProcessEvent event) { outputConsumer.flushBufferBeforeTerminating(); eventsProcessor.onFinishTesting(); Unity3dTestSessionManager.getInstance().disposeSession(uuid); Disposer.dispose(eventsProcessor); Disposer.dispose(outputConsumer); } @Override public void onTextAvailable(final ProcessEvent event, final Key outputType) { outputConsumer.process(event.getText(), outputType); } }); return uuid; } }