/* * Copyright 2013-2016 Sergey Ignatov, Alexander Zolotov, Florin Patan * * 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 com.goide.runconfig.testing; import com.goide.runconfig.GoModuleBasedConfiguration; import com.goide.runconfig.GoRunConfigurationBase; import com.goide.runconfig.testing.frameworks.gotest.GotestFramework; import com.goide.runconfig.testing.ui.GoTestRunConfigurationEditorForm; import com.goide.sdk.GoPackageUtil; import com.intellij.execution.configurations.*; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.testframework.TestConsoleProperties; import com.intellij.execution.testframework.sm.runner.OutputToGeneralTestEventsConverter; import com.intellij.openapi.module.Module; import com.intellij.openapi.options.SettingsEditor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.JDOMExternalizerUtil; import com.intellij.openapi.util.WriteExternalException; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import org.jdom.Element; import org.jetbrains.annotations.NotNull; public class GoTestRunConfiguration extends GoRunConfigurationBase<GoTestRunningState> { private static final String PATTERN_ATTRIBUTE_NAME = "pattern"; private static final String FILE_PATH_ATTRIBUTE_NAME = "filePath"; private static final String DIRECTORY_ATTRIBUTE_NAME = "directory"; private static final String PACKAGE_ATTRIBUTE_NAME = "package"; private static final String KIND_ATTRIBUTE_NAME = "kind"; private static final String FRAMEWORK_ATTRIBUTE_NAME = "framework"; @NotNull private String myPackage = ""; @NotNull private String myFilePath = ""; @NotNull private String myDirectoryPath = ""; @NotNull private String myPattern = ""; @NotNull private Kind myKind = Kind.DIRECTORY; private GoTestFramework myTestFramework = GotestFramework.INSTANCE; public GoTestRunConfiguration(@NotNull Project project, String name, @NotNull ConfigurationType configurationType) { super(name, new GoModuleBasedConfiguration(project), configurationType.getConfigurationFactories()[0]); } public OutputToGeneralTestEventsConverter createTestEventsConverter(@NotNull TestConsoleProperties consoleProperties) { return myTestFramework.createTestEventsConverter(consoleProperties); } @NotNull @Override protected GoTestRunningState newRunningState(ExecutionEnvironment env, Module module) { return myTestFramework.newRunningState(env, module, this); } @Override protected ModuleBasedConfiguration createInstance() { return new GoTestRunConfiguration(getProject(), getName(), GoTestRunConfigurationType.getInstance()); } @NotNull @Override public SettingsEditor<? extends RunConfiguration> getConfigurationEditor() { return new GoTestRunConfigurationEditorForm(getProject()); } @Override public void checkConfiguration() throws RuntimeConfigurationException { super.checkConfiguration(); GoModuleBasedConfiguration configurationModule = getConfigurationModule(); if (!myTestFramework.isAvailable(configurationModule.getModule())) { throw new RuntimeConfigurationError("Framework `" + myTestFramework.getName() + "` is not available in selected module"); } switch (myKind) { case DIRECTORY: String directoryPath = FileUtil.isAbsolutePlatformIndependent(myDirectoryPath) ? myDirectoryPath : FileUtil.join(getWorkingDirectory(), myDirectoryPath); if (!FileUtil.isAncestor(getWorkingDirectory(), directoryPath, false)) { throw new RuntimeConfigurationError("Working directory should be ancestor of testing directory"); } VirtualFile testingDirectory = LocalFileSystem.getInstance().findFileByPath(directoryPath); if (testingDirectory == null) { throw new RuntimeConfigurationError("Testing directory doesn't exist"); } break; case PACKAGE: Module module = configurationModule.getModule(); assert module != null; VirtualFile packageDirectory = GoPackageUtil.findByImportPath(myPackage, module.getProject(), module); if (packageDirectory == null || !packageDirectory.isDirectory()) { throw new RuntimeConfigurationError("Cannot find package '" + myPackage + "'"); } for (VirtualFile file : packageDirectory.getChildren()) { PsiFile psiFile = PsiManager.getInstance(getProject()).findFile(file); if (psiFile != null && myTestFramework.isAvailableOnFile(psiFile)) { return; } } String message = "Cannot find Go test files in '" + myPackage + "' compatible with `" + myTestFramework.getName() + "` framework"; throw new RuntimeConfigurationError(message); case FILE: VirtualFile virtualFile = findFile(getFilePath()); if (virtualFile == null) { throw new RuntimeConfigurationError("Test file doesn't exist"); } PsiFile file = PsiManager.getInstance(getProject()).findFile(virtualFile); if (file == null || !myTestFramework.isAvailableOnFile(file)) { message = "Framework `" + myTestFramework.getName() + "` is not available on file `" + myFilePath + "`"; throw new RuntimeConfigurationError(message); } break; } } @Override public void writeExternal(Element element) throws WriteExternalException { super.writeExternal(element); JDOMExternalizerUtil.addElementWithValueAttribute(element, FRAMEWORK_ATTRIBUTE_NAME, myTestFramework.getName()); JDOMExternalizerUtil.addElementWithValueAttribute(element, KIND_ATTRIBUTE_NAME, myKind.name()); if (!myPackage.isEmpty()) { JDOMExternalizerUtil.addElementWithValueAttribute(element, PACKAGE_ATTRIBUTE_NAME, myPackage); } if (!myDirectoryPath.isEmpty()) { JDOMExternalizerUtil.addElementWithValueAttribute(element, DIRECTORY_ATTRIBUTE_NAME, myDirectoryPath); } if (!myFilePath.isEmpty()) { JDOMExternalizerUtil.addElementWithValueAttribute(element, FILE_PATH_ATTRIBUTE_NAME, myFilePath); } if (!myPattern.isEmpty()) { JDOMExternalizerUtil.addElementWithValueAttribute(element, PATTERN_ATTRIBUTE_NAME, myPattern); } } @Override public void readExternal(@NotNull Element element) throws InvalidDataException { super.readExternal(element); try { String kindName = JDOMExternalizerUtil.getFirstChildValueAttribute(element, KIND_ATTRIBUTE_NAME); myKind = kindName != null ? Kind.valueOf(kindName) : Kind.DIRECTORY; } catch (IllegalArgumentException e) { myKind = Kind.DIRECTORY; } myPackage = StringUtil.notNullize(JDOMExternalizerUtil.getFirstChildValueAttribute(element, PACKAGE_ATTRIBUTE_NAME)); myDirectoryPath = StringUtil.notNullize(JDOMExternalizerUtil.getFirstChildValueAttribute(element, DIRECTORY_ATTRIBUTE_NAME)); myFilePath = StringUtil.notNullize(JDOMExternalizerUtil.getFirstChildValueAttribute(element, FILE_PATH_ATTRIBUTE_NAME)); myPattern = StringUtil.notNullize(JDOMExternalizerUtil.getFirstChildValueAttribute(element, PATTERN_ATTRIBUTE_NAME)); myTestFramework = GoTestFramework.fromName(JDOMExternalizerUtil.getFirstChildValueAttribute(element, FRAMEWORK_ATTRIBUTE_NAME)); } @NotNull public String getPattern() { return myPattern; } public void setPattern(@NotNull String pattern) { myPattern = pattern; } @NotNull public Kind getKind() { return myKind; } public void setKind(@NotNull Kind kind) { myKind = kind; } @NotNull public String getPackage() { return myPackage; } public void setPackage(@NotNull String aPackage) { myPackage = aPackage; } @NotNull public String getFilePath() { return myFilePath; } public void setFilePath(@NotNull String filePath) { myFilePath = filePath; } @NotNull public String getDirectoryPath() { return myDirectoryPath; } public void setDirectoryPath(@NotNull String directoryPath) { myDirectoryPath = directoryPath; } public void setTestFramework(@NotNull GoTestFramework testFramework) { myTestFramework = testFramework; } @NotNull public GoTestFramework getTestFramework() { return myTestFramework; } public enum Kind { DIRECTORY, PACKAGE, FILE } }